这两天学习了PE结构后,做了一个简单的内存加载demo。在完成这个demo期间也是遇到了很多问题,大部分的问题最后都得到了解决,但还是有一些问题依然困扰着我,我在最后将会提到。不过总的来说也算是顺利完成了这个demo。对于一个java程序员来说,理解内存和指针确实有些困难 。因此这次用C语言编写demo对我来说是个不小的挑战。不过同样也让我对底层有了更深入的了解。因此在这里做一个工作总结,加深一下印象,同时也希望有朋友能解答我的一些疑惑。

内存加载

  • win7内存加载
  • 节的映射
  • 修改重定位
  • 装载动态库
  • 修改入口点并跳转

win7内存加载

windows系统在启动一个程序前首先会对exe进行合法性检查等操作,紧接着就是划分4G的内存空间,创建进程和线程并把PE文件映射到2G的用户空间中,接着装载动态库并填写IAT表。然后按照重定位表进行重定位。最后启动线程执行程序入口点。我要做的是直接在内存中加载并运行test22.exe这个程序,因此我的程序只需要为test22.exe完成空间的申请、PE文件的内存映射、装载动态库填写IAT表、改写重定位表以及跳转到入口点就可以正常的运行test22.exe了。至于进程和线程的创建以及堆栈等资源直接由本程序初始化时的资源代替即可,我不需要考虑这些。接下来我将从以上的四个方面叙述我的工作过程。

节的映射

首先PE文件是由文件头部和各个节组成的。头部主要负责记载该PE文件的结构信息,其中对我们最有用的结构信息是选项表和数据目录以及节表。
在对节进行映射前我们需要根据选项表中的SizeOfImage项为程序申请内存空间,空间大小为SizeOfImage,紧接着就是根具节表中记录的节的信息把每一个节按照内存对齐的方式映射到内存中去。大概如下图所示:

节表的结构如下图所示。

内存申请代码:

在这里有个坑,在申请内存空间时一定要记得给执行权限,不然当程序跳转到这个内存空间的代码运行时就会直接报错。
节表加载代码:

修改重定位

节表加载完成后,由于我们申请的内存空间的起始地址NImageBase一般和PE文件的ImageBase是不一样的。而PE文件在编译生成时一些静态全局变量的地址是按照ImageBase+偏移生成的,因此代码中调用这些变量也是直接访问ImageBase+偏移这个地址。这样就会出错。因为ImageBase+偏移对我们来说可能是一个没用的地址。真正的变量是存放在NImageBase+偏移中的。所以我们需要把代码中访问ImageBase+偏移的代码改成访问NImageBase+偏移。

那么如何知道代码中哪些地方需要修改了?很幸运这些需要修改的地方都被记录在了重定位表中,我们只需要在数据目录中找到重定位表的位置信息就可以定位到重定位表,进而找到需要更改的代码。
重定位表按照PE文件大小分为很多项,每一项负责记录内存中长度为0x1000的数据块中需要重定位的地址信息。重定位表中的一项数据分别由前4个字节的重定位地址和四个字节的数据项长度以及后面每两个字节的地址信息组成。
我在读取到两个字节的地址信息后需要处理下(去掉最高位然后加上前4个字节的重定位地址)就可以得到需要更改的代码的内存地址。然后把ImageBase+偏移的代码改成NImageBase+偏移就可以了。
重定位表其中一项的图片如下:

RVA是需要修改的代码的内存地址。
重定位代码如下:

值得注意的是我高亮了的代码。这也是一个坑,exe和dll的重定位表有一个细微的差距,就是exe的重定位表会比dll多一个0项,如果不处理,那么就会改变不应该改变的代码,从而导致在运行过程中出现崩溃。

装载动态库

在处理完重定位后,还面临最后一个问题,加载动态库。每个程序都会或多或少引用一些动态库如user32.dll和kernel.dll等,PE文件中的IAT表负责存放动态库中被引用到的函数的地址,提供给程序访问调用。因此我们也需要填写IAT表,否则程序就无法正常运行。
要填写IAT表我们首先需要从数据目录中读取导入表的地址,然后根据导入表获得程序需要加载的动态库的名称以及调用的函数名称和对应的IAT表的位置。
导入表的每一项的长度为20字节,第1个4字节记录着函数名称地址数组的地址,倒数第1个4字节记录该库的IAT表地址,倒数第二个四字节则记录着动态库名称的地址。
导入表如下图:

函数名称地址数组:

值得注意的是地址数组每一项长度为4字节代表函数名称的地址,最后一个值为0的四字节表示数组结尾。同时在读取函数名称时需要跳过前2个字节
修复导入表代码:

值得注意的是在填写IAT表时,如果遇到这一项的IAT=0那么就可以不填写。同时填写IAT表的顺序和地址表是一致的

修改入口点并跳转

在完成上诉工作后,最后我们只需要修改选项头中的程序入口点(EntryPoint)为当前内存中的程序真实入口点的值,在写入头部到内存中就可以跳转到test22.exe程序执行了。
代码如下:

就成功啦

虽然最后做出来了,但还是有些问题不能理解,我看网上有些人说exe不能直接这样启动,而是需要启动一个进程然后把程序写入进程空间中在更改PEB中EAX为程序入口 地址才能执行。虽然这种方法确实可以,但我不太明白为什么我这样也成功了,是因为系统版本问题吗。

exe和dll的内存加载相关推荐

  1. 其原因可能是堆被损坏,这也说明 xxx.exe 中或它所加载的任何 DLL 中有 bug

    1.代码如下: string src ="abcdabcd"; char* dst = new char[8]; strcpy(dst,src.c_str()); delete[] ...

  2. 可能是堆被损坏,这也说明 XX.exe 中或它所加载的任何 DLL 中有 bug

    今天遇到一个很奇怪的问题, 当代码如下时: char* s = (char*)malloc(20*sizeof(char)); string buffer; const char* conchar; ...

  3. C++ windows已在xxx.exe中触发一个断点,其原因可能是堆被损坏,这说明xx.exe中或它所加载的任何DLL中有bug。

    windows已在xxx.exe中触发一个断点,其原因可能是堆被损坏,这说明xx.exe中或它所加载的任何DLL中有bug.  原因也可能是用户在xx.exe具有焦点时按下了F12.  输出窗口可能提 ...

  4. 静态链接库(LIB)和动态链接库(DLL),DLL的静态加载和动态加载,两种LIB文件。

    静态链接库(LIB)和动态链接库(DLL),DLL的静态加载和动态加载,两种LIB文件. 一. 静态链接库(LIB,也简称"静态库")与动态链接库(DLL,也简称"动态库 ...

  5. [Rootkit] 进程隐藏 - 内存加载(寄生僵尸进程)

    众所周知,windows下可执行文件必须符合一定的格式要求,微软官方称之为PE文件(关于PE文件的详细介绍这里就不赘述了,google一下可以找到大把):用户在界面双击exe时,有个叫做explore ...

  6. 支持64位系统的XOR加密后内存加载PE绕过杀毒软件

    http://bbs.pediy.com/showthread.php?t=203910 绝对自动支持32.64位的内存加载源码 无聊逛看雪时,看到了这个. 然后到github上找到了源.就是这里:h ...

  7. C语言实现shellcode通用框架二:文件下载执行或内存加载

    简介: 承接接上篇.上篇(C语言实现shellcode通用框架一:解密执行)我们的第二层shellcode核心代码都是事先加密好嵌套在第一层shellcode中,核心代码更新起来不方便.所以联网更新显 ...

  8. C++动态链接库DLL文件的加载

    本节内容 1.如何从DLL中获得资源(MFC DLL) 2.如何使用DEF文件导出函数 3.如何显式链接DLL 4.如何隐式链接DLL 5.如何在DLL中共享数据 6.如何在DLL中使用对话框资源(M ...

  9. 二、C++反作弊对抗实战 (进阶篇 —— 14.利用内存加载+重定向绕过inline iat hook)

    下面是成功绕过inline hook的运行效果: 一.前言 在前面的章节中讲述了inline hook.iat hook.seh/veh hook等原理以及代码实现,也在讲述inline hook时顺 ...

最新文章

  1. 五连阳回调买入法_只要出现“4连阳+1阴”形态,坚定满仓干进去,百分百是主升浪...
  2. linux c 字符串函数 replace indexOf substring 实现
  3. Cissp-【第3章 安全工程】-2021-2-24(322页-376页)
  4. Java入参关键字_Java基础17-成员变量、return关键字和多参方法
  5. [Leedcode][JAVA][第820题][字典树][Set]
  6. 谈身份管理之进阶篇 - 快速了解从管理到治理的最佳方案
  7. 使用 jQuery Mobile 与 HTML5 开发 Web App (十) —— jQuery Mobile 默认配置与事件基础
  8. Git 不能只会 pull 和 push,试试这5条提高效率的命令吧!
  9. git stash后怎么恢复_苹果换卡后怎么恢复通讯录?两种方法帮你解决
  10. macOS 安装和管理多个Python版本
  11. QQ去除未读状态的动画
  12. Ubuntu一些名词解释
  13. 计算机bios无法进入安全模式,电脑的BIOS设置能进入安全模式吗
  14. arcmap武汉市各个行政区域的森林覆盖率和水体覆盖率
  15. 登录微软账户后远程桌面连接提示用户名错误
  16. 分账功能对接解决方案
  17. 汾阳哪里有计算机培训班,汾阳市2020年第六期 吕梁山护工培训班开班
  18. 教你玩转iphone超实用的3D touch功能!
  19. CPP】【const 指针与引用】实验3实验内容5
  20. photoshop将图层导出到文件脚本不带数字序号、下划线方法

热门文章

  1. ios激活锁_如何检查iOS设备的激活锁状态
  2. 360随身WIFI作USB无线网卡的做法
  3. 关于while(t--)和while(--t)
  4. 学习笔记:FPGA之三人表决器
  5. [机缘参悟-30]:鬼谷子-内揵篇-同理心,站在对方的立场,拉近与对方的心理距离
  6. hc05与单片机连接图_lcd1602接线图_lcd1602与单片机连接图
  7. MPQ技术内幕(转载)
  8. Python--Flask在使用 SQLAlchemy出现'SQLALCHEMY_TRACK_MODIFICATIONS adds significant overhead and '
  9. 网站制作过程中需要注意的SEO知识
  10. PyG基于Node2Vec实现节点分类及其可视化