请问如何定位到指定进程的数据段?
选择一个正在运行的进程,已经得到进程 ID 和句柄,请问如何在我的程序中查看其数据段中的数据?
[解决办法]
很简单, 给你一个根据段名字查找段地址的例子,按你的情况,只需要用ReadProcessMemory把对方进程前4096字节读入本地内存然后调用这个函数就可以找到你感兴趣的段在对方内存内的偏移和大小:
DWORD GetSectionOffset(PVOID PE, LPSTR SectionName, PDWORD size)
{
PIMAGE_NT_HEADERS hdr = (PIMAGE_NT_HEADERS)(((PIMAGE_DOS_HEADER)PE)-> e_lfanew + (LONG)PE);
PIMAGE_SECTION_HEADER sec = (PIMAGE_SECTION_HEADER)((DWORD)hdr + sizeof(IMAGE_NT_HEADERS));
DWORD namelen = strlen(SectionName);
for( DWORD i =0; i < hdr-> FileHeader.NumberOfSections; i ++ )
{
LPSTR name = (LPSTR)(sec[i].Name + (DWORD)PE);
if( !strnicmp(name, SectionName, namelen) && (namelen > = 8 || name[namelen] == '\0 ') )
{
if( size )
*size = sec[i].Misc.VirtualSize;
return sec[i].VirtualAddress;
}
}
return 0;
}
[解决办法]
EnumProcessModules API可以列出一个Process里面的所有Module,还回来的HModule就是.exe Image Map到内存中的起始点,即PE的入口。把.exe对应那个Module,传到上面Function就可以了。
[解决办法]
楼主给分吧:
// 读取指定进程的节,以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;
}