Crashes after Injecting std functions in a process - c++

i am currently trying out PE injection and noticed that as soon as i use stuff like std::cout or std::string my target process which i injected in crashes.
Messageboxes or even printf() works fine. The code compiles without an error and i read about the import table not being at the same location in the injected process could cause it to crash but i have no idea what to do in order to fix it (re load the import table). Thanks in advance and here is the injection example:
#include <iostream>
#include <stdio.h>
#include <Windows.h>
void ThreadProc(PVOID p)
{
MessageBox(NULL,"Message from injected code!","Message",MB_ICONINFORMATION); //funktioniert einwandfrei
RedirectOutput();
std::cout << "hi"; //crashed
}
int main(int argc,char* argv[])
{
PIMAGE_DOS_HEADER pIDH;
PIMAGE_NT_HEADERS pINH;
PIMAGE_BASE_RELOCATION pIBR;
HANDLE hProcess,hThread;
PUSHORT TypeOffset;
PVOID ImageBase,Buffer,mem;
ULONG i,Count,Delta,*p;
printf("\nOpening target process\n");
hProcess=OpenProcess(
PROCESS_CREATE_THREAD|PROCESS_QUERY_INFORMATION|PROCESS_VM_OPERATION|PROCESS_VM_READ|PROCESS_VM_WRITE,
FALSE,
13371337);
if(!hProcess)
{
printf("\nError: Unable to open target process (%u)\n",GetLastError());
return -1;
}
ImageBase=GetModuleHandle(NULL);
printf("\nImage base in current process: %#x\n",ImageBase);
pIDH=(PIMAGE_DOS_HEADER)ImageBase;
pINH=(PIMAGE_NT_HEADERS)((PUCHAR)ImageBase+pIDH->e_lfanew);
printf("\nAllocating memory in target process\n");
mem=VirtualAllocEx(hProcess,NULL,pINH->OptionalHeader.SizeOfImage,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
if(!mem)
{
printf("\nError: Unable to allocate memory in target process (%u)\n",GetLastError());
CloseHandle(hProcess);
return 0;
}
printf("\nMemory allocated at %#x\n",mem);
Buffer=VirtualAlloc(NULL,pINH->OptionalHeader.SizeOfImage,MEM_COMMIT|MEM_RESERVE,PAGE_READWRITE);
memcpy(Buffer,ImageBase,pINH->OptionalHeader.SizeOfImage);
printf("\nRelocating image\n");
pIBR=(PIMAGE_BASE_RELOCATION)((PUCHAR)Buffer+pINH->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
Delta=(ULONG)mem-(ULONG)ImageBase;
printf("\nDelta: %#x\n",Delta);
while(pIBR->VirtualAddress)
{
if(pIBR->SizeOfBlock>=sizeof(IMAGE_BASE_RELOCATION))
{
Count=(pIBR->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))/sizeof(USHORT);
TypeOffset=(PUSHORT)(pIBR+1);
for(i=0;i<Count;i++)
{
if(TypeOffset[i])
{
p=(PULONG)((PUCHAR)Buffer+pIBR->VirtualAddress+(TypeOffset[i] & 0xFFF));
*p+=Delta;
}
}
}
pIBR=(PIMAGE_BASE_RELOCATION)((PUCHAR)pIBR+pIBR->SizeOfBlock);
}
printf("\nWriting relocated image into target process\n");
if(!WriteProcessMemory(hProcess,mem,Buffer,pINH->OptionalHeader.SizeOfImage,NULL))
{
printf("\nError: Unable to write process memory (%u)\n",GetLastError());
VirtualFreeEx(hProcess,mem,0,MEM_RELEASE);
CloseHandle(hProcess);
return -1;
}
VirtualFree(Buffer,0,MEM_RELEASE);
printf("\nCreating thread in target process\n");
hThread=CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)((PUCHAR)ThreadProc+Delta),NULL,0,NULL);
if(!hThread)
{
printf("\nError: Unable to create thread in target process (%u)\n",GetLastError());
VirtualFreeEx(hProcess,mem,0,MEM_RELEASE);
CloseHandle(hProcess);
return -1;
}
printf("\nWaiting for the thread to terminate\n");
WaitForSingleObject(hThread,INFINITE);
printf("\nThread terminated\n\nFreeing allocated memory\n");
VirtualFreeEx(hProcess,mem,0,MEM_RELEASE);
CloseHandle(hProcess);
return 0;
}

I think that answer simple - STL library request some initializations of global data. Via constructors of global objects, for example. But you just copy your code to target process. It don't invoke any initializations, that normally performed before call main function. Just try DLL injection instead.

You don't seem to be loading the CRT dll in the target process, so what I'm assuming is that when you try to call the cout function, you are jumping to unallocated memory.
If the DLL is in fact loaded in the target process, make sure it's loaded at the same address as it is in your own process. Otherwise you'll have to patch your import table to match that of the target process.

Related

Access violation error with injected dll C++

So recently I made my own dll injector to be able to debug my other app by injecting a debug dll in it; Using c++/cli for the interface and c++ for the code.
I tested the same code I used on this project on a C++ console app project and it worked without any problems.
The injection occurs inside the Init.cpp file, which essentially gets the provided dll path under the form of C:\\user\\documents\\debug.dll and checks if it exists. After that it gets the process id by passing the name, in this case myotherapp.exe, as a parameter. If successful it then get's the Handle to the process and store's it in g.h_process, it continues by allocating readable/writable memory in the process and then writing to this memory the path of the dll and finally use's LoadLibraryA to load the dll inside the process.
Init.cpp:
void Injector::Init(void)
{
Inject::Checks((char*)g.dll_path, g.procName);//checking for dll validity
}
bool Injector::Inject::Checks(char* dll_path, PCSTR procName)
{
if (!Utils::file_exists(dll_path))
return Utils::error("File does not exist.");
Utils::successInput("Prepared DLL for injection");
Utils::getProcId(procName, g.proc_id);
if (!g.proc_id) {
return Utils::error("Could not find specified process.");
}
g.h_process = OpenProcess(PROCESS_ALL_ACCESS, NULL, g.proc_id);
if (!g.h_process) {
return Utils::error("Failed to open a handle to process");
}
g.allocatedMemory = VirtualAllocEx(g.h_process, nullptr, MAX_PATH, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);//mem_reserver reserve memory then commit memory to be able to write to that memory
Allocate(g.allocatedMemory, dll_path);
Llib();
Release(dll_path, g.allocatedMemory);
return 0;
}
bool Injector::Inject::Allocate(void* allocatedMemory, char* dll_path)
{
if (!allocatedMemory)
return Utils::error("Failed to allocate memory");
if (!WriteProcessMemory(g.h_process, g.allocatedMemory, g.dll_path, MAX_PATH, nullptr))
return Utils::error("Failed to write process");
return true;
}
bool Injector::Inject::Llib() {
HANDLE h_thread = CreateRemoteThread(g.h_process, nullptr, NULL, LPTHREAD_START_ROUTINE(LoadLibraryA), g.allocatedMemory, NULL, nullptr);
if (!h_thread)
return Utils::error("Failed to create remote thread");
return true;
}
bool Injector::Inject::Release(PCSTR dll_path, void* allocatedMemory)
{
CloseHandle(g.h_process);
VirtualFreeEx(g.h_process, allocatedMemory, NULL, MEM_RELEASE);
return true;
}
The g.debug is just a flag which tells us if the console is enabled or not. found in the globals.hpp which just contains global variables.
You can also check the Utils namespace here.
The error:
The problem I'm experiencing here is whenever I inject my DLL into the process, my injector works fine with no errors but when I attach vs to the process I want to inject to I get an Access Violation error with the process exiting with an error code.
I don't understand, I can't see where I am accessing invalid memory.
Thanks in advance.

Ejecting dll by calling CreateRemoteThread : crash

I am trying to make for myself a tool for extracting/releasing dlls from processes. I have already experienced with LoadLibrary and injecting but this time the logic doesn't seem to apply.
This is my code:
HMODULE findModuleOffset(HANDLE proc, char *mod_name) {
//Finds module address in specified process. 0 if not found
HMODULE hMods[2048];
DWORD modules_byte_size;
if (EnumProcessModules(proc, hMods, sizeof(hMods), &modules_byte_size))
{
for (unsigned long i = 0; i < (modules_byte_size / sizeof(HMODULE)); i++) {
CHAR module_name[MAX_PATH];
// Get the full path to the module's file.
if (GetModuleFileNameExA(proc, hMods[i], module_name, sizeof(module_name))) {
if (strcmp(strrchr(module_name,'.')+1,"exe")!=0 && compareExeName(module_name, mod_name)) {
return hMods[i];
}
}
}
}
return 0;
}
bool compareExeName(char *path, char *partial_name) {
//This will substract the filename from path and compare it with partial_name
char *lastSlash = strrchr(path, '\\') + 1;
if (lastSlash != NULL && strstr(lastSlash, partial_name) == lastSlash) return 1;
return 0;
}
void unload_all_dll(char *dll_name) {
DWORD process_ids[2048];
DWORD process_byte_size; //size of filled process_ids in BYTES (after the call)
DWORD process_count; //count of all elements in process_ids
HMODULE ext_dll_module;
HANDLE opened_process;
HANDLE Hthread;
DWORD thread_exit_code = 1;
CHAR exe_path[1024];
if (EnumProcesses(process_ids, sizeof(process_ids), &process_byte_size)) {
process_count = process_byte_size / sizeof(DWORD);
for (int i = 0; i < process_count; i++) {
thread_exit_code = 0;
if ((opened_process = OpenProcess(PROCESS_ALL_ACCESS, false, process_ids[i])) == NULL) continue;
GetModuleFileNameExA(opened_process, 0, exe_path, MAX_PATH);
if ((ext_dll_module = findModuleOffset(opened_process, dll_name)) != 0) {
while (thread_exit_code == 0) {
if ((Hthread = CreateRemoteThread(opened_process, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleA("kernel32.dll"), "FreeLibrary"), (void*)ext_dll_module, 0, NULL)) == NULL) {
cout<<"Process closed meanwhile or dll unloaded";
break; //process has closed meanwhile
}
while (WaitForSingleObject(Hthread, 1000) == WAIT_TIMEOUT);
GetExitCodeThread(Hthread, &thread_exit_code);
}
cout << "Dll unloaded from " << exe_path << endl;
}
}
}
}
Warning:some variables names might be confusing(I am in hurry)
But every time I try to eject a dll everything crashes(of course,only the apps that contained the specfied dll). I tested everything I could and everything seems fine: the module address returned by findModuleOffset is good(checked against the value given by process explorer). I have no ideea what the return value of createremotethread or thread_exit_code is because the app crashes(it contasins the dll to be ejected..so...). Can you help me?
(moving from the comments)
Given that there are threads in the target process that are running code from the dll being unloaded, they are going to crash immediately after the dll gets freed - after all, the very pages of code that the CPU is executing are being unmapped!
To avoid the problem, the running threads have to be notified in some way, so they can terminate before unloading the dll; Windows provides many IPC methods, one rarely used is particularly well-fitted for this case, namely mailslots.
When the dll is injected, the "master" thread that gets created will create a mailslot with a well-known name, and periodically check if there's any message for him. When you want to unload the dlls, instead of brutally injecting a thread that forcefully frees the dll, just ask to your "inside man": post a message to the mailslot asking it to terminate1.
The thread will see that there's a message in the mailslot, take care to possibly terminate the other threads that were started inside the target process (a shared atomic variable + WaitForSingleObject can be used) and, when the cleanup is finished, call FreeLibraryAndExitThread to suicide both the last thread and the dll.
Notes
A particularly interesting peculiarity of mailslots is that, if they are created multiple times with the same name, messages sent to such a name will be delivered to all them, so if, as it seems, you want to shut down all the injected dlls at the same time, this greatly simplifies the controlling program - there's not even need to enumerate the running processes.

Can i block a program using ASM?

I am trying for a few days to block a cheat program for my game, i talked with several coders, and one said i can block it using ASM. The program hides very good, i cannot find it in memory, i cannot detect it scanning processes, so maybe this could be the solution? Can someone give me a example how can i detect and block a program with c++ and ASM?
This is my current method to detect and block cheats, using memory dumps:
void SystemProcessesScan()
{
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(hProcessSnap != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(PROCESSENTRY32);
if(Process32First(hProcessSnap, &pe32))
{
do
{
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
if(hProcess != NULL)
{
if(ScanProcessMemory(hProcess))
{
ExitProcess(0);
}
}
}
while(Process32Next(hProcessSnap, &pe32));
}
}
CloseHandle(hProcessSnap);
}
bool ScanProcessMemory(HANDLE hProcess)
{
for(int i = 0; i < MAX_PROCESS_DUMP; i++)
{
char aTmpBuffer[MAX_DUMP_SIZE];
SIZE_T aBytesRead = 0;
ReadProcessMemory(hProcess, (LPCVOID)g_ProcessesDumps[i].m_aOffset, (LPVOID)aTmpBuffer, sizeof(aTmpBuffer), &aBytesRead);
if(memcmp(aTmpBuffer, g_ProcessesDumps[i].m_aMemDump, MAX_DUMP_SIZE) == 0)
{
return true;
break;
}
}
return false;
}
The cheat injects a DLL into your game and it sounds like it uses manual mapping to hide the DLL in memory.
The best solution to detect it is to find a sequence of bytes that are unique to this DLL. Pattern scan your own game processes, if the signature is found, close the game or whatever you want to do at that point.
Search for C++ internal pattern scanning or signature scanning, there are dozens of sources floating around that are uses regularly for this purpose.
Due to it being manually mapped, you must scan all committed memory regions rather than looping through the list of modules. Use VirtualQuery() in a while loop starting with address 0 until it fails.

Unloading an Injected DLL

I have a DLL I inject into other processes using SetWindowsHookEx. Inside the DLL I increment the module's reference counter by calling GetModuleHandleEx so I can control when the module is unloaded.
At this point the module reference count "should be" 2 from both of those API calls. When the calling process shuts down, it calls UnhookWindowsHookEx, decrementing the reference count to 1. The DLL has a thread that waits on a few things, one of them being the handle of the process that called SetWindowsHookEx. When the process goes away the DLL does some cleanup, terminates all threads, cleans up memory and handles and then calls FreeLibraryAndExitThread. This decrements the counter and the DLL gets unloaded.
Here's my problem. There are a few processes, especially those without a UI, where the DLL never gets unloaded. I'm pretty confident I have cleaned up everything. And I know for a fact that none of my threads are running.
First of all, if you have any troubleshooting tips to help uncover the cause, that would be helpful. Otherwise, I was thinking about using some API like NtQueryInformationProcess to get the module address and confirm the module handle count is in fact zero, then call CreateRemoteThread to inject a call to LdrUnloadDll to unload the module address from within the process. What are your thoughts to this approach? Does anyone have any example code? I'm having difficulty finding out how to get the module handle count.
Okay.. here goes.. There are many ways to get the module info from a process. The undocumented way and the "documented" way.
Results (documented):
Here is the "documented" way..
#include <windows.h>
#include <TlHelp32.h>
#include <iostream>
#include <sstream>
int strcompare(const char* One, const char* Two, bool CaseSensitive)
{
#if defined _WIN32 || defined _WIN64
return CaseSensitive ? strcmp(One, Two) : _stricmp(One, Two);
#else
return CaseSensitive ? strcmp(One, Two) : strcasecmp(One, Two);
#endif
}
PROCESSENTRY32 GetProcessInfo(const char* ProcessName)
{
void* hSnap = nullptr;
PROCESSENTRY32 Proc32 = {0};
if ((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) == INVALID_HANDLE_VALUE)
return Proc32;
Proc32.dwSize = sizeof(PROCESSENTRY32);
while (Process32Next(hSnap, &Proc32))
{
if (!strcompare(ProcessName, Proc32.szExeFile, false))
{
CloseHandle(hSnap);
return Proc32;
}
}
CloseHandle(hSnap);
Proc32 = { 0 };
return Proc32;
}
MODULEENTRY32 GetModuleInfo(std::uint32_t ProcessID, const char* ModuleName)
{
void* hSnap = nullptr;
MODULEENTRY32 Mod32 = {0};
if ((hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ProcessID)) == INVALID_HANDLE_VALUE)
return Mod32;
Mod32.dwSize = sizeof(MODULEENTRY32);
while (Module32Next(hSnap, &Mod32))
{
if (!strcompare(ModuleName, Mod32.szModule, false))
{
CloseHandle(hSnap);
return Mod32;
}
}
CloseHandle(hSnap);
Mod32 = {0};
return Mod32;
}
std::string ModuleInfoToString(MODULEENTRY32 Mod32)
{
auto to_hex_string = [](std::size_t val, std::ios_base &(*f)(std::ios_base&)) -> std::string
{
std::stringstream oss;
oss << std::hex << std::uppercase << val;
return oss.str();
};
std::string str;
str.append(" =======================================================\r\n");
str.append(" Module Name: ").append(Mod32.szModule).append("\r\n");
str.append(" =======================================================\r\n\r\n");
str.append(" Module Path: ").append(Mod32.szExePath).append("\r\n");
str.append(" Process ID: ").append(std::to_string(Mod32.th32ProcessID).c_str()).append("\r\n");
str.append(" Load Count (Global): ").append(std::to_string(static_cast<int>(Mod32.GlblcntUsage != 0xFFFF ? Mod32.GlblcntUsage : -1)).c_str()).append("\r\n");
str.append(" Load Count (Process): ").append(std::to_string(static_cast<int>(Mod32.ProccntUsage != 0xFFFF ? Mod32.ProccntUsage : -1)).c_str()).append("\r\n");
str.append(" Base Address: 0x").append(to_hex_string(reinterpret_cast<std::size_t>(Mod32.modBaseAddr), std::hex).c_str()).append("\r\n");
str.append(" Base Size: 0x").append(to_hex_string(Mod32.modBaseSize, std::hex).c_str()).append("\r\n\r\n");
str.append(" =======================================================\r\n");
return str;
}
int main()
{
PROCESSENTRY32 ProcessInfo = GetProcessInfo("notepad.exe");
MODULEENTRY32 ME = GetModuleInfo(ProcessInfo.th32ProcessID, "uxtheme.dll");
std::cout<<ModuleInfoToString(ME);
}
The problem with the undocumented API is that I've never figured out why the load counts are always "6" for dynamic modules and "-1" for static modules.. For this reason, I will not post it..
It is BEST NOT to use undocumented API if you want just the load count. The undocumented API's only advantage is that you can use it to "un-link/hide" a module within a process (like viruses do).. It will "unlink/hide" it.. NOT "unload" it. This means that at any time, you can "re-link" it back into the process's module list.
Since you only need the module-reference-count, I've only included "documented" API which does exactly that.
I found the cause of the problem and the solution. I honestly feel quite stupid for missing it and struggling with it for so long.
As I mentioned in the original problem, the processes that are problematic do not have a UI. Turns out they do have a message pump running. The problem is nothing is sending messages to these processes without a UI after we call UnhookWindowsHookEx that would trigger the unloading. (In fact, I believe MSDN does state that window messages are not sent to processes when calling UnhookWindowsHookEx.)
By broadcasting WM_NULL to all processes after the injecting process calls UnhookWindowsHookEx the message pump wakes up in the injected processes and the DLL reference count is decremented. The DLL is unloaded immediately when the injected DLL finally calls FreeLibraryAndExitThread.
This is only part of the solution. If the injecting process is killed or crashes, no message is broadcasted so the DLL does not get unloaded from processes that do not have a UI. As I mention before I have a thread running in the DLL that waits on the injecting process handle. When the injecting process ends the DLL is signaled and then calls PostThreadMessage to send WM_NULL to each thread in the process. Then it waits until the DLL reference count is decremented before continuing and cleaning up before calling FreeLibraryAndExitThread. As a result, the DLL is unloaded almost immediately from all processes, UI or no UI.

Close handle to a mutex in another process

I want to close a handle to a mutex located in another process, so I can run more than one instance of the application.
I already know this can be done, see Process Explorer. Example: Windows Minesweeper (Windows 7) uses a mutex to only allow one game, so I thought I would use it as an example since it's pre-installed with Windows and therefore easier for you guys to guide me.
The mutex that I need to close is \Sessions\1\BaseNamedObjects\Oberon_Minesweeper_Singleton, which I found using Process Explorer.
After closing this mutex I was able to launch two games of Minesweeper, but I want to do this in my program using C++.
After some searching I have found that I might need the API DuplicateHandle. So far I haven't been able to close the handle on this mutex.
Here is my code so far:
#include <Windows.h>
#include <iostream>
using namespace std;
void printerror(LPSTR location){
printf("Error: %s_%d", location, GetLastError());
cin.get();
}
int main(){
DWORD pid = 0;
HWND hMineWnd = FindWindow("Minesweeper", "Minesveiper");
GetWindowThreadProcessId(hMineWnd, &pid);
HANDLE hProc =OpenProcess(PROCESS_DUP_HANDLE, 0, pid);
if(hProc == NULL){
printerror("1");
return 1;
}
HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS, TRUE, "Oberon_Minesweeper_Singleton");
if(hMutex == NULL){
printerror("2");
return 2;
}
if(DuplicateHandle(hProc, hMutex, NULL, 0, 0, FALSE, DUPLICATE_CLOSE_SOURCE) == 0){
printerror("3");
return 3;
}
if(CloseHandle(hMutex) == 0){
printerror("4");
return 4;
}
return 0;
}
This code returns 0, but the mutex is still there, and I am not able to launch more games of Minesweeper. I think some of my parameters to DuplicateHandle are wrong.
The second argument to DuplicateHandle expects "an open object handle that is valid in the context of the source process", however I believe the handle you're passing in would only be valid within the current process (OpenMutex creates a new handle to an existing mutex object). You'll likely need to determine what the mutex's handle is in the remote process, and use that value when calling DuplicateHandle.