├── .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