当前位置: 首页 > news >正文

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

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

1、流程:

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

2、实现

// 我自己定义的
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

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

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;
}

希望对你有所帮助

相关文章:

  • HackTheBox-Machines--Sense
  • 标题:Go语言中的YAML魔法:轻松配置你的环境
  • Python打印当前目录下,所有文件名的首字母
  • Centos7安装Docker和DockerCompose
  • DynamiCrafter ComfyUI 教程 | 对图片转视频的效果进行精细化控制
  • Spark_SparkOnHive_海豚调度跑任务写入Hive表失败解决
  • Mac/Linux getline 无法读取文件内容(读取内容无法显示)
  • 【数据库】MySQL表的操作
  • jenkins的简单使用
  • 函数尾调用优化
  • 面试官:对于MQ中的消息丢失你是如何理解的?
  • OpenAI助手API接入-问答对自动生成
  • 江苏大信环境科技有限公司:环保领域的开拓者与引领者
  • Anaconda中的常用科学计算工具
  • The Best Toolkit 最好用的工具集
  • 08.Android之View事件问题
  • Apache Zeppelin在Apache Trafodion上的可视化
  • JAVA_NIO系列——Channel和Buffer详解
  • laravel5.5 视图共享数据
  • leetcode378. Kth Smallest Element in a Sorted Matrix
  • MySQL数据库运维之数据恢复
  • PHP 7 修改了什么呢 -- 2
  • PHP 的 SAPI 是个什么东西
  • React-flux杂记
  • Redis提升并发能力 | 从0开始构建SpringCloud微服务(2)
  • Terraform入门 - 3. 变更基础设施
  • ViewService——一种保证客户端与服务端同步的方法
  • 阿里云容器服务区块链解决方案全新升级 支持Hyperledger Fabric v1.1
  • 解决iview多表头动态更改列元素发生的错误
  • 聊聊spring cloud的LoadBalancerAutoConfiguration
  • 盘点那些不知名却常用的 Git 操作
  • 批量截取pdf文件
  • 前端面试之CSS3新特性
  • 前嗅ForeSpider教程:创建模板
  • 收藏好这篇,别再只说“数据劫持”了
  • 小程序button引导用户授权
  • 走向全栈之MongoDB的使用
  • ionic入门之数据绑定显示-1
  • Java性能优化之JVM GC(垃圾回收机制)
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • 专访Pony.ai 楼天城:自动驾驶已经走过了“从0到1”,“规模”是行业的分水岭| 自动驾驶这十年 ...
  • ​​​​​​​Installing ROS on the Raspberry Pi
  • ​ssh-keyscan命令--Linux命令应用大词典729个命令解读
  • ​创新驱动,边缘计算领袖:亚马逊云科技海外服务器服务再进化
  • ​猴子吃桃问题:每天都吃了前一天剩下的一半多一个。
  • ###STL(标准模板库)
  • #pragma once
  • #我与Java虚拟机的故事#连载16:打开Java世界大门的钥匙
  • (51单片机)第五章-A/D和D/A工作原理-A/D
  • (C语言)fread与fwrite详解
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第2节(共同的基类)
  • (Repost) Getting Genode with TrustZone on the i.MX
  • (Windows环境)FFMPEG编译,包含编译x264以及x265
  • (八十八)VFL语言初步 - 实现布局
  • (超详细)语音信号处理之特征提取