安全中国首页 > 文章中心 > 编释语言
 
安全中国网友投稿专用上传FTP空间:
Ftp服务器:download.anqn.com
Ftp端口:21
用户名:anqn
密 码:anqn.com
 

《加密解密 技术内幕》1.26 PE教程7: Export Table(引出表)

更新时间:2008-3-10 0:15:57
责任编辑:池天
热 点:

 
FinalExit:
         push seh.PrevLink
         pop fs:[0]
         .if ValidPE==TRUE
           invoke ShowTheFunctions, hDlg, edi
         .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
ShowExportFunctions 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

RVAToFileMap 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
mov cx,[esi].FileHeader.NumberOfSections
movzx ecx,cx
assume edx:ptr IMAGE_SECTION_HEADER
.while ecx>0
   .if edi>=[edx].VirtualAddress
     mov eax,[edx].VirtualAddress
     add eax,[edx].SizeOfRawData
     .if edi<eax
       mov eax,[edx].VirtualAddress
       sub edi,eax
       mov eax,[edx].PointerToRawData
       add eax,edi
       add eax,pFileMap
       ret
     .endif
   .endif
   add edx,sizeof IMAGE_SECTION_HEADER
   dec ecx
.endw
assume edx:nothing
assume esi:nothing
mov eax,edi
ret
RVAToFileMap endp

ShowTheFunctions proc uses esi ecx ebx hDlg:DWORD, pNTHdr:DWORD
LOCAL temp[512]:BYTE
LOCAL NumberOfNames:DWORD
LOCAL Base:DWORD

mov edi,pNTHdr
assume edi:ptr IMAGE_NT_HEADERS
mov edi, [edi].OptionalHeader.DataDirectory.VirtualAddress
.if edi==0
  invoke MessageBox,0, addr NoExportTable,addr AppName,MB_OK+MB_ICONERROR
  ret
.endif
invoke SetDlgItemText,hDlg,IDC_EDIT,0
invoke AppendText,hDlg,addr buffer
invoke RVAToFileMap,pMapping,edi
mov edi,eax
assume edi:ptr IMAGE_EXPORT_DIRECTORY
mov eax,[edi].NumberOfFunctions
invoke RVAToFileMap, pMapping,[edi].nName
invoke wsprintf, addr temp,addr ExportTable, eax, [edi].nBase, [edi].NumberOfFunctions, [edi].NumberOfNames, [edi].AddressOfFunctions, [edi].AddressOfNames, [edi].AddressOfNameOrdinals
invoke AppendText,hDlg,addr temp
invoke AppendText,hDlg,addr Header
push [edi].NumberOfNames
pop NumberOfNames
push [edi].nBase
pop Base
invoke RVAToFileMap,pMapping,[edi].AddressOfNames
mov esi,eax
invoke RVAToFileMap,pMapping,[edi].AddressOfNameOrdinals
mov ebx,eax
invoke RVAToFileMap,pMapping,[edi].AddressOfFunctions
mov edi,eax
.while NumberOfNames>0
   invoke RVAToFileMap,pMapping,dword ptr [esi]
   mov dx,[ebx]
   movzx edx,dx
   mov ecx,edx
   shl edx,2
   add edx,edi
   add ecx,Base
   invoke wsprintf, addr temp,addr template,dword ptr [edx],ecx,eax
   invoke AppendText,hDlg,addr temp
   dec NumberOfNames
   add esi,4
   add ebx,2
.endw
ret
ShowTheFunctions endp
end start

分析:

mov edi,pNTHdr
assume edi:ptr IMAGE_NT_HEADERS
mov edi, [edi].OptionalHeader.DataDirectory.VirtualAddress
.if edi==0
  invoke MessageBox,0, addr NoExportTable,addr AppName,MB_OK+MB_ICONERROR
  ret
.endif

程序检验PE有效性后,定位到数据目录获取引出表的虚拟地址。若该虚拟地址为0,则文件不含引出符号。

mov eax,[edi].NumberOfFunctions
invoke RVAToFileMap, pMapping,[edi].nName
invoke wsprintf, addr temp,addr ExportTable, eax, [edi].nBase, [edi].NumberOfFunctions, [edi].NumberOfNames, [edi].AddressOfFunctions, [edi].AddressOfNames, [edi].AddressOfNameOrdinals
invoke AppendText,hDlg,addr temp

在编辑控件中显示IMAGE_EXPORT_DIRECTORY 结构的一些重要信息。

push [edi].NumberOfNames
pop NumberOfNames
push [edi].nBase
pop Base

由于我们要枚举所有函数名,就要知道引出表里的名字数目。nBase 在将AddressOfFunctions 数组索引转换成序数时派到用场。

invoke RVAToFileMap,pMapping,[edi].AddressOfNames
mov esi,eax
invoke RVAToFileMap,pMapping,[edi].AddressOfNameOrdinals
mov ebx,eax
invoke RVAToFileMap,pMapping,[edi].AddressOfFunctions
mov edi,eax

将三个数组的地址相应存放到esi,,ebx,edi中。准备开始访问。

.while NumberOfNames>0

直到所有名字都被处理完毕。

   invoke RVAToFileMap,pMapping,dword ptr [esi]

由于esi指向包含名字字符串RVAs的数组,所以[esi]含有当前名字的RVA,需要将它转换成虚拟地址,后面wsprintf要用的。

   mov dx,[ebx]
   movzx edx,dx
   mov ecx,edx
   add ecx,Base

ebx指向序数数组,值是字类型的。因此我们先要将其转换成双字,此时edx和ecx含有指向AddressOfFunctions 数组的索引。我们用edx作为索引值,而将ecx加上nBase得到函数的序数值。=

   shl edx,2
   add edx,edi

索引乘以4 (AddressOfFunctions 数组中每个元素都是4字节大小) 然后加上数组首地址,这样edx指向的就是所要函数的RVA了。

   invoke wsprintf, addr temp,addr template,dword ptr [edx],ecx,eax
   invoke AppendText,hDlg,addr temp

在编辑控件中显示函数的RVA, 序数, 和名字。

   dec NumberOfNames
   add esi,4
   add ebx,2
.endw

修正计数器,AddressOfNamesAddressOfNameOrdinals 两数组的当前指针,继续遍历直到所有名字全都处理完毕。

上一页 1 2 

 
相关文章
一日一文章
 
一日一软件
一日一动画