⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 importpe(7).asm

📁 参看PE文件的导入表的汇编程序
💻 ASM
字号:

.model flat,stdcall 
option casemap:none 
include windows.inc 
include kernel32.inc 
include comdlg32.inc 
include user32.inc 
includelib user32.lib 
includelib kernel32.lib 
includelib comdlg32.lib 

IDD_MAINDLG equ 101 
IDC_EDIT equ 1000 
IDM_OPEN equ 40001 
IDM_EXIT equ 40003 

DlgProc proto :DWORD,:DWORD,:DWORD,:DWORD 
ShowImportFunctions proto :DWORD 
ShowTheFunctions proto :DWORD,:DWORD 
AppendText proto :DWORD,:DWORD 

SEH struct 
PrevLink dd ? ; the address of the previous seh structure 
CurrentHandler dd ? ; the address of the new exception handler 
SafeOffset dd ? ; The offset where it's safe to continue execution 
PrevEsp dd ? ; the old value in esp 
PrevEbp dd ? ; The old value in ebp 
SEH ends 

.data 
AppName db "PE tutorial no.6",0 
ofn OPENFILENAME <> 
FilterString db "Executable Files (*.exe, *.dll)",0,"*.exe;*.dll",0 
             db "All Files",0,"*.*",0,0 
FileOpenError db "Cannot open the file for reading",0 
FileOpenMappingError db "Cannot open the file for memory mapping",0 
FileMappingError db "Cannot map the file into memory",0 
NotValidPE db "This file is not a valid PE",0 
CRLF db 0Dh,0Ah,0 
ImportDescriptor db 0Dh,0Ah,"================[ IMAGE_IMPORT_DESCRIPTOR ]=============",0 
IDTemplate db "OriginalFirstThunk = %lX",0Dh,0Ah 
           db "TimeDateStamp = %lX",0Dh,0Ah 
           db "ForwarderChain = %lX",0Dh,0Ah 
           db "Name = %s",0Dh,0Ah 
           db "FirstThunk = %lX",0 
NameHeader db 0Dh,0Ah,"Hint Function",0Dh,0Ah 
           db "-----------------------------------------",0 
NameTemplate db "%u %s",0 
OrdinalTemplate db "%u (ord.)",0 

.data? 
buffer db 512 dup(?) 
hFile dd ? 
hMapping dd ? 
pMapping dd ? 
ValidPE dd ? 

.code 
start: 
invoke GetModuleHandle,NULL 
invoke DialogBoxParam, eax, IDD_MAINDLG,NULL,addr DlgProc, 0 
invoke ExitProcess, 0 

DlgProc proc hDlg:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD 
.if uMsg==WM_INITDIALOG 
  invoke SendDlgItemMessage,hDlg,IDC_EDIT,EM_SETLIMITTEXT,0,0 
.elseif uMsg==WM_CLOSE 
  invoke EndDialog,hDlg,0 
.elseif uMsg==WM_COMMAND 
  .if lParam==0 
    mov eax,wParam 
    .if ax==IDM_OPEN 
      invoke ShowImportFunctions,hDlg 
    .else ; IDM_EXIT 
      invoke SendMessage,hDlg,WM_CLOSE,0,0 
    .endif 
  .endif 
.else 
  mov eax,FALSE 
  ret 
.endif 
mov eax,TRUE 
ret 
DlgProc endp 

SEHHandler proc uses edx pExcept:DWORD, pFrame:DWORD, pContext:DWORD, pDispatch:DWORD 
  mov edx,pFrame 
  assume edx:ptr SEH 
  mov eax,pContext 
  assume eax:ptr CONTEXT 
  push [edx].SafeOffset 
  pop [eax].regEip 
  push [edx].PrevEsp 
  pop [eax].regEsp 
  push [edx].PrevEbp 
  pop [eax].regEbp 
  mov ValidPE, FALSE 
  mov eax,ExceptionContinueExecution 
  ret 
SEHHandler endp 

ShowImportFunctions proc uses edi hDlg:DWORD 
  LOCAL seh:SEH 
  mov ofn.lStructSize,SIZEOF 
  ofn mov ofn.lpstrFilter, OFFSET FilterString 
  mov ofn.lpstrFile, OFFSET buffer 
  mov ofn.nMaxFile,512 
  mov ofn.Flags, OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST or OFN_LONGNAMES or OFN_EXPLORER or OFN_HIDEREADONLY 
  invoke GetOpenFileName, ADDR ofn 
  .if eax==TRUE 
    invoke CreateFile, addr buffer, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL 
    .if eax!=INVALID_HANDLE_VALUE 
      mov hFile, eax 
      invoke CreateFileMapping, hFile, NULL, PAGE_READONLY,0,0,0 
      .if eax!=NULL 
        mov hMapping, eax 
        invoke MapViewOfFile,hMapping,FILE_MAP_READ,0,0,0 
        .if eax!=NULL 
          mov pMapping,eax 
          assume fs:nothing 
          push fs:[0] 
          pop seh.PrevLink 
          mov seh.CurrentHandler,offset SEHHandler 
          mov seh.SafeOffset,offset FinalExit 
          lea eax,seh 
          mov fs:[0], eax 
          mov seh.PrevEsp,esp 
          mov seh.PrevEbp,ebp 
          mov edi, pMapping 
          assume edi:ptr IMAGE_DOS_HEADER 
          .if [edi].e_magic==IMAGE_DOS_SIGNATURE 
            add edi, [edi].e_lfanew 
            assume edi:ptr IMAGE_NT_HEADERS 
            .if [edi].Signature==IMAGE_NT_SIGNATURE 
              mov ValidPE, TRUE 
            .else 
              mov ValidPE, FALSE 
            .endif 
          .else 
            mov ValidPE,FALSE 
          .endif 
FinalExit: 
          push seh.PrevLink 
          pop fs:[0] 
          .if ValidPE==TRUE 
            invoke ShowTheFunctions, hDlg, edi    ;edi 这个时候指向的是IMAGE_NT_HEADERS
          .else 
            invoke MessageBox,0, addr NotValidPE, addr AppName, MB_OK+MB_ICONERROR 
          .endif 
          invoke UnmapViewOfFile, pMapping 
      .else 
          invoke MessageBox, 0, addr FileMappingError, addr AppName, MB_OK+MB_ICONERROR 
      .endif 
      invoke CloseHandle,hMapping 
    .else 
      invoke MessageBox, 0, addr FileOpenMappingError, addr AppName, MB_OK+MB_ICONERROR 
    .endif 
    invoke CloseHandle, hFile 
   .else 
   invoke MessageBox, 0, addr FileOpenError, addr AppName, MB_OK+MB_ICONERROR 
   .endif 
 .endif 
 ret 
ShowImportFunctions endp 

AppendText proc hDlg:DWORD,pText:DWORD 
   invoke SendDlgItemMessage,hDlg,IDC_EDIT,EM_REPLACESEL,0,pText 
   invoke SendDlgItemMessage,hDlg,IDC_EDIT,EM_REPLACESEL,0,addr CRLF 
   invoke SendDlgItemMessage,hDlg,IDC_EDIT,EM_SETSEL,-1,0 
   ret 
AppendText endp 

;根RVA值得到文件镜像偏移量
;pFileMap 是PE文件的文件镜像基址 
;这里返回的是文件镜像的偏移地址,
RVAToOffset PROC uses edi esi edx ecx pFileMap:DWORD,RVA:DWORD 
   mov esi,pFileMap 
   assume esi:ptr IMAGE_DOS_HEADER 
   add esi,[esi].e_lfanew 
   assume esi:ptr IMAGE_NT_HEADERS 
   mov edi,RVA ; edi == RVA 
   mov edx,esi 
   add edx,sizeof IMAGE_NT_HEADERS  ;edx到了节表处
   mov cx,[esi].FileHeader.NumberOfSections 
   movzx ecx,cx 
   assume edx:ptr IMAGE_SECTION_HEADER
   ;这里找到文件镜像偏移地址的思想过程有两步:
   ;1:传入的RVA比节表的RVA值大,
   ;2:如果a=RVA+SizeOfRawData  ,那么传入的RVA比a小
   ;上面两步满足之后,就可以可以肯定RVA所在的节表位置了
   .while ecx>0 ; check all sections 
     .if edi>=[edx].VirtualAddress 
       mov eax,[edx].VirtualAddress 
       add eax,[edx].SizeOfRawData ;注意:这里的SizeOfRawData是经过文件对齐处理后的本节的大小
       .if edi<eax ; The address is in this section 
         mov eax,[edx].VirtualAddress 
         sub edi,eax
         mov eax,[edx].PointerToRawData 
         add eax,edi ; eax == file offset 
         ret 
       .endif 
     .endif 
     add edx,sizeof IMAGE_SECTION_HEADER 
     dec ecx 
   .endw 
   assume edx:nothing 
   assume esi:nothing 
   mov eax,edi 
   ret 
RVAToOffset endp 

ShowTheFunctions proc uses esi ecx ebx hDlg:DWORD, pNTHdr:DWORD 
   LOCAL temp[512]:BYTE 
   invoke SetDlgItemText,hDlg,IDC_EDIT,0 
   invoke AppendText,hDlg,addr buffer 
   mov edi,pNTHdr 
   assume edi:ptr IMAGE_NT_HEADERS
   
   ;这里得到了导出表的RVA  
   mov edi, [edi].OptionalHeader.DataDirectory[sizeof IMAGE_DATA_DIRECTORY].VirtualAddress 
   
   ;注意这里是必须要进行的从RVA到实际的文件偏移地址的转换过程
   invoke RVAToOffset,pMapping,edi 
   mov edi,eax 
   add edi,pMapping ;注意一定要加一个文件镜像基址
  
   ;此时edi已经到达了导入表地址了,该地址处是一个IMAGE_IMPORT_DESCRIPTOR数组
   assume edi:ptr IMAGE_IMPORT_DESCRIPTOR 
   
   ;这里每一个IMAGE_IMPORT_DESCRIPTOR 代表的是引入一个dll文件,以一个全0的IMAGE_IMPORT_DESCRIPTOR结束
   .while !([edi].OriginalFirstThunk==0 && [edi].TimeDateStamp==0 && [edi].ForwarderChain==0 && [edi].Name1==0 && [edi].FirstThunk==0) 
     invoke AppendText,hDlg,addr ImportDescriptor 
     invoke RVAToOffset,pMapping, [edi].Name1 ;第一个dll文件信息
     mov edx,eax 
     add edx,pMapping 
     invoke wsprintf, addr temp, addr IDTemplate, [edi].OriginalFirstThunk,[edi].TimeDateStamp,[edi].ForwarderChain,edx,[edi].FirstThunk 
     invoke AppendText,hDlg,addr temp 
     .if [edi].OriginalFirstThunk==0 
        mov esi,[edi].FirstThunk 
     .else 
        mov esi,[edi].OriginalFirstThunk 
     .endif 
     invoke RVAToOffset,pMapping,esi 
     add eax,pMapping 
     mov esi,eax 
     invoke AppendText,hDlg,addr NameHeader 
     .while dword ptr [esi]!=0 
       test dword ptr [esi],IMAGE_ORDINAL_FLAG32 
       jnz ImportByOrdinal 
       invoke RVAToOffset,pMapping,dword ptr [esi] 
       mov edx,eax 
       add edx,pMapping 
       assume edx:ptr IMAGE_IMPORT_BY_NAME 
       mov cx, [edx].Hint 
       movzx ecx,cx 
       invoke wsprintf,addr temp,addr NameTemplate,ecx,addr [edx].Name1 
       jmp ShowTheText 
ImportByOrdinal: 
       mov edx,dword ptr [esi] 
       and edx,0FFFFh 
       invoke wsprintf,addr temp,addr OrdinalTemplate,edx 
ShowTheText: 
       invoke AppendText,hDlg,addr temp 
       add esi,4 
    .endw 
    add edi,sizeof IMAGE_IMPORT_DESCRIPTOR 
  .endw 
  ret 
ShowTheFunctions endp 
end start 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -