2

我有一个外部进程(exe 文件 DllProj.exe 正在运行),它有 SampleDll.dll 链接到它(隐式链接)。我可以借助我的函数 imageBase() 找到链接 dll 的基地址,但不能找到进程本身的基地址!有什么区别,为什么它不能按原样工作?

我的意思是,这段代码返回带有正确 DOS/NT-headers 的 pBase:

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;

但此代码返回为 FALSE:

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

这是我的程序:

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; 
}

PS:我的下一个目标是获取 DllProj.exe 的导入表(Sample.dll 所在的位置)和劫持 dll 的函数调用

4

2 回答 2

0

如何使用这个:

#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; 
}

信用在这里回答

于 2012-09-19T12:28:00.247 回答
0

您的代码没有任何问题,我编译了您的代码,它工作正常并将正确的地址输出到控制台。确保以管理员身份运行。这是使用我测试过的代码的项目:

#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;
}
于 2020-03-28T22:09:14.317 回答