PE
资源结构及读取
作者:
Sunline lisunlin0@yahoo.com.cn 2007
年
7
月
源代码下载 :http://download.csdn.net/source/359338 其中的 Source 文件夹中 .
下面的一些函数是我在学习 PE 结构时参考 Matt Pietrek 的《 A Tour of the Win32 Portable Executable File Format 》和 Microsoft 的《 Visual Studio, Microsoft Portable Executable and Common Object File Format Specification 》以及部分网上的代码所写成的,是研究如何直接读取 PE 资源的一手资料 ( 比如其中的 LoadString LoadAccelerators LoadMenu LoadIcon 函数,没有其它任何可用的参考资料 , 用 VC 调试时跟踪到相应的函数内部,通过汇编代码和自己丰富的想象力才搞清楚的。 ) ,希望可以给研究 PE 格式的朋友一些帮助。其中大部分是自己 Debug 得出的,可能有不妥的地方,敬请斧正。
源代码下载 :http://download.csdn.net/source/359338 其中的 Source 文件夹中 .
下面的一些函数是我在学习 PE 结构时参考 Matt Pietrek 的《 A Tour of the Win32 Portable Executable File Format 》和 Microsoft 的《 Visual Studio, Microsoft Portable Executable and Common Object File Format Specification 》以及部分网上的代码所写成的,是研究如何直接读取 PE 资源的一手资料 ( 比如其中的 LoadString LoadAccelerators LoadMenu LoadIcon 函数,没有其它任何可用的参考资料 , 用 VC 调试时跟踪到相应的函数内部,通过汇编代码和自己丰富的想象力才搞清楚的。 ) ,希望可以给研究 PE 格式的朋友一些帮助。其中大部分是自己 Debug 得出的,可能有不妥的地方,敬请斧正。
// ResFunc.cpp
// 描述:
// 从PE文件中取得资源
// 作者:
// SunLine 2007年07月
// Description:
// get resources from a pe module
// Authority:
// Write by Sunline July, 2007
// All rights reserved.
#include <windows.h>
#include "ResFunc.h"
#include "libc.h"
extern "C"
{
DWORD __stdcall _SizeofResource(HMODULE hModule, HRSRC hResInfo)
{
DWORD dwRet;
if(hResInfo)
dwRet = PIMAGE_RESOURCE_DATA_ENTRY(hResInfo)->Size;
else
dwRet = 0;
return dwRet;
}
HGLOBAL __stdcall _LoadResource( HMODULE hModule, HRSRC hResInfo)
{
HGLOBAL hRet;
if(hResInfo)
hRet = HGLOBAL((LPBYTE)hModule + PIMAGE_RESOURCE_DATA_ENTRY(hResInfo)->OffsetToData);
else
hRet = NULL;
return hRet;
}
LPVOID __stdcall _LockResource(HGLOBAL hResData)
{
return (LPVOID)hResData;
}
HRSRC __stdcall _FindResourceA( HMODULE hModule, LPCSTR lpName, LPCSTR lpType)
{
return _FindResourceExA(hModule, lpType, lpName, 0);
}
HRSRC __stdcall _FindResourceW( HMODULE hModule, LPCWSTR lpName, LPCWSTR lpType)
{
return _FindResourceExW(hModule, lpType, lpName, 0);
}
HRSRC __stdcall _FindResourceExA(HMODULE hModule, LPCSTR lpType, LPCSTR lpName, WORD wLanguage)
{
HRSRC hRsrc = NULL;
WCHAR wTypeName[MAX_PATH];
WCHAR wResName[MAX_PATH];
LPWSTR pwTypeName;
LPWSTR pwResName;
if(MAKEINTRESOURCEA(lpType) == lpType)
{
pwTypeName = (LPWSTR)lpType;
}
else
{
int nTypeLen = lstrlenA(lpType) + 1;
int nUnicodeStrLen = nTypeLen * sizeof(WCHAR);
pwTypeName = (LPWSTR)_malloc(nUnicodeStrLen);
nUnicodeStrLen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, /
lpType, nTypeLen, wTypeName, nUnicodeStrLen);
pwTypeName = wTypeName;
}
if(MAKEINTRESOURCEA(lpName) == lpName)
{
pwResName = (LPWSTR)lpName;
}
else
{
int nNameLen = lstrlenA(lpName) + 1;
int nUnicodeStrLen = nNameLen * sizeof(WCHAR);
nUnicodeStrLen = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, /
lpType, nNameLen, wResName, nUnicodeStrLen);
pwResName = wResName;
}
if(pwTypeName && pwResName)
{
hRsrc = _FindResourceExW(hModule, pwTypeName, pwResName, wLanguage);
}
else
hRsrc = NULL;
return hRsrc;
}
HRSRC __stdcall _FindResourceExW(HMODULE hModule, LPCWSTR lpType, LPCWSTR lpName, WORD wLanguage)
{
PIMAGE_RESOURCE_DATA_ENTRY res = NULL;
if(hModule == NULL)
hModule = GetModuleHandleW(NULL);
if((lpName != 0) && (lpType != 0))
{
if(!hModule)
hModule = GetModuleHandleA(NULL);
PIMAGE_RESOURCE_DIRECTORY pResDir = PIMAGE_RESOURCE_DIRECTORY( /
LPBYTE(hModule) + PIMAGE_NT_HEADERS((LPBYTE)hModule + /
PIMAGE_DOS_HEADER(hModule)->e_lfanew)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress/
);
ProcRes(res, hModule, LPBYTE(pResDir), pResDir, LEVELE_RESDIR, lpName, lpType, wLanguage);
}
return (HRSRC)res;
}
// Accelerators function
HACCEL __stdcall _LoadAcceleratorsA( HINSTANCE hInst, LPCSTR lpTableName)
{
int nAccItem = 0;
PACCTABENTRY pAccTabEntry = (PACCTABENTRY)_GetResDataA(hInst, lpTableName, (LPCSTR)RT_ACCELERATOR);
for(nAccItem = 0; TRUE; nAccItem++)
{
WORD wFlags = pAccTabEntry[nAccItem].fFlags;
if(wFlags & 0x80) // The entry is last in an accelerator table.
{
if(wFlags & 0x60) // 0x60 is binary 01100000, the low 5 bits is legal;
nAccItem = 0;
else