def hook(insn): global a if insn.getAddress() == 0x400740: for op in insn.getOperands(): if op.getType() == triton.OPERAND.REG: addr = pintool.getCurrentRegisterValue(op) print(hex(addr)) a = addr print("a:" + str(hex(a))) for i in range(4): c = pintool.getCurrentMemoryValue(a + i) print(str(i) + " : " + str(hex(c))) if insn.getAddress() == 0x40074a: print(hex(a)) for i in range(4): c = pintool.getCurrentMemoryValue(a + i) print(str(i) + " : " + str(hex(c))) if insn.getAddress() == 0x40074a: for op in insn.getOperands(): if op.getType() == triton.OPERAND.MEM: addr = op.getAddress() print(hex(addr)) c = pintool.getCurrentMemoryValue(addr) print(str(hex(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 instrafcb(instr): global calls if "call " in instr.getDisassembly(): #print("DISASM: ", instr.getDisassembly()) #print("DEST ADDR: ", hex(Pintool.getCurrentRegisterValue(Triton.registers.rip))) #print("==============================================================") instr_addr = instr.getAddress() if instr_addr not in calls.keys(): calls[hex(instr_addr)] = hex( Pintool.getCurrentRegisterValue(Triton.registers.rip))
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 hook(insn): global symvar_addr if insn.getAddress() == readBufIns: addr = pintool.getCurrentRegisterValue(Triton.registers.rcx) symvar_addr = addr print("Taint src addr head : " + str(hex(symvar_addr))) if insn.getAddress() == taintedIns: for op in insn.getOperands(): if op.getType() == triton.OPERAND.REG: print 'Found Target Ins \'%s\'' % (insn) exploit_mmap(insn, op) return
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 hook(insn): global symvar_addr if insn.getAddress() == 0x400740: addr = pintool.getCurrentRegisterValue(Triton.registers.rcx) print(hex(addr)) symvar_addr = addr print("hook") for i in range(4): c = pintool.getCurrentMemoryValue(symvar_addr + i) print(str(i) + " : " + str(hex(c))) if insn.getAddress() == taintedIns: for op in insn.getOperands(): if op.getType() == triton.OPERAND.REG: print 'Found Target Ins \'%s\'' % (insn) exploit_mmap(insn, op) return
def cafter(instruction): ofIgnored = [ OPCODE.X86.RCL, OPCODE.X86.RCR, OPCODE.X86.ROL, OPCODE.X86.ROR, OPCODE.X86.SAR, OPCODE.X86.SHL, OPCODE.X86.SHLD, OPCODE.X86.SHR, OPCODE.X86.SHRD, ] good = True bad = list() regs = Triton.getParentRegisters() for reg in regs: # Skip unsupported registers if reg.getName().startswith("dr"): continue cvalue = Pintool.getCurrentRegisterValue(reg) svalue = Triton.getSymbolicRegisterValue(reg) # Check register if cvalue != svalue: if reg.getName() == 'of' and instruction.getType() in ofIgnored: continue # On processors that do not support TZCNT, the instruction byte # encoding is executed as BSF. The key difference between TZCNT # and BSF instruction is that TZCNT provides operand size as output # when source operand is zero while in the case of BSF instruction, # if source operand is zero, the content of destination operand are # undefined. if instruction.getType() == OPCODE.X86.TZCNT and Travis == True: continue good = False bad.append({ 'reg': reg.getName(), 'svalue': svalue, 'cvalue': cvalue, 'expr': expr }) if bad: print("[%sKO%s] %#x: %s (%s%d register error(s)%s)" % (RED, ENDC, instruction.getAddress(), instruction.getDisassembly(), RED, len(bad), ENDC)) for w in bad: print(" Register : %s" % (w['reg'])) print(" Symbolic Value : %016x" % (w['svalue'])) print(" Concrete Value : %016x" % (w['cvalue'])) print(" Expression : %s" % (w['expr'])) # Check memory access for op in instruction.getOperands(): if op.getType() == OPERAND.MEM: nativeAddress = op.getAddress() astAddress = op.getLeaAst().evaluate() if nativeAddress != astAddress: good = False print("[%sKO%s] %#x: %s (%smemory error%s)" % (RED, ENDC, instruction.getAddress(), instruction.getDisassembly(), RED, ENDC)) print(" Native address : %016x" % (nativeAddress)) print(" Symbolic address : %016x" % (astAddress)) if len(instruction.getSymbolicExpressions()) == 0: print("[%s??%s] %#x: %s" % (BLUE, ENDC, instruction.getAddress(), instruction.getDisassembly())) return if good: print("[%sOK%s] %#x: %s" % (GREEN, ENDC, instruction.getAddress(), instruction.getDisassembly())) return else: #time.sleep(2) sys.exit(-1) return
def needReg(ctx, reg): ctx.setConcreteRegisterValue(reg, Pintool.getCurrentRegisterValue(reg)) return
def cafter(instruction): ofIgnored = [ OPCODE.RCL, OPCODE.RCR, OPCODE.ROL, OPCODE.ROR, OPCODE.SAR, OPCODE.SHL, OPCODE.SHLD, OPCODE.SHR, OPCODE.SHRD, ] bad = list() regs = Triton.getParentRegisters() for reg in regs: cvalue = Pintool.getCurrentRegisterValue(reg) seid = Triton.getSymbolicRegisterId(reg) if seid == SYMEXPR.UNSET: continue expr = Triton.unrollAstFromId(seid) svalue = expr.evaluate() #svalue = Triton.evaluateAstViaZ3(expr) # Check register if cvalue != svalue: if reg.getName() == 'of' and instruction.getType() in ofIgnored: continue bad.append({ 'reg': reg.getName() + str(instruction.getType()), 'svalue': svalue, 'cvalue': cvalue, 'expr': expr }) if bad: dump = '[KO] %#x: %s (%d register error(s))' %(instruction.getAddress(), instruction.getDisassembly(), len(bad)) for w in bad: dump += '\n Register : %s' %(w['reg']) dump += '\n Symbolic Value : %016x' %(w['svalue']) dump += '\n Concrete Value : %016x' %(w['cvalue']) dump += '\n Expression : %s' %(w['expr']) print dump with open('./semantics_issues', 'a') as fd: fd.write(dump+'\n') if len(instruction.getSymbolicExpressions()) == 0: dump = '[unsupported] %#x: %s' %(instruction.getAddress(), instruction.getDisassembly()) print dump with open('./semantics_issues', 'a') as fd: fd.write(dump+'\n') return # Reset everything Triton.resetEngines() return
def cafter(instruction): ofIgnored = [ OPCODE.X86.RCL, OPCODE.X86.RCR, OPCODE.X86.ROL, OPCODE.X86.ROR, OPCODE.X86.SAR, OPCODE.X86.SHL, OPCODE.X86.SHLD, OPCODE.X86.SHR, OPCODE.X86.SHRD, ] bad = list() regs = Triton.getParentRegisters() for reg in regs: cvalue = Pintool.getCurrentRegisterValue(reg) se = Triton.getSymbolicRegister(reg) if se is None: continue expr = se.getAst() svalue = expr.evaluate() # Check register if cvalue != svalue: if reg.getName() == 'of' and instruction.getType() in ofIgnored: continue bad.append({ 'reg': reg.getName(), 'svalue': svalue, 'cvalue': cvalue, 'expr': se.getAst() }) if bad: dump = '[KO] %#x: %s (%d register error(s))' % ( instruction.getAddress(), instruction.getDisassembly(), len(bad)) for w in bad: dump += '\n Register : %s' % (w['reg']) dump += '\n Symbolic Value : %016x' % (w['svalue']) dump += '\n Concrete Value : %016x' % (w['cvalue']) dump += '\n Expression : %s' % (w['expr']) print(dump) with open('./semantics_issues', 'a') as fd: fd.write(dump + '\n') if len(instruction.getSymbolicExpressions()) == 0: dump = '[unsupported] %#x: %s' % (instruction.getAddress(), instruction.getDisassembly()) print(dump) with open('./semantics_issues', 'a') as fd: fd.write(dump + '\n') return return
def needReg(ctx, reg): ctx.setConcreteRegisterValue(reg, Pintool.getCurrentRegisterValue(reg)) return
def cafter(instruction): ofIgnored = [ OPCODE.RCL, OPCODE.RCR, OPCODE.ROL, OPCODE.ROR, OPCODE.SAR, OPCODE.SHL, OPCODE.SHLD, OPCODE.SHR, OPCODE.SHRD, ] good = True bad = list() regs = Triton.getParentRegisters() for reg in regs: cvalue = Pintool.getCurrentRegisterValue(reg) se = Triton.getSymbolicRegister(reg) if se is None: continue expr = Triton.unrollAst(se.getAst()) svalue = expr.evaluate() #svalue = Triton.evaluateAstViaZ3(expr) # Check register if cvalue != svalue: if reg.getName() == 'of' and instruction.getType() in ofIgnored: continue # On processors that do not support TZCNT, the instruction byte # encoding is executed as BSF. The key difference between TZCNT # and BSF instruction is that TZCNT provides operand size as output # when source operand is zero while in the case of BSF instruction, # if source operand is zero, the content of destination operand are # undefined. if instruction.getType() == OPCODE.TZCNT and Travis == True: continue good = False bad.append({ 'reg': reg.getName(), 'svalue': svalue, 'cvalue': cvalue, 'expr': expr }) if bad: print "[%sKO%s] %#x: %s (%s%d register error(s)%s)" %(RED, ENDC, instruction.getAddress(), instruction.getDisassembly(), RED, len(bad), ENDC) for w in bad: print " Register : %s" %(w['reg']) print " Symbolic Value : %016x" %(w['svalue']) print " Concrete Value : %016x" %(w['cvalue']) print " Expression : %s" %(w['expr']) # Check memory access for op in instruction.getOperands(): if op.getType() == OPERAND.MEM: nativeAddress = op.getAddress() astAddress = op.getLeaAst().evaluate() if nativeAddress != astAddress: good = False print "[%sKO%s] %#x: %s (%smemory error%s)" %(RED, ENDC, instruction.getAddress(), instruction.getDisassembly(), RED, ENDC) print " Native address : %016x" %(nativeAddress) print " Symbolic address : %016x" %(astAddress) if len(instruction.getSymbolicExpressions()) == 0: print "[%s??%s] %#x: %s" %(BLUE, ENDC, instruction.getAddress(), instruction.getDisassembly()) return if good: print "[%sOK%s] %#x: %s" %(GREEN, ENDC, instruction.getAddress(), instruction.getDisassembly()) return else: #time.sleep(2) pass return