windows里面所有的exe程序,dll程序,lib程序,sys….都遵循PE结构
    即数据和指令按照一定顺序存放在文件中,这种格式叫做PE格式

    1、DLL文件装入进程地址空间后,是否是装入到dll文件规定的最合适的地址

    1. #include<windows.h>
    2. #include<tchar.h>
    3. #include<TlHelp32.h>
    4. #define ID 2520
    5. //这段代码直接在MSDN中拷贝的
    6. typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
    7. LPFN_ISWOW64PROCESS fnIsWow64Process;
    8. BOOL IsWow64(HANDLE hProcess) //稍微修改了下,判断是不是64位的程序
    9. {
    10. BOOL bIsWow64 = FALSE;
    11. //IsWow64Process is not available on all supported versions of Windows.
    12. //Use GetModuleHandle to get a handle to the DLL that contains the function
    13. //and GetProcAddress to get a pointer to the function if available.
    14. fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(
    15. GetModuleHandle(TEXT("kernel32")), "IsWow64Process");
    16. if (NULL != fnIsWow64Process)
    17. {
    18. if (!fnIsWow64Process(hProcess, &bIsWow64))
    19. {
    20. //handle error
    21. }
    22. }
    23. return bIsWow64;
    24. }
    25. //判断是否装入在合适的位置
    26. PVOID GetModulePreferredBaseAddr(DWORD dwProcessId, PVOID pvModuleRemote) {
    27. PVOID pvModulePreferredBaseAddr = NULL;
    28. IMAGE_DOS_HEADER idh;
    29. IMAGE_NT_HEADERS inth;
    30. // Read the remote module's DOS header
    31. Toolhelp32ReadProcessMemory(dwProcessId,
    32. pvModuleRemote, &idh, sizeof(idh), NULL); //pvModuleRemote起始地址
    33. // Verify the DOS image header
    34. if (idh.e_magic == IMAGE_DOS_SIGNATURE) {
    35. // Read the remote module's NT header
    36. Toolhelp32ReadProcessMemory(dwProcessId,
    37. (PBYTE)pvModuleRemote + idh.e_lfanew, &inth, sizeof(inth), NULL); //e_lfanew偏移量
    38. // Verify the NT image header
    39. if (inth.Signature == IMAGE_NT_SIGNATURE) {
    40. // This is valid NT header, get the image's preferred base address
    41. pvModulePreferredBaseAddr = (PVOID)inth.OptionalHeader.ImageBase;
    42. }
    43. }
    44. return(pvModulePreferredBaseAddr); //返回进程最合适的地址
    45. }
    46. int _tmain()
    47. {
    48. DWORD nFlags = 0;
    49. HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,ID);
    50. // BOOL Is32 = IsWow64(hProcess); //判断是否位32 位的程序
    51. // _tprintf(L"Is 32 Process!\n");
    52. nFlags = TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32;
    53. HANDLE hSnapshot = CreateToolhelp32Snapshot(nFlags, ID);
    54. MODULEENTRY32 me = {0};
    55. me.dwSize = sizeof(me);
    56. Module32First(hSnapshot,&me);
    57. do{
    58. PVOID pPre = GetModulePreferredBaseAddr(
    59. ID,me.modBaseAddr);
    60. //me.modBaseAddr:是现在这个模块或者说dll在进程地址空间中的地址
    61. //pPre获得的是,dll模块装入进程空间的最佳地址
    62. if (pPre!=me.modBaseAddr) //如果没有装入合适的位置,输出
    63. _tprintf(L"hModule=%0x,BaseAddr=%0x,ModSize=%0x,pPre=%0x,\n%s\n", me.hModule, me.modBaseAddr,
    64. me.modBaseSize,pPre, me.szModule);
    65. } while (Module32Next(hSnapshot, &me));
    66. _gettchar();
    67. CloseHandle(hProcess);
    68. return 0;
    69. }