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

📄 loader.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
//------------------------------------------------------------------------------
//
//      NK Kernel loader code
//
//
// Module Name:
//
//      loader.c
//
// Abstract:
//
//      This file implements the NK kernel loader for EXE/DLL
//
//
//------------------------------------------------------------------------------
//
// The loader is derived from the Win32 executable file format spec.  The only
// interesting thing is how we load a process.  When we load a process, we
// simply schedule a thread in a new process context.  That thread (in coredll)
// knows how to read in an executable, and does so.  Then it traps into the kernel
// and starts running in the new process.  Most of the code below is simply a direct
// implimentation of the executable file format specification
//
//------------------------------------------------------------------------------

#include "kernel.h"
#include "altimports.h"
#include "bldver.h"
#ifndef _PREFAST_
#pragma warning(disable: 4068) // Disable pragma warnings
#endif

#define SYSTEMDIR L"\\Windows\\"
#define SYSTEMDIRLEN 9

#define DBGDIR    L"\\Release\\"
#define DBGDIRLEN    9

#define LOAD_LIBRARY_IN_KERNEL  0x8000

struct KDataStruct *PtrKData;

fslog_t *LogPtr;
BOOL fForceCleanBoot;
BOOL fNoDebugger;
BOOL fDebuggerLoaded;

FREEINFO FreeInfo[MAX_MEMORY_SECTIONS];
MEMORYINFO MemoryInfo;


ROMChain_t FirstROM;
ROMChain_t *ROMChain, *OEMRomChain;

PROMINFO g_pROMInfo;

extern CRITICAL_SECTION VAcs, DbgApiCS, LLcs, ModListcs, PagerCS;
extern BOOL IsCommittedSecureSlot (DWORD addr);
extern PMODULE LoadMUI (HANDLE hModule, LPBYTE BasePtr, e32_lite* eptr);

DWORD   ROMDllLoadBase;     // this is the low water mark for DLL loaded into per-process's slot
DWORD   SharedDllBase;      // base of dlls loaded in slot 1

extern PFN_SHIMINITMODULE g_pfnShimInitModule;
extern PFN_SHIMWHICHMOD g_pfnShimWhichMod;
extern PFN_SHIMUNDODEPENDS g_pfnShimUndoDepends;
extern PFN_SHIMIOCONTROL g_pfnShimIoControl;
extern PFN_SHIMGETPROCMODLIST g_pfnShimGetProcModList;
extern PFN_SHIMCLOSEMODULE g_pfnShimCloseModule;
extern PFN_SHIMCLOSEPROCESS g_pfnShimCloseProcess;

DWORD MainMemoryEndAddress, PagedInCount;
DWORD (*pNKEnumExtensionDRAM)(PMEMORY_SECTION pMemSections, DWORD cMemSections);
DWORD (*pOEMCalcFSPages)(DWORD dwMemPages, DWORD dwDefaultFSPages);
DWORD dwOEMCleanPages;

void DbgrNotifyDllLoad (PTHREAD pth, PPROCESS pproc, BOOL fWait, PMODULE pMod);
void DbgrNotifyDllUnload (PTHREAD pth, PPROCESS pproc, BOOL fWait, PMODULE pMod);

typedef void (* NFC_t)(DWORD, DWORD, DWORD, DWORD);
NFC_t pNotifyForceCleanboot;
extern Name *pPath;
extern Name *pInjectDLLs;
extern LPDWORD pIsExiting;

LPName pDbgList;

BOOL IsPreloadedDlls (PMODULE pMod)
{
    if (((HANDLE) pMod == hCoreDll) || !strcmpW (L"mscoree.dll", pMod->lpszModName))
        return TRUE;
    if (pInjectDLLs) {
        LPTSTR p = (LPTSTR)(pInjectDLLs->name);
        while(*p) {
            if (!strcmpW (pMod->lpszModName, p))
                return TRUE;
            p += (strlenW(p)+1);
        }
    }
    return FALSE;
}

void FreeProcModList ()
{
    PMODULELIST pML;
    DEBUGCHK (LLcs.OwnerThread == hCurThread);
    for (pML = pCurProc->pLastModList; pML; pML = pCurProc->pLastModList) {
        pCurProc->pLastModList = pML->pNext;
        FreeMem (pML, HEAP_MODLIST);
    }
    pCurProc->wModCount = 0;
}


#ifdef SH3
extern unsigned int SH3DSP;
#endif

ROMHDR *const volatile pTOC = (ROMHDR *)-1;     // Gets replaced by RomLoader with real address

// ROM Header extension.  The ROM loader (RomImage) will set the pExtensions field of the table
// of contents to point to this structure.  This structure contains the PID and a extra field to point
// to further extensions.
const ROMPID RomExt = {
    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
    NULL
};

DWORD DecompressROM(LPBYTE BufIn, DWORD InSize, LPBYTE BufOut, DWORD OutSize, DWORD skip);
void GoToUserTime(void);
void GoToKernTime(void);

WCHAR lowerW(WCHAR ch) {
    return ((ch >= 'A') && (ch <= 'Z')) ? (ch - 'A' + 'a') : ch;
}

#pragma prefast(disable: 394, "Kernel local string functions, no buffer overrun risk")

int strcmponeiW(const wchar_t *pwc1, const wchar_t *pwc2) {
    while (*pwc1 && (lowerW(*pwc1) == *pwc2)) {
        pwc1++;
        pwc2++;
    }
    return (*pwc1 ? 1 : 0);
}

int strcmpdllnameW(LPCWSTR src, LPCWSTR tgt) {
    while (*src && (*src == lowerW(*tgt))) {
        src++;
        tgt++;
    }
    return ((*tgt && strcmponeiW(tgt,L".dll") && strcmponeiW(tgt,L".cpl")) || (*src && memcmp(src,L".dll",10) && memcmp(src,L".cpl",10))) ? 1 : 0;
}

int strcmpiAandW(LPCHAR lpa, LPCWSTR lpu) {
    while (*lpa && (lowerW((WCHAR)*lpa) == lowerW(*lpu))) {
        lpa++;
        lpu++;
    }
    return ((*lpa || *lpu) ? 1 : 0);
}

int kstrncmpi(LPCWSTR str1, LPCWSTR str2, int count) {
    wchar_t f,l;
    if (!count)
        return 0;
    do {
        f = lowerW(*str1++);
        l = lowerW(*str2++);
    } while (--count && f && (f == l));
    return (int)(f - l);
}

int kstrcmpi(LPCWSTR str1, LPCWSTR str2) {
    wchar_t f,l;
    do  {
        f = lowerW(*str1++);
        l = lowerW(*str2++);
    } while (f && (f == l));
    return (int)(f - l);
}

void kstrcpyW(LPWSTR p1, LPCWSTR p2) {
    while (*p2)
        *p1++ = *p2++;
    *p1 = 0;
}

#pragma prefast(pop)

o32_lite *FindOptr (o32_lite *optr, int nCnt, DWORD dwAddr)
{
    for (dwAddr = ZeroPtr (dwAddr) ; nCnt; nCnt --, optr ++) {
        if ((DWORD) (dwAddr - ZeroPtr(optr->o32_realaddr)) < optr->o32_vsize) {
            return optr;
        }
    }

    return NULL;
}

typedef BOOL (* OEMLoadInit_t)(LPWSTR lpszName);
typedef BOOL (* OEMLoadModule_t)(LPBYTE lpData, DWORD cbData);

OEMLoadInit_t pOEMLoadInit;
OEMLoadModule_t pOEMLoadModule;

ERRFALSE(!OEM_CERTIFY_FALSE);

ULONG FakeHDException (PEXCEPTION_RECORD ExceptionRecord, CONTEXT *ContextRecord, BOOLEAN SecondChance);

//------------------------------------------------------------------------------
// check if a particular module can be debugged
//------------------------------------------------------------------------------
BOOL ChkDebug (openexe_t *oeptr)
{
    BOOL fRet = TRUE, dwAttrib;

    DEBUGCHK (FA_PREFIXUP & oeptr->filetype);

    dwAttrib = (FA_DIRECTROM & oeptr->filetype)? oeptr->tocptr->dwFileAttributes : oeptr->dwExtRomAttrib;

    if (dwAttrib & MODULE_ATTR_NODEBUG) {
        if (pCurProc->hDbgrThrd || pCurProc->DbgActive || fDebuggerLoaded) {
            fRet = FALSE;
        } else {
            // set both the process flag and the global flag to prevent loading KD
            // or attaching debugger to this process
            pCurProc->fNoDebug = fNoDebugger = TRUE;
        }
    }
    DEBUGMSG(ZONE_LOADER1,(TEXT("ChkDebug returns %d\r\n"), fRet));

    return fRet;
}

//------------------------------------------------------------------------------
// check if we should load a module from debug directory
//------------------------------------------------------------------------------
BOOL IsInDbgList (LPCWSTR pszName)
{
    if (pDbgList) {
        LPCWSTR pTrav = pDbgList->name;
        do {
            if (!kstrcmpi (pszName, pTrav)) {
                return TRUE;
            }
            pTrav += strlenW (pTrav) + 1;
        } while (*pTrav);
    }
    return FALSE;
}


//------------------------------------------------------------------------------
// update the list for modules to be loaded from debug directory
// Note: nLen is the total length, including double 0 at the end
//------------------------------------------------------------------------------
BOOL SetDbgList (LPCWSTR pList, int nTotalLen)
{
    
    LPName  pNewList = NULL;
    
    if (pList) {
        int     idx = 0;

        // validate the list
        if (nTotalLen < 3) {    // at least 2 zeros + a charactor
            return FALSE;
        }

        // make sure it's in multi-sz format
        do {
            idx += strlenW (pList + idx) + 1;
        } while ((idx < nTotalLen) && pList[idx]);

        if ((idx > nTotalLen) || pList[idx]) {
            return FALSE;
        }

        // allocate memory
        if (!(pNewList = AllocName (nTotalLen * sizeof (WCHAR)))) {
            // out of memory or list too big
            return FALSE;
        }

        // copy the list
        memcpy (pNewList->name, pList, nTotalLen * sizeof(WCHAR));
    }

    // update the list
    EnterCriticalSection (&LLcs);

    if (pDbgList) {
        FreeName (pDbgList);
    }
    pDbgList = pNewList;
    
    LeaveCriticalSection (&LLcs);

    return TRUE;
}

//------------------------------------------------------------------------------
// read O32/E32 from filesys for FT_EXTIMAGE/FT_EXTXIP
//------------------------------------------------------------------------------
BOOL ReadExtImageInfo (HANDLE hf, DWORD dwCode, DWORD cbSize, LPVOID pBuf)
{
    DWORD cbRead;
    return SC_DeviceIoControl (hf, dwCode, NULL, 0, pBuf, cbSize, &cbRead, NULL)
        && (cbSize == cbRead);
}

DWORD CertVerify (HANDLE hFile, HANDLE *phTok, LPCWSTR pszName, DWORD dwFlags);


//------------------------------------------------------------------------------
// returns getlasterror code, or 0 for success
//------------------------------------------------------------------------------
DWORD
VerifyBinary(
    openexe_t *oeptr,
    LPWSTR lpszName,
    LPBYTE pbTrustLevel,
    HANDLE *phTok
    )
{
    HANDLE hTok = NULL;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -