📄 resource.c
字号:
for (loop = 0; loop < e32l.e32_objcnt; loop++, optr ++) {
if (optr->o32_rva == e32l.e32_unit[RES].rva) {
if (!(lpres = (LPBYTE)LocalAlloc(LMEM_FIXED, optr->o32_vsize))) {
return NULL;
}
cbRead = optr->o32_vsize;
if (!(optr->o32_flags & IMAGE_SCN_COMPRESSED) && (cbRead > optr->o32_psize))
cbRead = optr->o32_psize;
// Read the section, always use vsize
if (ReadFileWithSeek (oeptr->hf, lpres, cbRead, &cbRead, 0, optr->o32_dataptr, 0)) {
// memset the rest of the section to 0 if read less than vsize
if (cbRead < optr->o32_vsize)
memset (lpres+cbRead, 0, optr->o32_vsize-cbRead);
*o32rva = optr->o32_rva;
return lpres;
}
break; // loop
}
}
} else {
// OBJECT store
o32_obj o32;
for (loop = 0; loop < e32l.e32_objcnt; loop++) {
SetFilePointer (oeptr->hf, oeptr->offset+sizeof(e32_exe)+loop*sizeof(o32_obj), 0, FILE_BEGIN);
if (ReadFile (oeptr->hf, (LPBYTE)&o32, sizeof(o32_obj), &cbRead, 0)
&& (o32.o32_rva == e32l.e32_unit[RES].rva)) {
if (!(lpres = (LPBYTE)LocalAlloc(LMEM_FIXED, o32.o32_vsize))) {
return NULL;
}
SetFilePointer (oeptr->hf, o32.o32_dataptr, 0, FILE_BEGIN);
if (ReadFile (oeptr->hf, lpres, min(o32.o32_psize,o32.o32_vsize), &cbRead, 0)) {
*o32rva = o32.o32_rva;
return lpres;
}
break; // loop
}
}
}
// error case if reach here
if (lpres)
LocalFree (lpres);
return NULL;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#pragma prefast(disable: 322, "return value already set when except")
LPBYTE
OpenResourceFile(
LPCWSTR lpszFile,
BOOL *pInRom,
DWORD *o32rva
)
{
openexe_t oe;
LPBYTE lpres = NULL;
BOOL fResult = FALSE;
__try {
CALLBACKINFO cbi;
cbi.hProc = ProcArray[0].hProc;
cbi.pfn = (FARPROC) OpenExecutable;
cbi.pvArg0 = MapPtr(lpszFile);
if (fResult = PerformCallBack(&cbi, MapPtr(&oe), 0, 0)) {
lpres = FindResourceSection (&oe, o32rva);
}
} __except(EXCEPTION_EXECUTE_HANDLER) {
}
if (fResult)
CloseExe (&oe);
if (!lpres)
KSetLastError (pCurThread, ERROR_RESOURCE_NAME_NOT_FOUND);
else
*pInRom = IsKernelVa (lpres);
DEBUGMSG(ZONE_ENTRY,(L"SC_ExtractResource exit: lpres = %8.8lx\r\n", lpres));
return lpres;
}
#pragma prefast(pop)
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
LPVOID
ExtractOneResource(
LPBYTE lpres,
LPCWSTR lpszName,
LPCWSTR lpszType,
DWORD o32rva,
LPDWORD pdwSize
)
{
LPBYTE lpres2;
DWORD trva;
if (!(trva = FindType(lpres, lpres, (LPWSTR)lpszType)) ||
!(trva = FindType(lpres, lpres+(trva&0x7fffffff),(LPWSTR)lpszName)) ||
!(trva = FindFirst(lpres+(trva&0x7fffffff))) ||
(trva & 0x80000000)) {
KSetLastError(pCurThread,ERROR_RESOURCE_NAME_NOT_FOUND);
return 0;
}
trva = (ULONG)(lpres + trva);
if (!(lpres2 = (LPBYTE)LocalAlloc(LMEM_FIXED,((resdata_t *)trva)->size))) {
KSetLastError(pCurThread,ERROR_RESOURCE_NAME_NOT_FOUND);
return 0;
}
if (pdwSize)
*pdwSize = ((resdata_t *)trva)->size;
DEBUGMSG (ZONE_LOADER2, (L"ExtractOneResource: memcpy (%8.8lx, %8.8lx, %8.8lx)\n",
lpres2,lpres+((resdata_t *)trva)->rva-o32rva,((resdata_t *)trva)->size));
memcpy(lpres2,lpres+((resdata_t *)trva)->rva-o32rva,((resdata_t *)trva)->size);
return lpres2;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
LPVOID
SC_ExtractResource(
LPCWSTR lpszFile,
LPCWSTR lpszName,
LPCWSTR lpszType
)
{
LPBYTE lpres, lpres2;
BOOL inRom;
DWORD o32rva;
DEBUGMSG(ZONE_ENTRY,(L"SC_ExtractResource entry: %8.8lx %8.8lx %8.8lx\r\n",lpszFile,lpszName,lpszType));
if (!(lpres = OpenResourceFile(lpszFile, &inRom, &o32rva))) {
DEBUGMSG(ZONE_ENTRY,(L"SC_ExtractResource exit: %8.8lx\r\n",0));
return 0;
}
lpres2 = ExtractOneResource(lpres,lpszName,lpszType,o32rva,0);
if (!inRom)
LocalFree(lpres);
DEBUGMSG(ZONE_ENTRY,(L"SC_ExtractResource exit: %8.8lx\r\n",lpres2));
return lpres2;
}
typedef void (* KEICB_t)(LPVOID, PHEADER_AND_DIR,PWORD);
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
UINT
SC_KernExtractIcons(
LPCWSTR lpszFile,
int nIconIndex,
LPBYTE *pIconLarge,
LPBYTE *pIconSmall,
CALLBACKINFO *pcbi
)
{
LPBYTE lpres;
BOOL inRom;
UINT nRet = 0;
PHEADER_AND_DIR phd;
DWORD o32rva;
WORD index[2];
TRUSTED_API (L"SC_KernExtractIcons", 0);
if (!(lpres = OpenResourceFile(lpszFile, &inRom, &o32rva)))
return 0;
if (phd = (PHEADER_AND_DIR)ExtractOneResource(lpres, MAKEINTRESOURCE(nIconIndex), RT_GROUP_ICON, o32rva,0)) {
if (phd->ih.idCount) {
((KEICB_t)pcbi->pfn)(pcbi->pvArg0,phd,index);
if (pIconLarge && (*pIconLarge = ExtractOneResource(lpres, MAKEINTRESOURCE(phd->rgdir[index[0]].wOrdinal), RT_ICON, o32rva,0)))
nRet++;
if (pIconSmall && (*pIconSmall = ExtractOneResource(lpres, MAKEINTRESOURCE(phd->rgdir[index[1]].wOrdinal), RT_ICON, o32rva,0)))
nRet++;
}
LocalFree(phd);
}
if (!inRom)
LocalFree(lpres);
return nRet;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL
SC_VerQueryValueW(
VERBLOCK *pBlock,
LPWSTR lpSubBlock,
LPVOID *lplpBuffer,
PUINT puLen
)
{
LPWSTR lpSubBlockOrg, lpEndBlock, lpEndSubBlock, lpStart;
WCHAR cEndBlock, cTemp;
BOOL bString;
DWORD dwTotBlockLen, dwHeadLen;
int nCmp;
// validate parameters
if ((KERN_TRUST_FULL != pCurProc->bTrustLevel)
&& (!SC_MapPtrWithSize (pBlock, sizeof (VERBLOCK), hCurProc)
|| !SC_MapPtrWithSize (puLen, sizeof (UINT), hCurProc)
|| !SC_MapPtrWithSize (lplpBuffer, sizeof (LPVOID), hCurProc))) {
KSetLastError(pCurThread,ERROR_INVALID_DATA);
return FALSE;
}
*puLen = 0;
if ((int)pBlock->wTotLen < sizeof(VERBLOCK)) {
KSetLastError(pCurThread,ERROR_INVALID_DATA);
return FALSE;
}
if (!(lpSubBlockOrg = (LPWSTR)LocalAlloc(LPTR,(strlenW(lpSubBlock)+1)*sizeof(WCHAR)))) {
KSetLastError(pCurThread,ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
kstrcpyW(lpSubBlockOrg,lpSubBlock);
lpSubBlock = lpSubBlockOrg;
lpEndBlock = (LPWSTR)((LPBYTE)pBlock + pBlock->wTotLen - sizeof(WCHAR));
cEndBlock = *lpEndBlock;
*lpEndBlock = 0;
bString = FALSE;
while (*lpSubBlock) {
while (*lpSubBlock == L'\\')
++lpSubBlock;
if (*lpSubBlock) {
dwTotBlockLen = (DWORD)((LPSTR)lpEndBlock - (LPSTR)pBlock + sizeof(WCHAR));
if (((int)dwTotBlockLen < sizeof(VERBLOCK)) || (pBlock->wTotLen > (WORD)dwTotBlockLen))
goto NotFound;
dwHeadLen = DWORDUP(sizeof(VERBLOCK) - sizeof(WCHAR) + (strlenW(pBlock->szKey) + 1) * sizeof(WCHAR)) + DWORDUP(pBlock->wValLen);
if (dwHeadLen > pBlock->wTotLen)
goto NotFound;
lpEndSubBlock = (LPWSTR)((LPBYTE)pBlock + pBlock->wTotLen);
pBlock = (VERBLOCK*)((LPBYTE)pBlock+dwHeadLen);
for (lpStart=lpSubBlock; *lpSubBlock && (*lpSubBlock!=L'\\'); lpSubBlock++)
;
cTemp = *lpSubBlock;
*lpSubBlock = 0;
nCmp = 1;
while (((int)pBlock->wTotLen > sizeof(VERBLOCK)) && ((int)pBlock->wTotLen <= (LPBYTE)lpEndSubBlock-(LPBYTE)pBlock)) {
if (!(nCmp=kstrcmpi(lpStart, pBlock->szKey)))
break;
pBlock=(VERBLOCK*)((LPBYTE)pBlock+DWORDUP(pBlock->wTotLen));
}
*lpSubBlock = cTemp;
if (nCmp)
goto NotFound;
}
}
*puLen = pBlock->wValLen;
lpStart = (LPWSTR)((LPBYTE)pBlock+DWORDUP((sizeof(VERBLOCK)-sizeof(WCHAR))+(strlenW(pBlock->szKey)+1)*sizeof(WCHAR)));
*lplpBuffer = lpStart < (LPWSTR)((LPBYTE)pBlock+pBlock->wTotLen) ? lpStart : (LPWSTR)(pBlock->szKey+strlenW(pBlock->szKey));
bString = pBlock->wType;
*lpEndBlock = cEndBlock;
LocalFree(lpSubBlockOrg);
return (TRUE);
NotFound:
KSetLastError(pCurThread,ERROR_RESOURCE_NAME_NOT_FOUND);
*lpEndBlock = cEndBlock;
LocalFree(lpSubBlockOrg);
return (FALSE);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
DWORD
SC_GetFileVersionInfoSizeW(
LPWSTR lpFilename,
LPDWORD lpdwHandle
)
{
LPBYTE lpres;
BOOL inRom;
DWORD o32rva, dwRet = 0;
VERHEAD *pVerHead;
if (lpdwHandle) {
// validate parameters
if ((KERN_TRUST_FULL != pCurProc->bTrustLevel) && !SC_MapPtrWithSize (lpdwHandle, sizeof (DWORD), hCurProc)) {
KSetLastError(pCurThread,ERROR_INVALID_DATA);
return FALSE;
}
*lpdwHandle = 0;
}
DEBUGMSG(ZONE_ENTRY,(L"SC_GetFileVersionInfoSizeW entry: %8.8lx %8.8lx\r\n",lpFilename, lpdwHandle));
if (lpres = OpenResourceFile(lpFilename, &inRom, &o32rva)) {
if (pVerHead = (VERHEAD *)ExtractOneResource(lpres, MAKEINTRESOURCE(VS_VERSION_INFO), VS_FILE_INFO, o32rva, &dwRet)) {
if (((DWORD)pVerHead->wTotLen > dwRet) || (pVerHead->vsf.dwSignature != VS_FFI_SIGNATURE))
KSetLastError(pCurThread,ERROR_INVALID_DATA);
else
dwRet = pVerHead->wTotLen;
LocalFree(pVerHead);
}
if (!inRom)
LocalFree(lpres);
}
DEBUGMSG(ZONE_ENTRY,(L"SC_GetFileVersionInfoSizeW exit: %8.8lx\r\n",dwRet));
return dwRet;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL
SC_GetFileVersionInfoW(
LPWSTR lpFilename,
DWORD dwHandle,
DWORD dwLen,
LPVOID lpData
)
{
LPBYTE lpres;
BOOL inRom, bRet = FALSE;
DWORD o32rva, dwTemp;
VERHEAD *pVerHead;
if ((KERN_TRUST_FULL != pCurProc->bTrustLevel) && !SC_MapPtrWithSize (lpData, dwLen, hCurProc)) {
KSetLastError(pCurThread,ERROR_INVALID_DATA);
return FALSE;
}
DEBUGMSG(ZONE_ENTRY,(L"SC_GetFileVersionInfoW entry: %8.8lx %8.8lx %8.8lx %8.8lx\r\n",lpFilename, dwHandle, dwLen, lpData));
if (dwLen < sizeof(((VERHEAD*)lpData)->wTotLen))
KSetLastError(pCurThread,ERROR_INSUFFICIENT_BUFFER);
else if (lpres = OpenResourceFile(lpFilename, &inRom, &o32rva)) {
if (pVerHead = (VERHEAD *)ExtractOneResource(lpres, MAKEINTRESOURCE(VS_VERSION_INFO), VS_FILE_INFO, o32rva, &dwTemp)) {
if (((DWORD)pVerHead->wTotLen > dwTemp) || (pVerHead->vsf.dwSignature != VS_FFI_SIGNATURE))
KSetLastError(pCurThread,ERROR_INVALID_DATA);
else {
dwTemp = (DWORD)pVerHead->wTotLen;
if (dwTemp > dwLen)
dwTemp = dwLen;
memcpy(lpData,pVerHead,dwTemp);
((VERHEAD*)lpData)->wTotLen = (WORD)dwTemp;
bRet = TRUE;
}
LocalFree(pVerHead);
}
if (!inRom)
LocalFree(lpres);
}
DEBUGMSG(ZONE_ENTRY,(L"SC_GetFileVersionInfoSizeW exit: %d\r\n",bRet));
return bRet;;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
AToUCopy(
WCHAR *wptr,
LPBYTE aptr,
int maxlen
)
{
int len;
for (len = 1; (len<maxlen) && *aptr; len++)
*wptr++ = (WCHAR)*aptr++;
*wptr = 0;
}
#define COMP_BLOCK_SIZE PAGE_SIZE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -