Package Libs :: Module libanalize
[hide private]
[frames] | no frames]

Source Code for Module Libs.libanalize

   1  #!/usr/bin/env python 
   2   
   3  """ 
   4  (c) Immunity, Inc. 2004-2007 
   5   
   6   
   7  U{Immunity Inc.<http://www.immunityinc.com>} 
   8   
   9   
  10  """ 
  11   
  12  __VERSION__ = '1.3' 
  13   
  14  import UserList 
  15  import debugger 
  16   
  17  # REGISTER STATUS 
  18  RST_INVALID  =  0               # Register undefined 
  19  RST_VALUE    =  1               # Register contains regdata 
  20  RST_VFIXUP   =  2               # Reg contains regdata that is fixup 
  21  RST_INDIRECT =  3               # Register contains [regdata] 
  22   
  23   
  24  # DISASM MODE 
  25  DISASM_SIZE   = 0              # Determine command size only 
  26  DISASM_DATA   = 1              # Determine size and analysis data 
  27  DISASM_TRACE  = 2              # Trace integer registers 
  28  DISASM_FILE   = 3              # Disassembly, no symbols/registers 
  29  DISASM_CODE   = 4              # Disassembly, registers undefined 
  30  DISASM_ALL    = 5              # Completely disassembly 
  31  DISASM_RTRACE = 6              # Disassemble with run-trace registers 
  32   
  33  # Types for Opcode 
  34  C_TYPEMASK =  0xF0            # Mask for command type 
  35  C_CMD =       0x00            # Ordinary instruction 
  36  C_PSH =       0x10            # PUSH instruction 
  37  C_POP =       0x20            # POP instruction 
  38  C_MMX =       0x30            # MMX instruction 
  39  C_FLT =       0x40            # FPU instruction 
  40  C_JMP =       0x50            # JUMP instruction 
  41  C_JMC =       0x60            # Conditional JUMP instruction 
  42  C_CAL =       0x70            # CALL instruction 
  43  C_RET =       0x80            # RET instruction 
  44  C_FLG =       0x90            # Changes system flags 
  45  C_RTF =       0xA0            # C_JMP and C_FLG simultaneously 
  46  C_REP =       0xB0            # Instruction with REPxx prefix 
  47  C_PRI =       0xC0            # Privileged instruction 
  48  C_SSE =       0xD0            # SSE instruction 
  49  C_NOW =       0xE0            # 3DNow! instruction 
  50  C_BAD =       0xF0            # Unrecognized command 
  51   
  52  # Decode type 
  53  DEC_TYPEMASK = 0x1F     # Type of memory byte 
  54  DEC_UNKNOWN  = 0x00     # Unknown type 
  55  DEC_BYTE     = 0x01     # Accessed as byte 
  56  DEC_WORD     = 0x02     # Accessed as short 
  57  DEC_NEXTDATA = 0x03     # Subsequent byte of data 
  58  DEC_DWORD    = 0x04     # Accessed as long 
  59  DEC_FLOAT4   = 0x05     # Accessed as float 
  60  DEC_FWORD    = 0x06     # Accessed as descriptor/long pointer 
  61  DEC_FLOAT8   = 0x07     # Accessed as double 
  62  DEC_QWORD    = 0x08     # Accessed as 8-byte integer 
  63  DEC_FLOAT10  = 0x09     # Accessed as long double 
  64  DEC_TBYTE    = 0x0A     # Accessed as 10-byte integer 
  65  DEC_STRING   = 0x0B     # Zero-terminated ASCII string 
  66  DEC_UNICODE  = 0x0C     # Zero-terminated UNICODE string 
  67  DEC_3DNOW    = 0x0D     # Accessed as 3Dnow operand 
  68  DEC_SSE      = 0x0E     # Accessed as SSE operand 
  69  DEC_TEXT     = 0x10     # For use in t_result only 
  70  DEC_BYTESW   = 0x11     # Accessed as byte index to switch 
  71  DEC_NEXTCODE = 0x13     # Subsequent byte of command 
  72  DEC_COMMAND  = 0x1D     # First byte of command 
  73  DEC_JMPDEST  = 0x1E     # Jump destination 
  74  DEC_CALLDEST = 0x1F     # Call (and maybe jump) destination 
  75   
  76  DEC_PROCMASK = 0x60     # Procedure analysis 
  77  DEC_PROC     = 0x20     # Start of procedure 
  78  DEC_PBODY    = 0x40     # Body of procedure 
  79  DEC_PEND     = 0x60     # End of procedure 
  80   
  81  DEC_CHECKED  = 0x80     # Byte was analysed 
  82  DEC_SIGNED   = 0x100    # For use in t_result only 
  83   
  84  DECR_TYPEMASK = 0x3F    # Type of register or memory 
  85  DECR_BYTE     = 0x21    # Byte register 
  86  DECR_WORD     = 0x22    # Short integer register 
  87  DECR_DWORD    = 0x24    # Long integer register 
  88  DECR_QWORD    = 0x28    # MMX register 
  89  DECR_FLOAT10  = 0x29    # Floating-point register 
  90  DECR_SEG      = 0x2A    # Segment register 
  91  DECR_3DNOW    = 0x2D    # 3Dnow! register 
  92  DECR_SSE      = 0x2E    # SSE register 
  93   
  94  DECR_ISREG    = 0x20    # Mask to check that operand is register 
  95  DEC_CONST     = 0x40    # Immediate constant, used by Analyser 
  96   
  97  RegisterName = { (0,0,0,0,0,0,0,0):"", (1,0,0,0,0,0,0,0):"EAX",(0,1,0,0,0,0,0,0):"ECX",\ 
  98                   (0,0,1,0,0,0,0,0):"EDX", (0,0,0,1,0,0,0,0):"EBX",(0,0,0,0,1,0,0,0):"ESP",\ 
  99                   (0,0,0,0,0,1,0,0):"EBP", (0,0,0,0,0,0,1,0):"ESI", (0,0,0,0,0,0,0,1):"EDI"} 
 100   
 101  COUNT = 100 
102 -class opCode:
103 - def __init__(self, imm, addr):
104 self.imm = imm 105 self.address = addr 106 self.operand = []
107 108
109 - def _getfromtuple(self, opcode):
110 self.ip=opcode[0] # Instruction pointer 111 self.dump=opcode[1] # Hexadecimal dump of the command 112 self.result=opcode[2] # Disassembled command 113 self.comment=opcode[3] # Brief comment 114 self.opinfo=opcode[4] # Comments to command's operands (tuple[3]) 115 self.cmdtype=opcode[5] # One of C_xxx 116 self.memtype=opcode[6] # Type of addressed variable in memory 117 self.nprefix=opcode[7] # Number of prefixes 118 self.indexed=opcode[8] # Address contains register(s) 119 self.jmpconst=opcode[9] # Constant jump address 120 self.jmptable=opcode[10] # Possible address of switch table 121 self.adrconst=opcode[11] # Constant part of address 122 self.immconst=opcode[12] # Immediate constant 123 self.zeroconst=opcode[13] # Whether contains zero constant 124 self.fixupoffset=opcode[14] # Possible offset of 32-bit fixups 125 self.fixupsize=opcode[15] # Possible total size of fixups or 0 126 self.jmpaddr=opcode[16] # Destination of jump/call/return 127 self.condition=opcode[17] # 0xFF:unconditional, 0:false, 1:true 128 self.error=opcode[18] # Error while disassembling command 129 self.warnings=opcode[19] # Combination of DAW_xxx 130 self.optype=opcode[20] # Type of operand (extended set DEC_xxx) (tuple[3]) 131 self.operandsize=opcode[21] # Size of operand, bytes (tuple[3]) 132 self.opsize=opcode[22] #common opsize in bytes (this is the one you want, almost sure) 133 self.opgood=opcode[23] # Whether address and data valid (tuple[3]) 134 self.opaddr=opcode[24] # Address if memory, index if register (tuple[3]) 135 self.opdata=opcode[25] # Actual value (only integer operands) (tuple[3]) 136 #NOTE ABOUT self.operand: 137 #self.operand[n][0] = operand type DEC_xxx (mem) or DECR_xxx (reg,const) 138 #self.operand[n][1] = operand size 139 #self.operand[n][2][x] = where x any reg value from 0 to 7 = scales of registers 140 #self.operand[n][3] segment register 141 #self.operand[n][4] Constant 142 self.operand=opcode[26] # Full description of operand (tuple[3]) 143 144 145 self.regdata=opcode[27] # Registers after command is executed / status of registers list[(reg,status)] 146 self.addrdata=opcode[28] # Traced memory address 147 self.addrstatus=opcode[29] # Status of addrdata, one of RST_xxx 148 self.regstack=opcode[30] # Stack tracing buffer / status of stack items list[(stack,status)]
149 #self.nregstack=opcode[32] # Number of items in stack trace buffer 150 151 # We need to include more than one register 152 # ex: [EAX+EDI+2]
153 - def getOperandRegister(self, num):
154 try: 155 return RegisterName[ self.operand[num][2] ] 156 except KeyError: 157 return "[]"
158
159 - def getIP(self):
160 return self.ip
161
162 - def getAddress(self):
163 return self.address
164
165 - def getDump(self):
166 return self.dump
167
168 - def getResult(self):
169 return self.result
170
171 - def getDisasm(self):
172 return self.result
173
174 - def getComment(self):
175 return self.comment
176
177 - def getOpInfo(self):
178 return self.opinfo
179
180 - def isCmd(self):
181 return self.getCmdType() == C_CMD
182
183 - def isPush(self):
184 return self.getCmdType() == C_PSH
185
186 - def isPop(self):
187 return self.getCmdType() == C_POP
188
189 - def isCall(self):
190 return self.getCmdType() == C_CAL
191
192 - def isJmp(self):
193 return self.getCmdType() == C_JMP
194
195 - def isConditionalJmp(self):
196 return self.getCmdType() == C_JMC
197
198 - def isRet(self):
199 return self.getCmdType() == C_RET
200
201 - def isRep(self):
202 return self.getCmdType() == C_REP
203
204 - def getCmd(self):
205 return self.cmdtype
206
207 - def getCmdType(self):
208 # types are defined as C_* 209 return self.cmdtype & C_TYPEMASK
210
211 - def getMemType(self):
212 return self.memtype
213
214 - def getnPrefix(self):
215 return self.nprefix
216
217 - def getIndexed(self):
218 return self.indexed
219
220 - def getJmpConst(self):
221 return self.jmpconst
222
223 - def getJmpTable(self):
224 return self.jmptable
225
226 - def getAddrConst(self):
227 return self.adrconst
228
229 - def getImmConst(self):
230 return self.immconst
231
232 - def getZeroConst(self):
233 return self.zeroconst
234
235 - def getFixUpOffset(self):
236 return self.fixupoffset
237
238 - def getFixUpSize(self):
239 return self.fixupsize
240
241 - def getJmpAddr(self):
242 return self.jmpaddr
243
244 - def getCondition(self):
245 return self.condition
246
247 - def getError(self):
248 return self.error
249
250 - def getWarnings(self):
251 return self.warnings
252
253 - def getOpType(self):
254 return self.optype
255
256 - def getOpSize(self):
257 return self.opsize
258
259 - def getSize(self):
260 return self.opsize
261
262 - def getOpGood(self):
263 return self.opgood
264
265 - def getOpAddr(self):
266 return self.opaddr
267
268 - def getOpData(self):
269 return self.opdata
270
271 - def getRegData(self):
272 return self.regdata
273
274 - def getRegStatus(self):
275 return self.regdata
276
277 - def getAddrData(self):
278 return self.addrdata
279
280 - def getAddrStatus(self):
281 return self.addrstatus
282
283 - def getRegStack(self):
284 return self.regstack
285
286 - def getRstStatus(self):
287 return self.regstack
288
289 - def getnRegStack(self):
290 return "deprecated"
291 292 #NOTE: info panel is runtime information, no matter which opcode you use to fetch it 293 # you'll have the info IP linked. 294
295 - def getInfoPanel(self):
296 return debugger.Getinfopanel()
297
298 -class Decode(UserList.UserList):
299 - def __init__(self, address):
300 """ 301 Internal Information of the Analyzed Code 302 303 @type address: DWORD 304 @param address: Address in the range of the analized code you want to retrieve 305 """ 306 UserList.UserList.