ghost423543

ELF-ARM-Crypted

Nov 4th, 2020 (edited)
200
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.58 KB | None | 0 0
  1. import os
  2. from unicorn import *
  3. from unicorn.arm_const import *
  4. DIR = os.path.dirname(os.path.realpath(__file__))
  5.  
  6. # Create main unicorn emulator
  7. # mu = Uc (UC_ARCH_ARM, UC_MODE_LITTLE_ENDIAN)
  8. mu = Uc (UC_ARCH_ARM, UC_MODE_THUMB) # Warning, code in thumb mode (16 bits)
  9.  
  10. # Set base address and size of the .text and stack segment
  11. BASE = 0x10000
  12. STACK_ADDR = 0x300000
  13. STACK_SIZE = 1024*1024
  14.  
  15. # Map .text and stack segments
  16. mu.mem_map(BASE, 1024*1024)
  17. mu.mem_map(STACK_ADDR, STACK_SIZE)
  18.  
  19. # Write the complete code from the unpacked executable to .text segement
  20. mu.mem_write(BASE, open(DIR+"/cryptoarm_unpack",'rb').read())
  21.  
  22. # Initialize stack pointer in the middle of the stack segment
  23. mu.reg_write(UC_ARM_REG_SP, STACK_ADDR + STACK_SIZE//2)
  24.  
  25. # Some address given by ghidra analysis
  26. PROG_GHIDRA_BASE = 0x8000
  27. FN_ENTRY = 0x8798
  28. FN_END = 0x87f2
  29.  
  30. # Get start and end addresses emulated by unicorn
  31. code_offset_start = BASE + (FN_ENTRY - PROG_GHIDRA_BASE)
  32. code_offset_end = BASE + (FN_END - PROG_GHIDRA_BASE)
  33.  
  34. # Skip two instructions which set stack cookies
  35. instructions_skip_list = [BASE+(0x87a6-PROG_GHIDRA_BASE), BASE+(0x87ac-PROG_GHIDRA_BASE)]
  36.  
  37.  
  38. # strlen not callable by unicorn, we hook it
  39. strlen_cipher_addr = BASE+(0x87d2-PROG_GHIDRA_BASE) # 0x107d2
  40. # malloc not callable by unicorn, we hook it
  41. malloc_101h_addr = BASE+(0x87d8-PROG_GHIDRA_BASE)   # 0x107d8
  42. # address where unciphering function is called
  43. uncipher_call_addr = BASE+(0x87ee-PROG_GHIDRA_BASE) # 0x107ee
  44.  
  45. def hook_code(mu, address, size, user_data):
  46.     # print('>>> Tracing instruction at 0x%x, instruction size = 0x%x' %(address, size))        # usefull debug function to see where unicorn crash
  47.     if address in instructions_skip_list:
  48.         print("SKIP 0x%x" %(address))
  49.         mu.reg_write(UC_ARM_REG_PC , address+size | 1)  # Modify $PC register, warning, add "| 1" to keep te thumb mode
  50.  
  51.     if address == strlen_cipher_addr:
  52.         ret_len = 26
  53.         print("call strlen(cipher_text) at 0x%x - skip and set R0 to %d" % (address, ret_len))
  54.         mu.reg_write(UC_ARM_REG_R0, ret_len)
  55.         mu.reg_write(UC_ARM_REG_PC, address + size | 1)  # Modify $PC register, warning, add "| 1" to keep te thumb mode
  56.  
  57.     if address == malloc_101h_addr:
  58.         ret_addr = STACK_ADDR + STACK_SIZE - 0x1000      # Set static address for the malloc[0x101] put in stack !
  59.         print("call malloc(0x101) at 0x%x - skip and set R0 to 0x%x" % (address, ret_addr))
  60.         mu.reg_write(UC_ARM_REG_R0, ret_addr)
  61.         mu.reg_write(UC_ARM_REG_PC, address + size | 1)  # Modify $PC register, warning, add "| 1" to keep te thumb mode
  62.  
  63.     if address == uncipher_call_addr:
  64.         buffer_addr = mu.reg_read(UC_ARM_REG_R1)         # Get cipher buffer address
  65.         print("Cipher buffer located at 0x%x"%(buffer_addr))
  66.         # print("Cipher buffer content: [%s]" % (enhex(mu.mem_read(buffer_addr, 26))))
  67.         print("Cipher buffer content: [%s]" % (mu.mem_read(buffer_addr, 26)).hex())
  68.         key_addr = mu.reg_read(UC_ARM_REG_R6)
  69.         print("Key buffer located at 0x%x"%(key_addr))
  70.         print("Key buffer content: [%s]" % (mu.mem_read(key_addr, 257)).hex())
  71.    
  72.     # if code_offset_end< address:print(hex(address),hex(code_offset_end));input()
  73.     if address == code_offset_end:
  74.         flag_addr = mu.reg_read(UC_ARM_REG_R0)
  75.         print("Unciphering process ended at 0x%x" % (address))
  76.         print(mu.mem_read(flag_addr, 26))
  77.         print("Unciphered buffer content: [%s]" % ((mu.mem_read(flag_addr, 26)).decode()))
  78.  
  79. # Add our hook function to unicorn emulator
  80. mu.hook_add(UC_HOOK_CODE, hook_code)
  81.  
  82. # Start emulation
  83. # Note we start at ADDRESS | 1 to indicate THUMB mode.
  84. mu.emu_start(code_offset_start | 1, code_offset_end+2)
  85. ## Valid fl@g is ~^NHv<uz2O;T
Add Comment
Please, Sign In to add comment