1、C++源码
#include <iostream>
#include<windows.h>
int main()
{
int i = 1;
std::cin >> i;
if (i == 100)
{
MessageBoxA(0, 0, 0, 0);
}
return 0;
}
2、将上述源码编译成可执行文件PEParase.exe,备用
3、使用010Editor打开该exe文件,查找PE头尾部空白区,确定代码添加位置,如下图所示,此处选择的FOA位置是3C0h
4、确定插入的代码,此处选择在程序执行之前先弹出一个空白的消息框,对应的shellcode代码模板如下:
6A 00 6A 00 6A 00 6A 00 E8 00 00 00 00 E9 00 00 00 00
5、在OD中查看MessageBoxA函数的地址为0x75D9FD1E,如下图所示:
6、计算E8指令之后的偏移量(E8指令翻译成汇编代码是call指令):
E8指令地址 = (ImageBase+0x358) = 0x400000 + 0x3C8 = 0x4003C8
偏移量= 要跳转的虚拟内存地址 - E8指令的虚拟内存地址 - 5
E8指令后的值:0x75D9FD1E - 0x4003C8 - 5 = 0x75 99 F9 51
注意,计算出来的偏移量是大端序,后续写入shellcode中时需要转成小端序。
7、计算E9指令之后的偏移量(E9对应于汇编指令jmp),此处就是要跳转到程序的原OEP:
查看原OEP地址:0x11023
注意上述OEP是相对虚拟地址,计算时需要加上PE文件中的ImageBase,偏移量计算过程如下:
程序入口地址=0x11023+0x400000=0x411023
E9指令地址=(ImageBase + 0x3CD)=0x4003CD
E9之后的地址=入口地址-E9指令地址-5=0x00 01 0C 51
注意上述的偏移还是大端,写入shellcode时需要转成小端序,因此最终的shellcode代码如下:
6A 00 6A 00 6A 00 6A 00 E8 51 F9 99 75 E9 51 0C
01 00
在010Editor中将上述shellcode写入PeParase.exe文件的0x3C0处,如下所示:
8、在010Editor中将EOP改为3C0h,如下图所示
9、写入完成之后保存exe文件,此处我是另存为了PEParse_1_bigEndian.exe,然后使用OD打开该exe程序,显示如下:
可见修改是成功了的,但运行时翻车了(如下图),暂时还不清楚为啥,等日后回来填坑。