Re_day1

膜李冠成师傅

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
    6
    judge=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
附上解密脚本:

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

3

4

分奇偶数进行操作,偶数下标加2异或循环标志,奇数ascill减1异或循环标志

evr

1
2
3
4
5
6
7
8
9
10
11
#coding:utf8
v4 = [164,169,170,190,188,185,179,169,190,216,190]
for j in range(len(v4)):
word_41B2F0.append(((((j ^ 0x76) - 52) ^ 0x80) + 43) ^ v4[j])
print word_41B2F0
print len(word_41B2F0)
www = ""
for i in range(len(word_41B2F0)):
www = www + chr(word_41B2F0[len(word_41B2F0)-i-1])

print(www)
  • 分三段
  • 我是逆着将逻辑解密出来的,原始逻辑是flag先统一异或0x76,然后再分成三段[7:14][14:21][21:28],分别异或0xad, 0xbe, 0xef,之后再将奇偶位互换
  • 解密逻辑应该是先将奇偶位互换,再分别异或0xad, 0xbe, 0xef,再统一异或0x76
    -以下是代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#coding:utf8
flag = [30, 21, 2, 16, 13, 72, 72, 111, 221, 221, 72, 100, 99, 215, 46, 44, 254, 106, 109, 42, 242, 111, 154, 77, 139, 75, 30, 30, 14, 14, 14, 14, 14, 14, 11]
def do(a, b, and_a, xor_a, weiyi):
for i in range(a,b):
ji = (flag[i] & and_a) << weiyi
ou = (flag[i] >> weiyi) & and_a
shu = ji|ou
shu = shu^xor_a
flag[i] = shu
if __name__ == "__main__":
do(7, 14, 0x55, 0xad, 1)
do(14, 21, 0x33, 0xbe, 2)
do(21, 28, 0xf, 0xef, 4)

for i in range(len(flag)):
flag[i] = chr(flag[i] ^ 0x76)
print "".join(flag)

文章目录
  1. 1. Re_day1
    1. 1.0.0.1. 膜李冠成师傅
  • 1.1. 工具
  • 1.2. 技巧
    1. 1.2.1. 常见算法
    2. 1.2.2. 带混淆的代码(了解原理,找到地址)
    3. 1.2.3.
    4. 1.2.4. 反调试
    5. 1.2.5. 逆向工具分类
    6. 1.2.6. 逆向工具
    7. 1.2.7. 逆向流程
    8. 1.2.8. 真实的逆向工程
    9. 1.2.9. 技巧
    10. 1.2.10. 混淆
    11. 1.2.11.
    12. 1.2.12. 反调试
    13. 1.2.13. 使调试器失效
  • 1.3. re_0
  • 1.4. re_1
  • 1.5. re_2
  • 1.6. evr
  • |