简体   繁体   English

外部exe/dll或WTF的图像基地址?

[英]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).我有一个外部进程(exe 文件 DllProj.exe 正在运行),它有 SampleDll.dll 链接到它(隐式链接)。 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!我可以在函数 imageBase() 的帮助下找到链接的 dll 的基地址,但不能找到进程本身的基地址! What is the difference and why it's not working as is?有什么区别,为什么它不能按原样工作?

I mean, this code returns pBase with correct DOS/NT-headers:我的意思是,此代码返回带有正确 DOS/NT 标头的 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;

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

PS: My next goal is to get import-table of DllProj.exe (where Sample.dll is) and hiijack dll's function call PS:我的下一个目标是获取 DllProj.exe 的导入表(Sample.dll 所在的位置)和劫持 dll 的函数调用

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信用在这里回答

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM