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文件 · 17.4 资源(2) 下页:第17章 PE文件 · 17.4 资源(4)

第17章 PE文件

版权所有 © 云南伯恩科技 证书:粤ICP备09170368号