首先什么是壳
作者编好软件后,编译成exe可执行文件。
1.有一些版权信息需要保护起来,不想让别人随便改动,如作者的姓名等,即为了保护软件不被破解,通常都是采用加壳来进行保护。
2.需要把程序搞的小一点,从而方便使用。于是,需要用到一些软件,它们能将exe可执行文件压缩。
3.在黑客界给木马等软件加壳以躲避杀毒软件。
壳的分类:
压缩壳和加密壳
如何分辨加密壳和压缩壳,通用特点,Od载入时有入口警告或询问是压缩程序吗?普通压缩壳Od调试时候没有异常,加密壳全部有反跟踪代码,会有许多SEH陷阱使OD调试时产生异常。
找OEP的方法:
1. 单步跟踪 遇到跑飞的call要f7步入,遇到向上的跳转F4(执行到所选位置)不让它实现,一般大跳转会跳到OEP。一般压缩壳要F8步过,加密壳要F7步入。近call要f7跟进,远call要f8跟进。
2. ESP定律 ESP是种指针寄存器 遵循堆栈平衡原理
一般入栈之后 看关键句数据窗口跟随 下硬件断点,运行,删除硬件断点,单步几步。也可以记下ESP地址,并在左下角的Command中输入dd ESP所对应的地址。并回车。
FSG专用ESP定律 没有遵循堆栈平衡。 Popad下一行。下面堆栈窗口第四行固定位置,反汇编窗口跟随,下硬件断点,shift+F9,跳到OEP
3. 两次内存镜像法 经过两次调用内存,然后在.risc处下断点,shift+F9,运行 , 再内存 ,找CODE(资源),下断,再执行,出来单步跟,如果没有.rsrc的情况直接找00401000下断。
4. 模拟跟踪 前提无seh暗桩
1) Sfx跟踪 调试设置sfx选项卡
2) 查看内存 SFX,imports,relocations tc eip<地址
5. 最后一次异常法 取消忽略所有异常,除kernel32,看se句柄,转到表达式。下断点。
6. 查找popad,适用于简单压缩壳,不要勾选整个块
7. od脚本查找oep
8. 特殊方法
1) at GetVersion 适合于北斗3.0以下
2) 下断:BP IsDebuggerPresent运行,取消断点 返回到用户代码ALT+F9计算ss+edi 转到OEP!EXE32Pack 1.3x
3) at GetVersionretn下断点 单步附近跟。
4) BP VirtualFree SHIFT+F9,取消断点 ALT+F9查找 push 8000(特征码) 运行到这 单步跟 强壳
5) BP VirtualFree 两次SHIFT+F9中断后取消断点,Alt+F9返回 单步走。
6) Bp mov特殊值 然后分析,单步
7) bp VirtualAlloc SHIFT+F9运行取消断点 ALT+F9向下拉,看到JMP。运行到这(3到7是PECompact2.X)
8)
脱壳的方法:
1. Peid插件脱壳
2. Od插件脱壳 用ollydump脱壳调试进程,方式一(在内存镜像中搜索JMP[API]︱CALL[API])方式二(在脱壳文件中搜索DLL&API名称)
3. Lordpe脱壳然后重建输入表
4. 脱壳机
思考:
1. 如何从系统领空到程序领空?
2. 关于汇编的test的判断
3. 一些下条件断点的情况
需注意:
1. 加密壳必须修正镜像大小
2. 首先应该判断入口点是否正确Lordpe修正镜像大小,IMPORTREC抓取活动进程,输入oep,获取IAT,修正iat,显示无效函数,修复无效函数,剪切指针,转存文件。
3. 汉化的ir无法修复的话,尝试用英文版的。
4. 如果等级三跟踪死机,可能是od中打开的缘故,打开原来的文件,然后importrec再等级三跟踪。
5. Lordpe也可以重建PE试下。
6. 手动查找IAT 命令输入d 跟的call 数据窗口中跟随
7. 如何修复无效函数,先用等级一,尝试一下等级三。
8. WINHEX处理附加数据 [overlay]
9. 但是有些call是变形的Jmp,此时就需要F7步入,区别是否是变形Jmp的一个简单方法是比较call的目标地址和当前地址,如果两者离的很近,一般就是变形Jmp了。
常见语言的OEP(程序入口点):
Microsoft Visual C++ 6.0
00496EB8 >/$ 55 PUSH EBP ; (初始 cpu 选择)
00496EB9 |. 8BEC MOV EBP,ESP
00496EBB |. 6A FF PUSH -1
00496EBD |. 68 40375600 PUSH Screensh.00563740
00496EC2 |. 68 8CC74900 PUSH Screensh.0049C78C ; SE 处理程序安装
00496EC7 |. 64:A1 0000000>MOV EAX,DWORDPTR FS:[0]
00496ECD |. 50 PUSH EAX
00496ECE |. 64:8925 00000>MOV DWORD PTRFS:[0],ESP
00496ED5 |. 83EC 58 SUB ESP,58
Microsoft Visual C++ 6.0 [Overlay] E语言
00403831 >/$ 55 PUSH EBP
00403832 |. 8BEC MOV EBP,ESP
00403834 |. 6A FF PUSH -1
00403836 |. 68 F0624000 PUSH Nisy521.004062F0
0040383B |. 68 A44C4000 PUSH Nisy521.00404CA4 ; SE 处理程序安装
00403840 |. 64:A1 0000000>MOV EAX,DWORDPTR FS:[0]
00403846 |. 50 PUSH EAX
00403847 |. 64:8925 00000>MOV DWORD PTRFS:[0],ESP
Microsoft Visual Basic 5.0 / 6.0
00401166 - FF25 6C104000 JMP DWORD PTRDS:[<&MSVBVM60.#100>] ; MSVBVM60.ThunRTMain
0040116C > 68 147C4000 PUSH PACKME.00407C14
00401171 E8 F0FFFFFF CALL<JMP.&MSVBVM60.#100>
00401176 0000 ADD BYTE PTR DS:[EAX],AL
00401178 0000 ADD BYTE PTRDS:[EAX],AL
0040117A 0000 ADD BYTE PTRDS:[EAX],AL
0040117C 3000 XOR BYTE PTRDS:[EAX],AL
或省略第一行的JMP
00401FBC > 68 D0D44000 push dumped_.0040D4D0
00401FC1 E8 EEFFFFFF call<jmp.&msvbvm60.ThunRTMain>
00401FC6 0000 add byte ptrds:[eax],al
00401FC8 0000 add byte ptrds:[eax],al
00401FCA 0000 add byte ptrds:[eax],al
00401FCC 3000 xor byte ptrds:[eax],al
00401FCE 0000 add byte ptrds:[eax],al
delphi:
004A5C54 > 55 push ebp
004A5C55 8BEC mov ebp,esp
004A5C57 83C4 F0 add esp,-10
004A5C5A B8 EC594A00 moveax,openpro.004A59EC
BC++:
00401678 > /EB 10 jmp short btengine.0040168A
0040167A |66:623A bound di,dwordptr ds:[edx]
0040167D |43 inc ebx
0040167E |2B2B sub ebp,dword ptrds:[ebx]
00401680 |48 dec eax
00401681 |4F dec edi
00401682 |4F dec edi
00401683 |4B dec ebx
00401684 |90 nop
00401685 -|E9 98005400 jmp 00941722
0040168A \A1 8B005400 mov eax,dword ptrds:[54008B]
0040168F C1E0 02 shl eax,2
00401692 A3 8F005400 mov dword ptrds:[54008F],eax
00401697 52 push edx
00401698 6A 00 push 0
0040169A E8 99D01300 call<jmp.&KERNEL32.GetModuleHandleA>
0040169F 8BD0 mov edx,eax
MASM(汇编):
004035C9 > 6A 00 push 0
004035CB E8 A20A0000 call<jmp.&kernel32.GetModuleHandleA>
004035D0 A3 5B704000 mov dword ptrds:[40705B],eax
004035D5 68 80000000 push 80
004035DA 68 2C754000 push 11.0040752C
004035DF FF35 5B704000 push dword ptrds:[40705B]
004035E5 E8 820A0000 call<jmp.&kernel32.GetModuleFileNameA>
004035EA E8 87070000 call 11.00403D76
004035EF 6A 00 push 0
004035F1 68 0B364000 push 11.0040360B
004035F6 6A 00 push 0
004035F8 6A 64 push 64
004035FA FF35 5B704000 push dword ptrds:[40705B]
一些名词的概述:
esp
ESP(Extended stack pointer)是指针寄存器的一种(另一种为EBP)。用于堆栈指针。
ESP为栈指针,用于指向栈的栈顶(下一个压入栈的活动记录的顶部),而EBP为帧指针,指向当前活动记录的顶部。
栈指针与帧指针标识出了当前活动记录的位置。
当函数被调用的时候,执行如下操作:
⒈将帧指针压入栈中:push ebp
⒉用ebp保存当前栈指针:mov ebp,esp
⒊使得栈指针自减,自减得到的内存应当能够被用来存储被调用函数的本地状态:sub 0CCh,esp
ESP定律
call这个命令是访问子程序的一个汇编基本指令。也许你说,这个我早就知道了!别急请继续看完。
call真正的意义是什么呢?我们可以这样来理解:1.向堆栈中压入下一行程序的地址;2.JMP<