tguglanaklona
tguglanaklona

Reputation: 31

Image base address of foreign exe/dll or WTF?

I have a foreign process (exe-file DllProj.exe is running), that has SampleDll.dll linked to it (implicit linking). I can find the base address of the linked dll with the help of my function imageBase(), but not the base address of the process itself! What is the difference and why it's not working as is?

I mean, this code returns pBase with correct DOS/NT-headers:

LPVOID pBase = imageBase("DllProj.exe", "SampleDll.dll");
if (!pBase) 
    return false;
PIMAGE_DOS_HEADER pDosHeader = PIMAGE_DOS_HEADER((HMODULE)pBase); 
if (::IsBadReadPtr(pDosHeader, sizeof(IMAGE_DOS_HEADER)) ||
    IMAGE_DOS_SIGNATURE != pDosHeader->e_magic)
    return false;

but this code return is FALSE:

LPVOID pBase = imageBase("DllProj.exe", "DllProj.exe");
//and so on...

Here is my procedure:

LPVOID imageBase(LPSTR szVictimProcess, LPSTR szVictim)
{
    //находим процесс szVictimProcess
    DWORD aProcesses[1024], cbNeeded, nProcesses;
    unsigned int i;

    if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
        return NULL;
    nProcesses = cbNeeded / sizeof(DWORD);

    HANDLE ProcHandle = 0;
    TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
    for (i = 0; i < nProcesses; i++)
    {
        ProcHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, aProcesses[i]);

        if (NULL != ProcHandle) 
        {
            HMODULE hMod[1024];
            if ( EnumProcessModules(ProcHandle, hMod, sizeof(hMod), &cbNeeded) )
            {
                GetModuleBaseName(ProcHandle, hMod[0], szProcessName, sizeof(szProcessName)/sizeof(TCHAR)); // Get the process name
                if (0 == lstrcmpiA(szVictimProcess, szProcessName))
                {
                    //находим модуль szVictim
                    DWORD nModules = cbNeeded / sizeof(HMODULE);
                    char szModName[MAX_PATH];
                    for (unsigned int j = 0; j < nModules; j++)
                    {
                        if (GetModuleFileNameEx(ProcHandle, hMod[j], szModName, sizeof(szModName))) // Get the module name
                        {
                            shortName(szModName);
                            if (0 == lstrcmpiA(szModName, szVictim)) 
                            {
                                MODULEINFO info;
                                GetModuleInformation(ProcHandle, hMod[j], &info, sizeof(info));
                                return info.lpBaseOfDll;

                                //Equal To:
                                //return hMod[j];

                                //Debug:
                                //LPSTR string = new char[256];
                                //wsprintf(string,"\t%s (0x%08X)\n", szModName, hMod[j]);
                            }
                        }
                    }
                    break;
                }
            }
        }

        CloseHandle(ProcHandle);
    }

    return NULL; 
}

P.S.: My next goal is to get import-table of DllProj.exe (where Sample.dll is) and hiijack dll's function call

Upvotes: 2

Views: 1391

Answers (2)

GuidedHacking
GuidedHacking

Reputation: 3923

There is nothing wrong with your code, I compiled your code and it works fine and outputs the correct address to console. Make sure you run as administrator. This is the project using your code which I tested working:

#include <windows.h>
#include <iostream>
#include <psapi.h>
#include <string>

void shortName(LPSTR strToChange)
{
    std::string path(strToChange);
    std::string filename;

    size_t pos = path.find_last_of("\\");
    if (pos != std::string::npos)
        filename.assign(path.begin() + pos + 1, path.end());
    else
        filename = path;

    lstrcpy(strToChange, filename.data());
}

LPVOID imageBase(LPSTR szVictimProcess, LPSTR szVictim)
{
    DWORD aProcesses[1024], cbNeeded, nProcesses;
    unsigned int i;

    if (!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
        return NULL;
    nProcesses = cbNeeded / sizeof(DWORD);

    HANDLE ProcHandle = 0;
    TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
    for (i = 0; i < nProcesses; i++)
    {
        ProcHandle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, aProcesses[i]);

        if (NULL != ProcHandle)
        {
            HMODULE hMod[1024];
            if (EnumProcessModules(ProcHandle, hMod, sizeof(hMod), &cbNeeded))
            {
                GetModuleBaseName(ProcHandle, hMod[0], szProcessName, sizeof(szProcessName) / sizeof(TCHAR)); // Get the process name
                if (0 == lstrcmpiA(szVictimProcess, szProcessName))
                {
                    DWORD nModules = cbNeeded / sizeof(HMODULE);
                    char szModName[MAX_PATH];
                    for (unsigned int j = 0; j < nModules; j++)
                    {
                        if (GetModuleFileNameEx(ProcHandle, hMod[j], szModName, sizeof(szModName))) // Get the module name
                        {
                            shortName(szModName);
                            if (0 == lstrcmpiA(szModName, szVictim))
                            {
                                MODULEINFO info;
                                GetModuleInformation(ProcHandle, hMod[j], &info, sizeof(info));
                                return info.lpBaseOfDll;
                            }
                        }
                    }
                    break;
                }
            }
        }
        CloseHandle(ProcHandle);
    }
    return NULL;
}

int main(void)
{
    void* base = imageBase((char*)"ac_client.exe", (char*)"ac_client.exe");

    std::cout << "0x" << std::hex << base;
}

Upvotes: 0

Tony The Lion
Tony The Lion

Reputation: 63250

What about using this:

#pragma comment( lib, "psapi" )

DWORD GetModuleBase(HANDLE hProc, string &sModuleName) 
{ 
   HMODULE *hModules; 
   char szBuf[50]; 
   DWORD cModules; 
   DWORD dwBase = -1; 
   //------ 

   EnumProcessModules(hProc, hModules, 0, &cModules); 
   hModules = new HMODULE[cModules/sizeof(HMODULE)]; 

   if(EnumProcessModules(hProc, hModules, cModules/sizeof(HMODULE), &cModules)) { 
      for(int i = 0; i < cModules/sizeof(HMODULE); i++) { 
         if(GetModuleBaseName(hProc, hModules[i], szBuf, sizeof(szBuf))) { 
            if(sModuleName.compare(szBuf) == 0) { 
               dwBase = (DWORD)hModules[i]; 
               break; 
            } 
         } 
      } 
   } 

   delete[] hModules; 

   return dwBase; 
}

Credit to answer here

Upvotes: 0

Related Questions