def waitpid(self, tp): arg0 = tp.arch.get_func_arg(0) arg1 = tp.arch.get_func_arg(1) # FIXME: AARC64 and X86 32bits rdi = tp.arch.tc.getConcreteRegisterValue(tp.arch.tc.registers.rdi) rsi = tp.arch.tc.getConcreteRegisterValue(tp.arch.tc.registers.rsi) for c in self.contexts: if c.pid == tp.debugee.pid: if c.pid == arg0: break # FIXME: hack for root-me ringgit challenge, should not be part of actual api tp.arch.tc.setConcreteMemoryValue( triton.MemoryAccess( tp.arch.tc.getConcreteRegisterValue(tp.arch.tc.registers.rsi), tp.arch.psize), 0x57f) c.pending_action.acquire() sp = tp.arch.tc.getConcreteRegisterValue(tp.sp) ret_addr = tp.arch.tc.getConcreteMemoryValue( triton.MemoryAccess(tp.arch.tc.getConcreteRegisterValue(tp.sp), tp.arch.psize)) tp.arch.tc.setConcreteRegisterValue(tp.pc, ret_addr) tp.arch.tc.setConcreteRegisterValue(tp.sp, sp + tp.arch.psize)
def taint_argv(threadId): argc = ctx.getConcreteRegisterValue(ctx.getRegister(triton.REG.X86_64.RDI)) argv = ctx.getConcreteRegisterValue(ctx.getRegister(triton.REG.X86_64.RSI)) if argc < 2: return argv += 8 argc -= 1 # ignore argv[0] # Taint argv[:] argv_mem = triton.MemoryAccess(argv, argc * 8) if ctx.taintMemory(argv_mem): print("[!] TAINTED argv") # Taint argv[i][:] argv_bytes = ctx.getConcreteMemoryAreaValue(argv, argc * 8) for i in xrange(argc): argv_i = struct.unpack("<Q", argv_bytes[i * 8:(i + 1) * 8])[0] not_done = True offset = 0 while not_done: argv_blk = str( ctx.getConcreteMemoryAreaValue(argv_i + offset, BLK_SIZE)).split(b'\x00')[0] argv_blk_len = len(argv_blk) if argv_blk_len != 0: offset += BLK_SIZE if argv_blk_len < BLK_SIZE: not_done = False argv_i_mem = triton.MemoryAccess(argv_i, offset) if ctx.taintMemory(argv_i_mem): print("[!] TAINTED argv[" + str(i + 1) + "]") print("")
def get_func_arg(self, n): if n < len(self.regs): value = self.tc.getConcreteRegisterValue(self.regs[n]) else: offset = (n-len(self.regs))*self.psize value = self.tc.getConcreteMemoryValue(triton.MemoryAccess(self.tc.getConcreteRegisterValue(self.sp)+offset, self.psize)) return value
def reset(self): triton.resetEngines() triton.clearPathConstraints() triton.setArchitecture(self.arch) triton.enableMode(triton.MODE.ALIGNED_MEMORY, True) triton.enableMode(triton.MODE.ONLY_ON_SYMBOLIZED, True) triton.addCallback(self.memoryCaching, triton.CALLBACK.GET_CONCRETE_MEMORY_VALUE) triton.addCallback(self.constantFolding, triton.CALLBACK.SYMBOLIC_SIMPLIFICATION) for r in self.regs: if r in self.triton_regs: triton.setConcreteRegisterValue( triton.Register( self.triton_regs[r], self.regs[r] & ((1 << self.triton_regs[r].getBitSize()) - 1))) for m in cache: self.write_mem(m['start'], m["data"]) for address in self.inputs: self.inputs[address] = triton.convertMemoryToSymbolicVariable( triton.MemoryAccess(address, triton.CPUSIZE.BYTE))
def func_ret(self, value=None): if value is not None: self.tc.setConcreteRegisterValue(self.ret, value) sp = self.tc.getConcreteRegisterValue(self.sp) ret_addr = self.tc.getConcreteMemoryValue(triton.MemoryAccess(self.tc.getConcreteRegisterValue(self.sp), self.psize)) self.tc.setConcreteRegisterValue(self.pc, ret_addr) self.tc.setConcreteRegisterValue(self.sp, sp+self.psize)
def ptrace(self, tp): # FIXME: AARC64 and X86 32bits arg0 = tp.arch.get_func_arg(0) arg1 = tp.arch.get_func_arg(1) arg2 = tp.arch.get_func_arg(2) arg3 = tp.arch.get_func_arg(3) if arg0 == 12: rax, rdi = tp.debugee.pending.pop() tp.arch.tc.setConcreteMemoryValue( triton.MemoryAccess(arg3 + 10 * 8, tp.arch.psize), rax) tp.arch.tc.setConcreteMemoryValue( triton.MemoryAccess(arg3 + 14 * 8, tp.arch.psize), rdi) elif arg0 == 0x4206: for c in self.contexts: if c.pid == arg1: tp.debugee = c break elif arg0 == 7: print "[+] ptrace_cont" tp.debugee.cont.release() elif arg0 == 17: print "{}: ptrace(DETACH)".format(tp.pid) else: print "{}: ptrace({})".format(tp.pid, arg0) sp = tp.arch.tc.getConcreteRegisterValue(tp.sp) ret_addr = tp.arch.tc.getConcreteMemoryValue( triton.MemoryAccess(tp.arch.tc.getConcreteRegisterValue(tp.sp), tp.arch.psize)) tp.arch.tc.setConcreteRegisterValue(tp.pc, ret_addr) tp.arch.tc.setConcreteRegisterValue(tp.sp, sp + tp.arch.psize)
def symbolize_inputs(tid): rsi = pintool.getCurrentRegisterValue(Triton.registers.rsi) # argv addr = pintool.getCurrentMemoryValue(rsi + (triton.CPUSIZE.QWORD), triton.CPUSIZE.QWORD) # argv[1] # symbolize each character in argv[1], i.e the serial (including the terminating NULL) c = None s = '' while c != 0: c = pintool.getCurrentMemoryValue(addr) s += chr(c) Triton.setConcreteMemoryValue(addr, c) Triton.convertMemoryToSymbolicVariable( triton.MemoryAccess(addr, triton.CPUSIZE.BYTE)).setComment( 'argv[1][%d]' % (len(s) - 1)) addr += 1 print 'Symbolized argv[1]: %s' % (s)
def read_hook(tid): global symvar_addr data_len = pintool.getCurrentRegisterValue(Triton.registers.eax) print("Taint src length : " + str(data_len)) for i in range(data_len): c = pintool.getCurrentMemoryValue(symvar_addr + i) Triton.setConcreteMemoryValue(symvar_addr + i, c) Triton.convertMemoryToSymbolicVariable( triton.MemoryAccess( symvar_addr + i, triton.CPUSIZE.BYTE)).setComment('taintedByte ' + str(hex(symvar_addr + i)) + ' : ' + str(c)) print('Symbolized taintedByte ' + str(hex(symvar_addr)) + ' ~ ' + str(hex(symvar_addr + i)))
def read_hook(tid): global symvar_addr print("read_hook") for i in range(4): c = pintool.getCurrentMemoryValue(symvar_addr + i) #print(str(i)+" : "+str(hex(c))) Triton.setConcreteMemoryValue(symvar_addr + i, c) Triton.convertMemoryToSymbolicVariable( triton.MemoryAccess( symvar_addr + i, triton.CPUSIZE.BYTE)).setComment('taintedByte ' + str(hex(symvar_addr + i)) + ' : ' + str(c)) print('Symbolized taintedByte ' + str(hex(symvar_addr + i)) + ' : ' + str(c))
def symbolize_inputs(tid): rdi = pintool.getCurrentRegisterValue(Triton.registers.rdi) # argc rsi = pintool.getCurrentRegisterValue(Triton.registers.rsi) # argv # for each string in argv while rdi > 1: addr = pintool.getCurrentMemoryValue(rsi + ((rdi-1)*triton.CPUSIZE.QWORD), triton.CPUSIZE.QWORD) # symbolize the current argument string (including the terminating NULL) c = None s = '' while c != 0: c = pintool.getCurrentMemoryValue(addr) s += chr(c) Triton.setConcreteMemoryValue(addr, c) Triton.convertMemoryToSymbolicVariable(triton.MemoryAccess(addr, triton.CPUSIZE.BYTE)).setComment('argv[%d][%d]' % (rdi-1, len(s)-1)) addr += 1 rdi -= 1 print 'Symbolized argument %d: %s' % (rdi, s)
def symbolize_inputs(threadId): rdi = pintool.getCurrentRegisterValue(Triton.registers.rdi) # argc rsi = pintool.getCurrentRegisterValue(Triton.registers.rsi) # argv while rdi > 1: addr = pintool.getCurrentMemoryValue( rsi + ((rdi-1) * triton.CPUSIZE.QWORD), triton.CPUSIZE.QWORD) c = None s = "" while c != 0: c = pintool.getCurrentMemoryValue(addr) s += chr(c) Triton.setConcreteMemoryValue(addr, c) Triton.convertMemoryToSymbolicVariable( triton.MemoryAccess(addr, triton.CPUSIZE.BYTE) ).setComment(f"argv[{rdi-1}][{len(s)-1}]") addr += 1 rdi -= 1 print(f"Symbolized argument {rdi}: {s}")
def fork(self, tp): new_tp = self.create_process(context=tp) sp = tp.arch.tc.getConcreteRegisterValue(tp.sp) ret_addr = tp.arch.tc.getConcreteMemoryValue( triton.MemoryAccess(tp.arch.tc.getConcreteRegisterValue(tp.sp), tp.arch.psize)) tp.arch.tc.setConcreteRegisterValue(tp.pc, ret_addr) tp.arch.tc.setConcreteRegisterValue(tp.sp, sp + tp.arch.psize) assert (tp.pid + 1 == new_tp.pid) tp.arch.tc.setConcreteRegisterValue(tp.ret, tp.pid + 1) new_tp.arch.tc.setConcreteRegisterValue(tp.pc, ret_addr) new_tp.arch.tc.setConcreteRegisterValue(tp.sp, sp + tp.arch.psize) new_tp.arch.tc.setConcreteRegisterValue(tp.ret, 0) self._run(new_tp)
def add_input(self, addr, size): for offset in xrange(size): self.inputs[addr + offset] = triton.convertMemoryToSymbolicVariable( triton.MemoryAccess(addr + offset, triton.CPUSIZE.BYTE))
def poke(self, addr, size, value): return self.triton.setConcreteMemoryValue( triton.MemoryAccess(addr, size, value))
def peek(self, addr, size): return self.triton.getConcreteMemoryValue( triton.MemoryAccess(addr, size))
def set_func_arg(self, n, value): sp = self.tc.getConcreteRegisterValue(self.sp) offset = n*self.psize + self.psize self.tc.setConcreteMemoryValue(triton.MemoryAccess(sp + offset, self.psize), value) return value
def symbolize(self, addr, size): return self.tc.symbolizeMemory(triton.MemoryAccess(addr, size))
def set_memory_value(self, addr, value, size): return self.tc.setConcreteMemoryValue(triton.MemoryAccess(addr, size), value)
def get_func_arg(self, n): offset = n*self.arch.psize + self.arch.psize value = self.arch.tc.getConcreteMemoryValue(triton.MemoryAccess(self.arch.tc.getConcreteRegisterValue(self.sp)+offset, self.psize)) return value