Unicorn模拟执行
基操
导入与初始化
1 2 3
| from unicorn import * from unicorn.x86_const import * uc=Uc(UC_ARCH_X86,UC_MODE_64)
|
手动初始化内存、分配堆栈空间
1 2 3
| address=0x400000 stack_addr=0x410000 data_addr=0x420000
|
映射内存
1
| uc.mem_map(address,2*1024*1024)
|
内存读写
1 2
| uc.mem_read(address,length) uc.mem_write(address,Sub_code)
|
寄存器读写
1 2
| uc.reg_write(UC_X86_REG_ESP,stack_addr) uc.reg_read(UC_X86_REG_ESP)
|
原神启动
1 2
| uc.emu_start(Startaddr,Endaddr) uc.emu_stop()
|
实操
[鹤城杯 2021]Petition
这是个elf可执行文件,Python脚本也得放在Linux下跑。
每深入一层递归函数即为正确一位,类似于单字节加密,直接一个一个字符爆。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| from unicorn import * from capstone import * from unicorn.x86_const import * import binascii param=0 flag=b'' def hook_scanf(uc,address,size,data): if address==0x110b: edi=uc.reg_read(UC_X86_REG_EDI) uc.mem_write(edi,flag) def hook_code(uc,address,size,data): global param com=bytearray(b'1\xc0\x83\xf0\x01') code=uc.mem_read(address,5) if code==com: param=param+1 def init(): uc=Uc(UC_ARCH_X86,UC_MODE_32) address=0x0 stack_addr=0x10000 uc.mem_map(address,2*1024*1024) with open("Petition","rb") as f: code=f.read() uc.mem_write(address,code) uc.reg_write(UC_X86_REG_EIP,0x1040) uc.reg_write(UC_X86_REG_ESP,stack_addr) uc.mem_write(0x10c6,b'\x90\x90\x90\x90\x90') uc.mem_write(0x110b,b'\x90\x90\x90\x90\x90') uc.hook_add(UC_HOOK_CODE,hook_scanf) uc.hook_add(UC_HOOK_CODE,hook_code) try: uc.emu_start(0x1040,0x29c4) except Exception as e: print(e) uc.emu_stop() tmp=b'' for i in range(42): for j in range(32,128): flag=tmp+bytes([j]) print(flag) param=0 init() if(param==i+1): tmp+=bytes([j]) break init() print(tmp)
|