hdstub.c

来自「WinCE5.0部分核心源码」· C语言 代码 · 共 711 行 · 第 1/2 页

C
711
字号
            break;
    }
Done:
    DEBUGGERMSG (HDZONE_CLIENT, (L"--HdstubRegisterClient: %d\r\n", fResult));
    return fResult;
}


//
// Trap functions for hdstub.  These functions are called by kernel
// to notify of a specific event.
//
BOOL HdstubTrapException(PEXCEPTION_RECORD pex, CONTEXT *pContext,
        BOOLEAN b2ndChance)
{
    BOOL fHandled = FALSE;
    HDSTUB_CLIENT* pClientCur;
    
    DEBUGGERMSG(HDZONE_ENTRY, 
        (TEXT("++HdstubTrapException: pex = 0x%.8x, pContext = 0x%.8x, b2ndChance = %d, ExcAddr=0x%08X\r\n"),
        pex, pContext, b2ndChance, pex ? pex->ExceptionAddress : NULL));
   
    pClientCur = pClientListHead;
    while (pClientCur && !fHandled)
    {
        if ((pClientCur->dwFilter & HDSTUB_FILTER_EXCEPTION) && pClientCur->pfnException)
        {
            fHandled = pClientCur->pfnException(pex, pContext, b2ndChance);
        }
        pClientCur = pClientCur->pCliNext;
    }

    // Notify hardware support
    if (!fHandled && (*s_pulHDEventFilter & HDSTUB_FILTER_EXCEPTION))
    {
        fHandled = HwExceptionHandler (pex, pContext, b2ndChance);
        DEBUGGERMSG (HDZONE_HW, (L"  HdstubTrapException: hardware fHandled=%d\r\n", fHandled));
    }

    DEBUGGERMSG (HDZONE_ENTRY, (TEXT ("--HdstubTrapException: pex = 0x%.8x, fHandled = %d\r\n"), pex, fHandled));
    return fHandled;
}


static void HdstubTrapVmPageInRange (DWORD dwPageAddr, DWORD dwNumPages, BOOL bWriteable)
{
    BOOL fHandled = FALSE;
    HDSTUB_CLIENT *pClientCur;
    
    DEBUGGERMSG(HDZONE_ENTRY, (TEXT ("++HdstubTrapVmPageInRange: dwPageAddr=0x%.8x, dwNumPages=%d bWriteable=%d\r\n"),
        dwPageAddr, dwNumPages, bWriteable));

    pClientCur = pClientListHead;
    while (pClientCur && !fHandled)
    {
        if ((pClientCur->dwFilter & HDSTUB_FILTER_VMPAGEIN) && pClientCur->pfnVmPageIn)
            fHandled = pClientCur->pfnVmPageIn (dwPageAddr, dwNumPages, bWriteable);
        pClientCur = pClientCur->pCliNext;        
    }

    if (!fHandled && (*s_pulHDEventFilter & HDSTUB_FILTER_VMPAGEIN))
        HwPageInHandler (dwPageAddr, dwNumPages, bWriteable);

    DEBUGGERMSG(HDZONE_ENTRY, (TEXT ("--HdstubTrapVmPageInRange\r\n")));
}


void HdstubTrapVmPageIn (DWORD dwPageAddr, BOOL bWriteable)
{
    HdstubTrapVmPageInRange (dwPageAddr, 1, bWriteable);
}

void HdstubTrapModuleLoad(DWORD dwStructAddr)
{
    BOOL fHandled = FALSE;
    HDSTUB_CLIENT *pClientCur;
    
    DEBUGGERMSG(HDZONE_ENTRY, (TEXT("++HdstubTrapModuleLoad, dwStructAddr=0x%08X\r\n"),dwStructAddr));

    if (!InSysCall())
    {
        DEBUGGERMSG(HDZONE_ENTRY, (TEXT("  HdstubTrapModuleLoad: ++ EnterCriticalSection, hCurThread=0x%08X, OwnerThread=0x%08X\r\n"), 
                                  hCurThread, 
                                  csModLoad.OwnerThread));
        g_HdStubData.pfnEnterCriticalSection(&csModLoad);
        DEBUGGERMSG(HDZONE_ENTRY, (TEXT("  HdstubTrapModuleLoad: -- EnterCriticalSection, hCurThread=0x%08X, OwnerThread=0x%08X\r\n"), 
                                  hCurThread, 
                                  csModLoad.OwnerThread));
    }

    PageInModule (dwStructAddr);

    InterlockedIncrement(&(LONG)s_dwTaintedModuleCount);

    pClientCur = pClientListHead;
    while (pClientCur && !fHandled)
    {
        DEBUGGERMSG (HDZONE_CLIENT, (L"  HdstubTrapModuleLoad: Trying client 0x%.08x\r\n", pClientCur));
        if ((pClientCur->dwFilter & HDSTUB_FILTER_MODLOAD) && pClientCur->pfnModLoad)
        {
            DEBUGGERMSG (HDZONE_CLIENT, (TEXT("  HdstubTrapModuleLoad: Found client, calling 0x%.08x\r\n"), pClientCur->pfnModLoad));
            fHandled = pClientCur->pfnModLoad (dwStructAddr);
        }
        pClientCur = pClientCur->pCliNext;
    }

    if (!fHandled && ((*s_pulHDEventFilter & HDSTUB_FILTER_MODLOAD) || g_dwModInitCount))
    {
        if (g_dwModInitCount)
        {
            -- g_dwModInitCount;
        }
        HwModLoadHandler (dwStructAddr);
    }

    if (!InSysCall())
    {
        DEBUGGERMSG(HDZONE_ENTRY, (TEXT("  HdstubTrapModuleLoad: ++ LeaveCriticalSection, hCurThread=0x%08X, OwnerThread=0x%08X\r\n"), 
                                  hCurThread, 
                                  csModLoad.OwnerThread));
        g_HdStubData.pfnLeaveCriticalSection(&csModLoad);
        DEBUGGERMSG(HDZONE_ENTRY, (TEXT("  HdstubTrapModuleLoad: -- LeaveCriticalSection, hCurThread=0x%08X, OwnerThread=0x%08X\r\n"), 
                                  hCurThread, 
                                  csModLoad.OwnerThread));
    }


    DEBUGGERMSG(HDZONE_ENTRY, (TEXT("--HdstubTrapModuleLoad\r\n")));
}


void HdstubTrapModuleUnload(DWORD dwStructAddr)
{
    BOOL fHandled = FALSE;
    HDSTUB_CLIENT *pClientCur;
    
    DEBUGGERMSG(HDZONE_ENTRY, (TEXT("++HdstubTrapModuleUnload, dwStructAddr=0x%08X\r\n"),dwStructAddr));

    if (!InSysCall())
    {
        DEBUGGERMSG(HDZONE_ENTRY, (TEXT("  HdstubTrapModuleUnload: ++ EnterCriticalSection, hCurThread=0x%08X, OwnerThread=0x%08X\r\n"), 
                                  hCurThread, 
                                  csModLoad.OwnerThread));
        g_HdStubData.pfnEnterCriticalSection(&csModLoad);
        DEBUGGERMSG(HDZONE_ENTRY, (TEXT("  HdstubTrapModuleUnload: -- EnterCriticalSection, hCurThread=0x%08X, OwnerThread=0x%08X\r\n"), 
                                  hCurThread, 
                                  csModLoad.OwnerThread));
    }

    InterlockedIncrement(&(LONG)s_dwTaintedModuleCount);
    
    pClientCur = pClientListHead;
    while (pClientCur && !fHandled)
    {
        if ((pClientCur->dwFilter & HDSTUB_FILTER_MODUNLOAD) && pClientCur->pfnModUnload)
            fHandled = pClientCur->pfnModUnload (dwStructAddr);
        pClientCur = pClientCur->pCliNext;
    }

    if (!fHandled && (*s_pulHDEventFilter & HDSTUB_FILTER_MODUNLOAD))
        HwModUnloadHandler (dwStructAddr);

    if (!InSysCall())
    {
        DEBUGGERMSG(HDZONE_ENTRY, (TEXT("  HdstubTrapModuleUnload: ++ LeaveCriticalSection, hCurThread=0x%08X, OwnerThread=0x%08X\r\n"), 
                                  hCurThread, 
                                  csModLoad.OwnerThread));
        g_HdStubData.pfnLeaveCriticalSection(&csModLoad);
        DEBUGGERMSG(HDZONE_ENTRY, (TEXT("  HdstubTrapModuleUnload: -- LeaveCriticalSection, hCurThread=0x%08X, OwnerThread=0x%08X\r\n"), 
                                  hCurThread, 
                                  csModLoad.OwnerThread));
    }

    DEBUGGERMSG(HDZONE_ENTRY, (TEXT("--HdstubTrapModuleUnload\r\n")));
}


/*++

Routine Name:

    HdstubUnregisterClient

Routine Description:

    Remove a client from the list in hdstub.
    
Argument:

    pClient - Pointer to the client structure to remove from the list.

--*/
BOOL HdstubUnregisterClient (HDSTUB_CLIENT *pClient)
{
    BOOL fResult = TRUE;
    
    DEBUGGERMSG (HDZONE_CLIENT, (L"++HdstubUnregisterClient: 0x%.08x\r\n", pClient));
    if (pClient == pClientListHead)
    {
        DEBUGGERMSG (HDZONE_CLIENT, (L"  HdstubUnregisterClient: Updating head of list\r\n"));
        if (pClient)
            pClientListHead = pClient->pCliNext;
    }
    else
    {
        HDSTUB_CLIENT *pClientCur;

        pClientCur = pClientListHead;
        while (pClientCur)
        {
            if (pClientCur->pCliNext == pClient)
            {
                DEBUGGERMSG (HDZONE_CLIENT, (L"  HdstubUnregisterClient: Found client, removing.\r\n"));
                if (pClient)
                    pClientCur->pCliNext = pClient->pCliNext;
                goto Exit;
            }
            pClientCur = pClientCur->pCliNext;
        }
        DEBUGGERMSG (HDZONE_CLIENT, (L"  HdstubUnregisterClient: Unable to find client.\r\n"));
        fResult = FALSE;
    }
Exit:
    DEBUGGERMSG (HDZONE_CLIENT, (L"--HdstubUnregisterClient: %d.\r\n", fResult));
    return fResult;;
}


/*++

Routine Name:

    NotifyNewPages

Routine Description:

    Loop over the sections in a process / module and determine whether each section is
    unpageable.  If the section is going to end up unpageable, then manufacture a page-in
    event for that section.

--*/
static void NotifyNewPages (openexe_t *popenexe, DWORD dwNbObjects, o32_lite *pobj32)
{
    DWORD i;
    DWORD dwBaseAddress;

    DEBUGGERMSG (HDZONE_ENTRY, (L"++NotifyNewPages: 0x%08x, %d, 0x%08x\r\n", popenexe, dwNbObjects, pobj32));
    if (pobj32)
    {
        for (i = 0; i < dwNbObjects; i++)
        {
            dwBaseAddress = 0;

            if ((popenexe->filetype & FA_XIP)
                && !(pobj32[i].o32_flags & (IMAGE_SCN_COMPRESSED|IMAGE_SCN_MEM_WRITE)))
            {
                // XIP file and the section is not compressed / writeable
                DEBUGGERMSG (HDZONE_ENTRY, (L"  NotifyNewPages: XIP file, o32_ptr[%d] is not compressed / not RW\r\n", i));
                dwBaseAddress = pobj32[i].o32_realaddr;
            }
            else  if (!PageAble (popenexe) || (pobj32[i].o32_flags & IMAGE_SCN_MEM_NOT_PAGED))
            {
                // This section is guaranteed to never page
                DEBUGGERMSG (HDZONE_ENTRY, (L"  NotifyNewPages: Unpaged section o32_ptr[%d]\r\n", i));
                dwBaseAddress = pobj32[i].o32_realaddr;

                // If this section is RW, fixed-up, and not shared - put the pointer into slot 0
                if ((popenexe->filetype & FA_PREFIXUP)
                    && !(pobj32[i].o32_flags & IMAGE_SCN_MEM_SHARED)
                    && (pobj32[i].o32_flags & IMAGE_SCN_MEM_WRITE))
                {
                    DEBUGGERMSG (HDZONE_ENTRY, (L"  NotifyNewPages: prefixup, RW, unshared section o32_ptr[%d]\r\n", i));
                    // Zero pointer.  it's going into slot zero
                    dwBaseAddress = ZeroPtr (dwBaseAddress);
                }
            }

            if (dwBaseAddress)
            {
                // Have an address to report.
                DEBUGGERMSG (HDZONE_ENTRY, (L"  NotifyNewPages: o32_ptr[%d].o32_realaddr = 0x%08x\r\n", i, pobj32[i].o32_realaddr));
                DEBUGGERMSG (HDZONE_ENTRY, (L"  NotifyNewPages: o32_ptr[%d].o32_vsize = %d\r\n", i, pobj32[i].o32_vsize));
                HdstubTrapVmPageInRange (
                    PAGEALIGN_DOWN (dwBaseAddress),
                    (pobj32[i].o32_vsize + (PAGE_SIZE - 1)) >> VA_PAGE,
                    TRUE);
            }
            else
            {
                // No address.  
                DEBUGGERMSG (HDZONE_ENTRY, (L"  NotifyNewPages: o32_ptr[%d].o32_flags = 0x%08x -> 0, Ignoring\r\n", i, pobj32[i].o32_flags));
                DEBUGGERMSG (HDZONE_ENTRY, (L"  NotifyNewPages: o32_ptr[%d].o32_realaddr = 0x%08x -> 0, Ignoring\r\n", i, pobj32[i].o32_realaddr));
            }
        }
    }
    else
    {
        DEBUGGERMSG (HDZONE_ENTRY, (L"  NotifyNewPages: section array is null.\r\n"));
    }
    DEBUGGERMSG (HDZONE_ENTRY, (L"--NotifyNewPages\r\n"));
}


/*++

Routine Name:

    PageInModule

Routine Description:

    If the module that was just paged in is unpageable, then manufacture page in notification
    for the module.  This is essential for catching delayed assembly breakpoints on addresses
    within the loaded module.

--*/
static void PageInModule (DWORD dwVmBaseAddr)
{
    MODULE *pModule;

    DEBUGGERMSG (HDZONE_ENTRY, (L"++PageInModule: 0x%08x\r\n", dwVmBaseAddr));

    if ((MapPtr (dwVmBaseAddr) >= MapPtr ((DWORD) pCurProc->BasePtr))
        && (MapPtr (dwVmBaseAddr) < MapPtr ((DWORD) pCurProc->BasePtr + pCurProc->e32.e32_vsize)))
    {
        // Loaded a process.
        DEBUGGERMSG (HDZONE_ENTRY, (L"  PageInModule: Proc: %s\r\n", pCurProc->lpszProcName));
        NotifyNewPages (&pCurProc->oe, pCurProc->e32.e32_objcnt, pCurProc->o32_ptr);
    }
    else
    {
        // Just loaded a module
        pModule = pModList;
        while (pModule)
        {
            if (dwVmBaseAddr == ((DWORD) pModule->BasePtr) + 1)
            {
                DEBUGGERMSG (HDZONE_ENTRY, (L"  PageInModule: Mod use = 0x%08x\r\n", pModule->inuse));
                DEBUGGERMSG (HDZONE_ENTRY, (L"  PageInModule: refcnt[%d] = %d\r\n", pCurProc->procnum,
                    pModule->refcnt[pCurProc->procnum]));

                // Unlike processes, make sure that this is the first time the dll is loaded.
                if (!(pModule->inuse & (pModule->inuse - 1))    // Only one bit set.  Inuse != 0
                    && pModule->refcnt[pCurProc->procnum] < 2)  // And refcount is 0/1  (representing first instance)
                {
                    DEBUGGERMSG (HDZONE_ENTRY, (L"  PageInModule: Mod: %s\r\n", pModule->lpszModName));
                    NotifyNewPages (&pModule->oe, pModule->e32.e32_objcnt, pModule->o32_ptr);
                }
            }
            pModule = pModule->pMod;
        }
    }
    DEBUGGERMSG (HDZONE_ENTRY, (L"--PageInModule\r\n"));
}

⌨️ 快捷键说明

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