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

📄 spyengine.cpp

📁 A Windows CE API Inecptor Tools
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	return l_pRemoteMem;
}//void * AllocateMemInKernelProc

/*-------------------------------------------------------------------
   FUNCTION: LoadHookDllIntoProcess
   PURPOSE: In order to spy for APIs served by other processes, the 
    Spy interceptor routines must be accessible from these processes. 
    This can be achieved by loading the Spy DLL into these processes. 
    The way to do that is by using undocumented PerformCallBack4 
    routine to execute LoadLibrary in other processes. We cannot 
    simply call LoadLibrary exported from coredll, because it can be 
    intercepted by us, but the interceptor will crash because the 
    SpyEngine is not loaded yet into the process. Therefore, use 
    m_pOriginalLoadLibrary, which keeps a trap to the original 
    W32_LoadLibraryW handler.
   PARAMETERS:
    HANDLE p_hProcess - handle to the process where the DLL should
        be loaded.
   RETURNS:
    Instance handle of the loaded DLL in the target process.
-------------------------------------------------------------------*/
HINSTANCE SpyEngine::LoadHookDllIntoProcess(HANDLE p_hProcess)
{

    CALLBACKINFO CallbackInfo;
    CallbackInfo.m_hDestinationProcessHandle = p_hProcess;
    CallbackInfo.m_pFunction = (FARPROC)m_pOriginalLoadLibrary;
    CallbackInfo.m_pFirstArgument = 
        (LPVOID)m_pszSpyDllPathInKernelMemory;
    HTRACE(TG_DebugSpyBrief, 
        _T("Load our DLL in proc %x using fun %x\r\n"), 
        p_hProcess, m_pOriginalLoadLibrary);
    DWORD l_dwResult = PerformCallBack4(&CallbackInfo, 0, 0, 0);
    HTRACE(TG_DebugSpyBrief, _T("Loaded %x\r\n"), l_dwResult);
    return (HINSTANCE)l_dwResult;
}

/*-------------------------------------------------------------------
   FUNCTION: UnloadHookDllInProcess
   PURPOSE: UnloadHookDllInProcess is used to unload SpyDll 
    from a process, where it was loaded by LoadHookDllIntoProcess.
   PARAMETERS:
    HANDLE p_hProcess - handle to process where the DLL was loaded
    HINSTANCE p_hInst - instance handle of the loaded DLL
   RETURNS:
    TRUE on success, FALSE on failure
-------------------------------------------------------------------*/
BOOL SpyEngine::UnloadHookDllInProcess
(
    HANDLE p_hProcess, 
    HINSTANCE p_hInst
)
{
    DWORD l_dwResult = 0;
    if(!CallCoredllInProc(p_hProcess, _T("FreeLibrary"), 
        (DWORD)p_hInst, 0,0,0, &l_dwResult))
        return FALSE;
    HTRACE(TG_DebugSpyBrief, 
        _T("FreeLibrary(%x) in process %x ret %x\r\n"), 
        p_hInst, p_hProcess, l_dwResult);
    return l_dwResult;
}

/*-------------------------------------------------------------------
   FUNCTION: LoadHookDllInAllProcesses
   PURPOSE: Load our Spy DLL in all running processes so that these 
    processes will be able to access our interceptor routines.
-------------------------------------------------------------------*/
void SpyEngine::LoadHookDllInAllProcesses()
{
    HTRACE(TG_DebugSpyBrief, _T("LoadHookDllInAllProcesses()\r\n"));

    //Don't load Spy DLL into NK.EXE (process #0) because NK.EXE 
    //already has access to all addresses and because it is difficult
    //to unload from there.
    for(int l_iProcID = 1; l_iProcID < countof(m_Processes); 
        l_iProcID++)
    {
        PROCESSENTRY32 * l_pProcEntry = m_Processes + l_iProcID;
        if(!l_pProcEntry->dwSize)
            continue;//This slot is not used
        if(l_pProcEntry->th32ProcessID == GetCurrentProcessId())
            continue;//This is Spy itself.

        HANDLE l_hProc = OpenProcess(0, FALSE, 
            l_pProcEntry->th32ProcessID);
        if(l_hProc == NULL)
        {
            HTRACE(TG_Error, 
                _T("ERROR: Failed to open process %x %s\r\n"),
                l_pProcEntry->th32ProcessID,l_pProcEntry->szExeFile);
        }
        else
        {
            HTRACE(TG_DebugSpyBrief, 
                _T("Load our DLL in process %x %s\r\n"),
                l_pProcEntry->th32ProcessID,l_pProcEntry->szExeFile);
            m_hSpyDllLoaded[l_iProcID] = 
                LoadHookDllIntoProcess(l_hProc);
            CloseHandle(l_hProc);
        }
    }//for(int l_iProcID = 0; l_iProcID < countof(m_Processes);
    HTRACE(TG_DebugSpyBrief, 
        _T("LoadHookDllInAllProcesses() ends\r\n"));
}//void SpyEngine::LoadHookDllInAllProcesses

/*-------------------------------------------------------------------
   FUNCTION: CloseAPISet
   PURPOSE: CloseAPISet closes the API handle returned by 
    CreateAPISet. For some reason CloseAPISet routine is not 
    exported from coredll. So, call it using API trap.
   PARAMETERS:
    HANDLE p_hSet - API handle returned by CreateAPISet
-------------------------------------------------------------------*/
void CloseAPISet(HANDLE p_hSet)
{
    __try
    {
        ((void (*)(HANDLE)) IMPLICIT_CALL(HT_APISET, 0)) (p_hSet);
    }
    __except(1)
    {
        HTRACE(TG_Error, _T("ERROR: exception in CloseAPISet"));
    }
}

/*-------------------------------------------------------------------
   FUNCTION: CreateDuplicateMethodTable
   PURPOSE: CreateDuplicateMethodTable used to allocate memory in 
    the kernel process space and copy the given method and signature 
    table to this memory.
   PARAMETERS:
    int        p_iNumMethods - number of methods
    PFNVOID *  p_pMethods    - method table
    DWORD   *  p_pdwSignatures - signature table (May be NULL)
    PFNVOID ** p_ppReturnHookMthds- return the allocated method table
    DWORD   ** p_ppdwReturnHookSignatures - return the signatures
   RETURNS:
    TRUE on success, FALSE on failure
-------------------------------------------------------------------*/
BOOL CreateDuplicateMethodTable
(
    int        p_iNumMethods, 
    PFNVOID *  p_pMethods,
    DWORD   *  p_pdwSignatures,//May be NULL
    PFNVOID ** p_ppReturnHookMthds,
    DWORD   ** p_ppdwReturnHookSignatures
)
{
    int l_iSize = (sizeof(PFNVOID)*p_iNumMethods + 
                   sizeof(DWORD)*p_iNumMethods);
    LPBYTE l_pRemoteMem = (LPBYTE)AllocateMemInKernelProc(l_iSize);
    HTRACE(TG_DebugSpyBrief, 
        _T("Create method table at %x\r\n"), l_pRemoteMem);

    PFNVOID * l_pHookMthds = (PFNVOID *)l_pRemoteMem;
    DWORD   * l_pdwHookSignatures = 
        (DWORD*)(l_pRemoteMem + sizeof(PFNVOID)*p_iNumMethods);

    int i;
    for(i = 0; i < p_iNumMethods; i++)
    {
        HTRACE(TG_DebugSpyDetailed, 
            _T("Copy meth #%x %x from %x to %x\r\n"), i, 
            p_pMethods[i], &p_pMethods[i], &l_pHookMthds[i]);
        l_pHookMthds[i] = p_pMethods[i];
        //Our replaced API will be served by our process and we 
        //always should provide  a signature table. But the original
        //signature table pointer will be NULL if the original API 
        //is served by the kernel (therefore no pointer mapping is 
        //required). In that case fill our table by FNSIG0, which 
        //means that no mapping is required.
        l_pdwHookSignatures[i] = p_pdwSignatures? 
            p_pdwSignatures[i] : FNSIG0();
    }
    *p_ppReturnHookMthds = l_pHookMthds;
    *p_ppdwReturnHookSignatures = l_pdwHookSignatures;
    return TRUE;
}//CreateDuplicateMethodTable

/*-------------------------------------------------------------------
   FUNCTION: CreateAndRegisterApi
   PURPOSE: CreateAndRegisterApi calls undocumented methods 
    CreateAPISet, RegisterAPISet and QueryAPISetID to create, 
    register a new API and return it's ID
   PARAMETERS:
    char    * p_pszName       - API name
    int       p_iNumMethods   - number of methods
    PFNVOID * p_ppMethods     - method table
    DWORD   * p_pdwSignatures - method signatures
    HANDLE  * p_phReturnApiHandle - return API handle
   RETURNS:
    Positive API ID (index in the system API table)
    -1 on error
-------------------------------------------------------------------*/
int CreateAndRegisterApi
(
    char    * p_pszName,
    int       p_iNumMethods,
    PFNVOID * p_ppMethods,
    DWORD   * p_pdwSignatures,
    HANDLE  * p_phReturnApiHandle
)
{
    HANDLE l_hApiHandle = CreateAPISet(p_pszName, 
        p_iNumMethods, p_ppMethods, p_pdwSignatures);
    if(!l_hApiHandle)
    {
        HTRACE(TG_Error, 
            _T("ERROR: CreateAPISet(%c%c%c%c, %x, %x, %x) failed.")
            _T("Err %d"),
            p_pszName[0], p_pszName[1], p_pszName[2], p_pszName[3],
            p_iNumMethods, p_ppMethods, p_pdwSignatures,
            GetLastError());
        return -1;
    }
    if(!RegisterAPISet(l_hApiHandle, 0))
    {
        HTRACE(TG_Error,
            _T("ERROR: RegisterAPISet(%x) for API %c%c%c%c failed.")
            _T("Err %d"),
            l_hApiHandle, 
            p_pszName[0], p_pszName[1], p_pszName[2], p_pszName[3],
            GetLastError());
        CloseAPISet(l_hApiHandle);
        return -1;
    }
    int l_iAPISetID = QueryAPISetID(p_pszName);
    if(l_iAPISetID < 0)
    {
        HTRACE(TG_Error,
            _T("ERROR: QueryAPISetID(%c%c%c%c) failed. Err %d"),
            p_pszName[0], p_pszName[1], p_pszName[2], p_pszName[3],
            GetLastError());
        CloseAPISet(l_hApiHandle);//it also unregisters the API
        return -1;
    }
    HTRACE(TG_DebugSpyBrief, 
        _T("CreateAndRegisterApi(%c%c%c%c) NumM %x Mthds %x ")
        _T("Sign %x ret ID %d"),
        p_pszName[0], p_pszName[1], p_pszName[2], p_pszName[3],
        p_iNumMethods, p_ppMethods, p_pdwSignatures, l_iAPISetID);
    *p_phReturnApiHandle = l_hApiHandle;
    return l_iAPISetID;
}//int CreateAndRegisterApi

/*-------------------------------------------------------------------
   FUNCTION: CreateDuplicateApi
   PURPOSE: CreateDuplicateApi is used to create a copy of the
    system API (CINFO structure, method and signature tables).
    Then replace a pointer to the original CINFO by the new one.
    We keep a table m_HookedAPI of such replacement APIs, 
    so CreateDuplicateApi will not allocate a new API for the same
    original more than once.
   PARAMETERS:
    int p_iAPISetId - original API set ID to replace
   RETURNS:
    TRUE on success, FALSE on failure
-------------------------------------------------------------------*/
BOOL SpyEngine::CreateDuplicateApi(int p_iAPISetId)
{
    if(p_iAPISetId < 0 || p_iAPISetId >= countof(m_HookedAPI))
    {
        HTRACE(TG_Error, 
         _T("ERROR: CreateDuplicateApi argument %d is out of range"),
            p_iAPISetId);
        return FALSE;
    }
    HookedAPI * l_pHookedAPI = m_HookedAPI + p_iAPISetId;
    if(l_pHookedAPI->m_bUsed)
        return TRUE;
    HANDLE l_hCurProc = GetCurrentProcess();
    CINFO * l_pOrigApiSet = m_pSystemAPISets[p_iAPISetId];
    
    PFNVOID * l_pHookMthds = NULL;
    DWORD   * l_pdwHookSignatures = NULL;
    PFNVOID * l_pOrigMethods = (PFNVOID *)ConvertAddr
        (l_pOrigApiSet->m_ppMethods,l_pOrigApiSet->m_pProcessServer);
    DWORD   * l_pOrigSignatures = (DWORD *)ConvertAddr
      (l_pOrigApiSet->m_pdwMethodSignatures, 
      l_pOrigApiSet->m_pProcessServer);

    CreateDuplicateMethodTable(l_pOrigApiSet->m_wNumMethods,
        l_pOrigMethods, l_pOrigSignatures,
        &l_pHookMthds, &l_pdwHookSignatures);
    if(p_iAPISetId == SH_WIN32)
    {
        m_ppHookWin32Methods = l_pHookMthds;
        m_pdwHookWin32Signatures = l_pdwHookSignatures;
    }
    CINFO * l_pOurApiSet = (CINFO *)
        AllocateMemInKernelProc(sizeof(CINFO));
    //Use the same name, dispatch type, API ID and server 
    //as the original API:
    memcpy(l_pOurApiSet, l_pOrigApiSet, sizeof(CINFO));

    //But replace the method and signature tables:
    l_pOurApiSet->m_ppMethods = l_pHookMthds;
    l_pOurApiSet->m_pdwMethodSignatures = l_pdwHookSignatures;

    HTRACE(TG_DebugSpyBrief, 
        _T("Created duplicate CINFO at %x for API %x ")
        _T("dup mthds %x %x\r\n"),
        l_pOurApiSet, p_iAPISetId, 
        l_pHookMthds, l_pdwHookSignatures);

    //Now fill our HookedAPI structure so we can undo the 
    //API replacement later.
    l_pHookedAPI->m_bUsed = TRUE;
    l_pHookedAPI->m_bSwapped = FALSE;
    l_pHookedAPI->m_iOrigApiSetId = p_iAPISetId;
    l_pHookedAPI->m_pOrigApiSet = l_pOrigApiSet;
    l_pHookedAPI->m_pOurApiSet = l_pOurApiSet;
    
    //And finally, replace the pointer to the original CINFO
    //by the pointer to ours.
    HTRACE(TG_DebugSpyBrief, 
        _T("Before replace original API %x (CINFO %x by %x) ")
        _T("at %x\r\n"),
        p_iAPISetId,
        m_pSystemAPISets[p_iAPISetId], l_pOurApiSet,
        &m_pSystemAPISets[p_iAPISetId]);

    m_pSystemAPISets[p_iAPISetId] = l_pOurApiSet;
    l_pHookedAPI->m_bSwapped = TRUE;

    HTRACE(TG_DebugSpyBrief, 
        _T("After replace original API %x\r\n"), p_iAPISetId);
    return TRUE;
}//BOOL SpyEngine::CreateDuplicateApi

void DummyRoutine()
{
    //HTRACE(TG_DebugSpyBrief, _T("DummyRoutine"));
}

/*-------------------------------------------------------------------
   FUNCTION: SetPrivateApiMethod
   PURPOSE: SetPrivateApiMethod finds an unused slot in our private
    API method table and stores the given method to it.
   PARAMETERS:
    PFNVOID p_pHookMethod - pointer to the new method
   RETURNS:
    Trap to invoke the given method in our private API 
    or NULL on failure
-------------------------------------------------------------------*/

⌨️ 快捷键说明

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