Advertisement
Guest User

Untitled

a guest
Mar 20th, 2019
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.91 KB | None | 0 0
  1. """
  2. template_test_harness.py
  3.  
  4. Template which loads the context of a process into a Unicorn Engine,
  5. instance, loads a custom (mutated) inputs, and executes the
  6. desired code. Designed to be used in conjunction with one of the
  7. Unicorn Context Dumper scripts.
  8.  
  9. Author:
  10. Nathan Voss <njvoss299@gmail.com>
  11. """
  12.  
  13. import argparse
  14. import struct
  15. import binascii
  16.  
  17. from unicorn import *
  18. from unicorn.x86_const import * # TODO: Set correct architecture here as necessary
  19.  
  20. import unicorn_loader
  21.  
  22. # Simple stand-in heap to prevent OS/kernel issues
  23. unicorn_heap = None
  24.  
  25. # Start and end address of emulation
  26. START_ADDRESS = 0x00000000004004DA # TODO: Set start address here
  27. END_ADDRESS = 0x0000000000400511 # TODO: Set end address here
  28.  
  29. def hook_mem_read(uc, type, addr,*args):
  30. print(hex(addr))
  31. return False
  32.  
  33. def u32(data):
  34. return struct.unpack(">I", data)[0]
  35.  
  36. def p32(num):
  37. return struct.pack(">I", num)
  38.  
  39. """
  40. Implement target-specific hooks in here.
  41. Stub out, skip past, and re-implement necessary functionality as appropriate
  42. """
  43. def unicorn_hook_instruction(uc, address, size, user_data):
  44. # TODO: Setup hooks and handle anything you need to here
  45. # - For example, hook malloc/free/etc. and handle it internally
  46. pass
  47.  
  48. #------------------------
  49. #---- Main test function
  50.  
  51. def main():
  52.  
  53. parser = argparse.ArgumentParser()
  54. parser.add_argument('context_dir', type=str, help="Directory containing process context")
  55. parser.add_argument('input_file', type=str, help="Path to the file containing the mutated input content")
  56. parser.add_argument('-d', '--debug', default=False, action="store_true", help="Dump trace info")
  57. args = parser.parse_args()
  58.  
  59. print("Loading context from {}".format(args.context_dir))
  60. uc = unicorn_loader.AflUnicornEngine(args.context_dir, enable_trace=args.debug, debug_print=False)
  61.  
  62. # Instantiate the hook function to avoid emulation errors
  63. global unicorn_heap
  64. unicorn_heap = unicorn_loader.UnicornSimpleHeap(uc, debug_print=False)
  65. uc.hook_add(UC_HOOK_CODE, unicorn_hook_instruction)
  66.  
  67. uc.hook_add(UC_HOOK_MEM_READ_UNMAPPED, hook_mem_read)
  68.  
  69. # Execute 1 instruction just to startup the forkserver
  70. # NOTE: This instruction will be executed again later, so be sure that
  71. # there are no negative consequences to the overall execution state.
  72. # If there are, change the later call to emu_start to no re-execute
  73. # the first instruction.
  74. print("Starting the forkserver by executing 1 instruction")
  75. try:
  76. uc.emu_start(START_ADDRESS, 0, 0, count=1)
  77. except UcError as e:
  78. print("ERROR: Failed to execute a single instruction (error: {})!".format(e))
  79. return
  80.  
  81. def intr_hook(uc, intno, data):
  82. print 'interrupt=%d, v0=%d, pc=0x%08x' % (intno, uc.reg_read(UC_X86_REG_V0), uc.reg_read(UC_X86_REG_PC))
  83.  
  84. # hook interrupts for syscall
  85. uc.hook_add(UC_HOOK_INTR, intr_hook)
  86.  
  87. # Allocate a buffer and load a mutated input and put it into the right spot
  88. if args.input_file:
  89. print("Loading input content from {}".format(args.input_file))
  90. input_file = open(args.input_file, 'rb')
  91. input_content = input_file.read()
  92. input_file.close()
  93.  
  94. # TODO: Apply constraints to mutated input here
  95. # raise exceptions.NotImplementedError('No constraints on the mutated inputs have been set!')
  96. if len(input_content) > 0xFF:
  97. print("Test packet is too long (> {} bytes)".format(0xFF))
  98. return
  99.  
  100. # Allocate a new buffer and put the input into it.
  101. buf_addr = unicorn_heap.malloc(len(input_content))
  102. stack_addr = unicorn_heap.malloc(1024)
  103. uc.mem_write(buf_addr, input_content)
  104. print("INPUT CONTENT: " + input_content)
  105. print("INPUT CONTENT LENGTH: " + str(len(input_content)))
  106. print("Allocated mutated input buffer @ 0x{0:016x}".format(buf_addr))
  107.  
  108. # TODO: Set the input into the state so it will be handled
  109.  
  110. uc.reg_write(UC_X86_REG_RBP, stack_addr+512)
  111. uc.reg_write(UC_X86_REG_RSP, stack_addr+512)
  112.  
  113. # raise exceptions.NotImplementedError('The mutated input was not loaded into the Unicorn state!')
  114.  
  115.  
  116. # Run the test
  117. print("Executing from 0x{0:016x} to 0x{1:016x}".format(START_ADDRESS, END_ADDRESS))
  118. try:
  119. result = uc.emu_start(START_ADDRESS, END_ADDRESS, timeout=0, count=0)
  120. #result = uc.emu_start(START_ADDRESS, 0, timeout=0, count=1)
  121. except UcError as e:
  122. # If something went wrong during emulation a signal is raised to force this
  123. # script to crash in a way that AFL can detect ('uc.force_crash()' should be
  124. # called for any condition that you want AFL to treat as a crash).
  125. print("Execution failed with error: {}".format(e))
  126. uc.dump_regs()
  127. uc.force_crash(e)
  128.  
  129. print("Final register state:")
  130. uc.dump_regs()
  131.  
  132. print("Done.")
  133.  
  134. if __name__ == "__main__":
  135. main()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement