-
-
[未解决,已结帖] Unicorn在跑exe文件初始化时报错 100雪币
-
发表于: 2024-8-15 03:48 1132
-
问题描述
相关exe附件已上传,我先描述下问题所在,我在试图用unicorn模拟执行一个exe以获取所有间接跳转的具体值并patch,而这些值存储在data段,这些硬编码在程序运行时会进行重定位工作,于是我为了方便打算将映射的内存基地址直接设置为0x400000,原先设置的值为0,而在我修改后,代码开始报错。经过我闲的没事干的测试,似乎值大于大约0x157000时就开始报错。
代码:
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 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | from unicorn import * from unicorn.arm_const import * from unicorn.x86_const import * from capstone import * from keystone import * import pefile X86_REGISTERS = { "rax" : UC_X86_REG_RAX, "rbx" : UC_X86_REG_RBX, "rcx" : UC_X86_REG_RCX, "rdx" : UC_X86_REG_RDX, # 添加其他 x86 寄存器 } def hook_memory(uc, access, address, size, value, user_data): pc = uc.reg_read(UC_X86_REG_RIP) md = Cs(CS_ARCH_X86, CS_MODE_64) md.syntax = CS_OPT_SYNTAX_INTEL instruction_data = uc.mem_read(pc, 16 ) instructions = md.disasm(instruction_data, pc) print ( "内存出错*********************************" ) for i in instructions: machine_code = " " .join(f "{byte:02x}" for byte in i.bytes) print (f "0x{i.address:x}:\t{machine_code:<20}\t{i.mnemonic}\t{i.op_str}" ) print (f "Memory error at pc: 0x{pc:x}, address: 0x{address:x}, size: {size}" ) print ( "****************************************" ) def hook_code(uc, address, size, user_data): global sodata global Patch Patch = {} # Capstone 反汇编器实例 md = Cs(CS_ARCH_X86, CS_MODE_64) md.syntax = CS_OPT_SYNTAX_INTEL # Keystone 初始化 ks = Ks(KS_ARCH_X86, KS_MODE_64) if address + size > len (sodata): return print (f "RIP: {hex(mu.reg_read(UC_X86_REG_RIP))}" ) print ( hex (address - ADDRESS - 0x1000 + 0x400 )) ins = md.disasm(sodata[address - ADDRESS - 0x1000 + 0x400 :address - ADDRESS - 0x1000 + 0x400 + size], address) #减去偏移量0x1000再加上0x400就是在sodata中的相应位置 registers = [ "rax" , "rbx" , "rcx" , "rdx" ] for i in ins: machine_code = " " .join(f "{byte:02x}" for byte in i.bytes) print (f "Assembly: {i.mnemonic} {i.op_str}" ) if i.mnemonic = = "call" : # 打印 CALL 指令的汇编代码及机器码 print (f "CALL instruction found at {hex(i.address)}" ) print (f "Assembly: {i.mnemonic} {i.op_str}" ) print (f "Machine Code: {machine_code}" ) uc.reg_write(UC_X86_REG_RIP, address + i.size) print (f "指令从 {hex(address)} 跳转至 {hex(address + i.size)}" ) return # 跳过call指令 if i.mnemonic = = "jmp" : for p in registers: if i.op_str.startswith(p): reg_value = uc.reg_read(X86_REGISTERS[p]) print ( "寄存器值:" + str ( hex (reg_value))) offset = reg_value - address Patch[address] = offset jmp_inst, _ = ks.asm(f "jmp {offset}" ) uc.mem_write(address, bytes(jmp_inst)) uc.reg_write(UC_X86_REG_RIP, address + offset) print (f "Replaced jmp {p} with jmp {hex(offset)} at {hex(address)}" ) break def init(filename): global mu global sodata global pe global ADDRESS pe = pefile.PE(filename) entry_point = 0xBE70 with open (filename, mode = "rb" ) as f: sodata = f.read() if isinstance (sodata, bytearray): sodata = bytes(sodata) print ( "=========================Begin============================" ) try : mu = Uc(UC_ARCH_X86, UC_MODE_64) ADDRESS = 0x157000 #这里设置为0x400000是因为data段数据需要重定位,设为0x400000省去这一步 STACK_ADDRESS = 0x80000000 mu.mem_map(STACK_ADDRESS, 8 * 0x1000 * 0x1000 ) # 栈 mu.mem_map(ADDRESS, 32 * 1024 * 1024 ) # 16MB #将文件写入内存 for section in pe.sections: start = ADDRESS + section.VirtualAddress print ( hex (start)) file_offset = section.PointerToRawData section_data = sodata[file_offset:file_offset + section.SizeOfRawData] if section.Name.strip(b '\0' ).decode() = = '.text' : text_offet = section.VirtualAddress print (f ".text section address: {hex(start)}" ) mu.mem_write(start, section_data) # 写入文件 Text_Start = ADDRESS + entry_point + text_offet # 设置 rsp 和 rip 寄存器 mu.reg_write(UC_X86_REG_RSP, STACK_ADDRESS + 0x1000 * 4 ) mu.reg_write(UC_X86_REG_RIP,Text_Start) mu.hook_add(UC_HOOK_MEM_UNMAPPED, hook_memory, begin = ADDRESS, end = ADDRESS + 16 * 1024 * 1024 ) mu.hook_add(UC_HOOK_CODE, hook_code, begin = Text_Start, end = Text_Start + 0x10000 ) #print(f"Starting emulation from {hex(ADDRESS + entry_point + 0x400)} to {hex(ADDRESS + 0xD2000 + 0x400)}") md = Cs(CS_ARCH_X86, CS_MODE_64) md.syntax = CS_OPT_SYNTAX_INTEL ins = md.disasm(sodata[entry_point + 0x400 :entry_point + 0x400 + 0x400 ],Text_Start) #ADDRESS不设为0的话这里要重新写一下 #将反汇编内容打出================================================ for i in ins: machine_code = " " .join(f "{byte:02x}" for byte in i.bytes) #print(f"0x{i.address:x}:\t{machine_code:<20}\t{i.mnemonic}\t{i.op_str}") #=============================================================== print ( "设定模拟执行的入口地址:" , hex (Text_Start)) mu.emu_start(Text_Start, Text_Start + 0x10000 ) except UcError as e: print (f "ERROR: {e}" ) print (f "RIP: {hex(mu.reg_read(UC_X86_REG_RIP))}" ) print (f "RSP: {hex(mu.reg_read(UC_X86_REG_RSP))}" ) # 调用 init 函数 init( "C:\\Users\\rea1\\Desktop\\ofution.exe" ) print ( "test success" ) |
附一张ADDRESS=0时运行的结果
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2024-8-15 04:25
被螺丝兔编辑
,原因:
赞赏
他的文章
- [原创]zygisk改机模块demo 2850
- [原创]ByteCTF逆向WP 6705
- [原创]春秋杯Re2024WP 7017
- 腾讯游戏安全2024安卓初赛复现 27475
谁下载
无
看原图
赞赏
雪币:
留言: