⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 loader.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
    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 + -