type
Post
status
Published
date
May 16, 2023
slug
tech-reverse
summary
逆向知识汇总
tags
逆向
category
技术分享
icon
password
URL
逆向学习总结
学习内容
- 汇编基础
- 加壳与脱壳原理
- 脱壳基本方法
- 实践中遇到的问题与总结
汇编基础
加壳与脱壳原理
脱壳基本方法
名称 | 步骤 | 备注 |
单步跟踪法 | 1、F8单步步过,2、遇到向上的跳转,在跳转的下一行使用F4运行到此处3、继续单步,寻找大跳 | 跟踪过程中,注意跳转和call的地址,如果是大跳,基本是OEP地址,要特别注意未实现的大跳 |
ESP定律法 | 1、F8单步执行,观察寄存器窗口,若只有ESP变化,则可以使用该方法2、执行命令hr esp,设置硬件访问断点3、F9运行后基本来到OEP附近 | 下断点的代码位置最好在pushad附近 |
二次内存镜像法 | 1、在内存窗口中,找到主程序的rsrc段,并在次此设置内存访问断点,然后F9运行程序2、在内存窗口中,找到主程序的text段,同样设置内存访问断点,然后执行3、单步跟踪,直到调到OEP | 如果执行过程中不确定是否调到OEP,可以搜索字符串,看看是否有内容 |
最后一次异常法 | 1、打开调试选项,找到SFX设置页,选块方式跟踪整整入口处2、重新加载程序,自动跳到OEP | 对压缩壳比较有效,速度也最快1、sfx2、tc eip<xxxx |
模拟跟踪法 | 1、打开调试选项,选择忽略所有异常2、打开strongOD选项,关闭skip some exceptions3、统计shift+F9运行后,需要几次程序会运行起来,计n次4、重新加载程序,执行n-1次shift+F9,此时观察堆栈窗口,使用ctrl+G跳转到se指向的地址,下断点运行到此处5、F8单步跟踪,直到跳转到OEP | 运行过程中要及时清理断点,否则可能出现莫名其妙的未知错误 |
常见编程语言的入口特征
VB:
004012D4 > 68 54474000 push QQ个性网.00404754 004012D9 E8 F0FFFFFF call <jmp.&MSVBVM60.#100> 004012DE 0000 add byte ptr ds:[eax],al 004012E0 0000 add byte ptr ds:[eax],al 004012E2 0000 add byte ptr ds:[eax],al 004012E4 3000 xor byte ptr ds:[eax],al 004012E6 0000 add byte ptr ds:[eax],al 004012E8 48 dec eax
Delphi:
004A5C54 > 55 push ebp 004A5C55 8BEC mov ebp,esp 004A5C57 83C4 F0 add esp,-10 004A5C5A B8 EC594A00 mov eax,openpro.004A59EC
C++:
0040A41E > 55 push ebp 0040A41F 8BEC mov ebp,esp 0040A421 6A FF push -1 0040A423 68 C8CB4000 push 跑跑排行.0040CBC8 0040A428 68 A4A54000 push <jmp.&MSVCRT._except_handler3> 0040A42D 64:A1 00000000 mov eax,dword ptr fs:[0] 0040A433 50 push eax 0040A434 64:8925 0000000>mov dword ptr fs:[0],esp 0040A43B 83EC 68 sub esp,68 0040A43E 53 push ebx 0040A43F 56 push esi 0040A440 57 push edi
Masm:
004035C9 > 6A 00 push 0 004035CB E8 A20A0000 call <jmp.&kernel32.GetModuleHandleA> 004035D0 A3 5B704000 mov dword ptr ds:[40705B],eax 004035D5 68 80000000 push 80 004035DA 68 2C754000 push 11.0040752C 004035DF FF35 5B704000 push dword ptr ds:[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 ptr ds:[40705B]
常用的调用约定
架构 | 调用约定 | 传参方式 | 入栈顺序 | 清栈方式 |
x86 | __cdecl(c规范) | 栈 | 从右往左 | 栈外平衡,调用者清栈 |
x86 | pascal | 栈 | 从左往右 | 栈内平衡,被调者清栈 |
x86 | stdcall | 栈 | 从右往左 | 栈内平衡,被调者清栈 |
x86 | fastcall | 寄存器+栈 | 从右往左 | 栈内平衡,被调者清栈 |
x64 | 快速调用 | 寄存器+栈寄存器:rcx,rdx,r8,r9浮点数使用xmm寄存器在栈上会为四个寄存器变量分配空间 | 从右往左 | ㅤ |
常见编程语言的函数调用方式
编程语言 | 传参方式 | 返回值 | 备注 |
c | __cdecl约定 | 参数指定的内存地址,全局变量或eax若返回值超出eax接收范围,则使用edx接收 | ㅤ |
c++ | stdcall约定 | 同上 | ㅤ |
delphi | fastcall约定前三个参数使用eax,edx,ecx寄存器后面的参数采用栈传参,顺序从有往左 | 参数指定的内存地址,eax或edx | ㅤ |
实践中遇到的问题与总结
- 作者:紫电穿云
- 链接:https://zidy.eu.org/article/tech-reverse
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。



