Windows program entry point using EnumProcessModules returns unexpected value - c++

I am running a simple app and trying to read a specific offset within it's memory using Window's PSAPI.
when I run my debugger, I get the real value of the memory address, and the relative one to my ".exe" entry point.
yet, when I run the following code, the base module I get as an entry point together with my offset yields a different address(it's wrong, and off by a few (hexa)demical points).
what might be the problem?
ReadMemory is a template for ReadProcessMemory
HWND WINDOW_HANDLE;
HANDLE PROC_HANDLE;
DWORD PROC_ID;
DWORD address;
SIZE_T bytesRead;
int InitReadMemory(const char* windowClass,const char* caption, DWORD addressOffset)
{
DWORD cbNeeded;
DWORD dwdResult;
HMODULE mainModule;
BOOL enumResult;
//Get the window handle
WINDOW_HANDLE = FindWindow(windowClass, NULL);
if(WINDOW_HANDLE == NULL)
{
//Window was not foud
return 10;
}
//Get the process ID
dwdResult = GetWindowThreadProcessId(WINDOW_HANDLE, &PROC_ID);
if(dwdResult==0)
{
//Getting Process ID failed
return 20;
}
//Open the process
PROC_HANDLE = OpenProcess(PROCESS_ALL_ACCESS, false, PROC_ID);
if(PROC_HANDLE==NULL)
{
//Process failed to open
return 30;
}
/*
*Get the Main Module-
*first entry in the returned HMODULE array from
*EnumProcessModules
*/
enumResult = EnumProcessModules(PROC_HANDLE, &mainModule, sizeof(HMODULE), &cbNeeded);
if(enumResult != 0)
{
//Failed enumerating process modules
return 40;
}
//offset the requested memory address from the application's base address
address = (DWORD)((UINT_PTR)mainModule + addressOffset);
#ifdef DEBUG
using namespace std;
char filenameBuffer[64]="";
string number;
stringstream stristream;
stristream << address;
stristream >> number;
cout << number << "\r\n" << endl;
GetModuleFileNameEx(PROC_HANDLE, mainModule , filenameBuffer, 256);
cout << (byte)ReadMemory<byte>() << "\r\n" << number << "\r\n" << filenameBuffer << endl;
system("PAUSE");
#endif
return 1;}
thank you in advance :)
P.S. I'm mostly just looking for pointers ...
bah dum tsss
Update:
apparently, checking for GetLastError value, EnumProcessModules prompts a 299 error code after it is done. and debugging shows that mainModule holds nothing... yet EnumProcessModules returns 0 as in "no errors".
yesterday, I managed to get it AND get GetModuleFileName to work propery(same code, only added GetLastError).

Apparently, my problem was that I was running the tests with the snippet
enumResult = EnumProcessModules(PROC_HANDLE, &mainModule, sizeof(HMODULE), &cbNeeded)
if(enumResult != 0)
{
//Failed enumerating process modules
return 40;
}
and a successful run of EnumProcessModules yields a nonzero result! (thus causing me some confusion and faulted my whole debugging process)
after I figured this detail out, I ran some old tests again and found out that my target process is 64 bit, while I was running a 32 bit application.
changed to 64bit and now it works like a charm

Related

Calling a function from another process

I apologize in advance for my English :D
How can I call a function from a process, knowing the pointer to it?
I tried this:
Process.cpp:
DWORD pid;
HWND hwnd;
HANDLE phandle;
void Attach() {
hwnd = FindWindow(NULL, L"GTA:SA:MP");
if (!hwnd) {
cout << "Process is not found" << endl;
system("pause");
}
else if (hwnd) {
cout << "Process was successfully loaded" << endl;
GetWindowThreadProcessId(hwnd, &pid);
phandle = OpenProcess(PROCESS_VM_READ, 0, pid);
}
else
{
cout << "Error 0x01" << endl;
system("pause");
}
}
void GameText(const char* szText, int iTime, signed int iStyle)
{
typedef void(__stdcall* GameText_t)(const char*, int, signed int);
GameText_t pGameText = (GameText_t)((char*)phandle + 0x69F2B0);
return pGameText(szText, iTime, iStyle);
}
main.cpp:
int main()
{
std::cout << "Hello World!\n";
Attach();
GameText("~r~Test!", 1000, 5);
}
And I get the following exception:
An exception was thrown at the address 0x006EF7B6 in wh_mta.exe:
0xC0000005: access violation during execution at 0x006EF7B6.
Why is this happening? How can I call a function by its pointer through HANDLE?
P.S
Reading an integer through HANDLE works great.
int Read_Int(int address) {
int value;
ReadProcessMemory(phandle, (void*)address, &value, sizeof(value), 0);
return value;
}
Maybe 30 years ago that would have worked :D :D :D
Processes can't access each other's memory… Every process has their own image of the memory, so address 0xWHATEVER in a process does not contain the same data as 0xWHATEVER in another process!
You need to make a library or use some inter process communication (IPC).
What you are doing is adding the pointer to the HANDLE of the process. You need the address of the process in it's virtual address space. To do so, use EnumProcessModules andGetModuleFileNameEx to find the filename of the module with the function you want. (Could be an EXE or a DLL.) EnumProcessModules returns an array of HMODULES which are just addresses of module in the specified process's virtual address space. So loop through the array, then cast the HMODULE that you need to a PBYTE. Then, add the function pointer to it, then try to execute.
Also, according your code, you are going to execute the function in YOUR program. That's fine, just make sure that if it needs to run in the target program, you'll need to use CreateRemoteThread to run it there.

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.

Converting "application's" memory address

So I am writing my very first trainer for Microsoft's Spider Solitaire. First I needed to backwards-engineer all memory adresses until I found a static one. I used offsets so I can easily revert them back.
I've found this:
1000157F78 <-- starting value(never changes)
+ E8 <-- offsets to pointers
+ 14
002DC3D4 <-- final adress(changes every time)
This is how my trainer gets his final memory address:
DWORD FindFinalAddr(HANDLE hProc, BYTE offsets[], DWORD baseAddress, unsigned char pointerLevel)
{
DWORD pointer = baseAddress;
DWORD pTemp = 0;
DWORD pointerAddr = 0;
// set base address
ReadProcessMemory(hProc, (LPCVOID)pointer, &pTemp, (DWORD)sizeof(pTemp), NULL);
for (int c = 0; c < pointerLevel; c++)
{
pointerAddr = pTemp + (DWORD)offsets[c];
ReadProcessMemory(hProc, (LPCVOID)pointerAddr, &pTemp, (DWORD)sizeof(pTemp), NULL);
}
return pointerAddr;
}
In this case, I do(roughly) this: FindFinalAddr(hProc, {0xE8, 0x14}, 0x1000157F78, 2);
This works fine when Spider Solitaire is open and I have just found the static value.
But when I close it and re-open it's no longer valid.
I found out that 1000157F78 is actually SpiderSolitaire.exe+B5F78 It's like a offset. If I enter this in cheat engine I get the right memory address, but I can't just simply enter it in my code.
Now is my question: How do I convert SpiderSolitaire.exe+B5F78 to the right memory adress?
Note: SpiderSolitaire.exe is 64 bit.
EDIT:
I've tried the following:
void * entryPoint = (void*) hProc;
DWORD base_addr = ((DWORD)(entryPoint) + 0xB5F78);
But that doesn't work, because the entry point is 5C. The adress it should give(in this session) is FF7A5F78, but what really happens is 5C + B5F78 = B5F4D.
I think you can query the load address using GetModuleInformation, passing NULL for the module handle parameter. If that doesn't work, you can take the longer route through EnumProcessModules and GetModuleBaseName.
After a long period of research I've found my own answer!
This piece of code gets the module base address(AKA entry point)(you need to include TlHelp32.h and tchar.h):
DWORD getModuleBaseAddr(DWORD procId, TCHAR * lpszModuleName)
{
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, procId);
DWORD moduleBaseAddr = 0;
if (hSnapshot != INVALID_HANDLE_VALUE)
{
MODULEENTRY32 mentry32 = { 0 };
mentry32.dwSize = sizeof(MODULEENTRY32);
if (Module32First(hSnapshot, &mentry32))
{
do
{
if (_tcscmp(mentry32.szModule, lpszModuleName) == 0)
{
moduleBaseAddr = (DWORD)mentry32.modBaseAddr;
break;
}
} while (Module32Next(hSnapshot, &mentry32));
}
}
else
{
std::cout << "Error on finding module base address: " << GetLastError() << "\n";
}
return moduleBaseAddr;
}
You give it the pid and the name of the module(like game.exe), then it browses through modules and check if they are the same, and then it returns the base address.
Now, I tested this with Spider Solitaire. It gave me an error.
That is because my compiled code was 32 bit and SpiderSolitaire.exe was 64 bit, which was caused because my Windows 7 was 64 bit.
So make sure your code has the same platform target as the code you're aiming for!

Getting Base Address not working

I need the base Address of the exe "tibia.exe". This is what I got so far but it doesn't work. It always returns 0.
What's wrong?
DWORD MainWindow::getBaseAddress(DWORD dwProcessIdentifier)
{
TCHAR lpszModuleName[] = {'t','i','b','i','a','.','e','x','e','\0'}; //tibia.exe
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,
dwProcessIdentifier);
DWORD dwModuleBaseAddress = 0;
if(hSnapshot != INVALID_HANDLE_VALUE)
{
MODULEENTRY32 ModuleEntry32;
ModuleEntry32.dwSize = sizeof(MODULEENTRY32);
if(Module32First(hSnapshot, &ModuleEntry32))
{
do
{
if( wcscmp(ModuleEntry32.szModule, lpszModuleName) == 0)
{
dwModuleBaseAddress = (DWORD)ModuleEntry32.modBaseAddr;
break;
}
}
while(Module32Next(hSnapshot, &ModuleEntry32));
}
CloseHandle(hSnapshot);
}
return dwModuleBaseAddress;
}
//Call it here
tibiaWindow = FindWindow( L"TibiaClient", NULL);
DWORD PID;
GetWindowThreadProcessId( tibiaWindow, &PID );
DWORD baseAddress = getBaseAddress( PID );
if( baseAddress == 0 )
return false ;
Perhaps it's just because I was using them before ToolHelp32 was available (at least on the NT-based operating systems), but I tend to use the PSAPI functions for this kind of task. Using them, the code would look like this:
#include <windows.h>
#include <string>
#include <psapi.h>
#include <iostream>
int main(int argc, char **argv) {
HANDLE process = GetCurrentProcess();
if (argc != 1)
process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, atoi(argv[1]));
HMODULE handles[2048];
DWORD needed;
EnumProcessModules(process, handles, sizeof(handles), &needed);
for (int i = 0; i < needed / sizeof(handles[0]); i++) {
MODULEINFO info;
char name[1024];
GetModuleBaseName(process, handles[i], name, sizeof(name));
if (std::string(name).find(".exe") != std::string::npos) {
GetModuleInformation(process, handles[i], &info, sizeof(info));
std::cout << name << ": " << info.lpBaseOfDll << "\n";
break;
}
}
}
As it stands right now, this will let you enter a process ID on the command line, and show the load address of the first module it finds in that process with a name that includes ".exe". If you don't specify a process ID, it'll search through its own process (demos how the functions work, but otherwise pretty much useless).
Using either ToolHelp32 or PSAPI, you end up with a similar limitation: you need to compile this into a 64-bit executable for it to be able to "see" other 64-bit processes (i.e., when compiled as 32-bit code, they see only other 32-bit processes).
There are also some processes (e.g., CSRSS.exe) that neither will be able to open/enumerate successfully. As far as I know, the same processes will succeed/fail with PSAPI vs. ToolHelp32.
PSAPI does have one bit of clumsiness compared to ToolHelp32: dealing (well) with processes that have lots of modules is clumsy (at best). You call EnumProcessModules, and if you haven't given room for enough modules, the "Needed" parameter will be set to the space needed for the number of modules it contains. There's a race condition though: between the time that returns and the time you call EnumProcessModules again, the process could have loaded more DLLs, so that second call could fail the same way.
For the moment, I've just assumed that no process will use more than 2048 modules. To be really correct, you should have a while loop (or maybe a do/while loop) that starts with zero space, calls EnumProcessModules to find out how much space is needed, allocate that (perhaps with a little extra in case it loads more DLLs) and repeat until it succeeds.

Createprocess and 0xc0000142 error

i have the following test code:
#define CMDLINE ".\\dummyFolder\\dummyProc.exe op1 op2 op3"
int main(int argc, char **argv) {
STARTUPINFO info;
info.cb = sizeof(STARTUPINFO);
info.lpReserved = NULL;
info.cbReserved2 = 0;
info.lpReserved2 = NULL;
PROCESS_INFORMATION processInfo;
SECURITY_ATTRIBUTES procAttr;
procAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
procAttr.lpSecurityDescriptor = NULL;
procAttr.bInheritHandle = false;
SECURITY_ATTRIBUTES threadAttr;
procAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
procAttr.lpSecurityDescriptor = NULL;
procAttr.bInheritHandle = false;
bool handlersInheritable = true;
char cmdLine2[sizeof(CMDLINE)];
strcpy(cmdLine2, CMDLINE);
char AppName[sizeof(".\\dummyFolder\\dummyProc.exe")];
strcpy(AppName, ".\\dummyFolder\\dummyProc.exe");
if (CreateProcess(AppName, cmdLine2, &procAttr, &threadAttr,
handlersInheritable, 0, NULL, NULL, &info, &processInfo)) {
//::WaitForMultipleObjects(procQty, handlers, waitForAll, waitInterval);
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
CloseHandle(info.hStdError);
CloseHandle(info.hStdInput);
CloseHandle(info.hStdOutput);
} else {
std::cout << "Returned: " << GetLastError() << std::endl;
}
std::cout << "Exiting main process" << std::endl;
return 0;
}
This is just a test code for creating processes in windows. The problem is that when i launch "dummyProc.exe" i get a 0xc0000142 error.
The process dummyProc.exe runs fine from the command line, but not from within the code.
Here's the dummyProc code if it helps:
int main(int argc, char **argv) {
std::cout << "Working!!!!" << std::endl << "Receivedi: " << std::endl;
for (int i = 0; i < argc; ++i)
std::cout << argv[i] << std::endl;
return 0;
}
So, any ideas?
The most obvious thing that char cmdLine2[sizeof(CMDLINE)]; declares a string of length equal to your machine's pointer size. You need to use strlen(CMDLINE)+1 instead. Likewise for appName.
Note that the first parameter to CreateProcess does not need to be writeable. Just pass the string literal directly to it. No need for appName variable.
As for lpCommandLine which does need to be writeable it's easiest to do it like this:
char cmdline[] = "op1 op2 op3";
That gives you a writeable buffer. Note that you do not need to repeat the executable file name.
Another problem is that you have not initialized all the parameters to CreateProcess. For example the STARTUPINFO struct has 19 fields and you initialize only 3. You should initialize all your structs to 0 and then fill out any fields you need to be non-zero. Like this:
STARTUPINFO info = { 0 };
Do this for all the structs you pass.
You can, and should, pass NULL for the lpProcessAttributes and lpThreadAttributes parameters.
This answer is to relate another cause for 0xc0000142 - placed here (even though another answer was accepted for this question) because there is very little useful information on the intertubes about this error - and a shocking lack of any useful information on the subject from Microsoft - and so someone's internet search may get them here. (Well, mine did.)
So: You can get The application was unable to start correctly (0xc0000142) on starting a process written in C++ where you access though a null pointer in a constructor of a static object. (In my case it was in an initializer of a constructor of a static object.)
Your hint to this will be an event in the application log (event id 1000 source "Application Error") which has lines similar to the following:
Faulting module name: unknown, version: 0.0.0.0, time stamp: 0x00000000
Exception code: 0xc0000005
Fault offset: 0x0000000000000000
0xc0000005 is access violation, of course, and the offset of 0 (actually anything less than 0x10000 is a reference through a null pointer.
Anyway, the surprising thing (to me) is that evaluating statics happens before the debugger can attach (!!) so launching it with ImageFileExecutionOptions set or even directly within Visual Studio doesn't let you debug this thing!!
(And then of course you won't find 0xc0000142 in any Microsoft documentation whatsoever. Well done, NT team!)