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

Source Code for Module Libs.immutils

  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  MOSDEF utils for non-CANVAS users 
 11   
 12  """ 
 13   
 14   
 15  __VERSION__ = '1.0' 
 16   
 17  # TODO check: 
 18  # ----------- 
 19  # cparse: dInt 
 20  # spark: prettyprint 
 21  # x86opcodes: issignedbyte, intel_byte, intel_2byte 
 22  # pelib: hexdump 
 23  # mosdef: isprint, strisprint 
 24  # makeexe: binstring? 
 25   
 26  import sys, os 
 27  sys.path.append('.') 
 28   
 29  #try: 
 30  #    from internal import * 
 31  #except: 
32 -def __ignore(*args, **kargs):
33 return False
34 -def __retsamearg(arg):
35 return arg
36 devlog = __ignore 37 isdebug = __ignore 38 warnings_safely_ignore = __ignore 39 warning_restore = __ignore 40 deprecate = __ignore 41 uniqlist = __retsamearg 42 43 44 # -------------------- 45 # 46 # __MOSDEFimport__ 47 # 48 # -------------------- 49 # 50 # global options: (set it to False to desactivate) 51 _MOSDEFimport_hook = True # desactivate the current hook 52 _MOSDEFimport_cachefailedimport = True # cache can be dangerous (breaks reload()?) 53 # 54 # normally you DONT want to hack in the <MOSDEFimport> tag. 55 # NOTE: can we optimize speed here? 56 # 57 # <MOSDEFimport> begin 58 from traceback import format_exc
59 -def __MOSDEFimport__(*args):
60 global _failed_imported_module_table 61 def mod_hash(modname): 62 return hash(str(hash(str(sys.path))) + modname)
63 modname = args[0] 64 if __debug__: 65 if len(args) < 4 or args[3] == None: 66 devlog('MOSDEFimport', "IMPORT %s" % modname) 67 else: 68 if len(args[3]) == 1: 69 val = args[3][0] 70 else: 71 val = str(args[3])[1:-1] 72 devlog('MOSDEFimport', "FROM %s IMPORT %s" % (modname, val), nofile = True) 73 if _MOSDEFimport_cachefailedimport: 74 modhash = mod_hash(modname) 75 if modhash in _failed_imported_module_table: 76 devlog('MOSDEFimport', "already failed to import <%s>" % modname, nofile = True) 77 raise ImportError 78 cwd = os.getcwd() 79 filepath = os.path.dirname(globals()['__file__']) 80 mosdefpath = filepath.replace(cwd, ".") 81 #print "[!] mosdef cwd: %s"%cwd 82 #print "[!] filepath: %s"%filepath 83 #print "[!] mosdefpath: %s"%mosdefpath 84 sys.path = uniqlist(sys.path) 85 if cwd != mosdefpath and mosdefpath not in sys.path: 86 sys.path.insert(0, mosdefpath) 87 import_time = time.time() 88 try: 89 return sys.modules['__builtin__'].__import__orig(*args) 90 except: 91 if _MOSDEFimport_cachefailedimport: 92 _failed_imported_module_table += [modhash] 93 devlog('all', "failed to import <%s> (lost %ss)" % (modname, time.time() - import_time), nofile = True) 94 devlog('ImportError', format_exc(0).split('\n')[1], nodesc = True) 95 if isdebug('ImportErrorTrace'): 96 backtrace() 97 raise 98 import __builtin__ 99 if _MOSDEFimport_hook and not hasattr(__builtin__, '__import__orig'): 100 import time 101 __builtin__.__import__orig = __builtin__.__import__ 102 __builtin__.__import__ = __MOSDEFimport__ 103 _MOSDEFimport_hook = False 104 _failed_imported_module_table = [] 105 devlog('all', "__import__ hooked with __MOSDEFimport__") 106 del __builtin__ 107 # </MOSDEFimport> end 108 109 110 ##################################################### 111 # 112 # 113 # dictionary class that hold floats as integers 114 # 115 # 116 ##################################################### 117 118 import types 119
120 -class antifloatdict(types.DictType):
121
122 - def __init__(self, arg = {}):
123 if type(arg) == types.DictType: 124 d = {} 125 for item in arg.items(): 126 d.__setitem__(item[0], item[1]) 127 arg = d 128 return types.DictType.__init__(self, arg)
129
130 - def __setitem__(self, itemname, itemvalue):
131 if type(itemvalue) == types.FloatType: 132 itemvalue = int(itemvalue) 133 return types.DictType.__setitem__(self, itemname, itemvalue)
134
135 - def __getitem__(self, itemname):
136 item = types.DictType.__getitem__(self, itemname) 137 if type(item) == types.FloatType: 138 item = int(item) 139 return item
140
141 - def copy(self):
142 return antifloatdict(self)
143
144 -def hasbadchar(word,badchars):
145 try: 146 wordstr=intel_order(word) 147 except: 148 wordstr=str(word) 149 for ch in badchars: 150 if wordstr.count(ch): 151 return 1 152 return 0
153 154 155 156 ##################################################### 157 # 158 # 159 # little/big endian management functions 160 # 161 # 162 ##################################################### 163
164 -def check_bits_consistancy(bits):
165 assert not bits % 8, "bits should be sizeof(char) aligned, got %d" % bits
166
167 -def check_string_len(s, l, assertmsg=""):
168 if assertmsg != "": 169 assertmsg += "\n" 170 assert len(s) >= l, "%sexpecting a at_least_%d_chars string, got %d_chars instead.\nstring is: %s" % \ 171 (assertmsg, l, len(s), prettyprint(s))
172
173 -def split_int_bits(bits, i):
174 check_bits_consistancy(bits) 175 # we cast to uint_bits here to be sure to return (bits/8) x uint8 176 u = uint_bits(bits, i) 177 r = [] 178 for b in range(0, bits, 8): 179 r += [ (u >> (bits - (b + 8))) & 0xff ] 180 return r
181 182 # 0x12345678 -> [0x12, 0x34, 0x56, 0x78]
183 -def split_int32(int32):
184 return split_int_bits(32, int32)
185
186 -def int2list_bits(bits, i, swap=0):
187 check_bits_consistancy(bits) 188 l = split_int_bits(bits, i) 189 #devlog("int2list: l = %s" % l) 190 lc = [] 191 for n in l: 192 #devlog("int2list: n = 0x%x" % n) 193 lc += [chr(n)] 194 if swap: 195 lc.reverse() 196 return lc
197
198 -def int2list32(int32, swap=0):
199 return int2list_bits(32, int32, swap=swap)
200 201 #def int2list(int32): 202 # deprecate("use int2list32 instead") 203 # return int2list32(int32) 204
205 -def int2str_bits(bits, i, swap=0):
206 check_bits_consistancy(bits) 207 return "".join(int2list_bits(bits, i, swap=swap))
208
209 -def int2str32(int32, swap=0):
210 return int2str_bits(32, int32, swap=swap)
211
212 -def int2str16(int16, swap=0):
213 return int2str_bits(16, int16, swap=swap)
214
215 -def int2str32_swapped(int32):
216 return int2str_bits(32, int32, swap=1)
217
218 -def int2str16_swapped(int16):
219 return int2str_bits(16, int16, swap=1)
220 221 #def int2str(int32): 222 # deprecate("use int2str32 instead") 223 # return int2str32(int32) 224
225 -def str2int_bits(bits, s):
226 check_bits_consistancy(bits) 227 assert type(s) == type(""), "str2int_bits() expects a string argument, got %s" % type(s) 228 nchars = bits / 8 229 check_string_len(s, nchars, "str2int_bits(%d, s): string=<%s> len=%d" % (bits, s, len(s))) 230 r = 0 231 warnings_safely_ignore(FutureWarning) 232 for i in range(0, nchars): 233 #print "%d = %x << %d" % (ord(s[i]) << 8*i, ord(s[i]), 8*i) 234 r += ord(s[nchars-i-1]) << 8*i 235 warning_restore() 236 return r
237
238 -def str2int_bits_swapped(bits, s):
239 check_string_len(s, bits/8) 240 return byteswap_bits(bits, str2int_bits(bits, s))
241
242 -def str2int16(s):
243 return str2int_bits(16, s)
244
245 -def str2int32(s):
246 return str2int_bits(32, s)
247
248 -def str2int64(s):
249 return str2int_bits(64, s)
250
251 -def str2int16_swapped(s):
252 return str2int_bits_swapped(16, s)
253
254 -def str2int32_swapped(s):
255 return str2int_bits_swapped(32, s)
256
257 -def str2int64_swapped(s):
258 return str2int_bits_swapped(64, s)
259 260 # "\x12\x34\x56\x78" -> 0x12345678 261 #def str2int32_old(s): 262 # #return str2int_bits(32, s) 263 # assert type(s) == type(""), "str2int32() expects a string argument, got %s" % type(s) 264 # if len(s) < 4: 265 # devlog("str2int32: string=<%s> len=%d" % (s, len(s))) 266 # raise AssertionError, "str2int32 called with a less_than_4_chars string (%d chars)" % len(s) 267 # (a,b,c,d)=(ord(s[0]),ord(s[1]),ord(s[2]),ord(s[3])) 268 # return sint32((a << 24) + (b << 16) + (c << 8) + d) 269 270 #returns the integer that the 4 byte string represents 271 #Note: If you are getting OverflowError in this function, you need to upgrade to Python 272 #2.2. !! 273
274 -def str2bigendian(astring):
275 """ 276 oppposite of istr2int 277 """ 278 return str2int32(astring)
279 280 # >>> print "0x%x" % str2littleendian("\x12\x34\x56\x78") 281 # 0x78563412
282 -def str2littleendian(astring):
283 return byteswap_32(str2int32(astring))
284
285 -def byteswap_bits(bits, i):
286 check_bits_consistancy(bits) 287 r = 0 288 warnings_safely_ignore(FutureWarning) 289 for b in range(0, bits, 8): 290 r += (((i >> b) & 0xff) << (bits - (b + 8))) 291 warning_restore() 292 return r
293
294 -def byteswap_64(int64):
295 return byteswap_bits(64, int64)
296
297 -def byteswap_32(int32):
298 return byteswap_bits(32, int32)
299
300 -def byteswap_16(int16):
301 return byteswap_bits(16, int16)
302 303 """ 304 istr2halfword(halfword2bstr(dInt(x))) == byteswap_16(x) 305 """ 306 307 ##################################################### 308 # 309 # 310 # print crap nicely 311 # 312 # 313 ##################################################### 314 315 #wee little function for printing strings nicely
316 -def hexprint(s):
317 if not type(s) == type(""): 318 return "can not hexdump %s" % type(s) 319 tmp="" 320 for c in s: 321 tmp+="[0x%2.2x]"%ord(c) 322 return tmp
323 324 goodchars=".()~!#$%^&*()-=_/\\:<>" 325 #let's not mess up our tty
326 -def prettyprint(instring):
327 import string 328 if not type(instring) == type(""): 329 devlog("prettyprint got %s and not string" % type(instring)) 330 instring = str(instring) 331 #return "can not prettyprint %s" % type(instring) 332 tmp="" 333 for ch in instring: 334 #if (ch.isalnum() or ch in goodchars) and ord(ch)<127: 335 if ch in string.printable and ch not in ["\x0c"]: 336 tmp+=ch 337 else: 338 value="%2.2x" % ord(ch) 339 tmp+="["+value+"]" 340 341 return tmp
342
343 -def c_array(data, desc = None):
344 if not type(data) == type(""): 345 devlog("c_array() got %s and not string" % type(data)) 346 return "c_array() can not dump %s" % type(data) 347 if not len(data): 348 return "c_array() got void buffer" 349 350 ucharbuf = "unsigned char buf[] = \"" 351 for uchar in data: 352 ucharbuf += "\\x%02x" % ord(uchar) 353 ucharbuf += "\"; // %d byte" % len(data) 354 if len(data) > 1: 355 ucharbuf += "s" 356 if desc: 357 ucharbuf += ", %s" % desc 358 359 return ucharbuf
360
361 -def shellcode_dump(sc, align=0, alignpad=" ", alignmax=16, mode=None):
362 import types 363 assert type(align) == type(0), "error in arguments, expecting an int for 'align'" 364 if not type(sc) in [types.StringType, types.BufferType]: 365 devlog("shellcode_dump() got %s and not string" % type(sc)) 366 return type(sc) 367 if not len(sc): 368 return "void buffer" 369 if mode and mode.upper() == "RISC": 370 align=4 371 alignmax=4 372 if align: 373 alignmax *= align 374 buf = "" 375 i = 0 376 for c in sc: 377 buf += "%02x " % ord(c) 378 if align and (i % align) == (align - 1): 379 buf += alignpad 380 if alignmax and (i % alignmax) == (alignmax - 1): 381 buf += "\n" 382 i += 1 383 if buf[-1] == "\n": 384 buf = buf[:-1] 385 return buf
386
387 -def dummywrite(fd, data):
388 """ 389 we just want to write some data on any fd, opened or closed. 390 """ 391 import os 392 try: 393 os.write(fd, data) 394 except OSError, errargs: 395 import errno 396 if errargs.errno != errno.EBADF: 397 raise
398
399 -def warnmsg(msg):
400