Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

The method of simulating CPU instruction and Hook CPU execution status by Unicorn

2025-01-21 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)05/31 Report--

This article introduces the relevant knowledge of "Unicorn simulates CPU instructions and Hook CPU execution status". Many people will encounter such a dilemma in the operation of actual cases, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

Unicorn simulates CPU instruction and Hook CPU execution state adds memory access hook callback

Parameters.

Type: memory operation type READ, or WRITE

Address: current instruction address

Size: the length of read or write

Value: the value written (ignored when type=read)

User_data: user_data parameter set by hook_add

Add memory access exception handling hook callback

Parameters.

Type: memory operation type READ, or WRITE

Address: current instruction address

Size: the length of read or write

Value: the value written (ignored when type=read)

User_data: user_data parameter set by hook_add

Return value: true (continue simulation execution) false (stop simulation execution)

Simulate cpu to execute mov instruction

Goal:

Execute ordinary assembly code and simulate to make him run

.text: 00008ACA 0A 46 MOV R2, R1; Rd = Op2 / / put R1 on R2

.text: 00008ACC 03 46 MOV R3, R0; Rd = Op2 / / put R0 on R3

The above instruction code is:\ x0A\ x46\ x03\ x46

Import unicornimport capstoneimport binasciiCODE = b'\ x0A\ x46\ x03\ x46'# the mov command pulled from the test instruction IDA, does not involve the memory read and write command def print_result (mu): "outputs the debugging results, in the source code These are constants UC_ARM_REG_R0 = 66 UC_ARM_REG_R1 = 67 UC_ARM_REG_R2 = 68 UC_ARM_REG_R3 = 69 UC_ARM_REG_R4 = 70 "" msg = "" register output-register [R0], value: {} register [R1], value: {} register [R2] Value: {} register [R3], value: {} "" .format (mu.reg_read (66), # UC_ARM_REG_R0 source code corresponds to constant 66 mu.reg_read (67), mu.reg_read (68), mu.reg_read (69),) print (msg.strip () .format ('') '') def capstone_print (code): "capstone Test"print ("\ 033 [1 ") 32m-capstone output -\ 033 [0m ") CP = capstone.Cs (capstone.CS_ARCH_ARM, capstone.CS_MODE_THUMB) # specify THUMB instruction set for i in CP.disasm (code, 0, len (code)): print ('\ 033 [1 32m address:% s | Opcocode:% s | content:% s\ 033 [0mm% (i.address, i.mnemonic, i.op_str)) def uni_test (): "Map assembly fragments to unicorn virtual memory, point pc to the first instruction and execute" print ('- unicorn before execution -') # 1. Create instance mu = unicorn.Uc (unicorn.UC_ARCH_ARM, unicorn.UC_MODE_THUMB) # to specify the schema and mode, here use the arm schema, specify the THUMB instruction set # 2. Map the code snippet to the simulator's virtual address ADDRESS = 0x1000 # Mapping start address SIZE = 1024 # assign Map size # 3. Start mapping mu.mem_map (ADDRESS, SIZE) # initialization mapping parameter 1: address parameter 2: space size default after initialization: 0 mu.mem_write (ADDRESS, CODE) # write instruction parameter 1: write position parameter 2: write content # 4. Test read [Test] bytes=mu.mem_read (ADDRESS, 10) # Parameter 1: readout position Parameter 2: read bytes print ('address:% x, content:% bytes% (ADDRESS, binascii.b2a_hex (bytes) # read out is bates, use binascii to convert # write register # 5. The register initialization instruction set relates to R0Query R1 and R2. R3 4 registers mu.reg_write (unicorn.arm_const.UC_ARM_REG_R0, 0x100) # write 0x100 mu.reg_write (unicorn.arm_const.UC_ARM_REG_R1, 0x200) on R0 register # write 0x200 mu.reg_write (unicorn.arm_const.UC_ARM_REG_R2) on R1 register 0x300) # write 0x100 mu.reg_write (unicorn.arm_const.UC_ARM_REG_R3, 0x400) on R2 register # write 0x200 # 6. Pc pointer to address start follow_cpu (mu) # trace CPU hook print_result (mu) # output mu.emu_start (ADDRESS+1, ADDRESS+4) # THUMB instruction set so ADDRESS+1, parameter 1: start position Parameter 2: end position print ('- unicorn execution -') print_result (mu) # output def follow_cpu (mu): "" track cpu execution status for hook stack display "mu.hook_add (unicorn.UC_HOOK_CODE, hook_code) # here all are tracked by default You can also configure def hook_code (mu, address,size, user_data): "to define the callback function. Before entering the assembly instruction, you will run here mu: simulator address: execution address size: Assembly instruction size user_data: parameter added by hook_add" code=mu.mem_read (address,size) # read print ('033 [1 ")" 32m main__ = Hook cpu =\ 033 [0m') capstone_print (code) returnif _ _ name__ = = "_ _ main__": capstone_print (CODE) uni_test ()

Python

Execute memory operation commands such as STR

Add a STR instruction in the above example

.text: 00008B04 04 92 STR R2, [SP,#0x40+var_30]; Store to Memory / / register

The whole instruction code becomes\ x0A\ x46\ x03\ x46\ x04\ x92

In this case, it is not good to just write as above, because memory operation and advance mapping are required, otherwise an error will be reported during the hook cpu operation.

You need to add a callback function to map actively.

Def hook_mem_write_unmapped (mu, type, address, size, value, user_data): print ('033 [1tre32mcentury = Hook cpu =\ 033 [0m') if type==unicorn.UC_MEM_WRITE_UNMAPPED: mu.mem_map (0x0gery 0x1000) # active mapping Note: alignment is required when mapping! And the position and size set at the beginning! Print ("\ 033 [1bot 32m [active Mapping] address: 0x%x | hook_mem Type:% d | size:% d | value: 0x%x\ 033 [0m"% (address, type, size, value)) return True # returns True to continue execution, and returns False without executing the following

Python

_ copy _

Only in this way can the STR instruction be executed and the Hook CPU status be successful

Execute system instructions and basic blocks

If we want to simulate the Hook that executes assembly system instructions and basic blocks, then we also have to add callback functions ourselves.

Def hook_syscall (mu,intno,user_data): print (if intno==2: # example 2 is exit print ("system call exit!"). Print_result (mu) print ("\ 033 [0m") returndef hook_block (mu, address,size, user_data): # code = mu.mem_read (address,size) print ("print_result (mu) print ("\ 033 [0m ") return)

Python

_ copy _

Of course, this is just an example code that executes the launched

This is the end of the content of "Unicorn simulates CPU instructions and Hook CPU execution status". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report