PE
资源结构及读取
作者:
Sunline lisunlin0@yahoo.com.cn 2007
年
7
月
源代码下载 :http://download.youkuaiyun.com/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.youkuaiyun.com/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
nAccItem++;
break;
}
}
LPACCEL lpAcc = (LPACCEL)_malloc(nAccItem * sizeof(ACCEL));
for(int i = 0; i < nAccItem; i++)
{
//lpAcc[i].fVirt = pAccTabEntry[i].fFlags;
//lpAcc[i].key = pAccTabEntry[i].wAnsi;
//lpAcc[i].cmd = pAccTabEntry[i].wId;
lpAcc[i] = (ACCEL&)(pAccTabEntry[i]);
}
HACCEL hRet = CreateAcceleratorTableW(lpAcc, nAccItem);
return hRet;
}
HACCEL __stdcall _LoadAcceleratorsW( HINSTANCE hInst, LPCWSTR lpTableName)
{
int nAccItem = 0;
PACCTABENTRY pAccTabEntry = (PACCTABENTRY)_LoadResource((HMODULE)hInst,
_FindResourceW(hInst, (LPCWSTR)lpTableName, (LPCWSTR)RT_ACCELERATOR));
int i;
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
nAccItem++;
break;
}
};
LPACCEL lpAcc = (LPACCEL)_malloc(nAccItem * sizeof(ACCEL));
for(i = 0; i < nAccItem; i++)
{
//lpAcc[i].fVirt = pAccTabEntry[i].fFlags;
//lpAcc[i].key = pAccTabEntry[i].wAnsi;
//lpAcc[i].cmd = pAccTabEntry[i].wId;
lpAcc[i] = (ACCEL&)(pAccTabEntry[i]);
}
return CreateAcceleratorTableW(lpAcc, nAccItem);
}
BOOL __stdcall _DestroyAcceleratorTable(HACCEL hAccel)
{
if(hAccel)
{
_free(hAccel);
return TRUE;
}
else
return FALSE;
}
// String functions
int __stdcall _LoadStringA(LPVOID hInst, UINT uID, LPSTR lpBuffer, int nBufMax)
{
int nLen = 0;
LPCWSTR lpwStr = 0;
int nItem = (uID & 0xF);
PIMAGE_RESOURCE_DATA_ENTRY res = NULL;
ULONG_PTR uName = (LOWORD(uID)>>4) + 1;
if((uID != 0) && (lpBuffer != 0) && (nBufMax != 0))
{
PIMAGE_RESOURCE_DIRECTORY pResDir = PIMAGE_RESOURCE_DIRECTORY( /
LPBYTE(hInst) + PIMAGE_NT_HEADERS((LPBYTE)hInst + PIMAGE_DOS_HEADER(hInst)->e_lfanew)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress/
);
if(0 == ProcRes(res, hInst, LPBYTE(pResDir), pResDir, LEVELE_RESDIR, (LPCWSTR)uName, (LPCWSTR)RT_STRING, 0))
{
PWCHAR lpVoid = PWCHAR((LPBYTE)hInst + res->OffsetToData);
while(nItem != 0)
{
nItem--;
lpVoid += *(PWORD)lpVoid;
lpVoid++;
}
// nLen = *PWORD( lpVoid - sizeof(WORD));
PUSTR pStr = (PUSTR)lpVoid;
if(pStr->wLen <= nBufMax)
{
nLen = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, pStr->pBuffer, pStr->wLen, lpBuffer, nBufMax, 0, 0);
*((PCHAR)lpBuffer + nLen) = 0;
}
else
nLen = 0;
}
}
return nLen;
}
int __stdcall _LoadStringW(LPVOID hInst, UINT uID, LPWSTR lpBuffer, int nBufMax)
{
int nLen = 0;
LPCWSTR lpwStr = 0;
int nItem = (uID & 0xF);
PIMAGE_RESOURCE_DATA_ENTRY res = NULL;
ULONG_PTR uName = (LOWORD(uID)>>4) + 1; // 字符串是以字符串的ID号的16的模来分组的,即GroupId = uID / 16, String order in group = uID % 16
if((uID != 0) && (lpBuffer != 0) && (nBufMax != 0))
{
PIMAGE_RESOURCE_DIRECTORY pResDir = PIMAGE_RESOURCE_DIRECTORY( /
LPBYTE(hInst) + PIMAGE_NT_HEADERS((LPBYTE)hInst + PIMAGE_DOS_HEADER(hInst)->e_lfanew)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress/
);
if(0 == ProcRes(res, hInst, LPBYTE(pResDir), pResDir, LEVELE_RESDIR, (LPCWSTR)uName, (LPCWSTR)RT_STRING, 0))
{
PWCHAR lpVoid = PWCHAR((LPBYTE)hInst + res->OffsetToData);
while(nItem != 0)
{
nItem--;
lpVoid += *(PWORD)lpVoid;
lpVoid++;
}
//nLen = *PWORD( lpVoid - sizeof(WORD));
PUSTR pStr = (PUSTR)lpVoid;
if(pStr->wLen <= nBufMax)
{
nLen = pStr->wLen;
lstrcpyW((LPWSTR)lpBuffer, pStr->pBuffer);
*((PWCHAR)lpBuffer + nLen) = 0; // Write 0 to the trail
}
else
nLen = 0;
}
}
return nLen;
}
// ICON, Cursor and other image functions
// 使用ResourceHack.exe查看生成的ICON组,可以发现ICON是首先按 颜色升序,然后按 图标大小 降序来排列的
//
int __stdcall _LookupIconIdFromDirectory( PBYTE presbits, BOOL fIcon)
{
if(!presbits)
return 0;
int nRet = 0;
int cx_icon = GetSystemMetrics(SM_CXICON);
int cy_icon = GetSystemMetrics(SM_CYICON);
unsigned int dmBitsPerPel;
DEVMODE dvm;
BOOL bRet = EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&dvm);
dmBitsPerPel = dvm.dmBitsPerPel;
PRESICONCURSORHEADER pIconCursorHeader = (PRESICONCURSORHEADER)presbits;
int nItemCount = pIconCursorHeader->wItemCount;
PRESDIR pResDir = 0;
PRESDIR pRetResDir = 0;
pResDir = pRetResDir = (PRESDIR)(presbits + sizeof(RESICONCURSORHEADER));
if(fIcon) // lookup for icon
{
for( ; nItemCount > 0; nItemCount--)
{
unsigned int n;
n = dmBitsPerPel - pResDir->ResInfo.Icon.ColorCount;
if((n > 0) && ((pResDir->ResInfo.Icon.ColorCount - pRetResDir->ResInfo.Icon.ColorCount) > 0))
{
n = cx_icon - pResDir->ResInfo.Icon.Width;
if((n >= 0) && ((pResDir->ResInfo.Icon.Width - pRetResDir->ResInfo.Icon.Width) >= 0))
{
n = cy_icon - pResDir->ResInfo.Icon.Height;
if(n >= 0)
{
pRetResDir = pResDir;
}
}
}
else if(n == 0)
{
n = cx_icon - pResDir->ResInfo.Icon.Width;
if((n >= 0) && ((pResDir->ResInfo.Icon.Width - pRetResDir->ResInfo.Icon.Width) >= 0))
{
n = cy_icon - pResDir->ResInfo.Icon.Height;
if(n >= 0)
{
pRetResDir = pResDir;
}
}
}
pResDir++;
}
}
else // lookup for cursor
{
for( ; nItemCount > 0; nItemCount--)
{
unsigned int n;
n = cx_icon - pResDir->ResInfo.Cursor.Width;
if((n > 0) && ((pResDir->ResInfo.Cursor.Width - pRetResDir->ResInfo.Cursor.Width) > 0))
{
n = cy_icon - pResDir->ResInfo.Cursor.Height;
if(n >= 0)
{
pRetResDir = pResDir;
}
}
else if(n == 0)
{
n = cy_icon - pResDir->ResInfo.Cursor.Height;
if(n >= 0)
{
pRetResDir = pResDir;
}
}
pResDir++;
}
}
nRet = pRetResDir->IconCursorId;
return nRet;
}
HICON __stdcall _LoadIconA( HINSTANCE hInst, LPCSTR lpIconName)
{
HICON hIcon;
HRSRC hRsrc = NULL;
HGLOBAL hGlobal = NULL;
LPVOID lpRes = NULL;
int nID;
if(lpIconName > (LPCSTR)0x8000)
hIcon = LoadIconA(hInst, lpIconName);
else
{
if( (lpRes = _GetResDataA(hInst, lpIconName, (LPCSTR)RT_GROUP_ICON)) == NULL)
return NULL;
nID = _LookupIconIdFromDirectory( (PBYTE)lpRes, TRUE );
if( (hRsrc = _FindResourceA( hInst, MAKEINTRESOURCEA(nID), (LPCSTR)RT_ICON )) == NULL )
return NULL;
if( (hGlobal = _LoadResource( hInst, hRsrc )) == NULL )
return NULL;
if( (lpRes = _LockResource(hGlobal)) == NULL )
return NULL;
hIcon = CreateIconFromResource( (PBYTE)lpRes, _SizeofResource(hInst, hRsrc), TRUE, 0x00030000 );
}
return hIcon;
}
HICON __stdcall _LoadIconW( HINSTANCE hInst, LPCWSTR lpIconName)
{
HICON hIcon;
HRSRC hRsrc = NULL;
HGLOBAL hGlobal = NULL;
LPVOID lpRes = NULL;
int nID;
if(lpIconName > (LPCWSTR)0x8000)
hIcon = LoadIconW(hInst, lpIconName);
else
{
if( (lpRes = _GetResDataW(hInst, lpIconName, RT_GROUP_ICON)) == NULL)
return NULL;
nID = _LookupIconIdFromDirectory( (PBYTE)lpRes, TRUE );
if( (hRsrc = _FindResourceW( hInst, MAKEINTRESOURCEW(nID), (LPCWSTR)RT_ICON )) == NULL )
return NULL;
if( (hGlobal = _LoadResource( hInst, hRsrc )) == NULL )
return NULL;
if( (lpRes = _LockResource(hGlobal)) == NULL )
return NULL;
hIcon = CreateIconFromResource( (PBYTE)lpRes, _SizeofResource(hInst, hRsrc), TRUE, 0x00030000 );
}
return hIcon;
}
BOOL __stdcall _DestroyIcon(HICON hIcon)
{
return DestroyIcon(hIcon);
}
HCURSOR __stdcall _LoadCursorA(HINSTANCE hInst, LPCSTR lpCursorName)
{
HCURSOR hCursor;
HRSRC hRsrc = NULL;
HGLOBAL hGlobal = NULL;
LPVOID lpRes = NULL;
int nID;
if(lpCursorName > (LPCSTR)0x1000)
hCursor = LoadCursorA(hInst, lpCursorName);
else
{
if( (lpRes = _GetResDataA(hInst, lpCursorName, (LPCSTR)RT_GROUP_CURSOR)) == NULL )
return NULL;
nID = _LookupIconIdFromDirectory( (PBYTE)lpRes, FALSE );
if( (hRsrc = _FindResourceA( hInst, MAKEINTRESOURCEA(nID), (LPCSTR)RT_CURSOR)) == NULL )
return NULL;
if( (hGlobal = _LoadResource( hInst, hRsrc )) == NULL )
return NULL;
if( (lpRes = _LockResource(hGlobal)) == NULL )
return NULL;
hCursor = CreateIconFromResource( (PBYTE)lpRes, _SizeofResource(hInst,hRsrc), FALSE, 0x00030000 );
}
return hCursor;
}
HCURSOR __stdcall _LoadCursorW(HINSTANCE hInst, LPCWSTR lpCursorName)
{
HCURSOR hCursor;
HRSRC hRsrc = NULL;
HGLOBAL hGlobal = NULL;
LPVOID lpRes = NULL;
int nID;
if(lpCursorName > (LPCWSTR)0x1000)
hCursor = LoadCursorW(hInst, lpCursorName);
else
{
if( (lpRes = _GetResDataW(hInst, lpCursorName, RT_GROUP_CURSOR)) == NULL )
return NULL;
nID = _LookupIconIdFromDirectory( (PBYTE)lpRes, FALSE );
if( (hRsrc = _FindResourceW( hInst, MAKEINTRESOURCEW(nID), (LPCWSTR)RT_CURSOR)) == NULL )
return NULL;
if( (hGlobal = _LoadResource( hInst, hRsrc )) == NULL )
return NULL;
if( (lpRes = _LockResource(hGlobal)) == NULL )
return NULL;
hCursor = CreateIconFromResource( (PBYTE)lpRes, _SizeofResource(hInst,hRsrc), FALSE, 0x00030000 );
}
return hCursor;
}
BOOL __stdcall _DestroyCursor(HCURSOR hCursor)
{
return DestroyCursor(hCursor);
}
HBITMAP __stdcall _LoadBitmapA( HINSTANCE hInst, LPCSTR lpBitmapName)
{
HBITMAP hRet = NULL;
BITMAP *pBitMap;
HGLOBAL hResData = _GetResDataA(hInst, lpBitmapName, (LPCSTR)RT_BITMAP);
if(hResData)
{
pBitMap = (BITMAP *)_LockResource(hResData);
hRet = CreateBitmapIndirect(pBitMap);
}
return hRet;
}
HBITMAP __stdcall _LoadBitmapW( HINSTANCE hInst, LPCWSTR lpBitmapName)
{
HBITMAP hRet;
BITMAP *pBitMap = (BITMAP *)_GetResDataW(hInst, lpBitmapName, RT_BITMAP);
if(pBitMap)
hRet = CreateBitmapIndirect(pBitMap);
else
hRet = NULL;
return hRet;
}
BOOL __stdcall _DeleteObject(HGDIOBJ hObject)
{
return DeleteObject(hObject);
}
// Memu functions
HMENU __stdcall _LoadMenuA( HINSTANCE hInst, LPCSTR lpMenuName)
{
HMENU hMenu = NULL;
MENUTEMPLATEW *pMemnuTemplate = (MENUTEMPLATEW *)_GetResDataA(hInst, lpMenuName, (LPCSTR)RT_MENU);
if(pMemnuTemplate)
hMenu = LoadMenuIndirectA(pMemnuTemplate);
return hMenu;
}
HMENU __stdcall _LoadMenuW( HINSTANCE hInst, LPCWSTR lpMenuName)
{
HMENU hMenu = NULL;
MENUTEMPLATEW *pMemnuTemplate = (MENUTEMPLATEW *)_GetResDataW(hInst, lpMenuName, RT_MENU);
if(pMemnuTemplate)
hMenu = LoadMenuIndirectW(pMemnuTemplate);
return hMenu;
}
BOOL __stdcall _DestroyMenu(HMENU hMenu)
{
return DestroyMenu(hMenu);
}
// Dialog functions
HWND WINAPI _CreateDialogParamA( HINSTANCE hInst, LPCSTR lpTemplateName, HWND hWndParent,
DLGPROC lpDialogFunc, LPARAM dwInitParam)
{
HWND hWnd = 0;
LPCDLGTEMPLATEA pDlgTemplate = (LPCDLGTEMPLATEA)_GetResDataA(hInst, lpTemplateName, (LPCSTR)RT_DIALOG);
if(pDlgTemplate)
hWnd = CreateDialogIndirectParamA(hInst, pDlgTemplate, hWndParent, lpDialogFunc, dwInitParam);
return hWnd;
}
HWND WINAPI _CreateDialogParamW( HINSTANCE hInst, LPCWSTR lpTemplateName, HWND hWndParent,
DLGPROC lpDialogFunc, LPARAM dwInitParam)
{
HWND hWnd = 0;
LPCDLGTEMPLATEW pDlgTemplate = (LPCDLGTEMPLATEW)_GetResDataW(hInst, lpTemplateName, (LPCWSTR)RT_DIALOG);
if(pDlgTemplate)
hWnd = CreateDialogIndirectParamW(hInst, pDlgTemplate, hWndParent, lpDialogFunc, dwInitParam);
return hWnd;
}
INT_PTR __stdcall _DialogBoxParamA( HINSTANCE hInst, LPCSTR lpTemplateName, /
HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam)
{
INT_PTR hWnd = 0;
LPCDLGTEMPLATEA pDlgTemplate = (LPCDLGTEMPLATEA)_GetResDataA(hInst, lpTemplateName, (LPCSTR)RT_DIALOG);
if(pDlgTemplate)
hWnd = DialogBoxIndirectParamA(hInst, pDlgTemplate, hWndParent, lpDialogFunc, dwInitParam);
return hWnd;
}
INT_PTR __stdcall _DialogBoxParamW( HINSTANCE hInst, LPCWSTR lpTemplateName, /
HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam)
{
INT_PTR hWnd = 0;
LPCDLGTEMPLATEW pDlgTemplate = (LPCDLGTEMPLATEW)_GetResDataW(hInst, lpTemplateName, (LPCWSTR)RT_DIALOG);
if(pDlgTemplate)
hWnd = DialogBoxIndirectParamW(hInst, pDlgTemplate, hWndParent, lpDialogFunc, dwInitParam);
return hWnd;
}
// some assist functions
int __stdcall ProcRes(PIMAGE_RESOURCE_DATA_ENTRY &lpSResource,LPVOID lpFile, LPVOID lpResBase, /
PIMAGE_RESOURCE_DIRECTORY lpResDir, int dwLevel, LPCWSTR lpResName, LPCWSTR lpResType, WORD wLanguage)
{
int nRet = ERROR_UNKNOW;
__try
{
PIMAGE_RESOURCE_DIRECTORY pResDir = lpResDir;
WORD nResCount = pResDir->NumberOfIdEntries + pResDir->NumberOfNamedEntries;
PIMAGE_RESOURCE_DIRECTORY_ENTRY pResDirEntry = PIMAGE_RESOURCE_DIRECTORY_ENTRY((LPBYTE)pResDir + sizeof(IMAGE_RESOURCE_DIRECTORY));
nRet = ERROR_NORES;
while(nResCount != 0)
{
if(pResDirEntry->DataIsDirectory)
{
PIMAGE_RESOURCE_DIRECTORY lpSubResDir = PIMAGE_RESOURCE_DIRECTORY((LPBYTE)lpResBase + pResDirEntry->OffsetToDirectory);
if(dwLevel == LEVELE_RESDIR)
{
if(pResDirEntry->NameIsString)
{
PIMAGE_RESOURCE_DIR_STRING_U lpName = PIMAGE_RESOURCE_DIR_STRING_U((LPBYTE)lpResBase + pResDirEntry->NameOffset);
WORD nLen = lpName->Length;
PWCHAR pwStr = lpName->NameString;
if((_CmpNameW((LPCWSTR)lpResType, pwStr) == 0))
nRet = ProcRes(lpSResource,lpFile, lpResBase, lpSubResDir, LEVELE_RESITEM, lpResName, lpResType, wLanguage);
}
else
{
if( 0 == ((LPBYTE)lpResType - pResDirEntry->Name))
nRet = ProcRes(lpSResource,lpFile, lpResBase, lpSubResDir, LEVELE_RESITEM, lpResName, lpResType, wLanguage);
}
}
else if(dwLevel == LEVELE_RESITEM)
{
if(pResDirEntry->NameIsString) // 以字符串方式命名
{
PIMAGE_RESOURCE_DIR_STRING_U lpName = PIMAGE_RESOURCE_DIR_STRING_U((LPBYTE)lpResBase + pResDirEntry->NameOffset);
WORD nLen = lpName->Length;
PWCHAR pwStr = lpName->NameString;
if( 0 == _CmpNameW((LPCWSTR)lpName, pwStr))
nRet = ProcRes(lpSResource,lpFile, lpResBase, lpSubResDir, LEVELE_RES, lpResName, lpResType, wLanguage);
}
else // 以ID方式命名
{
if( 0 == ((LPBYTE)lpResName - pResDirEntry->Name))
nRet = ProcRes(lpSResource,lpFile, lpResBase, lpSubResDir, LEVELE_RES, lpResName, lpResType, wLanguage);
}
}
else
{
nRet = ERROR_UNKNOW;
break; // error
}
}
else // dwLevel == LEVELE_RES
{
lpSResource = PIMAGE_RESOURCE_DATA_ENTRY((LPBYTE)lpResBase + pResDirEntry->OffsetToData);
if(wLanguage != 0)
{
if(lpSResource->CodePage == (UINT)wLanguage)
{
nRet = ERROR_SUCCESS;
}
else
nRet = ERROR_LANGUAGE;
}
else // wLanguage == 0 , ignore the langue type
{
nRet = ERROR_SUCCESS;
}
}
if(nRet == ERROR_SUCCESS)
break;
pResDirEntry++;
nResCount--;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
nRet = ERROR_UNKNOW;
}
return nRet;
}
//LPVOID __stdcall GetResW(LPVOID hInst, LPCWSTR lpName, LPCWSTR lpType)
//{
// //RESOURCE res = {0, 0};
// PIMAGE_RESOURCE_DATA_ENTRY res;
// if((lpName != 0) && (lpType != 0))
// {
// PIMAGE_RESOURCE_DIRECTORY pResDir = PIMAGE_RESOURCE_DIRECTORY( /
// LPBYTE(hInst) + PIMAGE_NT_HEADERS((LPBYTE)hInst + PIMAGE_DOS_HEADER(hInst)->e_lfanew)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress/
// );
// ProcRes(res, hInst, LPBYTE(pResDir), pResDir, LEVELE_RESDIR, lpName, lpType, 0);
// }
// return (LPBYTE)hInst + res->OffsetToData;
//}
// common resource functions
// Accelerators function
// ICON, Cursor and other image functions
BOOL __stdcall IsStringA(LPCSTR lpcStr)
{
BOOL fRet;
/* version 1 */
//SYSTEM_INFO SystemInfo;
//GetSystemInfo(&SystemInfo);
//if((lpString > SystemInfo.lpMinimumApplicationAddress) && (lpString < SystemInfo.lpMaximumApplicationAddress))
//{
// fRet = TRUE;
//}
//else
// fRet = FALSE;
/* version 2 */
//if( ((LOWORD)lpcStr != 0) && ((ULONG_PTR)lpcStr >> (8*sizeof(WORD)) )
// fRet = TRUE;
//else
// fRet = FALSE;
/* version 3 */
__try
{
while(*lpcStr);
fRet = TRUE;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
fRet = FALSE;
}
return fRet;
}
BOOL __stdcall IsStringW(LPCWSTR lpcwStr)
{
BOOL fRet;
/* version 1 */
//SYSTEM_INFO SystemInfo;
//GetSystemInfo(&SystemInfo);
//if((lpString > SystemInfo.lpMinimumApplicationAddress) && (lpString < SystemInfo.lpMaximumApplicationAddress))
//{
// fRet = TRUE;
//}
//else
// fRet = FALSE;
/* version 2 */
//if( ((LOWORD)lpcStr != 0) && ((ULONG_PTR)lpcStr >> (8*sizeof(WORD)) )
// fRet = TRUE;
//else
// fRet = FALSE;
/* version 3 */
__try
{
while(*lpcwStr);
fRet = TRUE;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
fRet = FALSE;
}
return fRet;
}
int __stdcall _CmpNameW(LPCWSTR lpName1, LPCWSTR lpName2)
{
int nRet = 1;
__try
{
while( *lpName1 & *lpName2)
{
nRet = *lpName1 - *lpName2;
lpName1++;
lpName2++;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
nRet = 1;
}
return nRet;
}
}
本文深入探讨了Windows可执行文件(PE)的资源结构,包括对话框、字符串、图像等,并详细阐述了如何从PE文件中提取和读取这些资源。通过实例解析,了解微软的资源管理机制,有助于提升对Windows程序逆向分析和二进制修改的理解。
2263

被折叠的 条评论
为什么被折叠?



