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

📄 spyengine.cpp

📁 A Windows CE API Inecptor Tools
💻 CPP
📖 第 1 页 / 共 5 页
字号:
PFNVOID SpyEngine::SetPrivateApiMethod
(
    PFNVOID p_pHookMethod
)
{
    //We need to find an unused slot in our private API.
    //Start searching from slot #2 because slots #0 and #1 are
    //used for special purposes by the system.
    int i;
    for(i = 2; i < m_pHookAPISet->m_wNumMethods; i++)
    {
        if(m_pHookAPISet->m_ppMethods[i] == DummyRoutine)
        {
            break;
        }
    }
    if(i == m_pHookAPISet->m_wNumMethods)
    {
        HTRACE(TG_Error, 
            _T("ERROR: not enough free slots in hook table"));
        return NULL;
    }
    //Replace the DummyRoutine in our API table by the target method.
    m_pHookAPISet->m_ppMethods[i] = p_pHookMethod;

    //Now create a special "trap" address for this method:
    PFNVOID l_pHookTrap = (PFNVOID)GetAPIAddress(m_iHookAPISetID, i);
    return l_pHookTrap;
}

/*-------------------------------------------------------------------
   FUNCTION: HookMethod
   PURPOSE: HookMethod is the main routine of the SpyEngine.
   It is used to intercept the specified method in the specified API.
   PARAMETERS:
    int p_iAPISetId - the API set ID (index) to intercept
    int p_iMethodIndex - method index in the given API to intercept
    PFNVOID p_pHookMethod - interceptor method in the Spy DLL.
   RETURNS:
    Pointer to the original method. This pointer must be stored
    by the caller and used by the interceptor routine to call the 
    original method.
    NULL is returned on error.
-------------------------------------------------------------------*/
PFNVOID SpyEngine::HookMethod
(
    int p_iAPISetId, 
    int p_iMethodIndex, 
    PFNVOID p_pHookMethod
)
{
    HTRACE(TG_DebugSpyBrief, _T("HookMethod %x %x %x\r\n"),
        p_iAPISetId, p_iMethodIndex, p_pHookMethod);

    //First call CreateDuplicateApi to create a copy of the original 
    //API and swap pointers, so the copy will immediately be used.
    //Note that CreateDuplicateApi can be called many
    //times for the same API - it will only create a copy once, the
    //following calls will simply return the copy created earlier.
    //This allows calling HookMethod for several method from the 
    //same API.
    if(!CreateDuplicateApi(p_iAPISetId))
        return NULL;
    HookedAPI & l_rAPI = m_HookedAPI[p_iAPISetId];

    //Then prepare an address to the method table of the target API:
    PFNVOID * l_pOrigMethods = (PFNVOID *)ConvertAddr(
        l_rAPI.m_pOrigApiSet->m_ppMethods, 
        l_rAPI.m_pOrigApiSet->m_pProcessServer);

    HTRACE(TG_DebugSpyBrief, 
        _T("Replace method #%x(%x) in API %x by hook %x"),
        p_iMethodIndex, 
        ((PFNVOID*)l_rAPI.m_pOurApiSet->m_ppMethods)[p_iMethodIndex],
        l_rAPI.m_iOrigApiSetId,
        p_pHookMethod);

    PFNVOID l_pOrig = ((PFNVOID *)l_pOrigMethods)[p_iMethodIndex];

    //Finally, put our interceptor to the table of the target API:
    ((PFNVOID *)l_rAPI.m_pOurApiSet->m_ppMethods)[p_iMethodIndex] = 
        p_pHookMethod;

    //Check whether the method is duplicated in the "extra" table
    //and hook it there.
    for(int i = 0; i < SIZE_EXTRA_TABLE; i++)
    {
        if(m_ppHookExtraMethods[i] == l_pOrig)
        {
            HTRACE(TG_DebugSpyDetailed, 
               _T("Replace method #%x(%x) in Extra table by %x\r\n"),
                i, m_ppHookExtraMethods[i], p_pHookMethod);
            m_ppHookExtraMethods[i] = p_pHookMethod;
            break;
        }
    }
    return l_pOrig;
}//PFNVOID SpyEngine::HookMethod

/*-------------------------------------------------------------------
   FUNCTION: HookGetRomFileInfo
   PURPOSE: HookGetRomFileInfo is an interceptor for undocumented
    function GetRomFileInfo, which is called by coredll when a new
    process started to retrieve pointers to 2 system API method
    tables: Win32Methods and ExtraMethods. We must always intercept
    GetRomFileInfo to substitute these 2 pointers and also to load
    the Spy DLL into the new process.
   PARAMETERS:
    DWORD p_dwType - type of information. Value 3 is used to
        retrieve a pointer to Win32Methods, 4 - ExtraMethods.
        Other values are used to enumerate ROM files.
    LPWIN32_FIND_DATA p_pFindData - pointer to a structure to fill 
    DWORD p_dwSize - size of structure pointed by p_pFindData
   RETURNS:
    TRUE on success, FALSE on failure
-------------------------------------------------------------------*/
PFNVOID g_pOrigGetRomFileInfo = NULL;
BOOL HookGetRomFileInfo
(
    DWORD p_dwType, 
    LPWIN32_FIND_DATA p_pFindData, 
    DWORD p_dwSize
)
{
    InterlockedIncrement(&g_SpyEngine.m_lNumCalls);
    InterlockedIncrement(&g_SpyEngine.m_lNumHooksActive);

    HANDLE l_hCaller = GetCallerProcess();
    
    HTRACE(TG_DebugSpyDetailed, 
        _T("HookGetRomFileInfo enter type = %d\r\n"), p_dwType);

    BOOL l_bResult = FALSE;
    if(g_pOrigGetRomFileInfo)
    {
        CALLBACKINFO l_CallbackInfo;
        l_CallbackInfo.m_hDestinationProcessHandle = l_hCaller;
        l_CallbackInfo.m_pFunction = (FARPROC)g_pOrigGetRomFileInfo;
        l_CallbackInfo.m_pFirstArgument = (LPVOID)p_dwType;
    
        l_bResult = (BOOL)PerformCallBack4(&l_CallbackInfo, 
            (DWORD)p_pFindData, p_dwSize, 0);

        //Type 3 and 4 are special backdoors used by coredll to 
        //retrieve pointers to the system method tables.
        //We need to replace these system tables by our copy.
        //Also we know that coredll calls this routine when a 
        //new process starts, so it is a good opportunity to load 
        //the Spy dll into the new process.
        if(p_dwType == 3)
        {
            LPVOID * l_pRetVal = (LPVOID *)MapPtrToProcess
                ((LPVOID)p_pFindData, l_hCaller);
			
            HTRACE(TG_DebugSpyBrief, 
                _T("Replace SH_WIN32 methods %x by %x at %x ")
                _T("AllKMode %d\r\n"),
                *l_pRetVal, g_SpyEngine.m_ppHookWin32Methods, 
                l_pRetVal, *(BOOL*)p_dwSize);
            *l_pRetVal = g_SpyEngine.m_ppHookWin32Methods;
            HTRACE(TG_DebugSpyBrief, _T("Replaced\r\n"));

            DWORD l_dwIdx = GetProcessIndexFromID(l_hCaller);
            HTRACE(TG_InterceptedInfo, 
                _T("Process %x #%d started\r\n"),
                l_hCaller, l_dwIdx);
        }
        if(p_dwType == 4)
        {
            LPVOID * l_pRetVal = (LPVOID *)MapPtrToProcess
                ((LPVOID)p_pFindData, l_hCaller);
			
            HTRACE(TG_DebugSpyBrief, 
                _T("Replace Extra methods %x by %x at %x\r\n"),
                *l_pRetVal, 
                g_SpyEngine.m_ppHookExtraMethods, l_pRetVal);
            *l_pRetVal = g_SpyEngine.m_ppHookExtraMethods;
            HTRACE(TG_DebugSpyBrief, _T("Replaced\r\n"));

            //Pull ourselves to this new process
            DWORD l_dwIdx = GetProcessIndexFromID(l_hCaller);

            g_SpyEngine.m_hSpyDllLoaded[l_dwIdx] = 
                g_SpyEngine.LoadHookDllIntoProcess(l_hCaller);
        }
    }//if(g_pOrigGetRomFileInfo)
    
    HTRACE(TG_DebugSpyDetailed, 
        _T("HookGetRomFileInfo(%x,%x,%x) ret %x\r\n"),
        p_dwType, p_pFindData, p_dwSize, l_bResult);

    InterlockedDecrement(&g_SpyEngine.m_lNumHooksActive);
    return l_bResult;
}//BOOL HookGetRomFileInfo

/*-------------------------------------------------------------------
   FUNCTION: DoStart 
   PURPOSE: Spy engine startup routine. Called by StartSpy
    under an exception handler.
   RETURNS:
    TRUE on success, FALSE on failure
-------------------------------------------------------------------*/
BOOL SpyEngine::DoStart()
{
    m_dwOrigThreadId = GetCurrentThreadId();

    //Load toolhelp library and initialize pointers to it's functions
    if(!LoadToolHelp())
    {
        return FALSE;
    }

    //Use toolhelp to enumerate running processes and keep the info.
    InitProcessList();

    //Calculate the beginning of the current process's memory slot.
    //Use undocumented function GetProcessIndexFromID.
    //There is a confusion: name of the function suggests, that it 
    //expects process ID, but argument is declared as HANDLE.
    //In fact, CE process handles and IDs are identical.
    //Also rely on fact that each process's memory slot is 32 MB.
    //To get the base address shift 0x2000000 left by the process
    //index.
    //WARNING: using 3 undocumented features here.
    HANDLE hCurrent = GetCurrentProcess();
    m_dwCurrentProcBase = 0x2000000 * 
        (1 + GetProcessIndexFromID(hCurrent));

    //Now get access to the kernel data structures.
    m_pSystemAPISets = (CINFO**)(UserKInfo[KINX_APISETS]);
    DWORD dwMask = UserKInfo[KINX_API_MASK];

    HTRACE(TG_DebugSpyBrief, 
        _T("KernelInfo: UserKInfo = %x SystemAPISets = %x Mask =%x"),
        UserKInfo, m_pSystemAPISets, dwMask);

    //Need to keep a trap to the original LoadLibrary.
    m_pOriginalLoadLibrary = m_pSystemAPISets[SH_WIN32]->
        m_ppMethods[W32_LoadLibraryW];

    //Allocate memory in the kernel (NK.EXE), which will be 
    //accessible from all processes. We will use this memory as 
    //argument to LoadLibrary to load the Spy DLL into all processes.
    m_pszSpyDllPathInKernelMemory = (LPTSTR)
        AllocateMemInKernelProc(_MAX_PATH * sizeof(TCHAR));
    
    //g_hInst is a instance of the Spy DLL.
    //Put the path of Spy DLL to the shared memory:
    GetModuleFileName(g_hInst, 
        m_pszSpyDllPathInKernelMemory, _MAX_PATH);

    //Finally, pull the Spy DLL into all running processes.
    LoadHookDllInAllProcesses();

    //Do the same as coredll itself is doing when each new process 
    //is loaded: get direct pointers to a table of Win32 methods
    //and extra methods.
    BOOL bKernelMode;
    GetRomFileInfo(3, (LPWIN32_FIND_DATA)&m_ppWin32Methods, 
        (DWORD)&bKernelMode);
    GetRomFileInfo(4, (LPWIN32_FIND_DATA)&m_ppExtraMethods, 
        NULL);

    //Substitute the system API by our own. 
    //Later custom interceptors may hook other APIs as well,
    //but we always need to intercept the SH_WIN32 because:
    //1. we must intercept W32_GetRomFileInfo
    //2. pointer to SH_WIN32 is cached by coredll and we need to
    //   replace this cached pointer.
    CreateDuplicateApi(SH_WIN32);

    //Also create a copy of special "Extra methods" table.
    //This table is kept in the kernel and a pointer to is is
    //cached by coredll. Coredll uses it as a backdoor to some
    //system services. We, obviously, need to substitute this 
    //pointer as well.
    CreateDuplicateMethodTable(SIZE_EXTRA_TABLE,
        (PFNVOID *)m_ppExtraMethods, NULL,
        &m_ppHookExtraMethods, 
        &m_pdwHookExtraSignatures);

    //Replace pointers to SH_WIN32 table and "Extra Methods" table,
    //which are cached by coredll, by our copies.
    if(!HookCoredll(m_ppWin32Methods, m_ppHookWin32Methods) ||
       !HookCoredll(m_ppExtraMethods, m_ppHookExtraMethods))
    {
        //Undo the hooking:
        HookCoredll(m_ppHookWin32Methods, m_ppWin32Methods);
        HookCoredll(m_ppHookExtraMethods, m_ppExtraMethods);
        return FALSE;
    }

    m_bCoredllHooked = TRUE;

    //Now create our own private API. We will use it to wrap a 
    //pointer to some interceptor routines in an API trap.
    m_iNumOurApiMethods = NUM_OUR_API_METHODS;
    int l_iSize = (sizeof(PFNVOID) + sizeof(DWORD)) * 
        m_iNumOurApiMethods;
    //Allocate a table of pointers to methods and signatures.
    m_ppOurApiMethods = (PFNVOID *)malloc(l_iSize);
    if(!m_ppOurApiMethods)
    {
        HTRACE(TG_Error,
          _T("ERROR: failed to allocate %d bytes for our API table"),
            l_iSize);
        return FALSE;
    }
    m_pdwOurApiSignatures = (DWORD*)
        (LPBYTE(m_ppOurApiMethods) + 
        sizeof(PFNVOID)*m_iNumOurApiMethods);
    //Initially fill all entries with a pointer to DummyRoutine,
    //which does nothing. Later this pointer will be replaced by 
    //an actual interceptor routine.
    for(int i = 0; i < m_iNumOurApiMethods; i++)
    {
        m_ppOurApiMethods[i] = DummyRoutine;
        m_pdwOurApiSignatures[i] = FNSIG0();
    }
    //Finally, register our API
    m_iHookAPISetID = CreateAndRegisterApi("Hook",
        m_iNumOurApiMethods, 
        m_ppOurApiMethods, 
        m_pdwOurApiSignatures,
        &m_hOurApiHandle);
    if(m_iHookAPISetID < 0)
    {
        free(m_ppOurApiMethods);
        m_ppOurApiMethods = NULL;
        return FALSE;
    }
    //Get a pointer to our private API stored in the system table.
    m_pHookAPISet = m_pSystemAPISets[m_iHookAPISetID];

    //GetRomFileInfo must always be hooked to substitute pointers to 
    //system method tables retrieved by coredll when a new process 
    //starts.
    PFNVOID l_pTrapToHookGetRomFileInfo = 
        SetPrivateApiMethod((PFNVOID)HookGetRomFileInfo);
    g_pOrigGetRomFileInfo = HookMethod
        (SH_WIN32, W32_GetRomFileInfo, 
        l_pTrapToHookGetRomFileInfo);

    //Install custom interceptors.
    InstallInterceptors();

⌨️ 快捷键说明

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