使用 C++ 在当前进程中获取指定模块的基址

C++ 实现 , 获取指定模块在该进程中的基址

1、流程:

获取进程的所有模块信息-->遍历模块列表

2、实现

cpp 复制代码
// 我自己定义的
typedef struct moudle_date_ {
	HANDLE mhandle;   // 句柄
	char mname[64];   // 名称
	char* date;       // 数据
	DWORD mdword;     // 基址 
}moudle_date;

// 传入该进程的 pid 、需要查找模块的名称
moudle_date* getMoudle(DWORD pid, const char* name) {
	moudle_date* date = nullptr;
	/*
    CreateToolhelp32Snapshot()->获取指定进程以及这些进程使用的堆、模块和线程的快照。
    TH32CS_SNAPALL -> 包括系统中的所有进程和线程,以及 pid 中指定的进程的堆和模块。
    return value : 如果函数成功,它将返回指定快照的打开句柄。如果函数失败,它将返回 INVALID_HANDLE_VALUE
    */
	HANDLE handle = CreateToolhelp32Snapshot( TH32CS_SNAPALL,  pid );

	std::cout << "getMoudle::handle :" << std::hex<<handle << std::endl;
	if ( handle == INVALID_HANDLE_VALUE) {
		std::cout << "Error CreateToolhelp32Snapshot" << std::endl;
		return nullptr;
	}
	/*
	MODULEENTRY32:Windows API 中定义的一个结构体,用于存储模块的信息。
	*/
	MODULEENTRY32 info;
	memset(&info, 0, sizeof(info));
    // dwSize 结构体的大小,一定要设置,为 Module32First、Module32Next做准备
	info.dwSize = sizeof(MODULEENTRY32);

	char sname[256];
	strcpy_s(sname, sizeof(sname) , name);

	/*
	循环遍历模块 ,找到基址
	Module32First() : 检索与进程关联的第一个模块的相关信息。
	传入参数: CreateToolhelp32Snapshot返回的进程句柄、info(MODULEENTRY32)
	返回值 : bool类型,成功返回true. 失败返回false.
	*/
	bool ret = Module32First( handle, &info);
	if (!ret) {
        /*
        GetLastError(): 获取错误代码.
        返回类型 DWORD.
        */
		DWORD err = GetLastError();
		std::cout << "getMoudle::GetLastError : "<<err << std::endl;
		return nullptr;
	}
	while ( ret ) {
		// szModule -> 模块的名称
        // 注意: szModule的类型是 wchar_t 宽字节
        // 我们传入的模块名称 类型是 char ,所以需要进行类型转换,才能够比较
		if ( strcmp( UnicodeToUtf8(info.szModule) , sname)== 0 ) {
			date = new moudle_date;
            // modBaseAddr ->MODULEENTRY32结构体中的成员,模块的基址
			date->mdword = (DWORD)info.modBaseAddr;
			CloseHandle(handle);  // 清理资源
			return date;
		}
		/*
		Module32Next(): 获取下一个模块的信息
		*/
		ret = Module32Next( handle, &info);
	}
	return nullptr;
}

补充:UnicodeToUtf8 -> 如何将宽字符字符串转换为 UTF-8 编码的字符串UnicodeToUtf8

这些你可以不需要知道怎么实现的,直接拿来用就好了,没有人会去记这些东西。

cpp 复制代码
char* UnicodeToUtf8(const wchar_t* lpszStr)
{
	char* lpUtf8;
	int nLen;

	if (NULL == lpszStr)
		return NULL;

	nLen = ::WideCharToMultiByte(CP_UTF8, 0, lpszStr, -1, NULL, 0, NULL, NULL);
	if (0 == nLen)
		return NULL;

	lpUtf8 = new char[nLen + 1];
	if (NULL == lpUtf8)
		return NULL;
	memset(lpUtf8, 0, nLen + 1);
	nLen = ::WideCharToMultiByte(CP_UTF8, 0, lpszStr, -1, lpUtf8, nLen, NULL, NULL);
	if (0 == nLen)
	{
		delete[]lpUtf8;
		return NULL;
	}
	return lpUtf8;
}

希望对你有所帮助

相关推荐
草莓熊Lotso14 分钟前
《算法闯关指南:优选算法-双指针》--01移动零,02复写零
c语言·c++·经验分享·算法·leetcode
太阳的后裔19 分钟前
随笔一些用C#封装的控件
开发语言·c#
tianyuanwo19 分钟前
Rust语言组件RPM包编译原理与Cargo工具详解
开发语言·网络·rust·rpm
ajassi20004 小时前
开源 C++ QT Widget 开发(十五)多媒体--音频播放
linux·c++·qt·开源
CodeCraft Studio5 小时前
PDF处理控件Aspose.PDF教程:使用 Python 将 PDF 转换为 Base64
开发语言·python·pdf·base64·aspose·aspose.pdf
零点零一5 小时前
VS+QT的编程开发工作:关于QT VS tools的使用 qt的官方帮助
开发语言·qt
鹅毛在路上了7 小时前
C++, ffmpeg, libavcodec-RTSP拉流,opencv实时预览
c++·opencv·ffmpeg
John_ToDebug7 小时前
定制 ResourceBundle 的实现与 DuiLib 思想在 Chromium 架构下的应用解析
c++·chrome·ui
lingchen19067 小时前
MATLAB的数值计算(三)曲线拟合与插值
开发语言·matlab
gb42152877 小时前
java中将租户ID包装为JSQLParser的StringValue表达式对象,JSQLParser指的是?
java·开发语言·python