Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. ; ###############################################################################;
  2. ; DESCRIPTION: This code provide a simple (and not optimized) example
  3. ;            : of PE analisys. Find DOS Header, NT Header, show sections, and you
  4. ;            : can add a new section.
  5. ;            ; ------------------------------------------------------------------;
  6. ; UPDATE     : - Now PE Analyzer show to you the Import Table!
  7. ;            : - Menu Added;
  8. ;            ; ------------------------------------------------------------------;
  9. ;            : Future version: add more functionality.
  10. ;            :
  11. ;            : NOTE:
  12. ;            : Please, backup the original exe before adding a new section!
  13. ;            : (seems to be stable!)
  14. ; -------------------------------------------------------------------------------;
  15. ; COMPILATION: ml /c /coff file.asm
  16. ; LINKING    : link /SUBSYSTEM:CONSOLE file
  17. ; -------------------------------------------------------------------------------;
  18. ; AUTHOR     : Marco 'RootkitNeo' C.
  19. ; -------------------------------------------------------------------------------;
  20. ; LANGUAGE   : MASM32 (CUI Application)
  21. ; -------------------------------------------------------------------------------;
  22. ; VERSION    : 0.9.9 (Beta)
  23. ; -------------------------------------------------------------------------------;
  24. ; LICENSE    : GNU/GPL V.3
  25. ; ###############################################################################;
  26.  
  27.  
  28.  
  29. include     c:\masm32\include\masm32rt.inc
  30.  
  31.  
  32. ; Data Section
  33. ; -------------------------------------------------------------------------------
  34. .data
  35. dosHeader              IMAGE_DOS_HEADER < >
  36. ntHeader               IMAGE_NT_HEADERS < >
  37.  
  38. BUFFER_MAX             =    4
  39.  
  40. crlf                   db   13,10,0
  41. crlf2                  db   13,10,13,10,0
  42. tab                    db   9,0
  43.  
  44. FileName               db   MAX_PATH   dup(?)
  45.  
  46. welcome                db   "Welcome in PE Analyzer V. 0.9.9",13,10,"Software developed by Marco 'RootkitNeo' C.",13,10,13,10,0
  47.                            
  48. menu                   db   13,10,13,10,"Select an option:",13,10,"1. Read Section Table",13,10,
  49.                             "2. Add Section",13,10,"3. Show Import Table",13,10,"4. Exit",13,10,0
  50. ; add section strings
  51. newSectionString       db   13,10,13,10,"Section Name: ",0
  52. sectionSizeString      db   13,10,"Size: ",0
  53.  
  54. ; read file and check if is valid
  55. fnameString            db   "Enter File Name: ",0
  56. openfileString         db   "Opening File...",13,10,0
  57. readSuccessString      db   13,10,"File Successiful read!",13,10,0
  58. fileOffsetString       db   9,"File offset: 0x",0
  59. validHeaderString      db   13,10,13,10,"Valid PE Header ",13,10,0
  60. validNtHeaderString    db   13,10,13,10,"Valid NT Signature ",13,10,13,10,0
  61. writeSuccessString     db   13,10,13,10,"File successiful saved",13,10,0
  62.  
  63. ; Sections
  64. sectionNameString      db   13,10,13,10,"Name: ",0
  65. virtualSizeString      db   13,10,"Virtual Size: 0x",0
  66. virtualAddrString      db   13,10,"Virtual Address: 0x",0
  67. sizeRawDataString      db   13,10,"Size Of Raw Data: 0x",0
  68. ptrRawDataString       db   13,10,"Pointer To Raw Data: 0x",0
  69. charactString          db   13,10,"Characteristics: 0x",0
  70. addNewSectionString    db   13,10,13,10,"Add New Section? ('y', 'n'): ",0
  71.  
  72. ; Import table
  73. importTableString      db   13,10,"Import Table:",13,10,0
  74. nameModuleString       db   "Module Name: ",0
  75. functionsNameString    db   "Functions: ",13,10,0
  76.  
  77. ; Error messages
  78. createError            db   "Cannot open the file.",13,10,0
  79. allocError             db   "Cannot allocate the memory.",13,10,0
  80. readError              db   "Cannon read the file.",13,10,0
  81. invalidDosHeader       db   "Invalid DOS Header.",13,10,0
  82. invalidNtHeader        db   "Invalid NT Header.",13,10,0
  83. writeErrorString       db   "Write Error",0
  84. importTableErrorString db   "IT doesn't exist",13,10,0
  85. ordinalString          db   "Imported by Ordinal: 0x",0
  86.  
  87. closeFailed            db   "Close failed",13,10,0
  88.  
  89. showMoreText           db   13,10,"...[Press 'ESC' for go back to menu]...",0
  90. ;---------------------------------------------------------------------------------
  91.  
  92.  
  93. ; BSS Section
  94. ;---------------------------------------------------------------------------------
  95. .data?
  96. BaseAddress            dd            ?
  97. hFile                  DWORD         ?
  98. FileSize               DWORD         ?
  99. BR                     DWORD         ?
  100. buffer1                db   9    dup(?)
  101. buffer2                db   40   dup(?)
  102. buffer                 db   4    dup(?)
  103. choice                 db   4    dup(?)
  104. sectionName            db   20   dup(?)
  105. sectionSizeS           db   100  dup(?)
  106. importName             db            ?
  107.  
  108. sectionSize            dw            ?
  109. nameSize               dd            ?
  110. numberOfSections       dw            ?
  111. ;---------------------------------------------------------------------------------
  112.  
  113.  
  114.  
  115. ; Code section
  116. ;---------------------------------------------------------------------------------
  117. .code
  118. start:
  119.   call    main
  120.  
  121.   invoke  GetProcessHeap
  122.   invoke  HeapFree, eax, 0, BaseAddress
  123.   invoke  CloseHandle, hFile
  124.  
  125.   cmp     eax, 0 ; CloseHandle fail?
  126.   jne     _exit
  127.  
  128.   push    offset closeFailed
  129.   call    StdOut
  130.  
  131. _exit:
  132.   inkey
  133.  
  134.   push    0
  135.   call    ExitProcess
  136.  
  137.  
  138. ; // Main function
  139. ; ---------------------------------------------------------------------
  140. main      proc
  141.   push    offset welcome
  142.   call    StdOut
  143.  
  144.   call    loadFile
  145.   cmp     eax,0         ; 0 = load failed --> exit program
  146.   jne     skip_menu
  147.  
  148.   call    readDosHeader
  149.   cmp     eax, 0        ; 0 = DOS header doesn't exist --> exit program
  150.   jne     skip_menu
  151.  
  152.   call    readNtHeader
  153.   cmp     eax, 0        ; 0 = NT Header doesn't exist --> exit program
  154.   jne     skip_menu
  155.  
  156. menu_label:
  157.   print   offset menu
  158.  
  159.   push    4
  160.   push    offset choice
  161.   call    StdIn
  162.  
  163.   cmp     [choice], 31h      ; 1
  164.   jne     else_if1
  165.   call    readSectionTable
  166.   jmp     menu_label
  167. else_if1:
  168.   cmp     [choice], 32h      ; 2
  169.   jne     else1
  170.   call    addNewSection
  171.   jmp     menu_label
  172. else1:
  173.   cmp     [choice], 33h      ; 3
  174.   jne     exit_menu
  175.   call    readImportDescriptor
  176.   jmp     menu_label
  177. exit_menu:
  178.   cmp     [choice], 34h      ; 4
  179.   je      skip_menu
  180.   jmp     menu_label
  181.  
  182. skip_menu:
  183.    
  184.   ret
  185. main      endp
  186. ; ---------------------------------------------------------------------
  187. ; // End Main
  188.  
  189.  
  190. ; Read Dos Header
  191. ; ---------------------------------------------------------------------  
  192. loadFile  proc
  193.  
  194.   print    offset fnameString
  195.  
  196.   ; Read file name
  197.   push    MAX_PATH
  198.   push    offset FileName
  199.   call    StdIn
  200.  
  201.   print   offset openfileString
  202.    
  203.   ; Create file (Open file and get HANDLE)
  204.   invoke  CreateFile, addr FileName, GENERIC_READ or GENERIC_WRITE ,FILE_SHARE_READ OR FILE_SHARE_WRITE,0, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0
  205.   mov     hFile, eax
  206.  
  207.   cmp     hFile,INVALID_HANDLE_VALUE
  208.   jne     createSuccess
  209.   print   offset createError
  210.  
  211.   mov     eax, 1
  212.   ret
  213.  
  214. createSuccess:
  215.   invoke  GetFileSize,hFile,0
  216.   mov     FileSize,eax
  217.  
  218.   invoke  GetProcessHeap
  219.   invoke  HeapAlloc, eax, HEAP_NO_SERIALIZE + HEAP_ZERO_MEMORY, FileSize
  220.   mov     BaseAddress, eax
  221.  
  222.   cmp     BaseAddress, NULL
  223.   jne     allocSuccess
  224.   print   offset allocError
  225.  
  226.   mov     eax, 1
  227.   ret
  228.  
  229.   ; Memory allocation successiful. Now we can read...
  230. allocSuccess:
  231.   invoke  ReadFile, hFile, BaseAddress, FileSize, addr BR,0
  232.  
  233.   cmp     eax, 0
  234.   jne     readSuccess
  235.   print   offset readError
  236.  
  237.   mov     eax, 1
  238.  
  239. readSuccess:
  240.   print   offset readSuccessString
  241.  
  242.   mov     eax, 0
  243.  
  244.   ret
  245.  
  246. loadFile      endp
  247. ; ---------------------------------------------------------------------  
  248. ; // End load file
  249.  
  250. ;
  251. ; DOS Header
  252. ; ---------------------------------------------------------------------
  253. readDosHeader  proc  
  254.   ; same as C:
  255.   ; BYTE             *BaseAddress;
  256.   ; IMAGE_DOS_HEADER *dosHeader;
  257.   ; ..... (allocation memory for BaseAddress) ....
  258.   ; dosHeader = (IMAGE_DOS_HEADER *) BaseAddress;
  259.   invoke  RtlMoveMemory, ADDR dosHeader, BaseAddress, SIZEOF dosHeader
  260.  
  261.   cmp     dosHeader.e_magic, IMAGE_DOS_SIGNATURE ; MZ ?
  262.   je      valid_dos_header
  263.   print   offset invalidDosHeader
  264.  
  265.   mov     eax, 1
  266.   ret
  267.  
  268. valid_dos_header:
  269.   print   offset validHeaderString
  270.  
  271.   print   offset fileOffsetString
  272.   invoke  RtlZeroMemory,addr buffer,BUFFER_MAX
  273.   invoke  dw2hex,dosHeader.e_lfanew,addr buffer
  274.   print   offset buffer
  275.  
  276.   mov     eax, 0
  277.  
  278.   ret      
  279.  
  280. readDosHeader   endp
  281. ; ---------------------------------------------------------------------
  282. ;
  283.  
  284. ;
  285. ; NT Header
  286. ; ---------------------------------------------------------------------
  287. readNtHeader    proc
  288.   mov     eax, BaseAddress
  289.   add     eax, [dosHeader.e_lfanew]
  290.   invoke  RtlMoveMemory, ADDR ntHeader, eax, SIZEOF ntHeader
  291.  
  292.   cmp     ntHeader.Signature, IMAGE_NT_SIGNATURE   ; PE ?
  293.   je      valid_nt_header
  294.   print   offset invalidNtHeader
  295.  
  296.   mov     eax, 1
  297.   ret
  298.  
  299. valid_nt_header:
  300.   print   offset validNtHeaderString
  301.  
  302.   mov     eax, 0
  303.  
  304.   ret
  305.  
  306. readNtHeader    endp
  307. ; ---------------------------------------------------------------------
  308. ; End NT Header
  309.  
  310. ;
  311. ; Image Section Header
  312. ; ---------------------------------------------------------------------
  313. readSectionTable   proc uses esi
  314.  
  315.   xor     ebx, ebx
  316.   xor     esi, esi
  317.  
  318.   call    findNTHeader
  319.   assume  esi:ptr IMAGE_FILE_HEADER
  320.  
  321.   xor     ecx, ecx
  322.   mov     cx, [esi].NumberOfSections
  323.   movzx   ecx, cx
  324.  
  325.   call    findSectionHeader ; ...and store it's address in ESI register
  326.   assume  esi:ptr IMAGE_SECTION_HEADER
  327.  
  328.  
  329.   ; Print sections
  330. show_sections:
  331.   cmp     ecx, 0
  332.   je      exit_show
  333.  
  334.   ; Push ecx because lstrcpyn don't use
  335.   ; register preservation...
  336.   push    ecx
  337.  
  338.   push    offset sectionNameString
  339.   call    StdOut
  340.   invoke  RtlZeroMemory,addr buffer1,9
  341.   invoke  lstrcpyn,addr buffer1,addr [esi].Name1,8
  342.   print   offset buffer1
  343.  
  344.   push    offset virtualSizeString
  345.   call    StdOut
  346.   invoke  RtlZeroMemory,addr buffer,BUFFER_MAX
  347.   invoke  dw2hex, [esi].Misc.VirtualSize, addr buffer
  348.   print   offset  buffer
  349.  
  350.   push    offset virtualAddrString
  351.   call    StdOut
  352.   invoke  RtlZeroMemory,addr buffer,BUFFER_MAX
  353.   invoke  dw2hex, [esi].VirtualAddress, addr buffer
  354.   print   offset buffer
  355.  
  356.   push    offset sizeRawDataString
  357.   call    StdOut
  358.   invoke  RtlZeroMemory,addr buffer,BUFFER_MAX
  359.   invoke  dw2hex, [esi].SizeOfRawData, addr buffer
  360.   print   offset buffer
  361.  
  362.   push    offset ptrRawDataString
  363.   call    StdOut
  364.   invoke  RtlZeroMemory,addr buffer,BUFFER_MAX
  365.   invoke  dw2hex, [esi].PointerToRawData, addr buffer
  366.   print   offset buffer
  367.  
  368.   push    offset charactString
  369.   call    StdOut
  370.   invoke  RtlZeroMemory,addr buffer,BUFFER_MAX
  371.   invoke  dw2hex, [esi].Characteristics, addr buffer
  372.   print   offset buffer
  373.  
  374.   pop     ecx ; get the previously pushed value
  375.  
  376.   dec     ecx
  377.   add     esi, 28h
  378.  
  379.   jmp     show_sections
  380.  
  381. exit_show:
  382.  
  383.   ret
  384. readSectionTable  endp
  385. ; ---------------------------------------------------------------------
  386. ; End Image Section Header
  387.  
  388. ;
  389. ; Add new section
  390. ; ---------------------------------------------------------------------
  391. addNewSection    proc uses esi edi
  392.  
  393.   push    offset newSectionString
  394.   call    StdOut
  395.  
  396.   push    20
  397.   push    offset sectionName
  398.   call    StdIn
  399.  
  400.   push    offset sectionSizeString
  401.   call    StdOut
  402.  
  403.   push    100
  404.   push    offset sectionSizeS
  405.   call    StdIn
  406.  
  407.   invoke  atodw, offset sectionSizeS    ; string number to number
  408.   mov     sectionSize, ax
  409.   xor     eax, eax
  410.  
  411.   call    findNTHeader
  412.   assume  esi:ptr IMAGE_FILE_HEADER
  413.  
  414.   mov     ax, [esi].NumberOfSections
  415.   mov     numberOfSections, ax
  416.   inc     ax
  417.  
  418.   mov     [esi].NumberOfSections, ax
  419.  
  420.   add     esi, 14h ; OptionalHeader
  421.   assume  esi:ptr IMAGE_OPTIONAL_HEADER
  422.  
  423.   mov     eax, [esi].SectionAlignment
  424.   mov     dx, sectionSize
  425.   movzx   edx, dx
  426.   call    Alignment
  427.  
  428.   add     [esi].SizeOfImage, ecx
  429.  
  430.   xor     esi, esi
  431.   call    findSectionHeader
  432.   assume  esi:ptr IMAGE_SECTION_HEADER
  433.   ; esi point to the address of the image section header
  434.   mov     edi, esi
  435.   call    findLastSection
  436.  
  437.   assume  edi:ptr IMAGE_SECTION_HEADER
  438.   invoke  RtlZeroMemory, edi,IMAGE_SIZEOF_SECTION_HEADER
  439.  
  440.   invoke  szLen, addr sectionName
  441.   cmp     eax, IMAGE_SIZEOF_SHORT_NAME
  442.   jg      default_value
  443.   mov     nameSize, eax
  444.   jmp     jmp_else
  445. default_value:
  446.   mov     nameSize, IMAGE_SIZEOF_SHORT_NAME
  447. jmp_else:
  448.   invoke  RtlMoveMemory, addr [edi].Name1, addr sectionName ,nameSize
  449.  
  450.   xor     esi,esi
  451.   call    findNTHeader
  452.   add     esi, 14h ; OptionalHeader
  453.   assume  esi:ptr IMAGE_OPTIONAL_HEADER
  454.  
  455.   mov     eax, [esi].SectionAlignment
  456.   sub     edi, sizeof IMAGE_SECTION_HEADER
  457.   mov     edx, [edi].VirtualAddress
  458.   add     edx, [edi].Misc.VirtualSize
  459.   call    Alignment
  460.  
  461.   add     edi, sizeof IMAGE_SECTION_HEADER
  462.   mov     [edi].VirtualAddress, ecx
  463.   mov     ax, sectionSize
  464.   movzx   eax, ax
  465.   mov     [edi].Misc.VirtualSize, eax
  466.  
  467.   sub     edi, sizeof IMAGE_SECTION_HEADER
  468.  
  469.   xor     edx, edx
  470.   mov     eax, [edi].SizeOfRawData
  471.   mov     ebx, [esi].FileAlignment
  472.   div     ebx
  473.   cmp     edx, 0
  474.   je      continue
  475.   ; FASTCALL convention
  476.   mov     eax, [esi].FileAlignment
  477.   mov     edx, [edi].SizeOfRawData
  478.   call    Alignment
  479.   mov     [edi].SizeOfRawData, ecx
  480.   mov     ebx, [edi].PointerToRawData
  481.   add     ebx, [edi].SizeOfRawData
  482.   invoke  SetFilePointer, hFile, ebx, NULL, FILE_BEGIN
  483.  
  484.   invoke  SetEndOfFile, hFile
  485. continue:
  486.  
  487.   add     edi, sizeof IMAGE_SECTION_HEADER
  488.   invoke  GetFileSize, hFile, NULL
  489.   mov     FileSize, eax
  490.   mov     [edi].PointerToRawData, eax
  491.  
  492.   mov     eax, [esi].FileAlignment
  493.   mov     dx, sectionSize
  494.   movzx   edx, dx
  495.   call    Alignment
  496.  
  497.   mov     [edi].SizeOfRawData, ecx
  498.   mov     [edi].Characteristics, IMAGE_SCN_MEM_READ or IMAGE_SCN_MEM_EXECUTE
  499.   mov     [edi].NumberOfRelocations, 0000h
  500.   mov     [edi].NumberOfLinenumbers, 0000h
  501.   mov     [edi].PointerToRelocations, 00000000h
  502.   mov     [edi].PointerToLinenumbers, 00000000h
  503.  
  504.  
  505.   invoke  SetFilePointer, hFile, [edi].SizeOfRawData, NULL, FILE_END
  506.   invoke  SetEndOfFile, hFile
  507.  
  508.   invoke  SetFilePointer, hFile, 0, NULL, FILE_BEGIN
  509.   invoke  WriteFile, hFile, BaseAddress,FileSize, addr BR, NULL
  510.  
  511.   cmp     eax, 0
  512.   jne     write_success
  513.  
  514.   push    offset writeErrorString
  515.   call    StdOut
  516.  
  517.   mov     eax, 1
  518.   ret
  519. write_success:
  520.   push    offset writeSuccessString
  521.   call    StdOut
  522.  
  523.   mov     eax, 0
  524.   ret
  525.  
  526. addNewSection    endp
  527. ; ---------------------------------------------------------------------
  528. ;
  529.  
  530. ; Print Import Table information
  531. ; ---------------------------------------------------------------------
  532. readImportDescriptor  proc uses esi edi
  533.  
  534.   LOCAL   nameLen:DWORD
  535.  
  536.   call    findNTHeader
  537.   add     esi, 14h
  538.   assume  esi:ptr IMAGE_OPTIONAL_HEADER
  539.   ; Get Import Table address into DataDirectory array
  540.   ; sizeof IMAGE_DATA_DIRECTORY = 2nd member of the array -> Import Table (VirtualAddress)
  541.   mov     edx,[esi].DataDirectory[sizeof IMAGE_DATA_DIRECTORY].VirtualAddress
  542.  
  543.   ; EDX = RVA of the IT
  544.   call    RVAToOffset
  545.   cmp     edx, 0
  546.   jne     continue_read_import ; if valid, read import
  547.  
  548.   push    offset importTableErrorString
  549.   call    StdOut
  550.   mov     eax, 0
  551.   ret
  552.  
  553.   ; Read IMAGE_IMPORT_DESCRIPTOR
  554.   ; each member is a DLL import
  555. continue_read_import:
  556.   mov     esi, edx
  557.   add     esi, BaseAddress
  558.   assume  esi:ptr IMAGE_IMPORT_DESCRIPTOR
  559.  
  560.   push    offset importTableString
  561.   call    StdOut
  562.  
  563. while_descriptors:
  564.   ; IMAGE_THUNK_DATA (basicly the RVA)
  565.   ; contains pointer to
  566.   ; an IMAGE_IMPORT_BY_NAME
  567.   cmp     [esi].FirstThunk, 0
  568.   je      exit_descriptors_while
  569.  
  570.   ; Name of the module
  571.   mov     edx, [esi].Name1
  572.  
  573.   push    esi
  574.  
  575.   call    findNTHeader
  576.   add     esi, 14h
  577.   assume  esi:ptr IMAGE_OPTIONAL_HEADER
  578.  
  579.   call    RVAToOffset
  580.   add     edx, BaseAddress
  581.  
  582.   ; register preservation
  583.   ; RtlZeroMemory change the value of EDX
  584.   push    edx
  585.  
  586.   invoke  RtlZeroMemory,addr buffer,20
  587.   push    offset nameModuleString
  588.   call    StdOut
  589.  
  590.   pop     edx
  591.   ; restore the previously pushed value
  592.  
  593.   invoke  lstrcpyn,addr buffer, edx,19
  594.   print   offset buffer
  595.  
  596.   push    offset crlf
  597.   call    StdOut
  598.  
  599.   push    offset functionsNameString
  600.   call    StdOut
  601.  
  602.   pop     esi
  603.   assume  esi:ptr IMAGE_IMPORT_DESCRIPTOR
  604.   ; select correct array
  605.   mov     edx, [esi].OriginalFirstThunk
  606.   cmp     [esi].OriginalFirstThunk,0
  607.   cmove   edx, [esi].FirstThunk
  608.   push    esi
  609.  
  610.   ; same as before; convert RVA into file offset
  611.   call    RVAToOffset
  612.   add     edx, BaseAddress
  613.   mov     edi, edx
  614.   assume  edi:ptr IMAGE_IMPORT_DESCRIPTOR
  615.  
  616.   ; IMAGE_IMPORT_BY_NAME -> name of the functions
  617.   ; imported by modules  
  618. functions:
  619.   push    offset tab
  620.   call    StdOut
  621.  
  622.   cmp     dword ptr[edi], 0
  623.   jz      exit_functions
  624.  
  625.   ; check if it is imported by name or ordinal
  626.   test    dword ptr [edi],IMAGE_ORDINAL_FLAG32
  627.   jnz     importByOrdinal
  628.  
  629.   ; ---- Imported by name block ----
  630.   mov     edx, dword ptr [edi]
  631.   push    edi
  632.   call    RVAToOffset
  633.   pop     edi
  634.   add     edx, BaseAddress
  635.   assume  edx:ptr IMAGE_IMPORT_BY_NAME
  636.  
  637.   push    edx
  638.   invoke  RtlZeroMemory,addr buffer2,40
  639.   pop     edx
  640.  
  641.   invoke  lstrcpyn,addr buffer2,addr [edx].Name1,39
  642.  
  643.   push    offset buffer2
  644.   call    StdOut
  645.   jmp     printText
  646.   ; --- imported by ordinal block -----
  647. importByOrdinal:
  648.   mov     edx, dword ptr [edi]
  649.   and     edx, 0FFFFh
  650.  
  651.   push    edx
  652.   push    offset ordinalString
  653.   call    StdOut
  654.   invoke  RtlZeroMemory,addr buffer,BUFFER_MAX
  655.   pop     edx
  656.   invoke  dw2hex, addr [edx], addr buffer
  657.   print   offset buffer
  658.  
  659. printText:
  660.  
  661.   push    offset crlf
  662.   call    StdOut
  663.  
  664.   add     edi, 4
  665.   jmp     functions  ; read the next function
  666.  
  667. exit_functions:
  668.   push    offset showMoreText
  669.   call    StdOut
  670.  
  671.   ;inkey   "...[Show More]..."
  672.   getkey
  673.  
  674.   cmp     eax, 1Bh
  675.   je      exit_descriptors_while
  676.  
  677.   push    offset crlf2
  678.   call    StdOut
  679.  
  680.   pop     esi
  681.   add     esi, sizeof IMAGE_IMPORT_DESCRIPTOR ; 'jmp' to the next entry
  682.  
  683.   jmp     while_descriptors  ; read the next module name
  684.  
  685. exit_descriptors_while:
  686.  
  687.   ret
  688. readImportDescriptor  endp
  689. ; ------------------------------------------------------------------------
  690. ;
  691.  
  692.  
  693.  
  694.  
  695.  
  696. ; #########################################
  697. ; #          UTILITY PROCEDURES           #
  698. ; #########################################
  699.  
  700.  
  701. ; Find first IMAGE_SECTION_HEADER
  702. ; ------------------------------------------------------
  703. findSectionHeader proc
  704.  
  705.   mov     esi, BaseAddress
  706.   add     esi, dosHeader.e_lfanew
  707.   mov     bx, ntHeader.FileHeader.SizeOfOptionalHeader
  708.   movzx   ebx, bx
  709.   add     esi,ebx
  710.   add     esi, 18h ; ESI -> block of sections
  711.                    ; 18h -> Signature NT Header
  712.   ret
  713. findSectionHeader  endp
  714. ; -------------------------------------------------------
  715. ;
  716.  
  717. ;
  718. ; --------------------------------------------------;
  719. ; Get Last Section (IMAGE_SECTION_HEADER)
  720. ; last section = the section inserted by user
  721. ; --------------------------------------------------;
  722. findLastSection   proc
  723.  
  724.   xor     ecx, ecx
  725.  
  726.   find_section:
  727.   cmp     cx, numberOfSections
  728.   je      exit_find
  729.  
  730.   add     edi, sizeof IMAGE_SECTION_HEADER
  731.   inc     cx
  732.   jmp     find_section
  733.  
  734. exit_find:
  735.  
  736.   ret
  737.  
  738. findLastSection   endp
  739. ;---------------------------------------------------;
  740. ;
  741.  
  742. ;
  743. ; --------------------------------------------------;
  744. ; Memory location of NT Header                      ;
  745. ; --------------------------------------------------;
  746. findNTHeader proc
  747.  
  748.   xor     esi, esi
  749.  
  750.   mov     esi, BaseAddress
  751.   add     esi, dosHeader.e_lfanew
  752.   add     esi, 4h ; 4h = size of Signature
  753.                   ; now ESI point to IMAGE_FILE_HEADER struct
  754.  
  755.   ret
  756. findNTHeader endp
  757. ; --------------------------------------------------;
  758. ;
  759.  
  760. ;
  761. ; --------------------------------------------------;
  762. ; FASTCALL:                                         ;
  763. ; EAX = first parameter                             ;
  764. ; EDX = second parameter                            ;
  765. ; --------------------------------------------------;
  766. Alignment   proc
  767.  
  768.   mov     ecx, eax
  769.  
  770. calc:
  771.   cmp     edx, ecx
  772.   jle     exit_calc
  773.  
  774.   add     ecx, eax
  775.  
  776.   jmp     calc
  777. exit_calc:
  778.  
  779.   ret
  780. Alignment   endp
  781. ; ---------------------------------------------------;
  782. ;
  783.  
  784. ;
  785. ; ---------------------------------------------------;
  786. ; Convert RVA address into File Offset               ;
  787. ; return value in EDX                                ;
  788. ; ---------------------------------------------------;
  789. RVAToOffset   proc uses eax edi esi
  790.   LOCAL   limit:DWORD
  791.  
  792.   call    findSectionHeader
  793.   mov     edi, esi
  794.   pop     esi
  795.   assume  edi:ptr IMAGE_SECTION_HEADER
  796.   ;EDI = first section
  797.  
  798.   cmp     edx, [edi].PointerToRawData
  799.   jge     continue
  800.  
  801.   ret
  802.  
  803.  
  804. continue:  
  805.   push    ecx
  806.   push    ebx
  807.  
  808.   xor     ecx, ecx
  809.   mov     cx, ntHeader.FileHeader.NumberOfSections
  810.   movzx   ecx, cx
  811. while_sections:
  812.   cmp     ecx, 0
  813.   je      exit_while
  814.  
  815.   cmp     [edi].SizeOfRawData, 0
  816.   jne     raw_data_0
  817.   mov     eax, [edi].Misc.VirtualSize
  818.   jmp     continue_else
  819. raw_data_0:
  820.   mov     eax, [edi].SizeOfRawData
  821.  
  822. continue_else:
  823.   cmp     edx, [edi].VirtualAddress
  824.   jge     control_and
  825.   jmp     continue_while
  826. control_and:
  827.   add     eax, [edi].VirtualAddress
  828.   cmp     edx, eax
  829.   jl      another_control
  830.   jmp     continue_while
  831. another_control:
  832.   cmp     [edi].PointerToRawData, 0
  833.   je      return_value
  834.   sub     edx, [edi].VirtualAddress
  835.   add     edx, [edi].PointerToRawData
  836. return_value:
  837.   pop     ebx
  838.   pop     ecx
  839.   ret
  840.  
  841. continue_while:
  842.   dec     ecx
  843.   add     edi, sizeof IMAGE_SECTION_HEADER
  844.   jmp     while_sections
  845.  
  846. exit_while:
  847.   mov     edx, 0
  848.   pop     ebx
  849.   pop     ecx
  850.   ret
  851.  
  852. RVAToOffset    endp
  853. ; -----------------------------------------------------;
  854. ;
  855.  
  856.  
  857. end    start