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 header
Toolhelp32ReadProcessMemory(dwProcessId,
pvModuleRemote, &idh, sizeof(idh), NULL); //pvModuleRemote起始地址
// Verify the DOS image header
if (idh.e_magic == IMAGE_DOS_SIGNATURE) {
// Read the remote module's NT header
Toolhelp32ReadProcessMemory(dwProcessId,
(PBYTE)pvModuleRemote + idh.e_lfanew, &inth, sizeof(inth), NULL); //e_lfanew偏移量
// Verify the NT image header
if (inth.Signature == IMAGE_NT_SIGNATURE) {
// This is valid NT header, get the image's preferred base address
pvModulePreferredBaseAddr = (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;
}