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

10.3 调试事件转存进程内存

我们继续延申调试事件的话题,实现进程转存功能,进程转储功能是指通过调试API使获得了目标进程控制权的进程,将目标进程的内存中的数据完整地转存到本地磁盘上,对于加壳软件,通常会通过加密、压缩等手段来保护其代码和数据,使其不易被分析。在这种情况下,通过进程转储功能,可以将加壳程序的内存镜像完整地保存到本地,以便进行后续的分析。

在实现进程转储功能时,主要使用调试API和内存读写函数。具体实现方法包括:以调试方式启动目标进程,将其暂停在运行前的位置;让目标进程进入运行状态;使用ReadProcessMemory函数读取目标进程内存,并将结果保存到缓冲区;将缓冲区中的数据写入文件;关闭目标进程的调试状态。

首先老样子先来看OnException回调事件,当进程被断下时首先通过线程函数恢复该线程的状态,在进程被正确解码并运行起来时直接将该进程的EIP入口地址传递给MemDump();内存转存函数,实现转存功能;

void OnException(DEBUG_EVENT *pDebug, BYTE *bCode)
{CONTEXT context;DWORD dwNum;BYTE bTmp;// 打开当前进程与线程HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pDebug->dwProcessId);printf("[+] 当前打开进程句柄: %d 进程PID: %d \n", hProcess, pDebug->dwProcessId);HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, pDebug->dwThreadId);printf("[+] 当前打开线程句柄: %d 线程PPID: %d \n", hThread, pDebug->dwThreadId);// 暂停当前线程SuspendThread(hThread);// 读取出异常产生的首地址ReadProcessMemory(hProcess, pDebug->u.Exception.ExceptionRecord.ExceptionAddress, &bTmp, sizeof(BYTE), &dwNum);printf("[+] 当前异常产生地址为: 0x%08X \n", pDebug->u.Exception.ExceptionRecord.ExceptionAddress);// 设置当前线程上下文,获取线程上下文context.ContextFlags = CONTEXT_FULL;GetThreadContext(hThread, &context);printf("[-] 恢复断点前: EAX = 0x%08X  EIP = 0x%08X \n", context.Eax, context.Eip);// 将刚才的CC断点取消,也就是回写原始的指令集WriteProcessMemory(hProcess, pDebug->u.Exception.ExceptionRecord.ExceptionAddress, bCode, sizeof(BYTE), &dwNum);// 当前EIP减一并设置线程上下文context.Eip--;SetThreadContext(hThread, &context);printf("[+] 恢复断点后: EAX = 0x%08X  EIP = 0x%08X \n", context.Eax, context.Eip);printf("[+] 获取到动态入口点: 0x%08x \n", pDebug->u.CreateProcessInfo.lpBaseOfImage);// 转储内存镜像MemDump(pDebug, context.Eip, (char *)"dump.exe");// 恢复线程ResumeThread(hThread);CloseHandle(hThread);CloseHandle(hProcess);
}

MemDump函数中,首先通过调用CreateFile函数打开me32.szExePath路径也就是转存之前的文件,通过使用VirtualAlloc分配内存空间,分配大小是PE头中文件实际大小,接着OpenProcess打开正在运行的进程,并使用ReadProcessMemory读取文件的数据,此处读取的实在内存中的镜像数据,当读取后手动修正,文件的入口地址,及文件的对齐方式,接着定位PE节区数据,找到节区首地址,并循环将当前节区数据赋值到新文件缓存中,最后当一切准备就绪,通过使用WriteFile函数将转存后的文件写出到磁盘中;

void MemDump(DEBUG_EVENT *pDe, DWORD dwEntryPoint, char *DumpFileName)
{// 得到当前需要操作的进程PIDDWORD dwPid = pDe->dwProcessId;MODULEENTRY32 me32;// 对系统进程拍摄快照HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPid);me32.dwSize = sizeof(MODULEENTRY32);// 得到第一个模块句柄,第一个模块句柄也就是程序的本体BOOL bRet = Module32First(hSnap, &me32);printf("[+] 当前转储原程序路径: %s \n", me32.szExePath);// 打开源文件,也就是dump之前的文件HANDLE hFile = CreateFile(me32.szExePath, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);if (hFile == INVALID_HANDLE_VALUE)exit(0);// 判断PE文件的有效性IMAGE_DOS_HEADER imgDos = { 0 };IMAGE_NT_HEADERS imgNt = { 0 };DWORD dwReadNum = 0;// 读入当前内存程序的DOS头结构ReadFile(hFile, &imgDos, sizeof(IMAGE_DOS_HEADER), &dwReadNum, NULL);// 判断是否是一个合格的DOS头if (imgDos.e_magic != IMAGE_DOS_SIGNATURE)return;// 设置文件指针到NT头上SetFilePointer(hFile, imgDos.e_lfanew, 0, FILE_BEGIN);ReadFile(hFile, &imgNt, sizeof(IMAGE_NT_HEADERS), &dwReadNum, NULL);// 判断是否是合格的NT头if (imgNt.Signature != IMAGE_NT_SIGNATURE)return;// 得到EXE文件的大小DWORD BaseSize = me32.modBaseSize;printf("[+] 当前内存文件大小: %d --> NT结构原始大小: %d 一致性检测: True \n", BaseSize, imgNt.OptionalHeader.SizeOfImage);// 如果PE头中的大小大于实际内存大小,则以PE头中大小为模板if (imgNt.OptionalHeader.SizeOfImage > BaseSize){BaseSize = imgNt.OptionalHeader.SizeOfImage;}// 分配内存空间,分配大小是PE头中文件实际大小,并打开进程LPVOID pBase = VirtualAlloc(NULL, BaseSize, MEM_COMMIT, PAGE_READWRITE);printf("[+] 正在分配转储空间 句柄: %d \n", pBase);HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);// 读取文件的数据,此处读取的实在内存中的镜像数据bRet = ReadProcessMemory(hProcess, me32.modBaseAddr, pBase, me32.modBaseSize, NULL);// 判断PDOS头的有效性PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)pBase;if (pDos->e_magic != IMAGE_DOS_SIGNATURE)return;// 计算出NT头数据PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + (PBYTE)pBase);if (pNt->Signature != IMAGE_NT_SIGNATURE)return;// 设置文件的入口地址pNt->OptionalHeader.AddressOfEntryPoint = dwEntryPoint - pNt->OptionalHeader.ImageBase;printf("[*] 正在设置Dump文件相对RVA入口地址: 0x%08X \n", pNt->OptionalHeader.AddressOfEntryPoint);// 设置文件的对齐方式pNt->OptionalHeader.FileAlignment = 0x1000;printf("[*] 正在设置Dump文件的对齐值: %d \n", pNt->OptionalHeader.FileAlignment);// 找到节区首地址,并循环将当前节区数据赋值到新文件缓存中PIMAGE_SECTION_HEADER pSec = (PIMAGE_SECTION_HEADER)((PBYTE)&pNt->OptionalHeader + pNt->FileHeader.SizeOfOptionalHeader);for (int i = 0; i < pNt->FileHeader.NumberOfSections; i++){pSec->PointerToRawData = pSec->VirtualAddress;printf("[+] 正在将虚拟地址: 0x%08X --> 设置到文件地址: 0x%08X \n", pSec->VirtualAddress, pSec->PointerToRawData);pSec->SizeOfRawData = pSec->Misc.VirtualSize;printf("[+] 正在将虚拟大小: %d --> 设置到文件大小: %d \n", pSec->Misc.VirtualSize, pSec->SizeOfRawData);pSec++;}CloseHandle(hFile);// 打开转储后的文件.hFile = CreateFile(DumpFileName, GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);if (hFile == INVALID_HANDLE_VALUE)exit(0);printf("[*] 转储 %s 文件到本地 \n", DumpFileName);DWORD dwWriteNum = 0;// 将读取的数据写入到文件bRet = WriteFile(hFile, pBase, me32.modBaseSize, &dwWriteNum, NULL);if (dwWriteNum != me32.modBaseSize || FALSE == bRet)printf("写入错误 !");// 关闭于释放资源CloseHandle(hFile);VirtualFree(pBase, me32.modBaseSize, MEM_RELEASE);CloseHandle(hProcess);CloseHandle(hSnap);
}

读者可自行运行这段程序,当程序运行后即可将指定的一个文件内存数据完整的转存到磁盘中,输出效果如下图所示;

本文作者: 王瑞
本文链接: https://www.lyshark.com/post/5e2f7b11.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

相关文章:

10.3 调试事件转存进程内存

我们继续延申调试事件的话题&#xff0c;实现进程转存功能&#xff0c;进程转储功能是指通过调试API使获得了目标进程控制权的进程&#xff0c;将目标进程的内存中的数据完整地转存到本地磁盘上&#xff0c;对于加壳软件&#xff0c;通常会通过加密、压缩等手段来保护其代码和数…...

深度学习实战基础案例——卷积神经网络(CNN)基于MobileNetV3的肺炎识别|第3例

文章目录 前言一、数据集介绍二、前期工作三、数据集读取四、构建CA注意力模块五、构建模型六、开始训练 前言 Google公司继MobileNetV2之后&#xff0c;在2019年发表了它的改进版本MobileNetV3。而MobileNetV3共有两个版本&#xff0c;分别是MobileNetV3-Large和MobileNetV2-…...

机器学习 面试/笔试题(更新中)

1. 生成模型 VS 判别模型 生成模型&#xff1a; 由数据学得联合概率分布函数 P ( X , Y ) P(X,Y) P(X,Y),求出条件概率分布 P ( Y ∣ X ) P(Y|X) P(Y∣X)的预测模型。 朴素贝叶斯、隐马尔可夫模型、高斯混合模型、文档主题生成模型&#xff08;LDA&#xff09;、限制玻尔兹曼机…...

【算法题】100019. 将数组分割成最多数目的子数组

插&#xff1a; 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 坚持不懈&#xff0c;越努力越幸运&#xff0c;大家一起学习鸭~~~ 题目&#xff1a; 给你一个只包含 非负 整数的数组 n…...

commons-io工具类常用方法

commons-io是Apache Commons项目的一个模块&#xff0c;提供了一系列处理I/O&#xff08;输入/输出&#xff09;操作的工具类和方法。它旨在简化Java I/O编程&#xff0c;并提供更多的功能和便利性。 读取文件内容为字符串 String path"C:\\Users\\zhang\\Desktop\\myyii\…...

【Typescript】面向对象(上篇),包含类,构造函数,继承,super,抽象类

假期第七篇&#xff0c;对于基础的知识点&#xff0c;我感觉自己还是很薄弱的。 趁着假期&#xff0c;再去复习一遍 面向对象&#xff1a;程序中所有的操作都需要通过对象来完成 计算机程序的本质就是对现实事物的抽象&#xff0c;抽象的反义词是具体。比如照片是对一个具体的…...

【python】python中字典的用法记录

文章目录 序言1. 字典的创建和访问2. 字典如何添加元素3. 字典作为函数参数4. 字典排序 序言 总结字典的一些常见用法 1. 字典的创建和访问 字典是一种可变容器类型&#xff0c;可以存储任意类型对象 key : value&#xff0c;其中value可以是任何数据类型&#xff0c;key必须…...

基于Java的大学生心理咨询系统设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…...

Redis-双写一致性

双写一致性 双写一致性解决方案延迟双删&#xff08;有脏数据的风险&#xff09;分布式锁&#xff08;强一致性&#xff0c;性能比较低&#xff09;异步通知&#xff08;保证数据的最终一致性&#xff0c;高并发情况下会出现短暂的不一致情况&#xff09; 双写一致性 当修改了数…...

CustomTkinter:创建现代、可定制的Python UI

文章目录 介绍安装设置外观与主题外观模式主题设置自定义主题颜色窗口缩放CTkFont字体设置CTkImage图片Widgets窗口部件CTk Windows窗口CTk窗口CTkInputDialog对话框CTkToplevel顶级窗口布局pack布局palce布局Grid 网格布局Frames 框架Frames滚动框架...

华为OD机试真题【不含 101 的数】

1、题目描述 【不含 101 的数】 【题目描述】 小明在学习二进制时&#xff0c;发现了一类不含 101的数&#xff0c;也就是&#xff1a; 将数字用二进制表示&#xff0c;不能出现 101 。 现在给定一个整数区间 [l,r] &#xff0c;请问这个区间包含了多少个不含 101 的数&#…...

Spring IoC和DI详解

IOC思想 IoC&#xff08; Inversion of Control&#xff0c;控制反转&#xff09; 不是一门具体技术&#xff0c;而是一种设计思想&#xff0c; 是一种软件设计原则&#xff0c;它将应用程序的控制权&#xff08;Bean的创建和依赖关系&#xff09;从应用程序代码中解耦出来&am…...

mysql-binlog

1. 常用的binlog日志操作命令 1. 查看bin-log是否开启 show variables like log_%;2. 查看所有binlog日志列表 show master logs;3.查看master状态 show master status;4. 重置&#xff08;清空&#xff09;所有binlog日志 reset master;2. 查看binlog日志内容 1、使用mysqlb…...

通过BeanFactotyPostProcessor动态修改@FeignClient的path

最近项目有个需求&#xff0c;要在启动后&#xff0c;动态修改FeignClient的请求路径&#xff0c;网上找到的基本都是在FeignClient里使用${…}&#xff0c;通过配置文件来定义Feign的接口路径&#xff0c;这并不能满足我们的需求 由于某些特殊原因&#xff0c;我们的每个接口…...

数据结构与算法系列-二分查找

二分查找 什么是二分查找&#xff1f; 二分查找是一种针对有序集合&#xff0c;每次将要查找的区间缩小一半&#xff0c;直到找到查找元素&#xff0c;或区间被缩小为0。 如何实现二分查找&#xff1f; 实现有3个注意点&#xff1a; 终止条件是 low < high 2.求中点的算…...

CSS 毛玻璃特效运用目录

主要是记录毛玻璃相关的特效实践案例和实现思路。 章节名称完成度难度文章地址完整代码下载地址Glassmorphism 登录表单完成一般文章链接代码下载Glassmorphism 按钮悬停效果完成一般文章链接代码下载Glassmorphism 计算器完成一般文章链接代码下载Glassmorphism 卡片悬停效果…...

如何在Qt6中引入Network模块

2023年10月1日&#xff0c;周日凌晨 2023年10月2日&#xff0c;周一下午 第一次更新 目录 如果用的是CMakeQt Console ApplicationQt Widgets Application如果用的是qmake 如果用的是CMake find_package(Qt6 COMPONENTS Network REQUIRED) target_link_libraries(mytarget…...

2023/10/4 QT实现TCP服务器客户端搭建

服务器端&#xff1a; 头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTcpServer> #include <QTcpSocket> #include <QList> #include <QMessageBox> #include <QDebug>QT_BEGIN_NAMESPACE namespace Ui { cla…...

云原生边缘计算KubeEdge安装配置

1. K8S集群部署&#xff0c;可以参考如下博客 请安装k8s集群&#xff0c;centos安装k8s集群 请安装k8s集群&#xff0c;ubuntu安装k8s集群 2.安装kubEedge 2.1 编辑kube-proxy使用ipvs代理 kubectl edit configmaps kube-proxy -n kube-system #修改kube-proxy#大约在40多行…...

【LeetCode热题100】--35.搜索插入位置

35.搜索插入位置 使用二分查找&#xff1a; class Solution {public int searchInsert(int[] nums, int target) {int low 0,high nums.length -1;while(low < high){//注意每次循环完都要计算midint mid (low high)/2;if(nums[mid] target){return mid;}if(nums[mid]…...

在软件开发中正确使用MySQL日期时间类型的深度解析

在日常软件开发场景中&#xff0c;时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志&#xff0c;到供应链系统的物流节点时间戳&#xff0c;时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库&#xff0c;其日期时间类型的…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

提升移动端网页调试效率:WebDebugX 与常见工具组合实践

在日常移动端开发中&#xff0c;网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时&#xff0c;开发者迫切需要一套高效、可靠且跨平台的调试方案。过去&#xff0c;我们或多或少使用过 Chrome DevTools、Remote Debug…...

MySQL的pymysql操作

本章是MySQL的最后一章&#xff0c;MySQL到此完结&#xff0c;下一站Hadoop&#xff01;&#xff01;&#xff01; 这章很简单&#xff0c;完整代码在最后&#xff0c;详细讲解之前python课程里面也有&#xff0c;感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...

中科院1区顶刊|IF14+:多组学MR联合单细胞时空分析,锁定心血管代谢疾病的免疫治疗新靶点

中科院1区顶刊|IF14&#xff1a;多组学MR联合单细胞时空分析&#xff0c;锁定心血管代谢疾病的免疫治疗新靶点 当下&#xff0c;免疫与代谢性疾病的关联研究已成为生命科学领域的前沿热点。随着研究的深入&#xff0c;我们愈发清晰地认识到免疫系统与代谢系统之间存在着极为复…...

多模态大语言模型arxiv论文略读(110)

CoVLA: Comprehensive Vision-Language-Action Dataset for Autonomous Driving ➡️ 论文标题&#xff1a;CoVLA: Comprehensive Vision-Language-Action Dataset for Autonomous Driving ➡️ 论文作者&#xff1a;Hidehisa Arai, Keita Miwa, Kento Sasaki, Yu Yamaguchi, …...

使用homeassistant 插件将tasmota 接入到米家

我写一个一个 将本地tasmoat的的设备同通过ha集成到小爱同学的功能&#xff0c;利用了巴法接入小爱的功能&#xff0c;将本地mqtt转发给巴法以实现小爱控制的功能&#xff0c;前提条件。1需要tasmota 设备&#xff0c; 2.在本地搭建了mqtt服务可&#xff0c; 3.搭建了ha 4.在h…...