def inject_symbolic_input(state): # skip expensive call to fgets state.cpu.RIP = 0x5555555551a0 # manually inject symbolic variable in place of input with m.locked_context() as context: solution = state.new_symbolic_buffer(max_length) # constrain flag format state.constrain(solution[0] == ord('h')) state.constrain(solution[1] == ord('x')) state.constrain(solution[2] == ord('p')) state.constrain(solution[3] == ord('{')) # constrain characters to be printable ASCII or null byte for i in range(max_length): state.constrain( operators.OR( solution[i] == 0, operators.AND( ord(' ') <= solution[i], solution[i] <= ord('}')))) address = state.cpu.RSP + 0x30 context['input_address'] = address print("[+] input address: " + hex(state.cpu.RSP + 0x30)) state.cpu.write_bytes(address, solution)
def unconstrain_hook(state): """ unconstrain_hook writes unconstrained symbolic data to the memory location of the output. """ with m.locked_context() as context: # output param is RDI, symbolicate RAX context["return_addr"] = cpu.RAX logging.debug( f"Writing unconstrained buffer to output memory location" ) # initialize unconstrained symbolic input return_buf = state.new_symbolic_buffer(BUFFER_SIZE) # apply charset constraints based on user input for i in range(BUFFER_SIZE): if args.constraint == "alpha": state.constrain( operators.OR( operators.AND( ord("A") <= return_buf[i], return_buf[i] <= ord("Z")), operators.AND( ord("a") <= return_buf[i], return_buf[i] <= ord("z")), )) elif args.constraint == "num": state.constrain( operators.AND( ord("0") <= return_buf[i], return_buf[i] <= ord("9"))) elif args.constraint == "alphanum": raise NotImplementedError( "alphanum constraint set not yet implemented" ) elif args.constraint == "ascii": state.constrain( operators.AND( ord(" ") <= return_buf[i], return_buf[i] <= ord("}"))) # write to address state.cpu.write_bytes(context["return_addr"], return_buf)