📄 loader.c
字号:
DWORD dwTrust;
// for files in ROM -- fully trusted unless specified otherwise in the flag
// NOTE: we perform the test before testing pOEMLoadInit/pOEMLoadModule so
// OEM can have a close system with trusted model without implementing
// pOEMLoadInit/pOEMLoadModule. However, if an OEM has RAM filesys, he
// must implement the functions or files in RAM will be fully trusted.
if (FA_PREFIXUP & oeptr->filetype) {
DWORD dwAttrib = (FA_DIRECTROM & oeptr->filetype)? oeptr->tocptr->dwFileAttributes : oeptr->dwExtRomAttrib;
if (!ChkDebug (oeptr)) {
return (DWORD)NTE_BAD_SIGNATURE;
}
if (dwAttrib & MODULE_ATTR_NOT_TRUSTED) {
if (OEM_CERTIFY_FALSE == CertVerify (INVALID_HANDLE_VALUE, &hTok, lpszName, bAllKMode)) {
return (DWORD)NTE_BAD_SIGNATURE;
}
*pbTrustLevel = (BYTE) OEM_CERTIFY_RUN;
}
} else if (pTOC->ulKernelFlags & KFLAG_TRUSTROMONLY) {
*pbTrustLevel = KERN_TRUST_RUN;
} else {
dwTrust = CertVerify (oeptr->hf, &hTok, lpszName, bAllKMode);
if (OEM_CERTIFY_FALSE == dwTrust) {
return (DWORD)NTE_BAD_SIGNATURE;
}
*pbTrustLevel = (BYTE) dwTrust;
// using lagecy OAL trust model?
if (pOEMLoadModule && pOEMLoadInit && (OEM_CERTIFY_TRUST == dwTrust)) {
#define VBSIZE 1024
BYTE Buf[VBSIZE];
int iTrust;
DWORD len, pos, size, bytesread;
if (!pOEMLoadInit(lpszName)) {
return (DWORD)NTE_BAD_SIGNATURE;
}
len = SetFilePointer(oeptr->hf,0,0,2);
for (pos = 0; pos < len; pos += size) {
size = ((len - pos) > VBSIZE ? VBSIZE : (len - pos));
if (!ReadFileWithSeek(oeptr->hf,Buf,size,&bytesread,0,pos,0) || (bytesread != size)) {
return (DWORD)NTE_BAD_SIGNATURE;
}
if (!pOEMLoadModule(Buf,size)) {
return (DWORD)NTE_BAD_SIGNATURE;
}
}
if (!(iTrust = pOEMLoadModule(0,0))) {
return (DWORD)NTE_BAD_SIGNATURE;
}
if (iTrust != OEM_CERTIFY_TRUST) {
*pbTrustLevel = KERN_TRUST_RUN;
}
}
}
if (hTok && phTok) {
*phTok = hTok;
}
return 0;
}
//------------------------------------------------------------------------------
// change DllLoadBase (can only be called from filesys
//------------------------------------------------------------------------------
BOOL SetROMDllBase (DWORD cbSize, PROMINFO pInfo)
{
LPVOID pSlot0Base = NULL;
BOOL fRet = FALSE;
if (!pInfo) {
DEBUGMSG (1, (L"SetROMDllBase: Failed! (NULL ROMINFO)\r\n"));
return FALSE;
}
DEBUGCHK (cbSize == (sizeof(ROMINFO) + pInfo->nROMs * sizeof (LARGE_INTEGER)));
// grab loader CS
EnterCriticalSection (&LLcs);
// check parameters
if ((pCurProc->procnum != 1) // only filesys can make this call
|| g_pROMInfo // ROMInfo already set
|| (ROMDllLoadBase != (DWORD) DllLoadBase) // any non-ROM dll has been loaded
|| (pInfo->nROMs < 1) // at least one ROM
|| (cbSize > HEAP_SIZE1) // too many ROMs
) {
DEBUGMSG (1, (L"SetROMDllBase faild, (slot0 = %8.8lx, slot1 = %8.8lx, Cnt = %d, cbSize = %d)\r\n",
pInfo->dwSlot_0_DllBase, pInfo->dwSlot_1_DllBase, pInfo->nROMs, cbSize));
// allocate memory for ROMINFO
} else if (!(g_pROMInfo = (PROMINFO) AllocMem (HEAP_ROMINFO))) {
DEBUGMSG (1, (L"SetROMDllBase: AllocMem failed!\r\n"));
// reserve memory in the secure section
} else if ((pInfo->dwSlot_0_DllBase < ROMDllLoadBase)
&& !(pSlot0Base = VirtualAlloc ((LPVOID)(ProcArray[0].dwVMBase+pInfo->dwSlot_0_DllBase), ROMDllLoadBase - pInfo->dwSlot_0_DllBase,
MEM_RESERVE|MEM_IMAGE, PAGE_NOACCESS))) {
DEBUGMSG (1, (L"SetROMDllBase: VirtualAlloc Failed (%8.8lx -> %8.8lx)\r\n", pInfo->dwSlot_0_DllBase, ROMDllLoadBase));
// reserve memory in slot 1
} else if ((pInfo->dwSlot_1_DllBase < SharedDllBase)
&& !VirtualAlloc ((LPVOID)pInfo->dwSlot_1_DllBase, SharedDllBase - pInfo->dwSlot_1_DllBase,
MEM_RESERVE|MEM_IMAGE, PAGE_NOACCESS)) {
DEBUGMSG (1, (L"SetROMDllBase: VirtualAlloc Failed (%8.8lx -> %8.8lx)\r\n", pInfo->dwSlot_1_DllBase, SharedDllBase));
// succeed, save ROMINFO
} else {
int i, j;
// reserve the R/W section for all existing processes
for (i = 0; i < MAX_PROCESSES; i ++) {
if (ProcArray[i].dwVMBase) {
LARGE_INTEGER *pLimits = (LARGE_INTEGER *) (pInfo + 1);
for (j = 0; j < pInfo->nROMs; j ++, pLimits ++) {
VirtualAlloc((LPVOID)(pLimits->LowPart + ProcArray[i].dwVMBase), pLimits->HighPart - pLimits->LowPart, MEM_RESERVE|MEM_IMAGE, PAGE_NOACCESS);
}
}
}
memcpy (g_pROMInfo, pInfo, cbSize);
if (pInfo->dwSlot_0_DllBase < ROMDllLoadBase)
ROMDllLoadBase = DllLoadBase = pInfo->dwSlot_0_DllBase;
if (pInfo->dwSlot_1_DllBase < SharedDllBase)
SharedDllBase = pInfo->dwSlot_1_DllBase;
fRet = TRUE;
DEBUGMSG (1, (L"SetROMDllBase: Change DllLoadBase to %8.8lx, %8.8lx\r\n",
ROMDllLoadBase, SharedDllBase));
}
// free memory on error
if (!fRet) {
if (g_pROMInfo) {
FreeMem (g_pROMInfo, HEAP_ROMINFO);
g_pROMInfo = NULL;
}
if (pSlot0Base) {
VirtualFree (pSlot0Base, 0, MEM_RELEASE);
}
}
// release Loader CS
LeaveCriticalSection (&LLcs);
return fRet;
}
//------------------------------------------------------------------------------
// OpenFileFromFilesys: call into filesys to open a file
//
// return: 0 -- success
// ERROR_FILE_NOT_FOUND -- file doesn't exist
// ERROR_FILE_CORRUPT -- file is corrupted
//------------------------------------------------------------------------------
DWORD OpenFileFromFilesys (
LPWSTR lpszName,
openexe_t *oeptr,
BOOL fDbg
)
{
DWORD bytesread;
BY_HANDLE_FILE_INFORMATION bhfi;
// try open the file
if ((oeptr->hf = CreateFileW (lpszName,
GENERIC_READ,
FILE_SHARE_READ,
0,
OPEN_EXISTING,
fDbg? FILE_ATTRIBUTE_ROMMODULE : 0,
0)) == INVALID_HANDLE_VALUE)
return ERROR_FILE_NOT_FOUND;
// default to object store
oeptr->filetype = FT_OBJSTORE;
oeptr->bIsOID = (GetFileInformationByHandle (oeptr->hf, &bhfi)
&& ((ULONG)INVALID_HANDLE_VALUE != bhfi.dwOID));
if (oeptr->bIsOID) {
// is this an extern ROM MODULE?
if (bhfi.dwFileAttributes & FILE_ATTRIBUTE_ROMMODULE) {
oeptr->filetype = FT_EXTIMAGE;
oeptr->dwExtRomAttrib = bhfi.dwFileAttributes;
oeptr->bIsOID = 0;
} else {
oeptr->ceOid = bhfi.dwOID;
}
}
if (!oeptr->bIsOID) {
if (oeptr->lpName = AllocName ((strlenW (lpszName)+1)*2)) {
kstrcpyW (oeptr->lpName->name, lpszName);
} else {
CloseExe(oeptr);
oeptr->hf = INVALID_HANDLE_VALUE;
return ERROR_OUTOFMEMORY;
}
}
if (!(bhfi.dwFileAttributes & FILE_ATTRIBUTE_ROMMODULE)) {
// can't page from media that doesn't support pagingeven if paging is allowed
if (!ReadFileWithSeek(oeptr->hf,0,0,0,0,0,0)) {
oeptr->pagemode = PM_CANNOT_PAGE;
}
// read the offset information from PE header
if ((SetFilePointer(oeptr->hf,0x3c,0,FILE_BEGIN) != 0x3c) ||
!ReadFile(oeptr->hf,(LPBYTE)&oeptr->offset,4,&bytesread,0) || (bytesread != 4)) {
CloseExe(oeptr);
oeptr->hf = INVALID_HANDLE_VALUE;
return ERROR_FILE_CORRUPT;
}
}
DEBUGMSG(ZONE_OPENEXE,(TEXT("OpenExe %s: OSTORE: %8.8lx\r\n"),lpszName,oeptr->hf));
return 0; // succeeded
}
#define WINDOWS_DIR_OID 1
static BOOL IsInWinDir (LPCWSTR lpszName, DWORD nLen)
{
// Is the file in the Windows directory?
WIN32_FIND_DATA wfd;
HANDLE hFind;
// keep prefast happy, we never call this function with nLen >= MAX_PATH
if (MAX_PATH <= nLen) {
return FALSE;
}
wfd.dwOID = 0;
// we'll use wfd.cFileName as the tmp buffer to create path here.
memcpy(wfd.cFileName, lpszName, nLen*sizeof(WCHAR));
wfd.cFileName[nLen] = 0;
hFind = FindFirstFile (wfd.cFileName, &wfd);
if (INVALID_HANDLE_VALUE != hFind) {
CloseHandle (hFind);
}
return (WINDOWS_DIR_OID == wfd.dwOID);
}
static DWORD OpenFileFromROM (LPCWSTR pPlainName, openexe_t *oeptr)
{
ROMChain_t *pROM;
o32_rom *o32rp;
TOCentry *tocptr;
int loop;
for (pROM = ROMChain; pROM; pROM = pROM->pNext) {
// check ROM for any copy
tocptr = (TOCentry *)(pROM->pTOC+1); // toc entries follow the header
for (loop = 0; loop < (int)pROM->pTOC->nummods; loop++) {
if (!strcmpiAandW(tocptr->lpszFileName, pPlainName)) {
DEBUGMSG(ZONE_OPENEXE,(TEXT("OpenExe %s: ROM: %8.8lx\r\n"),pPlainName,tocptr));
o32rp = (o32_rom *)(tocptr->ulO32Offset);
DEBUGMSG(ZONE_LOADER1,(TEXT("(10) o32rp->o32_realaddr = %8.8lx\r\n"), o32rp->o32_realaddr));
oeptr->tocptr = tocptr;
oeptr->filetype = FT_ROMIMAGE;
return 0;
}
tocptr++;
}
}
return ERROR_FILE_NOT_FOUND;
}
#pragma prefast(disable: 412, "the length is checked before memset (prefast false positive)")
static DWORD TryDir (openexe_t *oeptr, LPCWSTR pDirName, int nDirLen, LPCWSTR pFileName, int nFileLen, BOOL fDbg)
{
WCHAR tmpname[MAX_PATH];
if (nDirLen + nFileLen >= MAX_PATH) {
// fail if path too long
return ERROR_FILE_NOT_FOUND;
}
// construct the path
memcpy (tmpname, pDirName, nDirLen * sizeof(WCHAR));
memcpy (&tmpname[nDirLen], pFileName, nFileLen * sizeof(WCHAR));
tmpname [nDirLen + nFileLen] = 0;
return OpenFileFromFilesys (tmpname, oeptr, fDbg);
}
#pragma prefast(pop)
static LPCWSTR GetPlainName (LPCWSTR pFullPath)
{
LPCWSTR pPlainName = pFullPath + strlenW (pFullPath);
while ((pPlainName != pFullPath) && (*(pPlainName-1) != (WCHAR)'\\') && (*(pPlainName-1) != (WCHAR)'/')) {
pPlainName --;
}
return pPlainName;
}
static DWORD TrySameDir (openexe_t *oeptr, LPCWSTR lpszFileName, PPROCESS pProc)
{
LPCWSTR pProcPath;
CEGUID sysguid;
CEOIDINFOEX ceoi;
if (pProc->oe.bIsOID) {
CREATE_SYSTEMGUID(&sysguid);
ceoi.wVersion = CEOIDINFOEX_VERSION;
if (!(CeOidGetInfoEx2 (&sysguid, pProc->oe.ceOid, &ceoi)))
return ERROR_FILE_NOT_FOUND;
pProcPath = ceoi.infFile.szFileName;
} else {
pProcPath = pProc->oe.lpName->name;
}
return TryDir (oeptr, pProcPath, GetPlainName (pProcPath) - pProcPath, lpszFileName, strlenW (lpszFileName), FALSE);
}
BOOL OpenExecutable (LPCWSTR lpszName, openexe_t *oeptr, BOOL bIsDll, BOOL bAllowPaging)
{
BOOL bIsAbs = ((*lpszName == '\\') || (*lpszName == '/'));
DWORD dwErr = ERROR_FILE_NOT_FOUND;
DWORD dwLastErr = KGetLastError (pCurThread);
int nTotalLen = strlenW (lpszName);
LPCWSTR pPlainName;
BOOL bIsInWindDir = FALSE;
DEBUGMSG (ZONE_OPENEXE,(TEXT("OpenExecutable: %s\r\n"),lpszName));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -