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

📄 spyengine.cpp

📁 A Windows CE API Inecptor Tools
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            MEMORY_BASIC_INFORMATION l_MemInfo;
            if(!VirtualQuery(l_pdwAddress, 
                &l_MemInfo, sizeof(l_MemInfo)))
                continue;
            if(l_MemInfo.Protect != PAGE_READWRITE && 
				l_MemInfo.Protect != PAGE_EXECUTE_READWRITE)
                continue;
            
            #if defined(ARM) || defined(SH3)
            if((DWORD)l_pdwAddress & 3)
                continue;
            #endif

            HTRACE(TG_DebugSpyDetailed, 
                _T("Before reading from %x\r\n"), l_pdwAddress);
            DWORD l_dwAddress2 = *l_pdwAddress;

            HTRACE(TG_DebugSpyDetailed, 
                _T("Comparing %x with %x\r\n"), 
                l_dwAddress2, p_pOldWin32Methods);
            if(l_dwAddress2 == (DWORD)p_pOldWin32Methods)
            {
                HTRACE(TG_DebugSpyDetailed, 
                    _T("Found pointer to table %x at %x\r\n"),
                    p_pOldWin32Methods, l_pdwAddress);
                l_dwAddressInCoredll = (DWORD)l_pdwAddress;
                break;
            }
        }
        __except(1)
        {//Exceptions in this code are not unusual
        }
    }//for(int i = 0; i < 256; i++)

    if(l_dwAddressInCoredll == 0)
    {
        HTRACE(TG_Error, 
        _T("ERROR: Failed to find cached table %x in method %s\r\n"),
            p_pOldWin32Methods, l_pszMethodName);
        FreeLibrary(l_hInst);
        return FALSE;
    }
    //OK, now we know where is cached table pointer is hiding.
    //Replace it in all running processes (each process has it's own
    //copy of coredll's data section). Here we rely on fact, that on 
    //CE a DLL is always loaded at the same address in all processes.
    for(int l_iProcID = 0; 
        l_iProcID < countof(g_SpyEngine.m_Processes); l_iProcID++)
    {
        PROCESSENTRY32 * l_pProcEntry = 
            g_SpyEngine.m_Processes + l_iProcID;
        if(!l_pProcEntry->dwSize)
            continue;//This slot is not used
        
        DWORD l_dwProcBaseAddr = 0x2000000 * (l_iProcID+1);
        DWORD * l_pdwAddress = (DWORD*)
            ((l_dwAddressInCoredll & 0x1ffffff) + 
            l_dwProcBaseAddr);
        __try
        {
            MEMORY_BASIC_INFORMATION l_MemInfo;
            if(!VirtualQuery(l_pdwAddress, 
                &l_MemInfo, sizeof(l_MemInfo)) ||
              (l_MemInfo.Protect != PAGE_READWRITE &&
               l_MemInfo.Protect != PAGE_EXECUTE_READWRITE))
            {
                //This seems to me normal for NK.EXE, so don't print
                //this as an error for NK.EXE.
                HTRACE(l_iProcID? TG_Error : TG_DebugSpyDetailed, 
                    _T("Failed to access address %x in process %s"),
                    l_pdwAddress, l_pProcEntry->szExeFile);
                continue;
            }

            if(*l_pdwAddress == (DWORD)p_pOldWin32Methods)
            {
                HTRACE(TG_DebugSpyDetailed, 
                    _T("replacing function pointer (%x by %x)")
                    _T(" at %x in process %x %s\r\n"),
                    *l_pdwAddress, p_pNewWin32Methods, l_pdwAddress, 
                    l_pProcEntry->th32ProcessID, 
                    l_pProcEntry->szExeFile);
                *l_pdwAddress = (DWORD)p_pNewWin32Methods;

                //Double check. This is not really necessary.
                FlushInstructionCache(GetCurrentProcess(), 0, 0);
                if(*l_pdwAddress != (DWORD)p_pNewWin32Methods)
                {
                    HTRACE(TG_Error, 
                        _T("ERROR: failed to replace function")
                        _T(" pointer (%x by %x) at %x\r\n"),
                        *l_pdwAddress, p_pNewWin32Methods, 
                        l_pdwAddress);
                }
                else
                {
                    HTRACE(TG_DebugSpyDetailed,
                        _T("replaced function pointer at %x\r\n"), 
                        l_pdwAddress);
                }
            }
            else
            {
                HTRACE(TG_DebugSpyDetailed, 
                    _T("Don't replace pointer (%x by %x)")
                    _T(" at %x in process %x %s\r\n"),
                    *l_pdwAddress, p_pNewWin32Methods, l_pdwAddress, 
                    l_pProcEntry->th32ProcessID, 
                    l_pProcEntry->szExeFile);
            }
        }
        __except(1)
        {
            HTRACE(TG_Error, 
                _T("ERROR: Exception trying to access address %x")
                _T(" in process %x %s\r\n"),
                l_pdwAddress, 
                l_pProcEntry->th32ProcessID,l_pProcEntry->szExeFile);
        }
    }//for(int l_iProcID = 0; l_iProcID < countof(m_Processes);)
    FreeLibrary(l_hInst);
    return TRUE;
}//BOOL HookCoredll

/*-------------------------------------------------------------------
   FUNCTION: ProcessAddress
   PURPOSE:  
   returns an address of memory slot for the given process index.
   PARAMETERS:
    BYTE p_byProcNum - process number (slot index) between 0 and 31
   RETURNS:
    Address of the memory slot.
-------------------------------------------------------------------*/
inline DWORD ProcessAddress(BYTE p_byProcNum)
{
    return 0x02000000 * (p_byProcNum+1);
}

/*-------------------------------------------------------------------
   FUNCTION: ConvertAddr
   PURPOSE:  
    ConvertAddr does the same as MapPtrToProcess - maps an address in
    slot 0 to the address in the slot of the given process. Unlike 
    MapPtrToProcess, which accepts process handle, ConvertAddr uses
    undocumented PROCESS structure.
   PARAMETERS:
    LPVOID p_pAddr - address to convert
    PPROCESS p_pProcess - internal kernel Process structure
   RETURNS:
    Address mapped to the slot of the given process
-------------------------------------------------------------------*/
LPVOID ConvertAddr(LPVOID p_pAddr, PPROCESS p_pProcess)
{
    if( ((DWORD)p_pAddr) < 0x2000000 && p_pProcess)
    {//Slot 0 and process is not the kernel
        LPVOID l_pOld = p_pAddr;
        BYTE l_byProcNum = 
            *(((LPBYTE)p_pProcess) + PROCESS_NUM_OFFSET);
        p_pAddr = (LPVOID) (((DWORD)p_pAddr) + 
            ProcessAddress(l_byProcNum));
        HTRACE(TG_DebugSpyDetailed, 
            _T("Converted address %x to %x for server %x\r\n"), 
            l_pOld, p_pAddr, l_byProcNum);
    }
    return p_pAddr;
}

/*-------------------------------------------------------------------
   FUNCTION: GetKernelProcessHandle
   PURPOSE:  returns handle to the kernel process (nk.exe)
   RETURNS: HANDLE of nk.exe
-------------------------------------------------------------------*/
HANDLE GetKernelProcessHandle()
{
//In CE 3.0 and PPC 2002 I used GetProcFromPtr((LPVOID)0x2000000)
//to get handle to process nk.exe, but in CE 4.0 this does not work.
//HANDLE hNKProc = GetProcFromPtr((LPVOID)0x2000000);
    
    //Use process #0 from the array of preloaded processes.
    HANDLE l_hNKProc = OpenProcess(0, FALSE, 
        g_SpyEngine.m_Processes[0].th32ProcessID);
    if(l_hNKProc == NULL)
    {
        HTRACE(TG_Error, 
            _T("ERROR: OpenProcess(%x) failed. Err %d\r\n"),
            g_SpyEngine.m_Processes[0].th32ProcessID,GetLastError());
        return FALSE;
    }
    return l_hNKProc;
}

/*-------------------------------------------------------------------
   FUNCTION: CallCoredllInProc
   PURPOSE:  CallCoredllInProc uses undocumented method 
    PerformCallBack4 to call exported methods from coredll.dll in 
    the specified process.
   PARAMETERS:
    HANDLE  p_hProcess - handle to the process, where the call should
        be made
    LPCTSTR p_pszMethodName - name of method exported from coredll, 
        such as VirtualAlloc, VirtualFree, etc.
    DWORD p_dwParam1, p_dwParam2, p_dwParam3, p_dwParam4 - arguments
    DWORD * p_pdwResult - pointer to the return value
   RETURNS:
    TRUE on success, FALSE on failure
-------------------------------------------------------------------*/
BOOL CallCoredllInProc
(
    HANDLE  p_hProcess,
    LPCTSTR p_pszMethodName,
    DWORD   p_dwParam1, DWORD p_dwParam2, 
    DWORD   p_dwParam3, DWORD p_dwParam4,
    DWORD * p_pdwResult)
{
    HINSTANCE l_hCoreDll = NULL;
    BOOL l_bReturn = FALSE;
    __try
    {
        //Use undocumented method PerformCallBack4 
        //to call method in NK.EXE.
        CALLBACKINFO CallbackInfo;
        CallbackInfo.m_hDestinationProcessHandle = p_hProcess;
        l_hCoreDll = LoadLibrary(_T("COREDLL"));
        CallbackInfo.m_pFunction = 
            (FARPROC)GetProcAddress(l_hCoreDll, p_pszMethodName);
        if(!CallbackInfo.m_pFunction)
        {
            HTRACE(TG_Error, 
                _T("GetProcAddress(%x, %s) failed. Err %d"), 
                l_hCoreDll, p_pszMethodName, GetLastError());
        }
        else
        {
            CallbackInfo.m_pFirstArgument = (LPVOID)p_dwParam1;
            DWORD l_dwResult = PerformCallBack4
                (&CallbackInfo, p_dwParam2, p_dwParam3, p_dwParam4);
            if(p_pdwResult)
            {
                *p_pdwResult = l_dwResult;
            }
            l_bReturn = TRUE;
        }
    }
    __except(1)
    {
        HTRACE(TG_Error, _T("Exception in CallCoredllInProc(%s)"), 
            p_pszMethodName);
        l_bReturn = FALSE;
    }
    if(l_hCoreDll)
    {
        FreeLibrary(l_hCoreDll);
    }
    return l_bReturn;
}//BOOL CallCoredllInProc

/*-------------------------------------------------------------------
   FUNCTION: CallCoredllInKernelProc
   PURPOSE:  CallCoredllInKernelProc uses undocumented method 
    PerformCallBack4 to call exported methods from coredll.dll in the
    kernel process (nk.exe).
   PARAMETERS:
    LPCTSTR p_pszMethodName - name of method exported from coredll, 
        such as VirtualAlloc, VirtualFree, etc.
    DWORD p_dwParam1, p_dwParam2, p_dwParam3, p_dwParam4 - arguments
    DWORD * p_pdwResult - pointer to the return value
   RETURNS:
    TRUE on success, FALSE on failure
-------------------------------------------------------------------*/
BOOL CallCoredllInKernelProc(LPCTSTR p_pszMethodName,
    DWORD p_dwParam1, DWORD p_dwParam2, 
    DWORD p_dwParam3, DWORD p_dwParam4,
    DWORD * p_pdwResult)
{
    HANDLE l_hNKProc = GetKernelProcessHandle();
    if(!l_hNKProc)
        return FALSE;
    BOOL l_bReturn = CallCoredllInProc(l_hNKProc, p_pszMethodName, 
        p_dwParam1, p_dwParam2, p_dwParam3, p_dwParam4, p_pdwResult);
    CloseHandle(l_hNKProc);
    return l_bReturn;
}//BOOL CallCoredllInKernelProc

/*-------------------------------------------------------------------
   FUNCTION: FreeMemInKernelProc
   PURPOSE:  FreeMemInKernelProc is used to free memory, which was 
    allocated in the nk.exe process space by AllocateMemInKernelProc.
   PARAMETERS:
    LPVOID p_pMem - memory to free
   RETURNS:
    TRUE on success, FALSE on failure
-------------------------------------------------------------------*/
BOOL FreeMemInKernelProc(LPVOID p_pMem)
{
    if(!CallCoredllInKernelProc(_T("VirtualFree"),
        (DWORD)p_pMem, 0, MEM_RELEASE, 0, NULL))
    {
        HTRACE(TG_Error, _T("Failed to free %x in NK.EXE"), p_pMem);
        return FALSE;
    }
    return TRUE;
}

/*-------------------------------------------------------------------
   FUNCTION: AllocateMemInKernelProc
   PURPOSE:  AllocateMemInKernelProc is used to allocate memory in 
    the process #0 - nk.exe, which is accessible from all other 
    processes. We need this memory to create duplicate method tables, 
    which we will use to substitute original method tables provided 
    by the kernel or by server processes.
   PARAMETERS:
    int p_iSize - size to allocate
   RETURNS:
    Pointer to the allocated memory in the kernel process
-------------------------------------------------------------------*/
void * AllocateMemInKernelProc(int p_iSize)
{
    LPVOID l_pAllocated = NULL;
    if(!CallCoredllInKernelProc(_T("VirtualAlloc"),
        0, p_iSize, MEM_COMMIT, PAGE_READWRITE, 
        (LPDWORD)&l_pAllocated))
    {
        HTRACE(TG_Error, 
            _T("Failed to allocate %d bytes in NK.EXE"), p_iSize);
        return NULL;
    }
    HTRACE(TG_DebugSpyBrief, 
        _T("VirtualAlloc(%d) in NK.EXE returned %x"), 
        p_iSize, l_pAllocated);
    //Currently l_pAllocated is slot 0 address, so it is not valid
    //unless the current process is NK.EXE. So we need to map
    //it to slot 1, which is the home of NK.EXE.
    HANDLE l_hNKProc = GetKernelProcessHandle();
    LPVOID l_pRemoteMem = l_hNKProc? 
        MapPtrToProcess(l_pAllocated, l_hNKProc) : NULL;
    if(!l_pRemoteMem)
    {
        HTRACE(TG_Error, 
            _T("Failed to map ptr %x to NK.EXE. Err %d"), 
            l_pAllocated, GetLastError());
        FreeMemInKernelProc(l_pAllocated);
    }
    CloseHandle(l_hNKProc);
    HTRACE(TG_DebugSpyBrief, 
        _T("AllocateMemInKernelProc(%d) ret %x\r\n"), 
        p_iSize, l_pRemoteMem);

⌨️ 快捷键说明

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