加壳与脱壳----壳的原理
PE结构体
1 PE文件结构图
PE文件用硬盘到能运行起来经历的步骤
1 将pe文件copy到内存
2 按内存对齐值对齐
3 加载dll
4 修复 IAT、重定位表
程序允许
操作系统通过读取PE文件的addressOfEntryPoint(OEP)+PE文件的imagebase加载基址位置开始执行代码
壳的原理
修改OEP将OEP指向自己的壳代码所在的地址运行,执行完后再跳回真正的OEP
难点:
1 代码放在哪里
放在可执行的区段里面,可以查看区段头看execute属性是否为1,
当然.text区段通常是可行的,因为.text代表的是代码段
那么代码如何放呢?肯定是不能覆盖原有的东西,需要在新的空白的地方来代码,通常由于对齐的原因,所以会有空白的地方产生,就在空白的地方写代码就好了
2 代码怎么写--shellcode
假设这里要写一个弹出MessageBoxA
就很简单
push 0 6A 00
push 0 6A 00
push 0 6A 00
push 0 6A 00
call MessageBoxA E8 xxxxxxx
E8 xxxx的硬编码等于两个函数地址偏移值-5
3 如何回到原始OEP 直接jmp回去就好了
jmp oep E9 xxxxxxx
E9 xxxx后面的硬编码等于地址相减再减2
Hello Shell--代码编写
对一个简单的exe添加壳,在调用exe前先调用一个壳代码,然后再返回执行正常的exe代码逻辑
1 找到要调用的MessageBoxA地址
因为这里要调用的是MessageBoxA的地址
所以这里我直接通过分析客户端找到了一个MessageBoxA的地址
直接在od里面输入API名称,然后就可以得到首地址,这里我的首地址是
0x74B61930
得到call 的硬编码
call xxxx
得硬编码对应的应该是E8 yyyyy
这里的yyyy = 要调用的函数的地址-当前地址-5的值
所以这里需要得到call这个指令的内存地址
这里的话直接通过loadPE,查找.text区段找到我们要实现存放硬编码的地址处理就好了
这里的黑色的范围就都是.text的范围
这里我选择0x00000850来处理
但是需要注意的是,这个是文件中的偏移地址FOA,需要计算成内存中的编译地址VOA才行
这里继续可以用LoraPE里面的
拿到VA就好了
拿到VA后,MessageBoxA-VA-5 = call后面的硬编码地址
2 得到jmp的地址
同样jmp 是E9 xxx
这个xxx的地址也和上一个call xxx的硬编码所求的方法一样
3 通过010 Editor修改