WIN32汇编语言教程:第17章 PE文件 · 17.4 资源(3)
and ebx,7fffffffh add ebx,_lpRes .if _dwLevel == 1 ;******************************************************************** ; 第一层:资源类型 ;******************************************************************** mov eax,[esi].Name1 .if eax & 80000000h and eax,7fffffffh add eax,_lpRes ;******************************************************************** ; 处理IMAGE_RESOURCE_DIR_STRING_U结构并将UNICODE转换成ANSI字符串 ;******************************************************************** movzx ecx,word ptr [eax] add eax,2 mov edx,eax invoke WideCharToMultiByte,CP_ACP,\ WC_COMPOSITECHECK,edx,ecx,\ addr @szResName,sizeof @szResName,\ NULL,NULL lea eax,@szResName .else ;******************************************************************** ; 当资源类型为标准类型的时候查表得到资源的字符串说明 ;******************************************************************** .if eax <= 10h dec eax mov ecx,sizeof szType mul ecx add eax,offset szType .else invoke wsprintf,addr @szResName,\ addr szLevel1byID,eax lea eax,@szResName .endif .endif invoke wsprintf,addr @szBuffer,addr szLevel1,eax ;******************************************************************** ; 第二层:资源ID(或名称) ;******************************************************************** .elseif _dwLevel == 2 mov edx,[esi].Name1 .if edx & 80000000h ;******************************************************************** ; 资源以字符串方式命名 ;******************************************************************** and edx,7fffffffh add edx,_lpRes movzx ecx,word ptr [edx] add edx,2 invoke WideCharToMultiByte,CP_ACP,\ WC_COMPOSITECHECK,edx,ecx,\ addr @szResName,sizeof @szResName,\ NULL,NULL invoke wsprintf,addr @szBuffer,\ addr szLevel2byName,addr @szResName .else ;******************************************************************** ; 资源以 ID 命名 ;******************************************************************** invoke wsprintf,addr @szBuffer,\ addr szLevel2byID,edx .endif .else .break .endif invoke _AppendInfo,addr @szBuffer invoke _ProcessRes,_lpFile,_lpRes,ebx,@dwNextLevel ;******************************************************************** ; 不是资源目录则显示资源详细信息(在第3层时的情况) ;******************************************************************** .else add ebx,_lpRes mov ecx,[esi].Name1 ;代码页 assume ebx:ptr IMAGE_RESOURCE_DATA_ENTRY mov eax,[ebx].OffsetToData invoke _RVAToOffset,_lpFile,eax invoke wsprintf,addr @szBuffer,addr szResData,\ eax,ecx,[ebx].Size1 invoke _AppendInfo,addr @szBuffer .endif add esi,sizeof IMAGE_RESOURCE_DIRECTORY_ENTRY pop ecx dec ecx .endw ;******************************************************************** _Ret: assume esi:nothing assume ebx:nothing popad ret _ProcessRes endp ;#################################################################### _ProcessPeFile proc _lpFile,_lpPeHead,_dwSize local @szBuffer[1024]:byte,@szSectionName[16]:byte pushad mov esi,_lpPeHead assume esi:ptr IMAGE_NT_HEADERS ;******************************************************************** ; 检测是否存在资源 ;******************************************************************** mov eax,[esi].OptionalHeader.DataDirectory[8*2].VirtualAddress .if ! eax invoke MessageBox,hWinMain,addr szErrNoRes,NULL,MB_OK jmp _Ret .endif push eax invoke _RVAToOffset,_lpFile,eax add eax,_lpFile mov esi,eax pop eax invoke _GetRVASection,_lpFile,eax invoke wsprintf,addr @szBuffer,addr szMsg,addr szFileName,eax invoke SetWindowText,hWinEdit,addr @szBuffer invoke _ProcessRes,_lpFile,esi,esi,1 ;******************************************************************** _Ret: assume esi:nothing popad ret _ProcessPeFile endp ;####################################################################
在本书的前面章节中有好几个例子都遇到了树型结构的处理问题,比如第10章的全盘搜索程序例子和内存映射文件中的例子,在那两个例子中都使用了递归调用的方法,本节的例子将同样使用递归的方法来处理资源目录树。
在_ProcessPeFile子程序中,程序首先从数据目录的第2项得到资源数据块的入口地址,并用它来调用_ProcessRes子程序,这个子程序将递归调用自己来处理所有资源目录树上的节点。
第17章 PE文件
版权所有 © 云南伯恩科技 证书:粤ICP备09170368号