error by creating process - c++

hello i want to get startet with programming with WIN32, therefore i wrote a programm that creates a process but in the line of code where i create the process the programm gets an error an dosn't work (abend). i don't know if the code in programm 1 is wrong or the code in the second programm that should be created by the first. ( I don't know if the code in the first programm after "createprocess" is right because i didn't get further with debugging, because in this line i get the error.(i tested it without the cout,waitforobject and close handle but i didn't work either )).
First Programm:
#include <iostream>
#include <windows.h>
#include <string>
using namespace std;
void main()
{
bool ret;
bool retwait;
STARTUPINFO startupinfo;
GetStartupInfo (&startupinfo);
PROCESS_INFORMATION pro2info;
ret = CreateProcess(NULL, L"D:\\betriebssystemePRA1PRO2.exe", NULL, NULL, false, CREATE_NEW_CONSOLE, NULL,
NULL, &startupinfo, &pro2info);
cout<<"hProcess: "<<pro2info.hProcess<<endl;
cout<<"dwProcessId: "<<pro2info.dwProcessId <<endl;
retwait= WaitForSingleObject (pro2info.hProcess, 100);
retwait= WaitForSingleObject (pro2info.hProcess, 100);
CloseHandle (pro2info.hProcess);//prozesshandle schließen
retwait= WaitForSingleObject (pro2info.hProcess, 100);
ExitProcess(0);
}
Seconde Programm:
#include <iostream>
#include <windows.h>
#include <string>
using namespace std;
void main()
{
int b;
b=GetCurrentProcessId();
cout<<b<<endl;
cout<<"Druecken Sie Enter zum Beenden"<<endl;
cin.get();
//warten bis Benutzer bestätigt
Sleep (700);
ExitProcess(0);
cout<<"test";
}
Thanks in advance

Notice the type of the lpCommandLine parameter to CreateProcess -- it is LPTSTR, not LPCTSTR, i.e. it is not const.
This means that CreateProcess reserves the right to actually modify the contents of lpCommandLine. However, you have provided a pointer to a string literal as parameter, and string literals are immutable (they come from your program's read-only data segment and attempts to alter them will typically result in an access violation error.)
To fix this, simply change your code not to use an immutable string literal:
wchar_t wcsCommandLine[] = L"D:\\betriebssystemePRA1PRO2.exe";
ret = CreateProcess(NULL, wcsCommandLine, NULL, NULL, ...
Interestingly enough, CreateProcessW (UNICODE) attempts to write to lpCommandLine whereas CreateProcessA (ANSI) does not, and surprise -- your first program is built as UNICODE (were you to build it as ANSI it would work out of the box, at least on Windows XP.)
I can confirm that, with the above modification, your code works.
Also note that:
unless you need to specify D:\\betriebssystemePRA1PRO2.exe's window title, position etc. you do not need to supply a STARTUPINFO structure at all, you can simply pass lpStartupInfo as NULL and a default will be used
you should not be calling WaitForSingleObject on a closed handle

You must set the size of the startupinfo struct:
startupinfo.cb = sizeof(startupinfo);
Maybe this is why CreateProcess is failing.
And by the way - why are you calling GetStartupInfo? You should just zero out the memory of startupinfo (besides setting the size as mentioned above).
See an example here.

Related

AccessException: Attempted To Read Or Write Protected/Corrupted Memory -- Known Exception, Unknown Reason?

Yes, I know there's a million threads on this exception, I've probably looked at 20-25 of them, but none of the causes seem to correlate to this, sadly (hence the title, known exception, unknown reason).
I've recently been gaining interest in InfoSec. As my first learners-project, I'd create a basic DLL Injector. Seems to be going well so far, however, this exception is grinding me up, and after some relatively extensive research I'm quite puzzled. Oddly enough, the exception also rises after the function completely finishes.
I couldn't really figure this out myself since external debuggers wouldn't work with my target application, and that was a whole new unrelated issue.
Solutions suggested & attempted so far:
Fix/Remove thread status checking (it was wrong)
Ensure the value behind DllPath ptr is being allocated, not the ptr
Marshaling the C# interop parameters
Anyway, here is my hunk of code:
#pragma once
#include "pch.h"
#include "injection.h" // only specifies UserInject as an exportable proto.
DWORD __stdcall UserInject(DWORD ProcessId, PCSTR DllPath, BOOL UseExtended) {
DWORD length;
CHAR* buffer;
LPVOID memry;
SIZE_T write;
HANDLE hProc;
HMODULE kr32;
HANDLE thread;
length = GetFullPathName(
DllPath,
NULL,
NULL,
NULL
);
AssertNonNull(length, INVALID_PATH);
kr32 = GetModuleHandle("kernel32.dll");
AssertNonNull(kr32, YOUREALLYMESSEDUP);
buffer = new CHAR[length];
GetFullPathName(
DllPath,
length,
buffer,
NULL
);
AssertNonNull(buffer, ERR_DEAD_BUFFER);
hProc = OpenProcess(
ADMIN,
FALSE,
ProcessId
);
AssertNonNull(hProc, INVALID_PROCID);
memry = VirtualAllocEx(
hProc,
nullptr,
sizeof buffer,
SHELLCODE_ALLOCATION,
PAGE_EXECUTE_READWRITE
);
AssertNonNull(memry, INVALID_BUFSIZE);
WriteProcessMemory(
hProc,
memry,
DllPath,
sizeof DllPath,
&write
);
AssertNonNull(write, ERR_SOLID_BUFFER);
auto decidePrototype = [](BOOL UseExtended, HMODULE kr32) -> decltype(auto) {
LPVOID procAddress;
if (!UseExtended) {
procAddress = (LPVOID)GetProcAddress(kr32, LOADLIB_ORD);
}
else {
procAddress = (LPVOID)GetProcAddress(kr32, LOADLIBX_ORD);
};
return (LPTHREAD_START_ROUTINE)procAddress;
};
auto loadLibraryAddress = decidePrototype(UseExtended, kr32);
thread = CreateRemoteThread(
hProc,
NULL,
NULL,
loadLibraryAddress,
memry,
NULL,
NULL
);
AssertNonNull(thread, INVALID_ROUTINE);
WaitForSingleObject(thread, INFINITE);
// The status stuff is quite weird; it was an attempt at debugging. The error occurs with or without this code.
// I left it because 50% of the comments below wouldn't make sense. Just be assured this code is positively *not* the problem (sadly).
// LPDWORD status = (LPDWORD)1;
// GetExitCodeThread(thread, status);
return TRUE // *status;
}
One obscure macro would be "ADMIN" which expands to "PROCESS_ALL_ACCESS", shortened to fit in better. Another is "AssertNonNull":
#define AssertNonNull(o, p) if (o == NULL) return p;
I've given a shot at debugging this code, but it doesn't halt at any specific point. I've thrown MessageBox tests past each operation (e.g allocation, writing) in addition to the integrity checks and didn't get any interesting responses.
I'm sorry I can't really add much extensive detail, but I'm really stone-walled here, not sure what to do, what information to get, or if there's anything to get. In short, I'm just not sure what to look for.
This is also being called from C#, 1% pseudocode.
[DllImport(path, CallingConvention = CallingConvention.StdCall)]
static extern int UserInject(uint ProcId, string DllPath, bool UseExtended);
uint validProcId; // integrity tested
string validDllPath; // integrity tested
UserInject(validProcId, validDllPath, true);
If you're interested in my testing application (for reproduction)
#include <iostream>
#include <Windows.h>
static const std::string toPrint = "Hello, World!\n";
int main()
{
while (true)
{
Sleep(1000);
std::cout << toPrint;
}
}
To my surprise, this wasn't as much an issue with the code as much as it was with the testing application.
The basic injection technique I used is prevented by various exploit protections & security mitigations that Visual Studio 2010+ applies to any applications built in release mode.
If I build my testing application in debug mode, there is no exception. If I use a non-VS built application, there is no exception.
I still need to fix how I create my threads, because no thread is created, but I've figured this out, that should be easy enough.

C++ program is not exiting after starting new executable file

Consider two C++ projects:
Project 1:
// projectOne.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
int _tmain(int argc, _TCHAR* argv[])
{
Sleep(5000);
system("projectTwo.exe");
return 0;
}
Project 2:
// projectTwo.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "windows.h"
int _tmain(int argc, _TCHAR* argv[])
{
Sleep(5000);
system("projectOne.exe");
return 0;
}
The behavior I seek is: projectOne starts => start projectTwo => projectOne ends => projectTwo will start projectOne => projectTwo ends => projectOne will start projectTwo.
However, the programs are not ending. For example, when projectOne starts projectTwo, it will not end projectOne when return 0; is run within projectOne. So after a few minutes, there will be multiple versions of the programs running at the same time. I was thinking it had to do with the system command. Maybe it waits until the project is complete until it goes to the next line of code, and this results in circling, but I am not sure. How can I fix this? I need the programs to end after one of them is called using the system command. I hope this question is clear.
system blocks the running thread until system returns and system will not return until the executed process has terminated.
There are many ways to solve this problem. The simplest and most likely to be portable is to use a std::thread to run system in a thread that runs concurrent to the main processing thread.
std::thread procthread([processToRun] {system(processToRun.c_str());});
procthread.detach();
Short, sweet, and as portable as anything calling system can be. The first line creates a thread and executes a lambda function that runs system on the provided process name. The second line disconnects the thread from the std::thread object and allows the thread to run free. Otherwise if procthread goes out of scope the thread will be terminated and bad things will very likely happen.
If you can't do this because your development system does not support C++11 or better, you can use operating system-specific threading, but if you have to use system-specific thread creation calls, you might as well use system-specific process creation calls to directly create the new process.
In POSIX systems, posix_spawn will likely be the go-to function. I don't have a machine at my disposal to test this on at the moment, so I'll just link to Starting a process using posix_spawn.
Under Windows, use CreateProcess or your variant of choice. The following code is based on Microsoft's Creating Processes documentation page and modified to be a little less Microsoft specific and not wait for the spawned process to complete before continuing execution.
char processToRun[] = "process to run"; //NOTE: Not a std::string!
STARTUPINFO si;
PROCESS_INFORMATION pi;
memset(&si, 0, sizeof(si));
si.cb = sizeof(si);
memset(&pi, 0, sizeof(pi));
// Start the child process.
if (!CreateProcess(NULL, // No module name (use command line)
processToRun, // Command line DANGER! won't accept const char*
// cannot use std::string::c_str
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi)) // Pointer to PROCESS_INFORMATION structure
{
std::cerr << "CreateProcess failed ("<<GetLastError()<<").\n";
return false;
}
// do stuff
// Close process and thread handles.
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return true;
Your approach makes in an endless loop and it will not end!!
You are spawning multiple instances of projectOne and projectTwo which in turn are creating more.. It's recursive -_-
EDIT
System WAITS!
SOLUTION
int execl(char * pathname, char * arg0, arg1, ..., argn, NULL);

CreateProcess won't start the proccess with arguments

So I used this code in order to start a console application with arguments:
#include <iostream>
#include <windows.h>
using namespace std;
void StartProgram(char argv[])
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
CreateProcess
(
TEXT("PlayerDebug.exe"),
(LPSTR)argv,
NULL,NULL,FALSE,
CREATE_NEW_PROCESS_GROUP | CREATE_NO_WINDOW,
NULL,NULL,
&si, &pi
);
};
int main()
{
StartProgram("sound.wav");
return 0;
}
"PlayerDebug.exe" display the arguments used to call it. But when I run it with CreateProcess the way I showed, it doesen't display anything. I checked and in Task Manager it seems to appear, but still does not display the arguments. I also tried to write cout << argv; in function void StartProgram(char argv[]) and it returned "sound.wav", which is correct. But it seems the argument is not passed to PlayerDebug.exe and I don't know why.
What I did wrong?
(I'm new at C++ programming)
The second parameter to CreateProcess is the full command line, not just the parameters to the EXE. Lets take two examples :
CreateProcess ("c:\\notepad.exe",
"c:\\notepad.exe c:\\wibble.txt",
...);
will work fine (if there is a copy of notepad.exe and a file called wibble.txt in the root of C:), whereas
CreateProcess ("c:\\notepad.exe",
"c:\\wibble.txt",
...);
will launch the EXE but fail to open the file. What this means is that when the help systems calls the second parameter the command line, it ain't lying - it wants the whole command line.
Note that you can use NULL as the first parameter if the whole command line is in the second param. That's how I normally use it in fact.

Calling _beginthreadx with Passing function Pointers

I'm interested to know if it is possible to call _beginthreadex with function pointer that is not known and NOT based on class design.
For example:
#include <stdio.h>
#include <process.h>
#include <windows.h>
int myThread(void* data)
{
printf("ThreadID: %d \n", GetCurrentThreadId());
return 1;
}
HANDLE callIntThreadFunc(void (*pFunction)(LPVOID), LPVOID pvFuncArgs)
{
//Expected to fail compilation due to __stcall
return (HANDLE) _beginthreadex(NULL, NULL, pFunction, (LPVOID) pvFuncArgs, NULL, NULL);
}
int main(int argc, char *argv[])
{
HANDLE hThread = callIntThreadFunc(myThread, NULL);
WaitForSingleObject(hThread , INFINITE);
return 0;
}
I'm aware that _beginthread can work when converting the function (by the following code):
return (HANDLE) _beginthread((void (*)(void*)) pFunction, 0, (LPVOID) pvFuncArgs);
So my question is if it possible to use _beginthreadex in such cases and if so how?
Any thoughts will be appreciated.
What do you mean by "not known and NOT based on class design"? For one, _beginthreadex() is not an object-oriented API.
As to the known part, well: when using a function pointer the compiler will at least need to know where the pointed function is (its address) and how to call it (what parameters it expects and what values it returns). If you deviate from that contract, nothing is guaranteed: the call might end up working reliably or not depending on the generated code.
In your example, _beginthreadex() is telling you that it expects a function that uses the __stdcall convention, takes an address as a parameter and returns no results. You're giving it a function that returns an int and takes an address parameter but (assuming default compiler settings) uses the regular C calling convention instead of __stdcall: therefore some stack corruption is likely. By using the cast, you're just telling the compiler to stop complaining and generate the call (whatever the consequences).
If you want to do something like in your example, it's safer to give _beginthreadex() a __stdcall function that calls whatever function you actually want to use.
Found the answer i was looking for - it is doable and its conversion matter as Lois said.
The following code make it happen, compile and spread the thread ;-)
return (HANDLE) _beginthreadex(NULL, NULL,(unsigned (__stdcall*)(void*)) pFunction, pvFuncArgs, NULL, NULL);
Thanks all.

OpenProcess handle invalid for ReadProcessMemory

I've made this simple class to open a process and read memory from it:
The problem is when I call ReadDWORD with any memory address ReadProcessMemory fails with error code 6: ERROR_INVALID_HANDLE, The handle is invalid. And I can't figure out what I'm doing wrong.
If I put the OpenProcess part in the ReadDWORD function it works fine. Is there something wrong with how I store the handle? Why does it become invalid before I use it?
Memory.h
#ifndef MEMORY_H
#define MEMORY_H
#include <windows.h>
#include <psapi.h>
#pragma comment(lib, "psapi.lib")
#include <iostream>
class Memory
{
public:
Memory();
Memory(DWORD offset);
~Memory();
DWORD ReadDWORD(DWORD addr);
private:
HANDLE m_hProc;
DWORD m_Offset;
};
#endif
Memory.cpp
#include "Memory.h"
Memory::Memory()
{
Memory(0);
}
Memory::Memory(DWORD offset)
{
m_hProc = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, false, 5444); // 5444 is the PID of a process I'm testing this with
m_Offset = offset;
}
Memory::~Memory()
{
CloseHandle(m_hProc);
}
DWORD Memory::ReadDWORD(DWORD addr)
{
// Optional memory offset
addr += m_Offset;
DWORD value = -1;
int result = ReadProcessMemory(m_hProc, (LPVOID)addr, &value, sizeof(DWORD), NULL);
if (result == 0)
std::cout << "ReadProcessMemory error: " << GetLastError() << std::endl;
return value;
}
Memory::Memory()
{
Memory(0);
}
This isn't doing what you think its doing: it's not actually calling the other constructor, instead it's creating a temporary that gets discarded. So you are opening the process, but in a separate temporary object, while this object remains uninitialized.
Safer approach is to have a separate Initialize(offset) method that you call from both ctors.
(The advice in the other answers is also good; check your return values, and where you get a E_INVALID_HANDLE, check that the handle is something that looks like a handle. Or set a breakpoint at the OpenHandle and ReadProcessMemory and check that the same value is being used in both places. C++ is often full of surprises, and there's often no substitute for just stepping through the code to make sure it's doing what you think it's doing.)
To access other processes, you often need to enable certain privileges. SeDebugPrivilege comes to mind. See here. Otherwise see the suggestion from Hans Passant (i.e. GetLastError).
You can use RtlAdjustPrivilege function to get SeDebugPrivilege.
NTSTATUS NTAPI RtlAdjustPrivilege(ULONG,BOOLEAN,BOOLEAN,PBOOLEAN); /*This is the
protoype of RtlAdjustPrivilege function.*/