📄 spyengine.cpp
字号:
HTRACE(TG_PrintAlways, _T("StartSpy successful"));
g_bStarted = TRUE;
return TRUE;
}//BOOL SpyEngine::DoStart()
/*-------------------------------------------------------------------
FUNCTION: DoStop
PURPOSE: Stop spy engine. Called by StopSpy
under an exception handler.
RETURNS:
TRUE on success, FALSE on failure
-------------------------------------------------------------------*/
BOOL SpyEngine::DoStop()
{
HTRACE(TG_DebugSpyBrief, _T("Unhook hooked APIs"));
int i;
if(m_bCoredllHooked)
{
HTRACE(TG_DebugSpyBrief, _T("UnHook core DLL"));
m_bCoredllHooked = FALSE;
HookCoredll(m_ppHookWin32Methods,
m_ppWin32Methods);
HookCoredll(m_ppHookExtraMethods,
m_ppExtraMethods);
}
for(i = 0; i < countof(m_HookedAPI); i++)
{
HookedAPI * l_pHookedAPI = m_HookedAPI + i;
if(!l_pHookedAPI->m_bUsed || !l_pHookedAPI->m_bSwapped)
continue;
HTRACE(TG_DebugSpyDetailed,
_T("Restore old api set %x orig CINFO %x, ours %x"),
l_pHookedAPI->m_iOrigApiSetId,
l_pHookedAPI->m_pOrigApiSet,
l_pHookedAPI->m_pOurApiSet);
//Copy the original table into our (eliminating all hooks)
PFNVOID * l_pOrigMethods = (PFNVOID *)ConvertAddr(
l_pHookedAPI->m_pOrigApiSet->m_ppMethods,
l_pHookedAPI->m_pOrigApiSet->m_pProcessServer);
for(int j = 0; j <
l_pHookedAPI->m_pOrigApiSet->m_wNumMethods; j++)
{
l_pHookedAPI->m_pOurApiSet->m_ppMethods[j] =
l_pOrigMethods[j];
}
//Swap back
m_pSystemAPISets[l_pHookedAPI->m_iOrigApiSetId] =
l_pHookedAPI->m_pOrigApiSet;
l_pHookedAPI->m_bSwapped = FALSE;
//Free duplicate tables and CINFO.
//WARNING: There may be a chance that they are still used
//by a dispatcher or Coredll on another thread.
//So, if crashes will happen after Stop - delay or
//remove this memory freeing
HTRACE(TG_DebugSpyBrief,
_T("Free duplicate tables at %x and CINFO at %x"),
l_pHookedAPI->m_pOurApiSet->m_ppMethods,
l_pHookedAPI->m_pOurApiSet);
FreeMemInKernelProc(l_pHookedAPI->m_pOurApiSet->m_ppMethods);
FreeMemInKernelProc(l_pHookedAPI->m_pOurApiSet);
l_pHookedAPI->m_pOurApiSet = NULL;
HTRACE(TG_DebugSpyDetailed,
_T("Restored old api set %x orig CINFO %x, ours %x"),
l_pHookedAPI->m_iOrigApiSetId,
l_pHookedAPI->m_pOrigApiSet,
l_pHookedAPI->m_pOurApiSet);
}//for(i = 0; i < countof(m_HookedAPI); i++)
if(m_hOurApiHandle)
{
CloseAPISet(m_hOurApiHandle);
HTRACE(TG_DebugSpyDetailed,
_T("After closed \"Hook\" API %x"),m_hOurApiHandle);
m_hOurApiHandle = NULL;
free(m_ppOurApiMethods);
m_ppOurApiMethods = NULL;
}
for(int l_iProcID = countof(m_hSpyDllLoaded)-1;
l_iProcID > 0; l_iProcID--)
{//Skip NK.EXE
PROCESSENTRY32 * l_pProcEntry = m_Processes + l_iProcID;
if(l_pProcEntry->dwSize == 0)
continue;
HANDLE l_hProc = OpenProcess(0, FALSE,
l_pProcEntry->th32ProcessID);
if(l_hProc == NULL)
{
HTRACE(TG_DebugSpyDetailed,
_T("WARNING: Failed to open process %x %s\r\n"),
l_pProcEntry->th32ProcessID,l_pProcEntry->szExeFile);
continue;
}
HTRACE(TG_DebugSpyDetailed,
_T("Unload SpyDll from proc %x %s"),
l_pProcEntry->th32ProcessID,
l_pProcEntry->szExeFile);
UnloadHookDllInProcess(l_hProc,
m_hSpyDllLoaded[l_iProcID]);
CloseHandle(l_hProc);
m_hSpyDllLoaded[l_iProcID] = NULL;
}
return TRUE;
}
/*-------------------------------------------------------------------
FUNCTION: StartSpy
PURPOSE: Exported routine called by Spy GUI to start monitoring
RETURNS:
TRUE on success, FALSE on failure
-------------------------------------------------------------------*/
extern "C" __declspec(dllexport)
BOOL StartSpy()
{
if(g_bStarted)
{
HTRACE(TG_DebugSpyBrief, _T("Spy already started"));
return TRUE;
}
HTRACE(TG_DebugSpyBrief, _T("->StartSpy"));
BOOL l_bResult = TRUE;
DWORD l_dwOldPermissions = 0;
__try
{
//Switch to kernel mode to get access to kernel memory
//(needed only on CE 4.0)
SetKMode(TRUE);
//Get access to memory slots of other processes
l_dwOldPermissions = SetProcPermissions(-1);
//Init global data
memset(&g_SpyEngine, 0, sizeof(g_SpyEngine));
l_bResult = g_SpyEngine.DoStart();
}
__except(1)
{
HTRACE(TG_Error, _T("Exception in StartSpy()"));
l_bResult = FALSE;
}
if(l_dwOldPermissions)
{
SetProcPermissions(l_dwOldPermissions);
}
SetKMode(FALSE);//Switch back to User mode(needed only on CE 4.0)
HTRACE(TG_DebugSpyBrief, _T("<-StartSpy ret %d"), l_bResult);
return l_bResult;
}//BOOL StartSpy()
/*-------------------------------------------------------------------
FUNCTION: StopSpy
PURPOSE: Exported routine called by Spy GUI to stop monitoring
RETURNS:
TRUE on success, FALSE on failure
-------------------------------------------------------------------*/
extern "C" __declspec(dllexport)
BOOL StopSpy()
{
HTRACE(TG_DebugSpyBrief, _T("->StopSpy"));
DWORD l_dwOldPermissions = 0;
BOOL l_bReturn = FALSE;
__try
{
g_bStarted = FALSE;
//Switch to kernel mode to get access to kernel memory
//(needed only on CE 4.0)
SetKMode(TRUE);
//Get access to memory slots of other processes
l_dwOldPermissions = SetProcPermissions(-1);
if(g_SpyEngine.DoStop())
{
l_bReturn = TRUE;
}
}
__except(1)
{
HTRACE(TG_Error, _T("Exception in StopSpy"));
l_bReturn = FALSE;
}
if(l_dwOldPermissions)
{
SetProcPermissions(l_dwOldPermissions);
}
//Switch back to User mode (needed only on CE 4.0)
SetKMode(FALSE);
HTRACE(TG_PrintAlways,
_T("StopSpy Ends. %d calls intercepted. ")
_T("%d calls still in progress"),
g_SpyEngine.m_lNumCalls, g_SpyEngine.m_lNumHooksActive);
if(g_SpyEngine.m_lNumHooksActive != 0)
{
l_bReturn = FALSE;
}
return l_bReturn;
}//BOOL StopSpy()
/*-------------------------------------------------------------------
FUNCTION: DumpApis
PURPOSE: DumpApis prints all registered APIs.
DumpApis is not needed for api spying.
It is used for information only.
-------------------------------------------------------------------*/
extern "C" __declspec(dllexport)
void DumpApis()
{
HTRACE(TG_InterceptedInfo, _T("Dump APIs:"));
DWORD l_dwOldPermissions = 0;
__try
{
SetKMode(TRUE);
//Get access to memory slots of other processes
l_dwOldPermissions = SetProcPermissions(-1);
CINFO ** l_pSystemAPISets =
(CINFO**)(UserKInfo[KINX_APISETS]);
for(int i = 0; i < NUM_SYSTEM_SETS; i++)
{
CINFO * l_pSet = l_pSystemAPISets[i];
if(!l_pSet)
{
continue;
}
LPBYTE l_pServer = (LPBYTE)l_pSet->m_pProcessServer;
HTRACE(TG_InterceptedInfo,
_T("#%x: %S disp %d type %d #meth %d ")
_T("pMeth %x sig %x srv %x %s\n"),
i,
l_pSet->m_szApiName,
l_pSet->m_byDispatchType,
l_pSet->m_byApiHandle,
l_pSet->m_wNumMethods,
l_pSet->m_ppMethods,
l_pSet->m_pdwMethodSignatures,
l_pServer,
l_pServer? (*(LPTSTR*)
(l_pServer + PROCESS_NAME_OFFSET)) : _T("") );
//If this API is served by an application - get it's
//address, if it is served by the kernel - use address 0
DWORD l_dwBaseAddress = 0;
if(l_pServer)
{
l_dwBaseAddress = ProcessAddress
(*(l_pServer + PROCESS_NUM_OFFSET));
}
//Add the base address to the method and signature
//tables pointers
PFNVOID * l_ppMethods = l_pSet->m_ppMethods;
if(l_ppMethods && (DWORD)l_ppMethods < 0x2000000)
{
l_ppMethods = (PFNVOID *)
((DWORD)l_ppMethods + l_dwBaseAddress);
}
DWORD * l_pdwMethodSignatures =
l_pSet->m_pdwMethodSignatures;
if(l_pdwMethodSignatures &&
(DWORD)l_pdwMethodSignatures < 0x2000000)
{
l_pdwMethodSignatures = (DWORD *)
((DWORD)l_pdwMethodSignatures +
l_dwBaseAddress);
}
if(l_ppMethods)
{
for(int j = 0; j < l_pSet->m_wNumMethods; j++)
{
PFNVOID l_pMethod = l_ppMethods?
l_ppMethods[j] : 0;
if(l_pMethod && (DWORD)l_pMethod < 0x2000000)
{
l_pMethod = (PFNVOID)
((DWORD)l_pMethod + l_dwBaseAddress);
}
DWORD l_dwSign = l_pdwMethodSignatures?
l_pdwMethodSignatures[j] : 0;
HTRACE(TG_InterceptedInfo,
_T("meth #%x: %x sign %x\n"),
j,
l_pMethod,
l_dwSign);
}
}
}//for(int i = 0; i < NUM_SYSTEM_SETS; i++)
}
__except(1)
{
HTRACE(TG_Error, _T("Exception in DumpApis"));
}
SetKMode(FALSE);
if(l_dwOldPermissions)
{
SetProcPermissions(l_dwOldPermissions);
}
}//void DumpApis()
/*-------------------------------------------------------------------
FUNCTION: DllMain
PURPOSE: Regular DLL initialization point. Used to initialize
per-process data structures, such as the tracing engine
-------------------------------------------------------------------*/
BOOL WINAPI DllMain(HANDLE hInstance, DWORD dwReason,
LPVOID /*lpReserved*/)
{
static long s_lLoadCount = 0;
DWORD l_dwProcessId = GetCurrentProcessId();
DWORD l_dwIdx = GetProcessIndexFromID((HANDLE)l_dwProcessId);
PROCESSENTRY32 * l_pEntry = &g_SpyEngine.m_Processes[l_dwIdx];
TCHAR l_szPath[_MAX_PATH];
GetModuleFileName(NULL, l_szPath, _MAX_PATH);
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
{
g_hInst = (HINSTANCE)hInstance;
if(InterlockedIncrement(&s_lLoadCount) == 1)
{
TraceInitialize();
//Show errors and warnings on the
//debugger's log window and in message boxes.
TraceAssignGroupsToStream(
TO_DebugMonitor | TO_MessageBox,
TG_MessageBox | TG_Error, (DWORD)-1);
//Print important messages to the debug monitor
TraceAssignGroupsToStream(TO_DebugMonitor,
TG_PrintAlways, TG_PrintAlways);
//Allocate a memory buffer and print
//intercepted trace to it
TraceUseMemMapFileBuffer(s_szTraceMapFile,
TRACE_SIZE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -