zoukankan      html  css  js  c++  java
  • C/C++ 定位文件 .text 区段地址

    首先声明,.text 区段的起始地址是需要计算的,无论是哪个结构体里都不会直接提供某个区段的直接地址(虚拟内存地址),我就是因为想偷懒所以翻了好久的结构体成员列表,结果头都翻炸了还是没找到, !!!∑(゚Д゚ノ)ノ

    计算过程:

    1.先看 IMAGE_DOS_HEADER STRUCT 这个结构体,它有一个成员 e_lfanew 指向了 NT 头。(我这里的e_lfanew = 0x100,需要根据实际情况来动态获取)

    2.再看 _IMAGE_NT_HEADERS 结构体,FileHeader 成员是文件头结构体对象,所以再加 0x4

    3.同理来到 _IMAGE_FILE_HEADER 结构体,SizeOfOptionalHeader 成员为可选头的大小,所以在加 0x14,最后因为可选头大小为 0xE0,所以总体的偏移就是:0x100+0x4+0x14+0xE0 = 0x1F8 = 504

    但这仅仅是偏移,如果我们想得到真实的虚拟内存地址,还需要得到模块地址,用模块地址+偏移才能得到 .text 区段的入口地址。那么问题来了,怎么得到模块地址呢?

    下面放上代码:

    HMODULE GetProcessModuleHandle(DWORD pid, CONST TCHAR* moduleName) {	// 根据 PID 、模块名(需要写后缀,如:".dll"),获取模块入口地址。
    	MODULEENTRY32 moduleEntry;
    	HANDLE handle = NULL;
    	handle = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid); //  获取进程快照中包含在th32ProcessID中指定的进程的所有的模块。
    	if (!handle) {
    		CloseHandle(handle);
    		return NULL;
    	}
    	ZeroMemory(&moduleEntry, sizeof(MODULEENTRY32));
    	moduleEntry.dwSize = sizeof(MODULEENTRY32);
    	if (!Module32First(handle, &moduleEntry)) {
    		CloseHandle(handle);
    		return NULL;
    	}
    	do {
    		if (_tcscmp(moduleEntry.szModule, moduleName) == 0) { return moduleEntry.hModule; }
    	} while (Module32Next(handle, &moduleEntry));
    	CloseHandle(handle);
    	return 0;
    }
    
    int main(){
    	HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);  // 进程快照句柄
    	PROCESSENTRY32 process = { sizeof(PROCESSENTRY32) };	// 存放进程快照的结构体
    
    	//  遍历进程
    	while (Process32Next(hProcessSnap, &process)) {
    		// 找到进程
    		string s_szExeFile = process.szExeFile; // char* 转 string
    		if (s_szExeFile == "HEX2ASCII.exe") {
    			HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process.th32ProcessID); // 进程句柄
    			
    			// 打印模块地址
    			cout << "HEX2ASCII.exe PE头地址:" << GetProcessModuleHandle(process.th32ProcessID, "HEX2ASCII.exe") << endl;
    			
    			// 把模块地址转换成 int ,方便后面的计算
    			int peAddress = (int)GetProcessModuleHandle(process.th32ProcessID, "HEX2ASCII.exe");
    			cout << ".text 区段起始地址:" << hex << peAddress + 504 << endl;
    			
    			// 读取 .text 区段的前 4 个字节,验证地址是否正确
    			DWORD szBuffer; // 内存数组暂存
    			ReadProcessMemory(hProcess, (LPVOID)(peAddress + 504), &szBuffer, 4, NULL);
    			cout << ".text 前4个字节::" << hex << szBuffer << endl;
    		}
    	}
    }
    


    版权声明: 本博客,文章与代码均为学习时整理的笔记,博客中除去明确标注有参考文献的文章,其他文章【均为原创】作品,转载请务必【添加出处】,您添加出处是我创作的动力!

    警告:如果您恶意转载本人文章,则您的整站文章,将会变为我的原创作品,请相互尊重!
  • 相关阅读:
    C# 依据鼠标坐标取网页内成员坐标.ie
    C# WebBrowser获取指定字符串的坐标
    C#获取网页中某个元素的位置,并模拟点击
    qq空间认证教程:借助企鹅媒体平台认证QQ公众空间
    QQ空间认证之数据篇
    QQ空间运营 怎么做一个QQ人气号?
    QQ空间|qq人气号怎么赚钱?
    QQ好友的价值玩法 及如何搞到几万好友?
    新媒体运营之如何月涨十万粉
    社群经济:如何利用社群做营销?
  • 原文地址:https://www.cnblogs.com/LyShark/p/15019772.html
Copyright © 2011-2022 走看看