Re_day1
膜李冠成师傅
工具
- Disassembler
- tracer
- Debugger
- Decompiler
- Emulator
- Symbolic Execution
技巧
常见算法
- Tea,XTea,XXTea,IDEA,RC4,RC5,RC6,AES,DES,IDEA,MD%,SHA256,SHA1
带混淆的代码(了解原理,找到地址)
- ollvm(符号执行ollvm)
- movefuscator(去除分支)
- push rax, ret(jmp rax替换成mov rax, 值; push rax; ret)
壳
- unpack -> execute
- unpack -> execute -> unpack -> execute
- unpack -> [decoder|encoded code] -> decode -> execute
- run the virtual machine
- case by case(适用unpack -> execute)
- esp law
- read/proc/[pid]/mem
反调试
- Debugger Detection
- API call, isDebuggerPresent()
- try {int3}, catch{}
- timestamp
- Debugger interfering
- Debugportt Overwrite
- Self Debugging
逆向工具分类
- Disassembler
- Tracer(函数级,指令级)
- Debugger(前两者可以实现一个简易的调试器)
- Decompiler(ida支持x86/x86-64/powerpc,jeb支持mips和web assembly)
- Emulator(模拟执行器,qemu,可以模拟cpu硬件)
- Symbolic Execution(符号执行,angr)
逆向工具
- ida,jeb,binaryninja,radare2综合的逆向工程平台,后两者没有反编译,但是静态分析的api更好用,radare2支持以太网合约调试,但通过retdec可以实现反编译功能
- od,windbg,gdb,调试器
- unicorn-engine,是模拟器
- capstone是全平台的反汇编引擎
- keystone是全平台的汇编引擎
- api monitor,pin(二进制插桩,支持函数级和指令级),processor trace(使用硬件来trace,否则不能检测)
- angr,二进制分析框架,一般用来做符号执行
- panda,集成的静态分析和动态调试工具,ali的自动逆向机器人是基于panda二次开发的
逆向流程
对于逆向,一般先收集信息 strings/file/binwalk/IDA etc. -> google/gihub
然后定位关键代码
- 控制流
- 数据交叉引用
- 代码交叉引用
- 内存搜索,设置r/w断点,比如说在内存中搜索用户输入,定位到内存块,然后在内存块下访问断点
- trace,打印出调用的函数
真实的逆向工程
- 源代码是由程序员写的
- 区分人工编写的代码和编译器加上区的代码
- 区分库函数和人工编写的函数
- 二进制文件是由编译器编译生成的
- 生成的程序是有规律的
- 代码重用很常见
- 开源代码不需要逆
- 可执行程序是可执行的
- 善用动态调试
- trace
- 符号执行
- 污点分析
- 耐心
- 7分猜,3分逆
技巧
代码是一块一块的看,而非一行一行的看
- 常见的加密算法/ACM算法
- 常见的数据结构,图/树/哈希表
- 常见的设计模式,proxy stub,工厂模式等等
- 常见的框架
混淆
混淆的例子
- ollvm,控制流平坦化
- movfuscator
- push rax, ret,相等于jmp rax
vm/smc,虚拟机壳
解混淆
- 模拟执行/符号执行
壳
不同的壳
- 先解压->再执行
- 解压一部分->执行一部分->重复
- 解压->得到解码器->解码->执行
- 使用虚拟机
反调试
调试器探测
- 调用api,IsDebuggerPresent等
- try{int3},catch{},int3异常在wei状态下会抛给调试器,catch就不会捕捉到该异常,从而达到检测调试器的目的
- timestamp,检测cpu时钟周期
- etc.
使调试器失效
- 重写DebugPort结构,调试器失效
- 另起子进程,然后使用父进程调试子进程,使子进程不能被调试,即Debugger Block
- etc.
re_0
常规逆向套路,函数加密解密的操作
- p键定义函数,假如函数无法读可以先取消定义(快捷键U) 然后再进行定义
- y键可以更改数据类型
函数解密脚本(python)
1
2
3
4
5
6judge=0x600B00
for i in range(182):
addr=0x600B00+i
byte=get_bytes(addr,1)
byte=ord(byte)^0xC
patch_byte(addr,byte)flag解密脚本
1
2
3
4
5
6
7
8#coding:utf8
if __name__ == "__main__":
flag = [0x66, 0x6d, 0x63, 0x64, 0x7f, 0x6b, 0x37, 0x64, 0x3b, 0x56, 0x60, 0x3b, 0x6e, 0x70]
a = ""
for i in range(len(flag)):
# print i
a = a + chr(flag[i] ^ i)
print(a)
re_1
一道常规的win的逆向
附上解密脚本:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#coding:utf8
s=';f1K3{c5:efl21t4;1t1zaxpim9}5+?gtux;=vc9v{v7+buhU{bT=-am2q}=fh[x\
k{y?xrqe{?}l5-sd2-Mo+:j{9=sY[dalvpx?z3{?no{[k5ll{zjsu5[kfla+r6Zg72o0s\
kq6cGl5cw[=d?3v9q5-vkjSv{4sqtg=f0cz{+jurjfl[tb]lrfF1;2}udhb?0g8{om:T\
4dh;z:oz-Dn=m=ux;o[gs9{+zqx+sq-dsxctcvykUs2oddrt43pwv:f0;njkrb9l\
os6g0{ih?rqantfx$sslqd:rvqixr;j{?o:sn+[i[yA11;gsmr8lm0?3};+iv+Tf:4Gtv2:\
-20upi0]7?77=;qzx{m-W;0vtueh]ko8d?=w:fbhd{E:;19?p=k:b+}doht6wpE\
q-z]2qbV1}dh416qw9:xm[;ed;:ecb-0:ni-s4u2kf6]2wn45amzjrun=ofkx-=h\
mgo-lz;j909=rmo7xcj4le0hxs[i]-vjl[?o12:sv4upio7ma1hRy7556+57krev:h\
LQ+1cx65z5v5];6n=[p83;n={zm{k2p'
if __name__ == "__main__":
flag = ""
for i in range(0, 330, 10):
flag = flag + s[i+1]
print flag
re_2



分奇偶数进行操作,偶数下标加2异或循环标志,奇数ascill减1异或循环标志
evr
- writeup:https://blog.csdn.net/whklhhhh/article/details/78536749
- ida在sp指针出错的时候,进行手动修复指针,即可进行反编译(Alt+k)。
- 反调试可以逐步进行nop,从而进行调试
- 用户名可以逆向出来
1 | #coding:utf8 |
- 分三段
- 我是逆着将逻辑解密出来的,原始逻辑是flag先统一异或0x76,然后再分成三段[7:14][14:21][21:28],分别异或0xad, 0xbe, 0xef,之后再将奇偶位互换
- 解密逻辑应该是先将奇偶位互换,再分别异或0xad, 0xbe, 0xef,再统一异或0x76
-以下是代码
1 | #coding:utf8 |
