windows里面所有的exe程序,dll程序,lib程序,sys….都遵循PE结构
即数据和指令按照一定顺序存放在文件中,这种格式叫做PE格式
1、DLL文件装入进程地址空间后,是否是装入到dll文件规定的最合适的地址
#include<windows.h>#include<tchar.h>#include<TlHelp32.h>#define ID 2520//这段代码直接在MSDN中拷贝的typedef BOOL(WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);LPFN_ISWOW64PROCESS fnIsWow64Process;BOOL IsWow64(HANDLE hProcess) //稍微修改了下,判断是不是64位的程序{BOOL bIsWow64 = FALSE;//IsWow64Process is not available on all supported versions of Windows.//Use GetModuleHandle to get a handle to the DLL that contains the function//and GetProcAddress to get a pointer to the function if available.fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process");if (NULL != fnIsWow64Process){if (!fnIsWow64Process(hProcess, &bIsWow64)){//handle error}}return bIsWow64;}//判断是否装入在合适的位置PVOID GetModulePreferredBaseAddr(DWORD dwProcessId, PVOID pvModuleRemote) {PVOID pvModulePreferredBaseAddr = NULL;IMAGE_DOS_HEADER idh;IMAGE_NT_HEADERS inth;// Read the remote module's DOS headerToolhelp32ReadProcessMemory(dwProcessId,pvModuleRemote, &idh, sizeof(idh), NULL); //pvModuleRemote起始地址// Verify the DOS image headerif (idh.e_magic == IMAGE_DOS_SIGNATURE) {// Read the remote module's NT headerToolhelp32ReadProcessMemory(dwProcessId,(PBYTE)pvModuleRemote + idh.e_lfanew, &inth, sizeof(inth), NULL); //e_lfanew偏移量// Verify the NT image headerif (inth.Signature == IMAGE_NT_SIGNATURE) {// This is valid NT header, get the image's preferred base addresspvModulePreferredBaseAddr = (PVOID)inth.OptionalHeader.ImageBase;}}return(pvModulePreferredBaseAddr); //返回进程最合适的地址}int _tmain(){DWORD nFlags = 0;HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,ID);// BOOL Is32 = IsWow64(hProcess); //判断是否位32 位的程序// _tprintf(L"Is 32 Process!\n");nFlags = TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32;HANDLE hSnapshot = CreateToolhelp32Snapshot(nFlags, ID);MODULEENTRY32 me = {0};me.dwSize = sizeof(me);Module32First(hSnapshot,&me);do{PVOID pPre = GetModulePreferredBaseAddr(ID,me.modBaseAddr);//me.modBaseAddr:是现在这个模块或者说dll在进程地址空间中的地址//pPre获得的是,dll模块装入进程空间的最佳地址if (pPre!=me.modBaseAddr) //如果没有装入合适的位置,输出_tprintf(L"hModule=%0x,BaseAddr=%0x,ModSize=%0x,pPre=%0x,\n%s\n", me.hModule, me.modBaseAddr,me.modBaseSize,pPre, me.szModule);} while (Module32Next(hSnapshot, &me));_gettchar();CloseHandle(hProcess);return 0;}
