0xc0000142 Error when calling CreateProcess while spoofing parent pid - c

I am currently trying to launch a program while spoofing the parent pid. Below is my code that does all the work..
int main(int argc, char* argv[]) {
STARTUPINFOEX si = { sizeof(si) };
PROCESS_INFORMATION pi;
SIZE_T attributeSize;
InitializeProcThreadAttributeList(NULL, 1, 0, &attributeSize);
si.lpAttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, attributeSize);
InitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &attributeSize);
DWORD dwParentPID = 14256; //cmd.exe pid
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwParentPID);
if (!hProcess) {
return -1;
}
UpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &hProcess, sizeof(HANDLE), NULL, NULL);
LPCWSTR spawnProcess1 = L"C:\\Users\\user\\source\\repos\\random_testing\\x64\\Debug\\test.exe";
CreateProcess(spawnProcess1, NULL, NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT, NULL, NULL, (STARTUPINFO*)&si, &pi);
return 0;
}
The second program I have is just a program that prints hello world.
test.exe
int main(int argc, char* argv[]) {
printf("Hello World!\n");
getchar();
return 1;
}
When I run the above code to spoof the PPID of test.exe I get an error "The application was unable to start correctly (0xc0000142). Click OK to close the application." I am trying to spoof the cmd.exe process.
If I try do CreateProcess on something like notepad or calc, it will work. But some reason it does not for my simple hello world.

Related

C - CreateProcess returning data from child process

I've done some research looking for the best method for retrieving data from a process created by CreateProcess(), but unfortunately, I have not had much luck. If anyone can point me in the proper direction that would be much appreciated.
I have a very basic console application in C. Here is the source,
int main() {
STARTUPINFO si;
PROCESS_INFORMATION pi;
char CommandLine[1024] = "\"\" \"501 Willow\" \"\" \"Greenville\" \"AL\" \"36037\"";
memset (&si, 0, sizeof(si));
memset (&pi, 0, sizeof(pi));
GetStartupInfo(&si);
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
if (CreateProcess (("C:\\pathTO\\ValidateRDI.exe"), CommandLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) != 0) {
printf("Separate Process created\n");
}
else {
printf("Separate Process not created. Error occurred\n");
}
WaitForSingleObject( pi.hProcess, INFINITE );
return 0;
}
The CreateProcess runs another C console application that calls a DLL like so,
typedef void (CALLBACK* LPFNDLLFUNC1)(char*,char*,char*,char*,char*,char*,char*,char*,char*,char*,char*);
int main(int argc, char* argv[]){
HMODULE hDLL;
LPFNDLLFUNC1 lpfnDllFunc;
char name[35+1] = "";
char addr1[35+1] = "";
char addr2[35+1] = "";
char city[20+1] = "";
char state[2+1] = "";
char zip[10+1] = "";
char rdi[1+1] = "";
char returnCode[2+1] = "";
char returnText[101] = "";
char errorWarningCode[2+1] = "";
char errorWarningText[100+1] = "";
sprintf(name, argv[0]);
sprintf(addr1, argv[1]);
sprintf(addr2, argv[2]);
sprintf(city, argv[3]);
sprintf(state, argv[4]);
sprintf(zip, argv[5]);
hDLL = LoadLibraryA((LPCSTR)"ValidateRDI.dll");
if (hDLL != NULL)
{
lpfnDllFunc = (LPFNDLLFUNC1)GetProcAddress(hDLL,"ValidateAddress");
if(lpfnDllFunc)
{
lpfnDllFunc(name,addr1,addr2,city,state,zip,rdi,returnCode,returnText,errorWarningCode,errorWarningText);
}
// free library
FreeLibrary(hDLL);
}
return 1;
}
Just for a heads up, I removed some error checking to slim down the code. How would I pass back the following values (or share the variables) to the console application that calls CreateProcess():
name
addr1
addr2
city
state
zip
rdi
returnCode
returnText
errorWarningCode
errorWarningText
Any and all help is appreciated. I've thought of writing the values to a file and then accessing the data once WaitForSingleObject( pi.hProcess, INFINITE ); returns, but there must be a more efficient/better method.

Child process inherits a handle from its parent process but fails to write in it

I want to have 2 processes write in the same file. I created a file in the first process (parent) and call the second process (child) . I have made the file inheritable and the second process inherits the handle as a command line argument.
Although the handle is not equal to INVALID_HANDLE_VALUE, the second process can't do anything with the file. WriteFile() ends with Error 6(the handle is invalid). The same is for LockFile(),Unlockfile().
What is wrong with the code and how can I fix it? I want to make 2 processes work with the same file.
Process 1:
#include <Windows.h>
#include <process.h>
int _tmain(int argc, _TCHAR* argv[])
{
_SECURITY_ATTRIBUTES sec_attr;
sec_attr.nLength = sizeof(_SECURITY_ATTRIBUTES);
sec_attr.bInheritHandle = true;
sec_attr.lpSecurityDescriptor = 0;
//argv[1] - the name of the file I want to create
HANDLE h = CreateFile(argv[1],GENERIC_READ | GENERIC_WRITE,FILE_SHARE_WRITE |
FILE_SHARE_READ,&sec_attr,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0);
STARTUPINFO sinfo;
ZeroMemory(&sinfo,sizeof(sinfo));
sinfo.cb = sizeof(sinfo);
PROCESS_INFORMATION pinfo;
char cmd[300] = "PATH to process 2";
CreateProcess(0,cmd,0,0,true,NORMAL_PRIORITY_CLASS,0,0,&sinfo,&pinfo);
char c = '1';
DWORD w;
WriteFile(h,&c,1,&w,0); //works fine
...
}
Process 2:
#include <Windows.h>
#include <process.h>
int _tmain(int argc, _TCHAR* argv[])
{
HANDLE h = argv[1];
if(h == INVALID_HANDLE_VALUE) {
//it's okay, h is NOT equal to INVALID_HANDLE_VALUE
}
char c = '2';
DWORD w;
WriteFile(h,&c,1,&w,0); //error 6
...
}
P.S. The first process succeeds in writing in the file. By that time the second process has already failed.
You may be creating the child process with an inheritable file handle, but you are not actually telling the child what the value of that handle is! The child is looking for that value in argv[1], but the code you have shown is not passing any value in that parameter! Even if there were, you are not retrieving the value correctly anyway.
Command-line parameters are always strings, so argv[1] is a pointer to a null-terminated string, not a handle. You have to convert the handle pointer to a string representation when you put it on the command-line, and then you have to parse that string back to a pointer when processing the command-line.
Try something more like this:
Process 1:
#include <Windows.h>
#include <process.h>
#include <stdio.h>
#include <tchar.h>
int _tmain(int argc, _TCHAR* argv[])
{
SECURITY_ATTRIBUTES sec_attr = {};
sec_attr.nLength = sizeof(sec_attr);
sec_attr.bInheritHandle = TRUE;
sec_attr.lpSecurityDescriptor = 0;
//argv[1] - the name of the file I want to create
HANDLE h = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, &sec_attr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (h == INVALID_HANDLE_VALUE)
{
// handle the error ...
return 1;
}
STARTUPINFO sinfo;
ZeroMemory(&sinfo, sizeof(sinfo));
sinfo.cb = sizeof(sinfo);
PROCESS_INFORMATION pinfo;
ZeroMemory(&pinfo, sizeof(pinfo));
_TCHAR cmd[MAX_PATH + 16] = {};
_tsprintf(cmd, _T("\"%s\" %p"), _T("PATH to process 2"), h);
// TODO: consider using STARTUPINFOEX instead so the child inherits
// ONLY the file handle and not ALL inheritable handles it doesn't
// care about:
//
// Programmatically controlling which handles are inherited by new processes in Win32
// https://blogs.msdn.microsoft.com/oldnewthing/20111216-00/?p=8873
//
if (!CreateProcess(0, cmd, 0, 0, TRUE, NORMAL_PRIORITY_CLASS, 0, 0, &sinfo, &pinfo))
{
// handle the error ...
return 1;
}
CloseHandle(pinfo.hThread);
CloseHandle(pinfo.hProcess);
char c = '1';
DWORD w;
WriteFile(h, &c, 1, &w, 0);
...
CloseHandle(h);
return 0;
}
Process 2:
#include <Windows.h>
#include <process.h>
#include <stdio.h>
#include <tchar.h>
int _tmain(int argc, _TCHAR* argv[])
{
if (argc < 2)
{
// ...
return 1;
}
//argv[1] - string representation of a handle to an open file
HANDLE h = INVALID_HANDLE_VALUE;
_stscanf(argv[1], _T("%p"), &h);
char c = '2';
DWORD w;
WriteFile(h, &c, 1, &w, 0);
...
CloseHandle(h);
return 0;
}
That being said, having two threads, let alone two processes, share a single file handle is NOT a good idea. A given file handle only has 1 read/write position in it, so sharing that handle is going to risk the threads/processes stepping all over each other, unless you provide some kind of synchronization between them so only one can access the file at a time.
Consider passing the target filename to the child process and let it open its own unique handle to the file, eg:
Process 1:
#include <Windows.h>
#include <process.h>
#include <stdio.h>
#include <tchar.h>
int _tmain(int argc, _TCHAR* argv[])
{
if (argc < 2)
{
// ...
return 1;
}
//argv[1] - the name of the file I want to create
HANDLE h = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
if (h == INVALID_HANDLE_VALUE)
{
// handle the error ...
return 1;
}
STARTUPINFO sinfo;
ZeroMemory(&sinfo, sizeof(sinfo));
sinfo.cb = sizeof(sinfo);
PROCESS_INFORMATION pinfo;
ZeroMemory(&pinfo, sizeof(pinfo));
_TCHAR cmd[(MAX_PATH *2) + 10] = {};
_tsprintf(cmd, _T("\"%s\" \"%s\""), _T("PATH to process 2"), argv[1]);
if (!CreateProcess(0, cmd, 0, 0, TRUE, NORMAL_PRIORITY_CLASS, 0, 0, &sinfo, &pinfo))
{
// handle the error ...
return 1;
}
char c = '1';
DWORD w;
WriteFile(h, &c, 1, &w, 0);
...
CloseHandle(h);
return 0;
}
Process 2:
#include <Windows.h>
#include <process.h>
#include <stdio.h>
#include <tchar.h>
int _tmain(int argc, _TCHAR* argv[])
{
if (argc < 2)
{
// ...
return 1;
}
//argv[1] - the name of the file I want to open
HANDLE h = CreateFile(argv[1], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if (h == INVALID_HANDLE_VALUE)
{
// handle the error ...
return 1;
}
char c = '2';
DWORD w;
WriteFile(h, &c, 1, &w, 0);
...
CloseHandle(h);
return 0;
}
Otherwise, consider having process 1 duplicate the file handle and then have process 2 inherit the duplicate instead of the original.

External command-line child process in C doesn't give output until it ends

I'm having strange issues spawning a process, i found almost nothing related to this...
I need to spawn a command-line child process and be capable of getting its output and sending input before it ends.
I can do it fine with cmd.exe, and runs smooth...
BUT when i try to do it with external command-line applications they doesn't output nothing to my program until end of execution. I can send input, it processes normally, the number of times i want to, and at finish of child i get ALL the accumulated output.
The related code is:
SECURITY_ATTRIBUTES secatr;
secatr.nLength = sizeof(SECURITY_ATTRIBUTES);
secatr.bInheritHandle = TRUE;
secatr.lpSecurityDescriptor = NULL;
CreatePipe(&stdin_read, &stdin_write, &secatr, 0);
CreatePipe(&stdout_read, &stdout_write, &secatr, 0);
SetHandleInformation(stdout_read, HANDLE_FLAG_INHERIT, 0);
SetHandleInformation(stdin_write, HANDLE_FLAG_INHERIT, 0);
STARTUPINFO si;
PROCESS_INFORMATION pi;
memset(&pi, 0, sizeof(PROCESS_INFORMATION));
memset(&si, 0, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
si.hStdError = si.hStdOutput = stdout_write;
si.hStdInput = stdin_read;
CreateProcess(NULL,c:\\\\app.exe, NULL, NULL, TRUE, 0, NULL, "c:\\\\", &si, &pi);
handleproceso = pi.hProcess;
handlethread = (HANDLE)_beginthreadex(NULL,0,&Read,NULL,0,NULL);
_beginthreadex(NULL,0,&Write,NULL,0,NULL);
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle( pi.hProcess );
CloseHandle( pi.hThread );
unsigned __stdcall Read(void *a){
char buff[100];
while(1){
memset(buff,0,sizeof(buff));
ReadFile( stdout_read, buff, sizeof(buff)-1, &dwRead, NULL);
send(socketcliente,buff,strlen(buff),0);
if(exit1){
exit1 = false;
break;
}
}
return 0;
}
unsigned __stdcall Write(void *a){
char ddd[100];
while(1){
memset(ddd,0,sizeof(ddd));
if(recv(socketcliente,ddd,sizeof(ddd)-1,0) == SOCKET_ERROR){
CloseHandle(handlethread);
TerminateProcess(handleproceso,1);
break;
}
WriteFile(stdin_write, ddd, strlen(ddd), &dwWritten, NULL);
if(strncmp(ddd,"exit",4) == 0){
exit1 = true;
//CloseHandle(handlethread);
break;
}
}
return 0;
}
I tried the MSDN example of How to spawn console processes with redirected standard handles , with the child process fflushing output buffer it receives the output fine...if I remove that fflush i get the same problem of other programs.
The portion of code looks as:
printf("Child echoing [%s]\n",szInput);
fflush(NULL); // Must flush output buffers or else redirection
// will be problematic.
What can I do if the program I want to spawn doesn't behave that way?Can I force its output or something?
I cannot find any response to that in the whole internet...Thank you in advance and apologies for my basic english.
Try:
fflush(stdout);
or at the beginning of your program just disable buffering:
setbuf(stdout, NULL);

Given I have PID and Process handle, can I write to stdin of existing process using C in WINAPI

I am trying to send a message to stdin of an existing process. This process writes to stdout, and therefore a command prompt is visible when the process is running.
I have looked here, but it is specific to .net. I would like to use C with the winapi.
Here is what I have tried:
I launch an exe that runs in a command prompt. When launched, the Process ID and Process Handle for the exe are captured by calling GetHandleOfProcessByExeName() (below). My understanding , through reading the MSDN page on WriteFile(), that I should be able to pass the handle of the process along with some text to the process pointed to by the handle. Say "prg.exe", is running on Windows 7. I get its process handle, then pass it along with a message to WriteToProcess().
I expect to see text appear on the command prompt, but this has not happened yet.
Relevant code:
int main(void)
{
HANDLE h = GetHandleOfProcessByExeName("prg.exe");
//this continually fails (returns FALSE)
BOOL status = WriteToProcess("test message", sizeof("test message"));
return 0;
}
HANDLE GetHandleOfProcessByExeName(char *exe)
{
PROCESSENTRY32 entry;
HANDLE hProcess=0;
entry.dwSize = sizeof(PROCESSENTRY32);
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (Process32First(snapshot, &entry) == TRUE)
{
while (Process32Next(snapshot, &entry) == TRUE)
{
if (stricmp(entry.szExeFile, exe) == 0)
{
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
CloseHandle(hProcess);
}
}
}
CloseHandle(snapshot);
return hProcess;
}
BOOL WriteToProcess(char *msg, size_t size)
{
BOOL status = FALSE;
status = WriteFile(gStdinWrite, msg, size, NULL, NULL);
return status; //TRUE for success
}
Edit to response to comments:
defined as file globals:
HANDLE gStdinRead = NULL;
HANDLE gStdinWrite = NULL;
int SystemX(char *cmd, int index)
{
STARTUPINFO sj;
PROCESS_INFORMATION pj;
SECURITY_ATTRIBUTES saAttr;
HANDLE h = 0;
int exit;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
ZeroMemory( &sj, sizeof(sj) );
sj.cb = sizeof(sj);
ZeroMemory( &pj, sizeof(pj) );
//create pipe and pass read end to CreateProcess
CreatePipe(&gStdinRead, &gStdinWrite, &saAttr, 0);
sj.hStdInput = gStdinRead;
sj.hStdOutput = gStdinWrite;
if(!CreateProcess(NULL, cmd, NULL, NULL, FALSE, 0, NULL, NULL, &sj, &pj))
{
return h;
}
//Wait until child processes exit.
WaitForSingleObject( pj.hProcess, IGNORE ); //ingnore signal
//Get exit code
GetExitCodeProcess(pj.hProcess, (LPDWORD)(&exit));
return exit;
}

Get the PID of the process started by CreateProcess()

Let me start off by stating that I'm not from C background. I'm a PHP developer. So everything that I've coded so far is by taking bits and pieces from other examples and fine tuning them to meet my requirements. So please bear with me if I ask way too basic or obvious questions.
I'm starting FFmpeg using CreateProcess() through
int startFFmpeg()
{
snprintf(cmd, sizeof(cmd), "D:\\ffpmeg\bin\ffmpeg.exe -i D:\\video.mpg -r 10 D:\\frames");
PROCESS_INFORMATION pi;
STARTUPINFO si={sizeof(si)};
si.cb = sizeof(STARTUPINFO);
int ff = CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
return ff;
}
What I need to do is get the PID of that process and then check later to see if it still running after some time. This is basically what I'm looking for:
int main()
{
int ff = startFFmpeg();
if(ff)
{
// great! FFmpeg is generating frames
// then some time later
if(<check if ffmpeg is still running, probably by checking the PID in task manager>) // <-- Need this condition
{
// if running, continue
}
else
{
startFFmpeg();
}
}
return 0;
}
I did some research and found out that PID is returned within the PROCESS_INFORMATION, but I couldn't find an example showing how to fetch it.
Some metadata
OS : Windows 7
Language : C
IDE : Dev C++
Pull it from the PROCESS_INFORMATION structure you pass as the last parameter to CreateProcess(), in your case pi.dwProcessId
However, to check if it is still running, you may want to just wait on the process handle.
static HANDLE startFFmpeg()
{
snprintf(cmd, sizeof(cmd), "D:\\ffpmeg\bin\ffmpeg.exe -i D:\\video.mpg -r 10 D:\\frames");
PROCESS_INFORMATION pi = {0};
STARTUPINFO si = {0};
si.cb = sizeof(STARTUPINFO);
if (CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
{
CloseHandle(pi.hThread);
return pi.hProcess;
}
return NULL;
}
In your launching main() you can then do something like...
int main()
{
HANDLE ff = startFFmpeg();
if(ff != NULL)
{
// wait with periodic checks. this is setup for
// half-second checks. configure as you need
while (WAIT_TIMEOUT == WaitForSingleObject(ff, 500))
{
// your wait code goes here.
}
// close the handle no matter what else.
CloseHandle(ff);
}
return 0;
}
You might like to use the win32 api function GetProcessId().
#include <windows.h>
...
BOOL bSuccess = FALSE;
LPTSTR pszCmd = NULL;
PROCESS_INFORMATION pi = {0};
STARTUPINFO si = {0};
si.cb = sizeof(si);
pszCmd = ... /* assign something useful */
bSuccess = CreateProcess(NULL, pszCmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
if (bSuccess)
{
DWORD dwPid = GetProcessId(pi.hProcess);
...
}
else
... /* erorr handling */
For details please see here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms683215%28v=vs.85%29.aspx

Resources