├── README.md ├── peparser.asm ├── peparser.exe └── peparser.inc /README.md: -------------------------------------------------------------------------------- 1 | PE-Parser-MASM32 2 | ================ 3 | 4 | A PE32/PE32+ parser written in MASM32 5 | 6 | STATUS: paused. 7 | 8 | TO-DO: 9 | - add support for PE32+ 10 | - re-do the exports parsing 11 | - adding the resourcing parsing 12 | -------------------------------------------------------------------------------- /peparser.asm: -------------------------------------------------------------------------------- 1 | .386 2 | .model flat, stdcall 3 | option casemap :none 4 | 5 | include peparser.inc 6 | 7 | .data 8 | ;OpenFileName 9 | openFileName OPENFILENAME <> 10 | filterString db "Executable Files (*.exe, *.dll)", 0, "*.exe;*.dll", 0 11 | db "All Files", 0, "*.*", 0 12 | ;Strings 13 | ;Insert db "Insert an *.exe filename: ", 0 14 | ErrorMsg db 10, 13, "[-] Error while extracting PE information!", 0 15 | MappedOk db 10, 13, "[+] The file is mapped in memory!", 10, 13, 10, 13, 0 16 | DOSHeader db "[!] DOS Header", 10, 13, 10, 13, 0 17 | PEHeader db 10, 13, 10, 13, "[!] PE Header", 10, 13, 10, 13, 0 18 | OptHeader db 10, 13, 10, 13, "[!] Optional Header", 10, 13, 10, 13, 0 19 | DataDir db 10, 13, 10, 13, "[!] Data Directories", 10, 13, 10, 13, 0 20 | Sections db 10, 13, 10, 13, "[!] Sections", 0 21 | Imports db 10, 13, 10, 13, "[!] Imports", 0 22 | Exports db 10, 13, 10, 13, 10, 13, "[!] Exports", 10, 13, 10, 13, 0 23 | Resources db 10, 13, 10, 13, "[!] Resources", 10, 13, 10, 13, 0 24 | sectionless db 10, 13, 9, "[-] Sectionless PE", 10, 13, 0 25 | no_exports db 9, "[-] No exports table found", 0 26 | cmd db "pause > NUL", 0 27 | Format db "%x", 0 28 | Format1 db "%s", 10, 13, 0 29 | ;DOS Header 30 | e_magic_str db 9, "e_magic: 0x", 0 31 | e_lfanew_str db 10, 13, 9, "e_lfanew: 0x", 0 32 | ;PE Header 33 | signature_str db 9, "signature: 0x", 0 34 | machine_str db 10, 13, 9, "machine: 0x", 0 35 | numberOfSections_str db 10, 13, 9, "numberOfSections: 0x", 0 36 | sizeOfOptionalHeader_str db 10, 13, 9, "sizeOfOptionalHeader: 0x", 0 37 | characteristics_str db 10, 13, 9, "characteristics: 0x", 0 38 | ;Optional Header 39 | magic_str db 9, "magic: ", 0 40 | addressOfEntryPoint_str db 10, 13, 9, "addressOfEntryPoint: 0x", 0 41 | imageBase_str db 10, 13, 9, "imageBase: 0x", 0 42 | sectionAlignment_str db 10, 13, 9, "sectionAlignment: 0x", 0 43 | fileAlignment_str db 10, 13, 9, "fileAlignment: 0x", 0 44 | majorSubsystemVersion_str db 10, 13, 9, "majorSubsystemVersion: 0x", 0 45 | sizeOfImage_str db 10, 13, 9, "sizeOfImage: 0x", 0 46 | sizeOfHeaders_str db 10, 13, 9, "sizeOfHeaders: 0x", 0 47 | subsystem_str db 10, 13, 9, "subsystem: 0x", 0 48 | numberOfRvaAndSizes_str db 10, 13, 9, "numberOfRvaAndSizes: 0x", 0 49 | ;Data Directories 50 | ex_dir_rva db 9, "export directory RVA: 0x", 0 51 | ex_dir_size db 10, 13, 9, "export directory size: 0x", 0 52 | imp_dir_rva db 10, 13, 9, "import directory RVA: 0x", 0 53 | imp_dir_size db 10, 13, 9, "import directory size: 0x", 0 54 | res_dir_rva db 10, 13, 9, "resource directory RVA: 0x", 0 55 | res_dir_size db 10, 13, 9, "resource directory size: 0x", 0 56 | exc_dir_rva db 10, 13, 9, "exception directory RVA: 0x", 0 57 | exc_dir_size db 10, 13, 9, "exception directory size: 0x", 0 58 | sec_dir_rva db 10, 13, 9, "security directory RVA: 0x", 0 59 | sec_dir_size db 10, 13, 9, "security directory size: 0x", 0 60 | rel_dir_rva db 10, 13, 9, "relocation directory RVA: 0x", 0 61 | rel_dir_size db 10, 13, 9, "relocation directory size: 0x", 0 62 | debug_dir_rva db 10, 13, 9, "debug directory RVA: 0x", 0 63 | debug_dir_size db 10, 13, 9, "debug directory size: 0x", 0 64 | arch_dir_rva db 10, 13, 9, "architecture directory RVA: 0x", 0 65 | arch_dir_size db 10, 13, 9, "architecture directory size: 0x", 0 66 | reserved_dir_rva db 10, 13, 9, "reserved directory RVA: 0x", 0 67 | reserved_dir_size db 10, 13, 9, "reserved directory size: 0x", 0 68 | TLS_dir_rva db 10, 13, 9, "TLS directory RVA: 0x", 0 69 | TLS_dir_size db 10, 13, 9, "TLS directory size: 0x", 0 70 | conf_dir_rva db 10, 13, 9, "configuration directory RVA: 0x", 0 71 | conf_dir_size db 10, 13, 9, "configuration directory size: 0x", 0 72 | bound_dir_rva db 10, 13, 9, "bound import directory RVA: 0x", 0 73 | bound_dir_size db 10, 13, 9, "bound import directory size: 0x", 0 74 | IAT_dir_rva db 10, 13, 9, "IAT directory RVA: 0x", 0 75 | IAT_dir_size db 10, 13, 9, "IAT directory size: 0x", 0 76 | delay_dir_rva db 10, 13, 9, "delay directory RVA: 0x", 0 77 | delay_dir_size db 10, 13, 9, "delay directory size: 0x", 0 78 | NET_dir_rva db 10, 13, 9, ".NET directory RVA: 0x", 0 79 | NET_dir_size db 10, 13, 9, ".NET directory size: 0x", 0 80 | ;Section Headers 81 | sec_name db 10, 13, 10, 13, 9, "name: ", 0 82 | virt_size db 10, 13, 9, "virtual size: 0x", 0 83 | virt_address db 10, 13, 9, "virtual address: 0x", 0 84 | raw_size db 10, 13, 9, "raw size: 0x", 0 85 | raw_address db 10, 13, 9, "raw address: 0x", 0 86 | reloc_address db 10, 13, 9, "relocation address: 0x", 0 87 | linenumbers db 10, 13, 9, "linenumbers: 0x", 0 88 | reloc_number db 10, 13, 9, "relocations number: 0x", 0 89 | linenumbers_number db 10, 13, 9, "linenumbers number: 0x", 0 90 | characteristics db 10, 13, 9, "characteristics: 0x", 0 91 | ;Imports 92 | dll_name db 10, 13, 10, 13, 9, "DLL name: ", 0 93 | functions_list db 10, 13, 10, 13, 9, "Functions list: ", 10, 13, 0 94 | hint db 10, 13, 9, 9, "Hint: 0x", 0 95 | function_name db 9, "Name: ", 0 96 | ;Exports 97 | numberOfFunctions db 10, 13, 9, "NumberOfFunctions: 0x", 0 98 | nName db 9, "nName: ", 0 99 | nBase db 10, 13, 9, "nBase: 0x", 0 100 | numberOfNames db 10, 13, 9, "numberOfNames: 0x", 0 101 | exportedFunctions db 10, 13, 9, "Function list:", 10, 13, 0 102 | RVA db 10, 13, 9, "RVA: 0x", 0 103 | ordinal db 9, "Ordinal: 0x", 0 104 | funcName db 9, "Name: ", 0 105 | ;Resources 106 | resource_name db 9, "resource name: ", 0 107 | 108 | .data? 109 | ;DOS Header 110 | e_lfanew dd ? 111 | ;Optional Header 112 | addr_opt_header dd ? 113 | ;Handlers 114 | ;hConsoleIn dd ? 115 | hConsoleOut dd ? 116 | hFile dd ? 117 | hMap dd ? 118 | pMapping dd ? 119 | bytesWritten dd ? 120 | ;fileName dd ? 121 | sections_count dd ? 122 | sizeOfOptionalHeader dd ? 123 | ;numberOfRvaAndSizes dd ? 124 | buffer db 512 dup (?) 125 | ;vars for Import Dumping 126 | sectionHeaderOffset dd ? 127 | importsRVA dd ? 128 | ;vars for Export Table 129 | exportsRVA dd ? 130 | exportedNamesOffset dd ? 131 | exportedFunctionsOffset dd ? 132 | exportedOrdinalsOffset dd ? 133 | numberOfNamesValue dd ? 134 | nBaseValue dd ? 135 | 136 | .code 137 | start: 138 | ;GetOpenFileName 139 | mov openFileName.lStructSize, sizeof openFileName 140 | mov openFileName.lpstrFilter, offset filterString 141 | mov openFileName.lpstrFile, offset buffer 142 | mov openFileName.nMaxFile, 512 143 | mov openFileName.Flags, OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST or OFN_LONGNAMES or OFN_EXPLORER or OFN_HIDEREADONLY 144 | invoke GetOpenFileName, addr openFileName 145 | 146 | ;Getting standard console I/O 147 | ;invoke GetStdHandle, STD_INPUT_HANDLE 148 | ;mov hConsoleIn, eax 149 | invoke GetStdHandle, STD_OUTPUT_HANDLE 150 | mov hConsoleOut, eax 151 | 152 | ;Get console input filename (max 100 chars) 153 | ;push offset Insert 154 | ;call print 155 | ;invoke ReadConsole, hConsoleIn, addr fileName, 64h, addr bytesWritten, 0 156 | ;Input string always contains 0xD, 0xA (13, 10) = carriage return. Little trick to NULL terminate the input string. 157 | ;mov eax, offset fileName 158 | ;add eax, bytesWritten 159 | ;sub eax, 2 160 | ;mov byte ptr [eax], 0 161 | 162 | ;Loading the file 163 | ;CONSOLE LOAD: invoke CreateFile, addr fileName, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 164 | invoke CreateFile, addr buffer, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 165 | mov hFile, eax 166 | 167 | ;Check if the file handle is valid 168 | cmp eax, INVALID_HANDLE_VALUE 169 | je errorExit 170 | 171 | invoke CreateFileMapping, hFile, 0, PAGE_READONLY, 0, 0, 0 172 | mov hMap, eax 173 | 174 | ;Check if the map handle is valid 175 | cmp eax, INVALID_HANDLE_VALUE 176 | je errorExit 177 | 178 | invoke MapViewOfFile, hMap, FILE_MAP_READ, 0, 0, 0 179 | mov pMapping, eax 180 | 181 | ;Check if the file is correctly mapped in memory 182 | cmp eax, 0 183 | je errorExit 184 | 185 | ;File correctly mapped 186 | push offset MappedOk 187 | call print 188 | 189 | ;DOS HEADER EXTRACTION 190 | mov edi, pMapping 191 | assume edi: ptr IMAGE_DOS_HEADER 192 | 193 | ;Check if the file is a DOS file 194 | cmp [edi].e_magic, IMAGE_DOS_SIGNATURE 195 | jne errorExit 196 | 197 | ;PRINT OUT DOS HEADER INFORMATION 198 | push offset DOSHeader 199 | call print 200 | push offset e_magic_str 201 | call print 202 | movzx edx, [edi].e_magic 203 | call print_f 204 | push offset e_lfanew_str 205 | call print 206 | mov edx, [edi].e_lfanew 207 | call print_f 208 | 209 | ;Check if the file is a PE file 210 | add edi, edx ;address of the PE Header 211 | assume edi: ptr IMAGE_NT_HEADERS 212 | cmp [edi].Signature, IMAGE_NT_SIGNATURE 213 | jne errorExit 214 | 215 | ;PRINT OUT PE HEADER INFORMATION 216 | push offset PEHeader 217 | call print 218 | push offset signature_str 219 | call print 220 | mov edx, [edi].Signature 221 | call print_f 222 | add edi, SIZEOF_NT_SIGNATURE 223 | assume edi: ptr IMAGE_FILE_HEADER 224 | push offset machine_str 225 | call print 226 | movzx edx, [edi].Machine 227 | call print_f 228 | push offset numberOfSections_str 229 | call print 230 | movzx edx, [edi].NumberOfSections 231 | push edx 232 | pop sections_count 233 | call print_f 234 | push offset sizeOfOptionalHeader_str 235 | call print 236 | movzx edx, [edi].SizeOfOptionalHeader 237 | push edx 238 | pop sizeOfOptionalHeader 239 | call print_f 240 | push offset characteristics_str 241 | call print 242 | movzx edx, [edi].Characteristics 243 | call print_f 244 | 245 | ;PRINT OUT OPTIONAL HEADER INFORMATION 246 | add edi, SIZEOF_IMAGE_FILE_HEADER 247 | assume edi: ptr IMAGE_OPTIONAL_HEADER 248 | 249 | push offset OptHeader 250 | call print 251 | push offset magic_str 252 | call print 253 | movzx edx, [edi].Magic 254 | call print_f 255 | push offset addressOfEntryPoint_str 256 | call print 257 | mov edx, [edi].AddressOfEntryPoint 258 | call print_f 259 | push offset imageBase_str 260 | call print 261 | mov edx, [edi].ImageBase 262 | call print_f 263 | push offset sectionAlignment_str 264 | call print 265 | mov edx, [edi].SectionAlignment 266 | call print_f 267 | push offset fileAlignment_str 268 | call print 269 | mov edx, [edi].FileAlignment 270 | call print_f 271 | push offset majorSubsystemVersion_str 272 | call print 273 | movzx edx, [edi].MajorSubsystemVersion 274 | call print_f 275 | push offset sizeOfImage_str 276 | call print 277 | mov edx, [edi].SizeOfImage 278 | call print_f 279 | push offset sizeOfHeaders_str 280 | call print 281 | mov edx, [edi].SizeOfHeaders 282 | call print_f 283 | push offset subsystem_str 284 | call print 285 | movzx edx, [edi].Subsystem 286 | call print_f 287 | push offset numberOfRvaAndSizes_str 288 | call print 289 | mov edx, [edi].NumberOfRvaAndSizes 290 | call print_f 291 | 292 | ;TO BE IMPLEMENTED CHECK OF THE IMAGE_DATA_DIRECTORY 293 | ;Even so, in the case where the size of the OH is 0, it won't work well. In that case I think you must trust the value in NumberOfRvaAndSizes, as long as it is less than 0x10. 294 | ;I lost the one born under the Saturn's Symbol, I really miss you. 295 | mov edx, sizeOfOptionalHeader 296 | sub edx, IMAGE_OPTIONAL_HEADER.NumberOfRvaAndSizes + 4 297 | cmp edx, 0 298 | je sections_start 299 | 300 | ;IMAGE DATA DIRECTORY 301 | add edi, 60h ;address of the Image Data Directory Start 302 | 303 | push offset DataDir 304 | call print 305 | push offset ex_dir_rva 306 | call print 307 | mov edx, dword ptr [edi] 308 | mov exportsRVA, edx 309 | call print_f 310 | push offset ex_dir_size 311 | call print 312 | mov edx, dword ptr [edi + 4h] 313 | call print_f 314 | push offset imp_dir_rva 315 | call print 316 | mov edx, dword ptr [edi + 8h] 317 | mov importsRVA, edx 318 | call print_f 319 | push offset imp_dir_size 320 | call print 321 | mov edx, dword ptr [edi + 0Ch] 322 | call print_f 323 | push offset res_dir_rva 324 | call print 325 | mov edx, dword ptr [edi + 10h] 326 | call print_f 327 | push offset res_dir_size 328 | call print 329 | mov edx, dword ptr [edi + 14h] 330 | call print_f 331 | push offset exc_dir_rva 332 | call print 333 | mov edx, dword ptr [edi + 18h] 334 | call print_f 335 | push offset exc_dir_size 336 | call print 337 | mov edx, dword ptr [edi + 1Ch] 338 | call print_f 339 | push offset sec_dir_rva 340 | call print 341 | mov edx, dword ptr [edi + 20h] 342 | call print_f 343 | push offset sec_dir_size 344 | call print 345 | mov edx, dword ptr [edi + 24h] 346 | call print_f 347 | push offset rel_dir_rva 348 | call print 349 | mov edx, dword ptr [edi + 28h] 350 | call print_f 351 | push offset rel_dir_size 352 | call print 353 | mov edx, dword ptr [edi + 2Ch] 354 | call print_f 355 | push offset debug_dir_rva 356 | call print 357 | mov edx, dword ptr [edi + 30h] 358 | call print_f 359 | push offset debug_dir_size 360 | call print 361 | mov edx, dword ptr [edi + 34h] 362 | call print_f 363 | push offset arch_dir_rva 364 | call print 365 | mov edx, dword ptr [edi + 38h] 366 | call print_f 367 | push offset arch_dir_size 368 | call print 369 | mov edx, dword ptr [edi + 3Ch] 370 | call print_f 371 | push offset reserved_dir_rva 372 | call print 373 | mov edx, dword ptr [edi + 40h] 374 | call print_f 375 | push offset reserved_dir_size 376 | call print 377 | mov edx, dword ptr [edi + 44h] 378 | call print_f 379 | push offset TLS_dir_rva 380 | call print 381 | mov edx, dword ptr [edi + 48h] 382 | call print_f 383 | push offset TLS_dir_size 384 | call print 385 | mov edx, dword ptr [edi + 4Ch] 386 | call print_f 387 | push offset conf_dir_rva 388 | call print 389 | mov edx, dword ptr [edi + 50h] 390 | call print_f 391 | push offset conf_dir_size 392 | call print 393 | mov edx, dword ptr [edi + 54h] 394 | call print_f 395 | push offset bound_dir_rva 396 | call print 397 | mov edx, dword ptr [edi + 58h] 398 | call print_f 399 | push offset bound_dir_size 400 | call print 401 | mov edx, dword ptr [edi + 5Ch] 402 | call print_f 403 | push offset IAT_dir_rva 404 | call print 405 | mov edx, dword ptr [edi + 60h] 406 | call print_f 407 | push offset IAT_dir_size 408 | call print 409 | mov edx, dword ptr [edi + 64h] 410 | call print_f 411 | push offset delay_dir_rva 412 | call print 413 | mov edx, dword ptr [edi + 68h] 414 | call print_f 415 | push offset delay_dir_size 416 | call print 417 | mov edx, dword ptr [edi + 6Ch] 418 | call print_f 419 | push offset NET_dir_rva 420 | call print 421 | mov edx, dword ptr [edi + 70h] 422 | call print_f 423 | push offset NET_dir_size 424 | call print 425 | mov edx, dword ptr [edi + 74h] 426 | call print_f 427 | 428 | ;SECTIONS 429 | sub edi, 60h 430 | sections_start: 431 | add edi, sizeof IMAGE_OPTIONAL_HEADER 432 | assume edi: ptr IMAGE_SECTION_HEADER 433 | mov sectionHeaderOffset, edi 434 | 435 | push offset Sections 436 | call print 437 | 438 | mov ebx, sections_count 439 | cmp ebx, 0 440 | jne sections 441 | push offset sectionless 442 | call print 443 | 444 | sections: 445 | cmp ebx, 0 446 | je imports 447 | sub ebx, 1 448 | push offset sec_name 449 | call print 450 | push edi 451 | call print 452 | push offset virt_size 453 | call print 454 | mov edx, dword ptr [edi + 8h] 455 | call print_f 456 | push offset virt_address 457 | call print 458 | mov edx, [edi].VirtualAddress 459 | call print_f 460 | push offset raw_size 461 | call print 462 | mov edx, [edi].SizeOfRawData 463 | call print_f 464 | push offset raw_address 465 | call print 466 | mov edx, [edi].PointerToRawData 467 | call print_f 468 | push offset reloc_address 469 | call print 470 | mov edx, [edi].PointerToRelocations 471 | call print_f 472 | push offset linenumbers 473 | call print 474 | mov edx, [edi].PointerToLinenumbers 475 | call print_f 476 | push offset reloc_number 477 | call print 478 | movzx edx, [edi].NumberOfRelocations 479 | call print_f 480 | push offset linenumbers_number 481 | call print 482 | movzx edx, [edi].NumberOfLinenumbers 483 | call print_f 484 | push offset characteristics 485 | call print 486 | mov edx, [edi].Characteristics 487 | call print_f 488 | add edi, 28h 489 | jmp sections 490 | 491 | ;Imports 492 | imports: 493 | push offset Imports 494 | call print 495 | mov edi, importsRVA 496 | call RVAtoOffset 497 | mov edi, eax 498 | add edi, pMapping 499 | assume edi:ptr IMAGE_IMPORT_DESCRIPTOR 500 | next_import_DLL: 501 | cmp [edi].OriginalFirstThunk, 0 502 | jne extract_import 503 | cmp [edi].TimeDateStamp, 0 504 | jne extract_import 505 | cmp [edi].ForwarderChain, 0 506 | jne extract_import 507 | cmp [edi].Name1, 0 508 | jne extract_import 509 | cmp [edi].FirstThunk, 0 510 | jne extract_import 511 | jmp exports ;no more imports to extract, go to exports 512 | 513 | extract_import: 514 | push edi 515 | mov edi, [edi].Name1 516 | call RVAtoOffset 517 | pop edi 518 | mov edx, eax 519 | add edx, pMapping 520 | push offset dll_name ;DLL Name 521 | call print 522 | push edx 523 | call print 524 | cmp [edi].OriginalFirstThunk, 0 525 | jne useOriginalFirstThunk 526 | mov esi, [edi].FirstThunk 527 | jmp useFirstThunk 528 | useOriginalFirstThunk: 529 | mov esi, [edi].OriginalFirstThunk 530 | useFirstThunk: 531 | push edi 532 | mov edi, esi 533 | call RVAtoOffset 534 | pop edi 535 | add eax, pMapping 536 | mov esi, eax 537 | 538 | push offset functions_list ;functions list 539 | call print 540 | extract_functions: 541 | cmp dword ptr [esi], 0 542 | je next_DLL 543 | test dword ptr [esi], IMAGE_ORDINAL_FLAG32 544 | jnz useOrdinal 545 | push edi 546 | mov edi, dword ptr [esi] 547 | call RVAtoOffset 548 | pop edi 549 | mov edx, eax 550 | add edx, pMapping 551 | assume edx:ptr IMAGE_IMPORT_BY_NAME 552 | mov cx, [edx].Hint ;point to the Hint 553 | movzx ecx, cx 554 | push offset hint 555 | call print 556 | push edx 557 | mov edx, ecx 558 | call print_f 559 | pop edx 560 | push offset function_name 561 | call print 562 | lea edx, [edx].Name1 ;point to the function Name 563 | push edx 564 | call print 565 | jmp next_import 566 | useOrdinal: 567 | mov edx, dword ptr [esi] 568 | and edx, 0FFFFh 569 | call print_f 570 | next_import: 571 | add esi, 4 572 | jmp extract_functions 573 | next_DLL: 574 | add edi, sizeof IMAGE_IMPORT_DESCRIPTOR 575 | jmp next_import_DLL 576 | 577 | ;Exports 578 | exports: 579 | push offset Exports 580 | call print 581 | 582 | cmp exportsRVA, 0 583 | jne extract_exports 584 | push offset no_exports 585 | call print 586 | jmp resources 587 | 588 | extract_exports: 589 | mov edi, exportsRVA 590 | call RVAtoOffset 591 | mov edi, eax 592 | add edi, pMapping 593 | assume edi:ptr IMAGE_EXPORT_DIRECTORY 594 | ;nName 595 | push edi 596 | mov edi, [edi].nName 597 | call RVAtoOffset 598 | add eax, pMapping 599 | pop edi 600 | push offset nName 601 | call print 602 | push eax 603 | call print 604 | ;nBase 605 | push offset nBase 606 | call print 607 | mov edx, [edi].nBase 608 | mov nBaseValue, edx 609 | call print_f 610 | ;numberOfFunctions 611 | push offset numberOfFunctions 612 | call print 613 | mov edx, [edi].NumberOfFunctions 614 | call print_f 615 | ;NumberOfNames 616 | push offset numberOfNames 617 | call print 618 | mov edx, [edi].NumberOfNames 619 | mov numberOfNamesValue, edx 620 | call print_f 621 | ;exported functions 622 | push offset exportedFunctions 623 | call print 624 | ;check for ordinal exports 625 | mov edx, [edi].NumberOfFunctions 626 | cmp edx, [edi].NumberOfNames 627 | ;je noOrdinalExports 628 | ;ordinal exports 629 | push edi 630 | mov edi, [edi].AddressOfNameOrdinals 631 | call RVAtoOffset 632 | add eax, pMapping 633 | mov exportedOrdinalsOffset, eax 634 | pop edi 635 | noOrdinalExports: 636 | ;AddressOfFunctions 637 | push edi 638 | mov edi, [edi].AddressOfFunctions 639 | call RVAtoOffset 640 | add eax, pMapping 641 | mov exportedFunctionsOffset, eax 642 | pop edi 643 | ;AddressOfNames 644 | push edi 645 | mov edi, [edi].AddressOfNames 646 | call RVAtoOffset 647 | add eax, pMapping 648 | mov exportedNamesOffset, eax 649 | pop edi 650 | next_export: 651 | cmp numberOfNamesValue, 0 652 | jle resources 653 | mov eax, exportedOrdinalsOffset 654 | mov dx, [eax] 655 | movzx edx, dx 656 | mov ecx, edx 657 | shl edx, 2 658 | add edx, exportedFunctionsOffset 659 | add ecx, nBaseValue 660 | ;RVA 661 | push offset RVA 662 | call print 663 | mov edx, dword ptr [edx] 664 | call print_f 665 | ;Ordinal 666 | push offset ordinal 667 | call print 668 | mov edx, ecx 669 | call print_f 670 | ;name 671 | push offset funcName 672 | call print 673 | mov edx, dword ptr exportedNamesOffset 674 | mov edi, dword ptr [edx] 675 | call RVAtoOffset 676 | add eax, pMapping 677 | push eax 678 | call print 679 | ;increment indexes 680 | dec numberOfNamesValue 681 | add exportedNamesOffset, 4 ;point to the next name in the array 682 | add exportedOrdinalsOffset, 2 683 | jmp next_export 684 | 685 | ;Resources 686 | resources: 687 | push offset Resources 688 | call print 689 | 690 | ;Closing handles, unmap the file and exit 691 | invoke UnmapViewOfFile, pMapping 692 | invoke CloseHandle, hFile 693 | invoke CloseHandle, hMap 694 | push offset cmd 695 | call system 696 | invoke ExitProcess, EXIT_SUCCESS 697 | 698 | errorExit: 699 | invoke CloseHandle, hFile 700 | invoke CloseHandle, hMap 701 | push offset ErrorMsg 702 | call print 703 | push offset cmd 704 | call system 705 | invoke ExitProcess, EXIT_FAILURE 706 | 707 | ;Print routine: writes a string to the console 708 | ;1) string to write 709 | print proc 710 | pushad 711 | mov ebx, dword ptr [esp + 36] 712 | invoke lstrlen, ebx 713 | invoke WriteConsole, hConsoleOut, ebx, eax, addr bytesWritten, 0 714 | popad 715 | ret 4 716 | print endp 717 | 718 | ;print_num routine: write a number to the console 719 | ;Before calling the procedure the value has to be moved in EDX 720 | ;1) number to write 721 | ;2) length of the number 722 | print_f proc 723 | pushad 724 | push edx 725 | push offset Format 726 | call printf 727 | add esp, 8 728 | popad 729 | ret 730 | print_f endp 731 | 732 | ;Converts an RVA to an Offset 733 | ;The RVA is received into EDI, converted and the offset is put into EAX 734 | RVAtoOffset proc 735 | mov edx, sectionHeaderOffset 736 | assume edx:ptr IMAGE_SECTION_HEADER 737 | mov ecx, sections_count 738 | sections_cicle: 739 | cmp ecx, 0 740 | jle end_routine 741 | cmp edi, [edx].VirtualAddress 742 | jl next_section 743 | mov eax, [edx].VirtualAddress 744 | add eax, [edx].SizeOfRawData 745 | cmp edi, eax 746 | jge next_section 747 | mov eax, [edx].VirtualAddress 748 | sub edi, eax 749 | mov eax, [edx].PointerToRawData 750 | add eax, edi 751 | ret 752 | next_section: 753 | add edx, sizeof IMAGE_SECTION_HEADER 754 | dec ecx 755 | jmp sections_cicle 756 | end_routine: 757 | mov eax, edi 758 | ret 759 | RVAtoOffset endp 760 | 761 | end start 762 | -------------------------------------------------------------------------------- /peparser.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fvrmatteo/PE-Parser-MASM32/8552c1d5f2522eccda4fd82dff50b72f4a864981/peparser.exe -------------------------------------------------------------------------------- /peparser.inc: -------------------------------------------------------------------------------- 1 | include \masm32\include\windows.inc 2 | include \masm32\include\kernel32.inc 3 | include \masm32\include\msvcrt.inc 4 | include \masm32\include\comdlg32.inc 5 | includelib \masm32\lib\msvcrt.lib 6 | includelib \masm32\lib\kernel32.lib 7 | includelib \masm32\lib\comdlg32.lib 8 | 9 | extrn printf :near 10 | extrn system :near 11 | 12 | SIZEOF_NT_SIGNATURE equ sizeof DWORD 13 | SIZEOF_IMAGE_FILE_HEADER equ 14h --------------------------------------------------------------------------------