为了监视系统运行中的进程内部数据,需要定位指定进程的节表。    请问在使用 OpenProcess 获得一个正在运行的进程句柄后,如何确定该进程中的节表个数?如何确定每个节表在该进程地址空间中的地址?    望高手不吝赐教,谢谢。

解决方案 »

  1.   

    if(hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, NULL, pe.th32ProcessID))
    {
      HMODULE hModule;
      DWORD cbNeeded;
      MODULEINFO modinfo;
      LPVOID lpbuf = NULL;
      UINT nRead;
      if(EnumProcessModules(hProcess, &hModule, sizeof(HMODULE), &cbNeeded))
      {
         GetModuleInformation( hProcess, hModule, &modinfo, sizeof(MODULEINFO) );
         lpbuf = new BYTE[modinfo.SizeOfImage];
         ReadProcessMemory(hProcess, modinfo.lpBaseOfDll, lpbuf, modinfo.SizeOfImage, &nRead);
         /*
           这里请自己从lpbuf中定位并读取想要的节内容。
         */
      }
      if(lpbuf)
         delete[] lpbuf;
    }
      

  2.   

    /*
            这里请自己从lpbuf中定位并读取想要的节内容。
        */    lpbuf 应该不是 IMAGE_SECTION_HEADER 指针或 IMAGE_FILE_HEADER 吧?
      

  3.   

    楼主给分吧:
    // 读取指定进程的节,以notepad.exe为例,VS2005测试通过.
    //
    #include <windows.h>
    #include <Psapi.h>
    #pragma comment(lib, "psapi.lib")int main(int argc, char* argv[])
    {
    PROCESS_INFORMATION ProcInfo = {0};
    STARTUPINFO StartInfo = {0};
    CreateProcess(NULL, "notepad.exe", NULL, NULL, FALSE, 0, NULL, NULL, &StartInfo, &ProcInfo);
    CloseHandle(ProcInfo.hProcess);
    CloseHandle(ProcInfo.hThread);
    HANDLE hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, NULL, ProcInfo.dwProcessId);
    if(hProcess)
    {
    HMODULE hModule;
    DWORD cbNeeded;
    MODULEINFO modinfo;
    LPVOID lpbuf = NULL;
    SIZE_T nRead;
    if(EnumProcessModules(hProcess, &hModule, sizeof(HMODULE), &cbNeeded))
    {
    GetModuleInformation( hProcess, hModule, &modinfo, sizeof(MODULEINFO) );
    lpbuf = new BYTE[modinfo.SizeOfImage];
    memset(lpbuf, 0, modinfo.SizeOfImage);
    ReadProcessMemory(hProcess, modinfo.lpBaseOfDll, lpbuf, modinfo.SizeOfImage, &nRead);
    //取得节数目
    PIMAGE_FILE_HEADER pfh;
    int nSectionCount; pfh = (PIMAGE_FILE_HEADER) ((LPVOID)((BYTE *)(lpbuf)+((PIMAGE_DOS_HEADER)(lpbuf))->e_lfanew+sizeof(DWORD)));
    nSectionCount = pfh->NumberOfSections;
    int i;
    PIMAGE_SECTION_HEADER psh; psh = (PIMAGE_SECTION_HEADER) ((LPVOID)((BYTE *)(lpbuf)+((PIMAGE_DOS_HEADER)(lpbuf))->e_lfanew+sizeof(DWORD)+sizeof(IMAGE_FILE_HEADER)+sizeof(IMAGE_OPTIONAL_HEADER)));
    // 注意:Pe中节是根据数据的属性来分的,而不管数据之间的逻辑关系
    // 所以只根据属性来判断节是否为数据节。这一规则在有节合并的Pe中犹为明显。
    // 如果想根据节名称来做,我这里用名称来判定。
    for(i=0; i < nSectionCount; i++)
    {
    if(0 == lstrcmp(".data", (char *)psh->Name))
    {
    /*
    do something you want;
    */
    MessageBox(0, "section .data", "hello", 0);
    }
    psh++;
    }
    }
    if(lpbuf)
    delete[] lpbuf;
    } return 0;
    }