PE文件资源解析(八)字符串资源的解析

字符串资源,在这里指的是资源类型为RT_STRING的资源信息。通过ResHacker看到的效果图如下:

字符串资源存储编码格式是UNICODE,解析代码如下: 

HRSRC hResrc = ::FindResourceEx((HMODULE)hModule, lpType, lpName, wLanguage);
DWORD dwSize = ::SizeofResource((HMODULE)hModule, hResrc);
HGLOBAL hGlobal = ::LoadResource((HMODULE)hModule, hResrc);
if (hGlobal == NULL)
	return;

BYTE* lpResrc = (BYTE*)LockResource(hGlobal);
if (lpResrc == NULL)
	return;

HGLOBAL hAllocMem = GlobalAlloc(GMEM_FIXED, dwSize);
char* pMem = (char*)GlobalLock(hAllocMem);
memcpy(pMem, lpResrc, dwSize);
// 每16个字符串为一个串组,字符串的排序以字符串的资源ID号为依据,
// 0 - 15为第一串组,16 - 31位第二串组,32 - 47位第三串组,...。
// 串组ID号从1开始,字符串ID号从0开始。由此可以得到如下公式:
// 串组ID = (取整)(字符串ID / 16) + 1
// 串组ID = pParam->dwResID
CStringW swStringTable = L"STRINGTABLE\r\n";
if (wLanguage == 2052)
	swStringTable.Append(L"LANGUAGE LANG_CHINESE,\r\n");
else if (wLanguage == 1033)
	swStringTable.Append(L"LANGUAGE LANG_ENGLISH,\r\n");
swStringTable.Append(L"{");
int offset = 0;
for (int i = 1; i <= 16; i++)
{
	// 计算字符串长度
	short length = *(short*)(&pMem[offset]);
	// 判断字符串长度
	if (length > 0)
	{
		swStringTable.AppendFormat(L"\r\n  %d,\t\"", ((DWORD)lpName) * 16 + i - 1);
		// 字符编码是UNICODE
		wchar_t* pResult = new wchar_t[length + 1];
		memset(pResult, 0, sizeof(wchar_t) * (length + 1));
		memcpy((wchar_t*)pResult, (wchar_t*)(&pMem[offset + 2]), length * sizeof(wchar_t));
		swStringTable.Append(pResult);
		delete[] pResult;
		swStringTable.AppendFormat(L"\"");
	}
	offset += 2 + length * sizeof(wchar_t);
}
swStringTable.Append(L"\r\n}");
GlobalUnlock(hAllocMem);
GlobalFree(hAllocMem);
//swStringTable就是解析出来的结果

猜你喜欢

转载自blog.csdn.net/u012156872/article/details/105677287