Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WinCE: How can I determine the module that contains a code address?

I wrote a solution that involved OpenProcess, EnumProcessModules, GetModuleInformation and GetModuleBaseName, but apparently EnumProcessModules and GetModuleBaseName do not exist in Windows CE! What alternative is there?

like image 370
Qwertie Avatar asked Jan 20 '26 08:01

Qwertie


1 Answers

I found a way to do this with CreateToolhelp32Snapshot, Module32First, Module32Next, Process32First and Process32Next. First you have to get a list of modules, then search through the list of modules to find the desired address.

#include <Tlhelp32.h>

struct MyModuleInfo
{
    BYTE* Base;
    HMODULE Handle;
    DWORD Size;
    enum { MaxNameLen = 36 };
    TCHAR Name[MaxNameLen];
};

bool GetModuleList(vector<MyModuleInfo>& moduleList)
{
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPMODULE | TH32CS_GETALLMODS, 0);
    if (hSnapshot == INVALID_HANDLE_VALUE)
        return false;

    MODULEENTRY32 moduleInfo;
    moduleInfo.dwSize = sizeof(moduleInfo);
    if (Module32First(hSnapshot, &moduleInfo)) do {
        MyModuleInfo myInfo;
        myInfo.Handle = moduleInfo.hModule;
        myInfo.Base = moduleInfo.modBaseAddr;
        myInfo.Size = moduleInfo.modBaseSize;
        memcpy(myInfo.Name, moduleInfo.szModule, min(sizeof(myInfo.Name), sizeof(moduleInfo.szModule)));
        myInfo.Name[myInfo.MaxNameLen-1] = '\0';
        moduleList.push_back(myInfo);
    } while (Module32Next(hSnapshot, &moduleInfo));

    // The module list obtained above only contains DLLs! To get the EXE files
    // also, we must call Process32First and Process32Next in a loop.
    PROCESSENTRY32 processInfo;
    processInfo.dwSize = sizeof(processInfo);
    if (Process32First(hSnapshot, &processInfo)) do {
        MyModuleInfo myInfo;
        myInfo.Handle = NULL; // No handle given
        myInfo.Base = (BYTE*)processInfo.th32MemoryBase;
        myInfo.Size = 0x800000; // No size provided! Allow max 8 MB
        memcpy(myInfo.Name, processInfo.szExeFile, min(sizeof(myInfo.Name), sizeof(processInfo.szExeFile)));
        myInfo.Name[myInfo.MaxNameLen-1] = '\0';
        moduleList.push_back(myInfo);
    } while(Process32Next(hSnapshot, &processInfo));

    // Debug output
    for (int i = 0; i < (int)moduleList.size(); i++) {
        MyModuleInfo& m = moduleList[i];
        TRACE(_T("%-30s: 0x%08x - 0x%08x\n"), m.Name, (DWORD)m.Base, (DWORD)m.Base + m.Size);
    }

    CloseToolhelp32Snapshot(hSnapshot);
    return true;
}

const MyModuleInfo* GetModuleForAddress(vector<MyModuleInfo>& moduleList, void* address)
{
    for (int m = 0; m < (int)moduleList.size(); m++) {
        const MyModuleInfo& mInfo = moduleList[m];
        if (address >= mInfo.Base && address < mInfo.Base + mInfo.Size)
            return &mInfo;
    }
    return NULL;
}
like image 110
Qwertie Avatar answered Jan 23 '26 20:01

Qwertie