├── .gitignore ├── README.md ├── taint.py └── taint ├── Constants.py ├── OpData.py ├── Operand.py ├── Operation.py ├── TaintMap.py └── funct.py /.gitignore: -------------------------------------------------------------------------------- 1 | taint/exp 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | imm-taint-trace 2 | =============== 3 | 4 | A taint tracer written via Immunity's plugin system. Taint is tracked on registers and memory locations. Currently, ~40 commonly used instructions are implemented. 5 | To track taint, following rules are utilized to determine propagation: 6 | - If data is copied from a tainted source to an untainted destination, taint the destination. 7 | - If data is copied from an untainted source to a tainted destination, clear the destination. 8 | - If data is copied from a memory location through a tainted register, taint the destination. 9 | - If data is copied from a tainted memory location through an untainted register, taint the destination. 10 | - If data is copied from a untainted memory location through an untainted register, clear the destination. 11 | - If the destination is set to a constant value, clear the destination. 12 | 13 | Install 14 | ------- 15 | Copy `taint.py` and the `taint` directory into Immunity Debugger's `PyCommands` directory. 16 | 17 | Help 18 | ---- 19 | For help, run the command without any arguments. 20 | -------------------------------------------------------------------------------- /taint.py: -------------------------------------------------------------------------------- 1 | __VERSION__ = '0.2' 2 | DESC = "None" 3 | 4 | import re 5 | import sys 6 | 7 | from Constants import * 8 | from OpData import * 9 | from TaintMap import * 10 | from funct import * 11 | 12 | from immlib import * 13 | from libanalyze import * 14 | 15 | #Issues 16 | # -Does not account for flags (SETZ?) 17 | # -At the moment the table is only used to id stuff... 18 | # -Gen a graph of data flow 19 | # -No FPU instructions are supported, no FPU Regs either, and DEFINITELY not the FPU flags... 20 | # -If I use ctypes, might be better? (The registers) 21 | 22 | def usage(imm): 23 | imm.log("Usage: !taint cmd ") 24 | imm.log(" step") 25 | imm.log(" trace") 26 | imm.log(" list") 27 | imm.log(" reg/rreg") 28 | imm.log(" mem/rmem") 29 | 30 | def main(args): 31 | if not args: 32 | return "Usage: !taint cmd " 33 | if(args[0] == 'trace'): return ttrace() 34 | if(args[0] == 'step'): 35 | try: steps = int(args[1]) 36 | except: steps = 1 37 | return ttrace(steps) 38 | if(args[0] == 'clear'): 39 | tgen(True) 40 | return "Map cleared" 41 | #try: 42 | if(args[0] == 't'): return ttest() #Debug command 43 | if(args[0] == 'st'): return tscripttest() #Debug command 44 | if(args[0] == 'list'): return tlist() 45 | if(args[0] == 'reg' and len(args)>1): return treg(args[1].upper(), True) 46 | if(args[0] == 'rreg' and len(args)>1): return treg(args[1].upper(), False) 47 | if(args[0] == 'mem' and len(args)>2): return tmem(int(args[1]), int(args[2]), True) 48 | if(args[0] == 'rmem' and len(args)>2): return tmem(int(args[1]), int(args[2]), False) 49 | #except: pass 50 | return "Invalid command" 51 | 52 | 53 | """Commands""" 54 | def tscripttest(): 55 | #Tests for all functionality 56 | imm = Debugger() 57 | tmap = tgen() 58 | 59 | def ttest(): 60 | imm = Debugger() 61 | tmap = tgen(True) 62 | treg('EAX', True) 63 | ttrace(1) 64 | tlist() 65 | 66 | def tgen(force = False): 67 | imm = Debugger() 68 | tmap = imm.getKnowledge('taintmap') 69 | if(not tmap or force): 70 | tmap = TaintMap() 71 | imm.addKnowledge('taintmap', tmap, True) 72 | return tmap 73 | 74 | def tlist(): 75 | imm = Debugger() 76 | tmap = tgen() 77 | tregs = tmap.allreg() 78 | tmem = tmap.allmem() 79 | 80 | imm.log("-----") 81 | imm.log("Registers") 82 | for i in tregs: 83 | if(not any(tregs[i])): continue 84 | imm.log(" " + [key for key, value in REG_MAP.items() if value == i | REGB_32BIT][0] + ":" + str(tregs[i])) 85 | imm.log("Memory") 86 | for i in tmem: 87 | imm.log(" " + hex(i) + ":" + str(tmem[i])) 88 | return "" 89 | 90 | def treg(x, t): 91 | imm = Debugger() 92 | tmap = tgen() 93 | 94 | try: 95 | i = REGSZ_MAP[REG_MAP[x] & REGB_SIZEMASK] 96 | tmap.setreg(REG_MAP[x], list(TMMDA_MAP[i] if t else TMMDN_MAP[i])) 97 | imm.addKnowledge('taintmap', tmap, True) 98 | return "Taint " + ("set" if t else "cleared") 99 | except: return "Invalid register" 100 | 101 | def tmem(x, y, t): 102 | imm = Debugger() 103 | tmap = tgen() 104 | try: 105 | sz = [] 106 | for i in range(0, y): sz.append(TMM_ALL if t else TMM_NONE) 107 | tmap.setmem(x, sz) 108 | imm.addKnowledge('taintmap', tmap, True) 109 | return "Taint " + ("set" if t else "cleared") 110 | except: return "Invalid memory address" 111 | 112 | def ttrace(steps = -1): 113 | imm = Debugger() 114 | tmap = tgen() 115 | if(imm.getStatus() == 0 or imm.getStatus() == 4): return "Not running!" 116 | 117 | regs = imm.getRegs(); 118 | stack = [] 119 | stack.append(imm.getFunctionBegin(regs['EIP'])) #FIXME: Might not always be right 120 | 121 | imm.log(" " * (len(stack) - 1) + "<" + hex(regs['EIP']) + ">") 122 | 123 | #This loop runs until the code returns to the caller 124 | while(len(stack) and imm.getStatus() != 0 and imm.getStatus() != 4): #EIP points to next instr 125 | imm.stepIn() #Instr is now execd. Regs aren't updated yet! 126 | steps -= 1 127 | opdata = OpData(regs, imm.disasm(regs['EIP'])) #Parse 128 | regs = imm.getRegs(); 129 | 130 | #If the opcode was successfully parsed 131 | if(opdata.valid): 132 | _checkTaint(imm, opdata, tmap) #Update our map 133 | 134 | #Check what type of instr it is and change the stack appropriately 135 | otype = opdata.opcode.getCmdType() 136 | if(otype == C_RET): 137 | stack.pop() 138 | if(otype == C_CAL): #FIX: Use getCallTree() instead? 139 | stack.append(regs['EIP']) 140 | imm.log(" " * (len(stack) - 1) + "<" + hex(regs['EIP']) + ">") 141 | else: 142 | imm.log('SKIP') 143 | 144 | imm.addKnowledge('taintmap', tmap, True) 145 | if(steps == 0): break 146 | return "" 147 | """Commands""" 148 | 149 | def _checkTaint(imm, op, tmap): 150 | opmap = [] 151 | 152 | #Generate the mask 153 | for opn in op.operations: 154 | if (opn.type == OPRTN_NONE): 155 | pass 156 | elif(opn.type == OPRTN_ARITH): 157 | res = [] 158 | for src in opn.src: 159 | mask, unused = _getOperandTaint(src, tmap) 160 | res = _addOperandTaint(res, mask) 161 | #Taint everything if there's any taint 162 | if(any(res)): 163 | res = list(TMMDA_MAP[len(res)]) 164 | opmap.append({'dest':opn.dest, 'mask':res}) 165 | elif(opn.type == OPRTN_OVERWRITE): 166 | mask, unused = _getOperandTaint(opn.src[0], tmap) 167 | opmap.append({'dest':opn.dest, 'mask':mask}) 168 | 169 | #Apply it! 170 | for opn in opmap: 171 | for dest in opn['dest']: 172 | #if dest size != src size, fix 173 | mask = opn['mask'] 174 | if(dest.size != len(mask)): 175 | if(any(mask)): 176 | mask = list(TMMDA_MAP[dest.size]) 177 | if (dest.type == OPRND_REG): 178 | tmap.setreg(dest.data[0], mask) 179 | elif(dest.type == OPRND_MEM): 180 | #If the dest is indexed by a tainted reg, taint everything 181 | unused, index_taint = _getOperandTaint(dest, tmap) 182 | if(index_taint): 183 | mask = list(TMMDA_MAP[len(mask)]) 184 | tmap.setmem(dest.addr, mask) 185 | 186 | def _addOperandTaint(maska, maskb): 187 | ret = [] 188 | sz = max(len(maska), len(maskb)) 189 | 190 | typea = TMM_ALL if any(maska) else TMM_NONE 191 | typeb = TMM_ALL if any(maskb) else TMM_NONE 192 | while(len(maska) < sz): maska.insert(0, typea) 193 | while(len(maskb) < sz): maskb.insert(0, typeb) 194 | 195 | for i in range(sz): 196 | ret.append(TMM_ALL if maska[i] or maskb[i] else TMM_NONE) 197 | return ret 198 | 199 | def _getOperandTaint(oprnd, tmap): 200 | if (oprnd.type == OPRND_NONE): 201 | return [], False 202 | elif(oprnd.type == OPRND_REG): 203 | return tmap.getreg(oprnd.data[0], list(TMMDA_MAP[oprnd.size])), False 204 | elif(oprnd.type == OPRND_MEM): 205 | #If any indexed register is tainted, then consider everything tainted 206 | if(any([any(tmap.getreg(i, list(TMMDA_MAP[REGSZ_MAP[i & REGB_SIZEMASK]]))) for i in oprnd.data])): 207 | return list(TMMDA_MAP[oprnd.size]), True 208 | return tmap.getmem(oprnd.addr, list(TMMDA_MAP[oprnd.size])), False 209 | elif(oprnd.type == OPRND_CONST): 210 | return list(TMMDN_MAP[oprnd.size]), False 211 | elif(oprnd.type == OPRND_CLEAN): 212 | return list(TMMDN_MAP[oprnd.size]), False 213 | elif(oprnd.type == OPRND_DIRTY): 214 | return list(TMMDA_MAP[oprnd.size]), False 215 | -------------------------------------------------------------------------------- /taint/Constants.py: -------------------------------------------------------------------------------- 1 | REGB_NONE = 0x00 2 | REGB_REGMASK= 0xF0 3 | REGB_XAX = 0x01<<4 4 | REGB_XBX = 0x02<<4 5 | REGB_XCX = 0x03<<4 6 | REGB_XDX = 0x04<<4 7 | REGB_XSP = 0x05<<4 8 | REGB_XBP = 0x06<<4 9 | REGB_XSI = 0x07<<4 10 | REGB_XDI = 0x08<<4 11 | 12 | REGB_SIZEMASK= 0xE 13 | REGB_32BIT = 0x8 14 | REGB_16BIT = 0x4 15 | REGB_8BIT = 0x2 16 | 17 | REGB_RLO = 0x0 18 | REGB_RHI = 0x1 19 | 20 | REG_MAP = { 21 | '':REGB_NONE, 22 | 'EAX':REGB_XAX|REGB_32BIT, 'AX':REGB_XAX|REGB_16BIT, 'AL':REGB_XAX|REGB_8BIT, 'AH':REGB_XAX|REGB_8BIT|REGB_RHI, 23 | 'EBX':REGB_XBX|REGB_32BIT, 'BX':REGB_XBX|REGB_16BIT, 'BL':REGB_XBX|REGB_8BIT, 'BH':REGB_XBX|REGB_8BIT|REGB_RHI, 24 | 'ECX':REGB_XCX|REGB_32BIT, 'CX':REGB_XCX|REGB_16BIT, 'CL':REGB_XCX|REGB_8BIT, 'CH':REGB_XCX|REGB_8BIT|REGB_RHI, 25 | 'EDX':REGB_XDX|REGB_32BIT, 'DX':REGB_XDX|REGB_16BIT, 'DL':REGB_XDX|REGB_8BIT, 'DH':REGB_XDX|REGB_8BIT|REGB_RHI, 26 | 'ESP':REGB_XSP|REGB_32BIT, 'SP':REGB_XSP|REGB_16BIT, 27 | 'EBP':REGB_XBP|REGB_32BIT, 'BP':REGB_XBP|REGB_16BIT, 28 | 'ESI':REGB_XSI|REGB_32BIT, 'SI':REGB_XSI|REGB_16BIT, 29 | 'EDI':REGB_XDI|REGB_32BIT, 'DI':REGB_XDI|REGB_16BIT 30 | } 31 | 32 | IMMREG_MAP = [ 33 | [], 34 | [REG_MAP['AL'], REG_MAP['CL'], REG_MAP['DL'], REG_MAP['BL'], REG_MAP['AH'], REG_MAP['CH'], REG_MAP['DH'], REG_MAP['BH']], 35 | [REG_MAP['AX'], REG_MAP['CX'], REG_MAP['DX'], REG_MAP['BX'], REG_MAP['SP'], REG_MAP['BP'], REG_MAP['SI'], REG_MAP['DI']], 36 | [], 37 | [REG_MAP['EAX'], REG_MAP['ECX'], REG_MAP['EDX'], REG_MAP['EBX'], REG_MAP['ESP'], REG_MAP['EBP'], REG_MAP['ESI'], REG_MAP['EDI']] 38 | ] 39 | 40 | REGSZ_MAP = { 41 | REGB_NONE : 0, 42 | REGB_8BIT : 1, 43 | REGB_16BIT: 2, 44 | REGB_32BIT: 4 45 | } 46 | 47 | DATSZ_MAP = { 48 | 'DWORD': 4, 49 | 'WORD' : 2, 50 | 'BYTE' : 1 51 | } -------------------------------------------------------------------------------- /taint/OpData.py: -------------------------------------------------------------------------------- 1 | from Operation import * 2 | from Operand import * 3 | from Constants import * 4 | from funct import * 5 | 6 | from immlib import * 7 | from libanalyze import * 8 | 9 | imm = Debugger() 10 | 11 | class OpData: 12 | def __init__(self, regs, opc): 13 | self.opcode = opc 14 | self.operations= [] 15 | self.operands = [] 16 | self.valid = False 17 | 18 | opc_cmdname = opc.getDisasm().split(' ')[0].lower() 19 | opc_cmdtype = opc.getCmdType() 20 | 21 | 22 | #Populate operands 23 | for i in range(0, 3): 24 | oprnd = None 25 | opc_oprnd = opc.operand[i] 26 | otype = opc_oprnd[0] 27 | osize = opc_oprnd[1] 28 | 29 | if (otype & DECR_ISREG): 30 | self.operands.append(Operand(OPRND_REG, osize, [IMMREG_MAP[osize][opc_oprnd[2].index(1)]])) 31 | 32 | elif(otype & DEC_CONST): 33 | self.operands.append(Operand(OPRND_CONST, osize, [opc_oprnd[3]])) 34 | 35 | #Special case for lea 36 | elif(otype == DEC_UNKNOWN and osize == 4): 37 | for i in range(len(opc_oprnd[2])): 38 | if(not opc_oprnd[2][i]): continue 39 | self.operands.append(Operand(OPRND_REG, osize, [IMMREG_MAP[osize][i]])) 40 | 41 | elif(otype & DEC_TYPEMASK): 42 | self.operands.append(Operand(OPRND_MEM, osize, [IMMREG_MAP[osize][i] for i in len(opc_oprnd[2]) if opc_oprnd[2][i]], calcaddr(opc_oprnd, regs))) 43 | 44 | 45 | #Figure out what type of operation it is and parse accordingly 46 | if (opc_cmdtype == C_CMD): 47 | if (opc_cmdname in ['adc','add','sub','sbb','and','or','xor','shld','shrd']): 48 | self.operations.append(Operation(OPRTN_ARITH, [self.operands[0], self.operands[1]], [self.operands[0]])) 49 | 50 | elif(opc_cmdname in ['inc','dec','not','neg','shl','shr','sal','sar','shr','rcl','rcr','rol','ror']): 51 | self.operations.append(Operation(OPRTN_ARITH, [self.operands[0]], [self.operands[0]])) 52 | 53 | elif(opc_cmdname in ['mov','movsx','movzx']): 54 | self.operations.append(Operation(OPRTN_OVERWRITE, [self.operands[1]], [self.operands[0]])) 55 | 56 | elif(opc_cmdname in ['lea']): 57 | self.operations.append(Operation(OPRTN_ARITH, self.operands[1:], [self.operands[0]])) 58 | 59 | elif(opc_cmdname in ['div','idiv','mul','imul','imul','imul']): 60 | ocount = len(self.operands) 61 | if (ocount == 1): 62 | oxsize = self.operands[0].size 63 | dest = [] 64 | if (oxsize == 1): 65 | dest.append(Operand(OPRND_REG, 2, [REG_MAP['AX']])) 66 | elif(oxsize == 2): 67 | dest += [Operand(OPRND_REG, 2, [REG_MAP['DX']]), Operand(OPRND_REG, 2, [REG_MAP['AX']])] 68 | elif(oxsize == 4): 69 | dest += [Operand(OPRND_REG, 4, [REG_MAP['EDX']]), Operand(OPRND_REG, 4, [REG_MAP['EAX']])] 70 | self.operations.append(Operation(OPRTN_ARITH, [self.operands[0], Operand(OPRND_REG, oxsize, [IMMREG_MAP[oxsize][0]])], dest)) 71 | elif(ocount == 2): 72 | self.operations.append(Operation(OPRTN_ARITH, [self.operands[0], self.operands[1]], [self.operands[0]])) 73 | elif(ocount == 3): 74 | self.operations.append(Operation(OPRTN_ARITH, [self.operands[1], self.operands[2]], [self.operands[0]])) 75 | 76 | elif(opc_cmdname in ['cbw','cwd']): 77 | self.operations.append(Operation(OPRTN_ARITH, [Operand(OPRND_REG, 1, [REG_MAP['AL']])], [Operand(OPRND_REG, 2, [REG_MAP['DX']]), Operand(OPRND_REG, 2, [REG_MAP['AX']])])) 78 | 79 | elif(opc_cmdname in ['cwde','cdq']): 80 | dest = [Operand(OPRND_REG, 4, [REG_MAP['EAX']])] 81 | if(opc_cmdname == 'cdq'): dest.append(Operand(OPRND_REG, 4, [REG_MAP['EDX']])) 82 | self.operations.append(Operation(OPRTN_ARITH, [Operand(OPRND_REG, 2, [REG_MAP['AX']])], dest)) 83 | 84 | elif(opc_cmdname in ['smsw']): 85 | self.operations.append(Operation(OPRTN_OVERWRITE, [Operand(OPRND_CLEAN, 2)], [self.operands[0]])) 86 | 87 | elif(opc_cmdname in ['xchg','xadd']): 88 | self.operations.append(Operation(OPRTN_OVERWRITE, [self.operands[0]], [self.operands[1]])) 89 | type = OPRTN_OVERWRITE 90 | src = [self.operands[1]] 91 | if(opc_cmdname == 'xadd'): 92 | type = OPRTN_ARITH 93 | src.append(self.operands[0]) 94 | self.operations.append(Operation(type, src, [self.operands[0]])) 95 | 96 | elif(opc_cmdname in ['cmp', 'test', 'nop']): 97 | pass 98 | 99 | else: 100 | imm.log('Not implemented!' + opc_cmdname) 101 | return 102 | 103 | elif(opc_cmdtype == C_PSH): 104 | self.operations.append(Operation(OPRTN_OVERWRITE, [self.operands[0]], [Operand(OPRND_MEM, 4, [REG_MAP['ESP']], regs['ESP'] - 4)])) 105 | 106 | elif(opc_cmdtype == C_POP): 107 | self.operations.append(Operation(OPRTN_OVERWRITE, [Operand(OPRND_MEM, 4, [REG_MAP['ESP']], regs['ESP'])], [self.operands[0]])) 108 | 109 | elif(opc_cmdtype == C_MMX): 110 | imm.log('Not implemented!' + opc_cmdname) 111 | return 112 | 113 | elif(opc_cmdtype == C_FLT): 114 | imm.log('Not implemented!' + opc_cmdname) 115 | return 116 | 117 | elif(opc_cmdtype == C_JMP): 118 | #Don't care about this instruction type 119 | pass 120 | 121 | elif(opc_cmdtype == C_JMC): 122 | #Don't care about this instruction type 123 | pass 124 | 125 | elif(opc_cmdtype == C_CAL): 126 | #Don't care about this instruction type 127 | pass 128 | 129 | elif(opc_cmdtype == C_RET): 130 | #Don't care about this instruction type 131 | pass 132 | 133 | elif(opc_cmdtype == C_FLG): 134 | imm.log('Not implemented!' + opc_cmdname) 135 | return 136 | 137 | elif(opc_cmdtype == C_RTF): 138 | imm.log('Not implemented!' + opc_cmdname) 139 | return 140 | 141 | elif(opc_cmdtype == C_REP): 142 | imm.log('Not implemented!' + opc_cmdname) 143 | return 144 | 145 | elif(opc_cmdtype == C_PRI): 146 | imm.log('Not implemented!' + opc_cmdname) 147 | return 148 | 149 | elif(opc_cmdtype == C_SSE): 150 | imm.log('Not implemented!' + opc_cmdname) 151 | return 152 | 153 | elif(opc_cmdtype == C_NOW): 154 | imm.log('Not implemented!' + opc_cmdname) 155 | return 156 | 157 | elif(opc_cmdtype == C_BAD): 158 | imm.log('Bad op encountered') 159 | return 160 | 161 | else: 162 | imm.log('Unknown op encountered') 163 | return 164 | 165 | 166 | #If we're here, the opcode is valid 167 | self.valid = True -------------------------------------------------------------------------------- /taint/Operand.py: -------------------------------------------------------------------------------- 1 | OPRND_NONE = 0x0 2 | OPRND_REG = 0x1 3 | OPRND_MEM = 0x2 4 | OPRND_CONST= 0x3 5 | OPRND_CLEAN= 0x4 6 | OPRND_DIRTY= 0x5 7 | 8 | class Operand: 9 | def __init__(self, type = OPRND_NONE, size = 0, data = [], addr = 0): 10 | self.type = type 11 | self.size = size 12 | self.addr = addr #The resolved address 13 | self.data = list(data) 14 | #OPRND_REG: data = [REG_MAP.XXX] 15 | #OPRND_MEM: data = [REG_MAP.XXX, ...], addr = * 16 | #OPRND_CONST: data = [*] -------------------------------------------------------------------------------- /taint/Operation.py: -------------------------------------------------------------------------------- 1 | OPRTN_NONE = 0x0 2 | OPRTN_ARITH = 0x1 3 | OPRTN_OVERWRITE= 0x2 4 | 5 | class Operation: 6 | def __init__(self, type = OPRTN_NONE, src = [], dest = []): 7 | self.type = type 8 | self.src = list(src) 9 | self.dest = list(dest) -------------------------------------------------------------------------------- /taint/TaintMap.py: -------------------------------------------------------------------------------- 1 | from Constants import * 2 | 3 | TMM_BITZERO = 0x01 4 | TMM_BITONE = 0x02 5 | TMM_BITTWO = 0x04 6 | TMM_BITTHREE= 0x08 7 | TMM_BITFOUR = 0x10 8 | TMM_BITFIVE = 0x20 9 | TMM_BITSIX = 0x40 10 | TMM_BITSEVEN= 0x80 11 | TMM_LO = 0x0F 12 | TMM_HI = 0xF0 13 | TMM_NONE = 0x00 14 | TMM_ALL = 0xFF 15 | 16 | TMMDN_BYTE = [TMM_NONE] 17 | TMMDN_WORD = [TMM_NONE,TMM_NONE] 18 | TMMDN_WORDX= [TMM_NONE,TMM_NONE,TMM_NONE] 19 | TMMDN_DWORD= [TMM_NONE,TMM_NONE,TMM_NONE,TMM_NONE] 20 | TMMDN_MAP = [ 21 | [], #0 22 | TMMDN_BYTE, #1 23 | TMMDN_WORD, #2 24 | TMMDN_WORDX,#3 25 | TMMDN_DWORD #4 26 | ] 27 | 28 | TMMDA_BYTE = [TMM_ALL] 29 | TMMDA_WORD = [TMM_ALL,TMM_ALL] 30 | TMMDA_WORDX= [TMM_ALL,TMM_ALL,TMM_ALL] 31 | TMMDA_DWORD= [TMM_ALL,TMM_ALL,TMM_ALL,TMM_ALL] 32 | TMMDA_MAP = [ 33 | [], #0 34 | TMMDA_BYTE, #1 35 | TMMDA_WORD, #2 36 | TMMDA_WORDX, 37 | TMMDA_DWORD #4 38 | ] 39 | 40 | class TaintMap: 41 | def __init__(self): 42 | self.map = {} 43 | self.reg = {} 44 | 45 | def setreg(self, regd, mask): 46 | reg = regd & REGB_REGMASK 47 | try: self.reg[reg] 48 | except: self.reg[reg] = list(TMMDN_DWORD) 49 | c = 4 - 2 * len(mask) if regd & REGB_RHI else 4 - len(mask) 50 | for i in range(c, 4 - len(mask) if regd & REGB_RHI else 4): 51 | self.reg[reg][i] = mask[i - c] 52 | def clearreg(self, regd, mask): 53 | reg = regd & REGB_REGMASK 54 | try: self.reg[reg] 55 | except: self.reg[reg] = list(TMMDN_DWORD) 56 | c = 4 - 2 * len(mask) if regd & REGB_RHI else 4 - len(mask) 57 | for i in range(c, 4 - len(mask) if regd & REGB_RHI else 4): 58 | self.reg[reg][i] &= ~mask[i - c] 59 | def getreg(self, regd, mask): 60 | ret = [] 61 | reg = regd & REGB_REGMASK 62 | try: self.reg[reg] 63 | except: self.reg[reg] = list(TMMDN_DWORD) 64 | c = 4 - 2 * len(mask) if regd & REGB_RHI else 4 - len(mask) 65 | for i in range(c, 4 - len(mask) if regd & REGB_RHI else 4): 66 | try: ret.append(self.reg[reg][i] & mask[c]) 67 | except: ret.append(TMM_NONE) 68 | return ret 69 | 70 | def setmem(self, addr, mask): 71 | for i in range(0, len(mask)): 72 | self.map[addr + i] = mask[i] 73 | if(self.map[addr + i] == TMM_NONE): del self.map[addr + i] 74 | def clearmem(self, addr, mask): 75 | for i in range(0, len(mask)): 76 | self.map[addr + i] &= ~mask[i] 77 | if(self.map[addr + i] == TMM_NONE): del self.map[addr + i] 78 | def getmem(self, addr, mask): 79 | ret = [] 80 | for i in range(0, len(mask)): 81 | try: ret.append(self.map[addr + i] & mask[i]) 82 | except: ret.append(TMM_NONE) 83 | return ret 84 | 85 | def allreg(self): 86 | return self.reg 87 | def emptyreg(self): 88 | self.reg = {} 89 | 90 | def allmem(self): 91 | return self.map 92 | def emptymem(self): 93 | self.map = {} 94 | -------------------------------------------------------------------------------- /taint/funct.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | 4 | def calcaddr(oprnd, regs): 5 | addr = oprnd[3] 6 | for i in range(len(oprnd[2])): 7 | addr = (addr + oprnd[2][i] * regs[Registers32BitsOrder[i]]) & 0xffffffff 8 | return addr 9 | 10 | #Debugging stuff 11 | def ByteToHex(byteStr): 12 | return ''.join( [ "%02X" % ord( x ) for x in byteStr ] ).strip() 13 | 14 | def readstr(imm, addr): 15 | chunk=16 16 | offset=0 17 | ret="" 18 | while(1): 19 | len=chunk 20 | buf=imm.readMemory(addr+chunk*offset, chunk) 21 | offset+=1 22 | for i in range(0, chunk): 23 | if(ord(buf[i])==0): 24 | len=i 25 | break 26 | ret+=buf[0:len] 27 | if(len