├── .gitattributes ├── .gitignore ├── 2.TXT ├── ApiSpy ├── ApiSpy.cpp ├── ApiSpy.vcproj ├── CeApiSpy.rc ├── TrcView.cpp └── resource.h ├── ApiSpyDLL ├── ApiSpyDLL.sln └── ApiSpyDLL.vcproj ├── common ├── HTrace.cpp ├── HTrace.h ├── Interceptors.cpp ├── SpyControl.h ├── SpyEngine.cpp ├── SpyEngine.h └── SysDecls.h ├── coredll.list.txt ├── mwinreg.h ├── name_wince_syscalls.idc └── psyscall.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ################# 2 | ## Eclipse 3 | ################# 4 | 5 | *.pydevproject 6 | .project 7 | .metadata 8 | bin/ 9 | tmp/ 10 | *.tmp 11 | *.bak 12 | *.swp 13 | *~.nib 14 | local.properties 15 | .classpath 16 | .settings/ 17 | .loadpath 18 | 19 | # External tool builders 20 | .externalToolBuilders/ 21 | 22 | # Locally stored "Eclipse launch configurations" 23 | *.launch 24 | 25 | # CDT-specific 26 | .cproject 27 | 28 | # PDT-specific 29 | .buildpath 30 | 31 | 32 | ################# 33 | ## Visual Studio 34 | ################# 35 | 36 | ## Ignore Visual Studio temporary files, build results, and 37 | ## files generated by popular Visual Studio add-ons. 38 | 39 | # User-specific files 40 | *.suo 41 | *.user 42 | *.sln.docstates 43 | 44 | # Build results 45 | 46 | [Dd]ebug/ 47 | [Rr]elease/ 48 | x64/ 49 | build/ 50 | [Bb]in/ 51 | [Oo]bj/ 52 | 53 | # MSTest test Results 54 | [Tt]est[Rr]esult*/ 55 | [Bb]uild[Ll]og.* 56 | 57 | *_i.c 58 | *_p.c 59 | *.ilk 60 | *.meta 61 | *.obj 62 | *.pch 63 | *.pdb 64 | *.pgc 65 | *.pgd 66 | *.rsp 67 | *.sbr 68 | *.tlb 69 | *.tli 70 | *.tlh 71 | *.tmp 72 | *.tmp_proj 73 | *.log 74 | *.vspscc 75 | *.vssscc 76 | .builds 77 | *.pidb 78 | *.log 79 | *.scc 80 | 81 | # Visual C++ cache files 82 | ipch/ 83 | *.aps 84 | *.ncb 85 | *.opensdf 86 | *.sdf 87 | *.cachefile 88 | 89 | # Visual Studio profiler 90 | *.psess 91 | *.vsp 92 | *.vspx 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | 101 | # TeamCity is a build add-in 102 | _TeamCity* 103 | 104 | # DotCover is a Code Coverage Tool 105 | *.dotCover 106 | 107 | # NCrunch 108 | *.ncrunch* 109 | .*crunch*.local.xml 110 | 111 | # Installshield output folder 112 | [Ee]xpress/ 113 | 114 | # DocProject is a documentation generator add-in 115 | DocProject/buildhelp/ 116 | DocProject/Help/*.HxT 117 | DocProject/Help/*.HxC 118 | DocProject/Help/*.hhc 119 | DocProject/Help/*.hhk 120 | DocProject/Help/*.hhp 121 | DocProject/Help/Html2 122 | DocProject/Help/html 123 | 124 | # Click-Once directory 125 | publish/ 126 | 127 | # Publish Web Output 128 | *.Publish.xml 129 | *.pubxml 130 | 131 | # NuGet Packages Directory 132 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 133 | #packages/ 134 | 135 | # Windows Azure Build Output 136 | csx 137 | *.build.csdef 138 | 139 | # Windows Store app package directory 140 | AppPackages/ 141 | 142 | # Others 143 | sql/ 144 | *.Cache 145 | ClientBin/ 146 | [Ss]tyle[Cc]op.* 147 | ~$* 148 | *~ 149 | *.dbmdl 150 | *.[Pp]ublish.xml 151 | *.pfx 152 | *.publishsettings 153 | 154 | # RIA/Silverlight projects 155 | Generated_Code/ 156 | 157 | # Backup & report files from converting an old project file to a newer 158 | # Visual Studio version. Backup files are not needed, because we have git ;-) 159 | _UpgradeReport_Files/ 160 | Backup*/ 161 | UpgradeLog*.XML 162 | UpgradeLog*.htm 163 | 164 | # SQL Server files 165 | App_Data/*.mdf 166 | App_Data/*.ldf 167 | 168 | ############# 169 | ## Windows detritus 170 | ############# 171 | 172 | # Windows image file caches 173 | Thumbs.db 174 | ehthumbs.db 175 | 176 | # Folder config file 177 | Desktop.ini 178 | 179 | # Recycle Bin used on file shares 180 | $RECYCLE.BIN/ 181 | 182 | # Mac crap 183 | .DS_Store 184 | 185 | 186 | ############# 187 | ## Python 188 | ############# 189 | 190 | *.py[co] 191 | 192 | # Packages 193 | *.egg 194 | *.egg-info 195 | dist/ 196 | build/ 197 | eggs/ 198 | parts/ 199 | var/ 200 | sdist/ 201 | develop-eggs/ 202 | .installed.cfg 203 | 204 | # Installer logs 205 | pip-log.txt 206 | 207 | # Unit test / coverage reports 208 | .coverage 209 | .tox 210 | 211 | #Translations 212 | *.mo 213 | 214 | #Mr Developer 215 | .mr.developer.cfg 216 | -------------------------------------------------------------------------------- /2.TXT: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hjgode/ApiSpy/05f90b14c21345c7ecf9f3c7ca881d8ea5638cf0/2.TXT -------------------------------------------------------------------------------- /ApiSpy/ApiSpy.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************** 2 | Module : ApiSpy.cpp - part of ApiSpy implementation 3 | Written 2003 by Dmitri Leman 4 | for an article about CE Api Spy. 5 | Purpose: Contains CE Api Spy GUI implementation 6 | 7 | This file was compiled using eMbedded Visual C++ 3.0 8 | with Pocket PC 2002 SDK and 4.0 with Standard SDK. 9 | ********************************************************************/ 10 | 11 | #include 12 | #include 13 | #ifdef WIN32_PLATFORM_PSPC 14 | #include 15 | #pragma comment (lib,"aygshell.lib") 16 | #else 17 | #include 18 | #endif 19 | 20 | #include "Resource.h" 21 | #include "../common/SpyEngine.h" 22 | #include "../common/HTrace.h" 23 | #include "../common/SpyControl.h" 24 | #include "../common/SysDecls.h" 25 | 26 | #define TRACE_SIZE 0x100000 27 | 28 | static const TCHAR s_szTitle[] = _T("ApiSpy"); 29 | static const TCHAR s_szClass[] = _T("ApiSpyClass"); 30 | static const TCHAR s_szTraceViewClass[] = _T("ApiSpyTraceClass"); 31 | 32 | 33 | typedef BOOL T_StartSpy(); 34 | typedef BOOL T_StopSpy(); 35 | typedef void T_DumpApis(); 36 | 37 | T_StartSpy * g_pStartSpy = NULL; 38 | T_StopSpy * g_pStopSpy = NULL; 39 | T_DumpApis * g_pDumpApis = NULL; 40 | 41 | HINSTANCE g_hInstExe = NULL, g_hInstSpyDll = NULL; 42 | HWND g_hWndMain = NULL, g_hWndTrace = NULL, g_hWndMenuBar = NULL; 43 | int g_iOptionsMenuPos = 4; 44 | HMENU g_hOptionsMenu = NULL; 45 | DWORD g_dwCheckedGroups = 0; 46 | 47 | /*------------------------------------------------------------------- 48 | FUNCTION: LoadSpyDLL 49 | PURPOSE: Load Spy DLL 50 | RETURNS: 51 | TRUE on success, FALSE on failure 52 | -------------------------------------------------------------------*/ 53 | BOOL LoadSpyDLL() 54 | { 55 | if(g_hInstSpyDll) 56 | return TRUE; 57 | g_hInstSpyDll = LoadLibrary(s_szApiSpyDll); 58 | if(!g_hInstSpyDll) 59 | { 60 | HTRACE(TG_MessageBox, 61 | _T("ERROR: failed to load SpyDLL %s. Err %d"), 62 | s_szApiSpyDll, GetLastError()); 63 | return FALSE; 64 | } 65 | g_pStartSpy = (T_StartSpy*)GetProcAddress 66 | (g_hInstSpyDll, _T("StartSpy")); 67 | g_pStopSpy = (T_StopSpy*)GetProcAddress 68 | (g_hInstSpyDll, _T("StopSpy")); 69 | g_pDumpApis = (T_DumpApis*)GetProcAddress 70 | (g_hInstSpyDll, _T("DumpApis")); 71 | if(!g_pStartSpy || !g_pStopSpy || !g_pDumpApis) 72 | { 73 | HTRACE(TG_MessageBox, 74 | _T("ERROR: failed to get SpyDLL routines")); 75 | return FALSE; 76 | } 77 | return TRUE; 78 | }//BOOL LoadSpyDLL() 79 | 80 | /*------------------------------------------------------------------- 81 | FUNCTION: StartSpy 82 | PURPOSE: Load Spy DLL and call StartSpy to start monitoring 83 | RETURNS: 84 | TRUE on success, FALSE on failure 85 | -------------------------------------------------------------------*/ 86 | BOOL StartSpy() 87 | { 88 | if(!g_hInstSpyDll) 89 | { 90 | LoadSpyDLL(); 91 | } 92 | if(!g_pStartSpy) 93 | { 94 | return FALSE; 95 | } 96 | return g_pStartSpy(); 97 | } 98 | 99 | /*------------------------------------------------------------------- 100 | FUNCTION: StopSpy 101 | PURPOSE: call StopSpy to stop monitoring and unload Spy DLL 102 | RETURNS: 103 | TRUE on success, FALSE on failure 104 | -------------------------------------------------------------------*/ 105 | BOOL StopSpy() 106 | { 107 | if(!g_hInstSpyDll) 108 | { 109 | return TRUE;//If DLL was not loaded, don't need to stop 110 | } 111 | if(!g_pStopSpy) 112 | { 113 | return FALSE; 114 | } 115 | if(!g_pStopSpy()) 116 | { 117 | return FALSE; 118 | } 119 | if(g_hInstSpyDll) 120 | { 121 | FreeLibrary(g_hInstSpyDll); 122 | g_hInstSpyDll = NULL; 123 | } 124 | return TRUE; 125 | } 126 | 127 | /*------------------------------------------------------------------- 128 | FUNCTION: DumpApis 129 | PURPOSE: Load Spy DLL and call DumpApis to dump all system APIs 130 | -------------------------------------------------------------------*/ 131 | void DumpApis() 132 | { 133 | if(!g_hInstSpyDll) 134 | { 135 | LoadSpyDLL(); 136 | } 137 | if(!g_pDumpApis) 138 | { 139 | return; 140 | } 141 | g_pDumpApis(); 142 | } 143 | 144 | /*------------------------------------------------------------------- 145 | FUNCTION: OnSave 146 | PURPOSE: Display Save File dialog and save trace buffer to a file 147 | -------------------------------------------------------------------*/ 148 | void OnSave(HWND p_hWndOwner) 149 | { 150 | OPENFILENAME l_Open; 151 | TCHAR l_szBuffer[_MAX_PATH]; 152 | *l_szBuffer = 0; 153 | memset(&l_Open, 0, sizeof(l_Open)); 154 | l_Open.lStructSize = sizeof(l_Open); 155 | l_Open.hwndOwner = p_hWndOwner; 156 | l_Open.lpstrFilter = _T("Text files\0*.TXT\0All files\0*.*\0"); 157 | l_Open.lpstrFile = l_szBuffer; 158 | l_Open.nMaxFile = _MAX_PATH; 159 | l_Open.lpstrTitle = _T("Save trace buffer"); 160 | if(!GetSaveFileName(&l_Open)) 161 | return; 162 | TraceDumpBufferToFile(l_szBuffer); 163 | } 164 | 165 | /*------------------------------------------------------------------- 166 | FUNCTION: OnCreateWindow 167 | PURPOSE: Handle WM_CREATE message. Create menu bar and trace 168 | view window. 169 | RETURNS: 170 | TRUE on success, FALSE on failure 171 | -------------------------------------------------------------------*/ 172 | BOOL OnCreateWindow 173 | ( 174 | HWND p_hWnd, 175 | UINT p_uiMsg, 176 | WPARAM p_wParam, 177 | LPARAM p_lParam 178 | ) 179 | { 180 | g_hWndMain = p_hWnd; 181 | g_hWndTrace = CreateWindowEx(0, s_szTraceViewClass, NULL, 182 | WS_CHILD | WS_VISIBLE, 0, 0, 0, 0, 183 | g_hWndMain, NULL, NULL, NULL); 184 | #ifdef WIN32_PLATFORM_PSPC 185 | // Create a Done button and size it. 186 | SHINITDLGINFO l_InitInfo; 187 | 188 | l_InitInfo.dwMask = SHIDIM_FLAGS; 189 | l_InitInfo.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIZEDLG; 190 | l_InitInfo.hDlg = p_hWnd; 191 | SHInitDialog(&l_InitInfo); 192 | 193 | SHMENUBARINFO l_MenuBarInfo; 194 | memset(&l_MenuBarInfo, 0, sizeof(SHMENUBARINFO)); 195 | l_MenuBarInfo.cbSize = sizeof(l_MenuBarInfo); 196 | l_MenuBarInfo.hwndParent = p_hWnd; 197 | l_MenuBarInfo.dwFlags = 0; 198 | l_MenuBarInfo.nToolBarId = IDR_MENUBAR; 199 | l_MenuBarInfo.hInstRes = g_hInstExe; 200 | if(!SHCreateMenuBar(&l_MenuBarInfo)) 201 | { 202 | HTRACE(TG_MessageBox, 203 | _T("Warning: SHCreateMenuBar failed. Error = %d\r\n"), 204 | GetLastError()); 205 | } 206 | g_hWndMenuBar = l_MenuBarInfo.hwndMB; 207 | HMENU l_hMenu = (HMENU) 208 | SendMessage(g_hWndMenuBar, SHCMBM_GETSUBMENU, 0,IDC_OPTIONS); 209 | #else 210 | g_hWndMenuBar = CommandBar_Create(g_hInstExe, p_hWnd, 1); 211 | if(!g_hWndMenuBar) 212 | { 213 | HTRACE(TG_MessageBox, 214 | _T("Warning: CommandBar_Create failed. Error = %d\r\n"), 215 | GetLastError()); 216 | return FALSE; 217 | } 218 | if(!CommandBar_InsertMenubar(g_hWndMenuBar, 219 | g_hInstExe, IDR_MENUBAR, 0)) 220 | { 221 | HTRACE(TG_MessageBox, 222 | _T("Warning: CommandBar_InsertMenubar failed. ") 223 | _T("Error = %d\r\n"), 224 | GetLastError()); 225 | } 226 | CommandBar_AddAdornments(g_hWndMenuBar, 0, 0); 227 | CommandBar_Show(g_hWndMenuBar, TRUE); 228 | 229 | g_hOptionsMenu = CommandBar_GetMenu(g_hWndMenuBar, 0); 230 | g_hOptionsMenu = GetSubMenu(g_hOptionsMenu, g_iOptionsMenuPos); 231 | 232 | DWORD l_dwStyle = GetWindowLong(p_hWnd, GWL_STYLE); 233 | SetWindowLong(p_hWnd, GWL_STYLE, l_dwStyle & ~WS_CAPTION); 234 | ShowWindow(p_hWnd, SW_SHOWMAXIMIZED); 235 | HMENU l_hMenu = g_hOptionsMenu; 236 | #endif 237 | DWORD l_dwGroupsDebug = 238 | TraceGetAssignedGroupsToStream(TO_DebugMonitor); 239 | DWORD l_dwGroupsMem = 240 | TraceGetAssignedGroupsToStream(TO_MemoryBuffer); 241 | g_dwCheckedGroups = (l_dwGroupsDebug | l_dwGroupsMem) & 242 | (TG_InterceptedInfo | TG_DebugSpyBrief | 243 | TG_DebugSpyDetailed); 244 | CheckMenuItem(l_hMenu, IDC_TRACE_INTERCEPTED, MF_BYCOMMAND | 245 | (g_dwCheckedGroups & TG_InterceptedInfo)? 246 | MF_CHECKED : MF_UNCHECKED); 247 | CheckMenuItem(l_hMenu, IDC_TRACE_SPY_BRIEF, MF_BYCOMMAND | 248 | (g_dwCheckedGroups & TG_DebugSpyBrief)? 249 | MF_CHECKED : MF_UNCHECKED); 250 | CheckMenuItem(l_hMenu, IDC_TRACE_SPY_DETAILED, MF_BYCOMMAND | 251 | (g_dwCheckedGroups & TG_DebugSpyDetailed)? 252 | MF_CHECKED : MF_UNCHECKED); 253 | CheckMenuItem(l_hMenu, IDC_OUTPUT_MEM, MF_BYCOMMAND | 254 | (l_dwGroupsMem & TG_InterceptedInfo)? 255 | MF_CHECKED : MF_UNCHECKED); 256 | CheckMenuItem(l_hMenu, IDC_OUTPUT_DEBUG, MF_BYCOMMAND | 257 | (l_dwGroupsDebug & TG_InterceptedInfo)? 258 | MF_CHECKED : MF_UNCHECKED); 259 | return TRUE; 260 | }//BOOL OnCreateWindow 261 | 262 | /*------------------------------------------------------------------- 263 | FUNCTION: OnSize 264 | PURPOSE: Handle WM_SIZE message. Resize menu bar and trace view 265 | -------------------------------------------------------------------*/ 266 | void OnSize 267 | ( 268 | int p_iWidth, 269 | int p_iHeight 270 | ) 271 | { 272 | #ifdef WIN32_PLATFORM_PSPC 273 | int l_iMenuHeight = 0; 274 | #else 275 | if(!g_hWndMenuBar) 276 | return; 277 | int l_iMenuHeight = CommandBar_Height(g_hWndMenuBar); 278 | SetWindowPos(g_hWndMenuBar, NULL, 0, 0, 279 | p_iWidth, l_iMenuHeight, SWP_NOZORDER); 280 | #endif 281 | SetWindowPos(g_hWndTrace, NULL, 0, l_iMenuHeight, 282 | p_iWidth, p_iHeight - l_iMenuHeight, SWP_NOZORDER); 283 | } 284 | 285 | /*------------------------------------------------------------------- 286 | FUNCTION: CheckTraceOption 287 | PURPOSE: Handle check boxes in the Options menu to enable/disable 288 | different trace groups and outputs. 289 | PARAMETERS: 290 | int p_iID - menu item ID 291 | BOOL p_bChangeGroups - TRUE to change groups, FALSE - outputs 292 | DWORD p_dwTraceOutputs - which outputs to change 293 | DWORD p_dwTraceGroups - which trace groups to toggle 294 | -------------------------------------------------------------------*/ 295 | void CheckTraceOption 296 | ( 297 | int p_iID, 298 | BOOL p_bChangeGroups, 299 | DWORD p_dwTraceOutputs, 300 | DWORD p_dwTraceGroups 301 | ) 302 | { 303 | #ifdef WIN32_PLATFORM_PSPC 304 | HMENU l_hMenu = (HMENU) 305 | SendMessage(g_hWndMenuBar, SHCMBM_GETSUBMENU, 0, IDC_OPTIONS); 306 | #else 307 | HMENU l_hMenu = g_hOptionsMenu; 308 | #endif 309 | DWORD l_dwState = CheckMenuItem(l_hMenu, p_iID, MF_BYCOMMAND); 310 | if(l_dwState & MF_CHECKED) 311 | { 312 | CheckMenuItem(l_hMenu, p_iID, MF_BYCOMMAND | MF_UNCHECKED); 313 | TraceAssignGroupsToStream(p_dwTraceOutputs, 314 | 0, p_dwTraceGroups);//Clear groups 315 | if(p_bChangeGroups) 316 | { 317 | g_dwCheckedGroups &= ~p_dwTraceGroups; 318 | } 319 | } 320 | else 321 | { 322 | CheckMenuItem(l_hMenu, p_iID, MF_BYCOMMAND | MF_CHECKED); 323 | TraceAssignGroupsToStream(p_dwTraceOutputs, 324 | p_dwTraceGroups, p_dwTraceGroups);//set groups 325 | if(p_bChangeGroups) 326 | { 327 | g_dwCheckedGroups |= p_dwTraceGroups; 328 | } 329 | } 330 | //Save changes 331 | TraceReadWriteSettings(HKEY_CURRENT_USER, s_szSettingsRegPath, 332 | true, p_dwTraceOutputs); 333 | } 334 | 335 | /*------------------------------------------------------------------- 336 | FUNCTION: OnCommand 337 | PURPOSE: Handle WM_COMMAND message. 338 | -------------------------------------------------------------------*/ 339 | void OnCommand 340 | ( 341 | HWND p_hWnd, 342 | UINT p_uiMsg, 343 | WPARAM p_wParam, 344 | LPARAM p_lParam 345 | ) 346 | { 347 | WORD l_wNotifyCode = HIWORD(p_wParam); 348 | WORD l_wID = LOWORD(p_wParam); 349 | 350 | switch(l_wID) 351 | { 352 | case IDOK: 353 | case IDCANCEL: 354 | if(!StopSpy()) 355 | { 356 | HTRACE(TG_MessageBox, 357 | _T("Cannot exit because hook(s) are still in use.") 358 | _T("Try terminating running applications to ") 359 | _T("release hooks.")); 360 | return; 361 | } 362 | DestroyWindow(p_hWnd); 363 | break; 364 | case IDC_START: 365 | StopSpy(); 366 | StartSpy(); 367 | break; 368 | case IDC_OPTIONS_EXIT: 369 | StopSpy(); 370 | PostQuitMessage(1); 371 | break; 372 | case IDC_STOP: 373 | StopSpy(); 374 | break; 375 | case IDC_DUMP_APIS: 376 | DumpApis(); 377 | break; 378 | case IDC_SAVE: 379 | OnSave(p_hWnd); 380 | break; 381 | case IDC_TRACE_INTERCEPTED: 382 | CheckTraceOption(IDC_TRACE_INTERCEPTED, TRUE, 383 | TO_DebugMonitor | TO_MemoryBuffer, TG_InterceptedInfo); 384 | break; 385 | case IDC_TRACE_SPY_BRIEF: 386 | CheckTraceOption(IDC_TRACE_SPY_BRIEF, TRUE, 387 | TO_DebugMonitor | TO_MemoryBuffer, TG_DebugSpyBrief); 388 | break; 389 | case IDC_TRACE_SPY_DETAILED: 390 | CheckTraceOption(IDC_TRACE_SPY_DETAILED, TRUE, 391 | TO_DebugMonitor | TO_MemoryBuffer, TG_DebugSpyDetailed); 392 | break; 393 | case IDC_OUTPUT_DEBUG: 394 | CheckTraceOption(IDC_OUTPUT_DEBUG, FALSE, 395 | TO_DebugMonitor, g_dwCheckedGroups); 396 | break; 397 | } 398 | }//void OnCommand 399 | 400 | /*------------------------------------------------------------------- 401 | FUNCTION: WindowProc 402 | PURPOSE: Window procedure for the main GUI window 403 | -------------------------------------------------------------------*/ 404 | LRESULT CALLBACK WindowProc 405 | ( 406 | HWND p_hWnd, 407 | UINT p_uiMsg, 408 | WPARAM p_wParam, 409 | LPARAM p_lParam 410 | ) 411 | { 412 | switch(p_uiMsg) 413 | { 414 | case WM_CREATE: 415 | OnCreateWindow(p_hWnd, p_uiMsg, p_wParam, p_lParam); 416 | break; 417 | case WM_SIZE: 418 | OnSize(LOWORD(p_lParam), HIWORD(p_lParam)); 419 | break; 420 | case WM_COMMAND: 421 | OnCommand(p_hWnd, p_uiMsg, p_wParam, p_lParam); 422 | break; 423 | case WM_CLOSE: 424 | DestroyWindow(p_hWnd); 425 | break; 426 | case WM_DESTROY: 427 | PostQuitMessage(1); 428 | break; 429 | } 430 | return DefWindowProc(p_hWnd, p_uiMsg, p_wParam, p_lParam); 431 | } 432 | 433 | /*------------------------------------------------------------------- 434 | FUNCTION: WinMain 435 | PURPOSE: Application entry point 436 | -------------------------------------------------------------------*/ 437 | int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 438 | LPWSTR lpCmdLine, int nShowCmd ) 439 | { 440 | HWND l_hWnd = FindWindow(s_szClass, NULL); 441 | if(l_hWnd) 442 | { 443 | SetForegroundWindow(l_hWnd); 444 | return 0; 445 | } 446 | TraceInitialize(); 447 | 448 | //Show errors and warnings on the 449 | //debugger's log window and in message boxes. 450 | TraceAssignGroupsToStream(TO_DebugMonitor | TO_MessageBox, 451 | TG_MessageBox | TG_Error, (DWORD)-1); 452 | 453 | //Print important messages to the debug monitor 454 | TraceAssignGroupsToStream(TO_DebugMonitor, 455 | TG_PrintAlways, TG_PrintAlways); 456 | 457 | //Allocate a memory buffer and print intercepted trace to it 458 | TraceUseMemMapFileBuffer(s_szTraceMapFile, TRACE_SIZE, 459 | TG_MessageBox | TG_Error | 460 | TG_InterceptedInfo | TG_PrintAlways, (DWORD)-1); 461 | 462 | //After we assigned default values, read current settings from 463 | //registry 464 | TraceReadWriteSettings(HKEY_CURRENT_USER, s_szSettingsRegPath, 465 | false, TO_DebugMonitor | TO_MemoryBuffer); 466 | 467 | g_hInstExe = hInstance; 468 | 469 | //Register trace viewer window 470 | RegisterTraceView(s_szTraceViewClass); 471 | 472 | WNDCLASS l_Class; 473 | memset(&l_Class, 0, sizeof(l_Class)); 474 | l_Class.lpfnWndProc = WindowProc; 475 | l_Class.lpszClassName = s_szClass; 476 | RegisterClass(&l_Class); 477 | 478 | CreateWindowEx(0, s_szClass, s_szTitle, WS_VISIBLE, 479 | CW_DEFAULT, CW_DEFAULT, CW_DEFAULT, CW_DEFAULT, 480 | NULL, NULL, NULL, NULL); 481 | 482 | MSG l_Msg; 483 | while(GetMessage(&l_Msg, NULL, 0, 0)) 484 | { 485 | TranslateMessage(&l_Msg); 486 | DispatchMessage(&l_Msg); 487 | } 488 | 489 | StopSpy(); 490 | 491 | HTRACE(TG_DebugSpyBrief, _T("Before TraceUnInitialize")); 492 | TraceUnInitialize(); 493 | return 0; 494 | }//int WINAPI WinMain 495 | -------------------------------------------------------------------------------- /ApiSpy/ApiSpy.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 26 | 29 | 32 | 35 | 38 | 41 | 52 | 55 | 61 | 64 | 79 | 82 | 85 | 88 | 91 | 94 | 97 | 103 | 105 | 106 | 113 | 116 | 119 | 122 | 125 | 128 | 139 | 142 | 148 | 151 | 167 | 170 | 173 | 176 | 179 | 182 | 185 | 191 | 193 | 194 | 195 | 196 | 197 | 198 | 203 | 206 | 207 | 210 | 211 | 214 | 215 | 218 | 219 | 222 | 223 | 224 | 229 | 232 | 233 | 236 | 237 | 240 | 241 | 244 | 245 | 246 | 251 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | -------------------------------------------------------------------------------- /ApiSpy/CeApiSpy.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #include "resource.h" 4 | 5 | #define APSTUDIO_READONLY_SYMBOLS 6 | ///////////////////////////////////////////////////////////////////////////// 7 | // 8 | // Generated from the TEXTINCLUDE 2 resource. 9 | // 10 | #include "windows.h" 11 | #include 12 | #define I_IMAGENONE (-2) 13 | #define NOMENU 0xFFFF 14 | #define SHMENUBAR RCDATA 15 | 16 | ///////////////////////////////////////////////////////////////////////////// 17 | #undef APSTUDIO_READONLY_SYMBOLS 18 | 19 | ///////////////////////////////////////////////////////////////////////////// 20 | // English (U.S.) resources 21 | 22 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 23 | #ifdef _WIN32 24 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 25 | #pragma code_page(1252) 26 | #endif //_WIN32 27 | 28 | ///////////////////////////////////////////////////////////////////////////// 29 | // 30 | // Menu 31 | // 32 | 33 | IDR_MENUBAR MENU 34 | BEGIN 35 | MENUITEM "Start", IDC_START 36 | MENUITEM "Stop", IDC_STOP 37 | MENUITEM "Save", IDC_SAVE 38 | MENUITEM "ApiDump", IDC_DUMP_APIS 39 | POPUP "Options" 40 | BEGIN 41 | MENUITEM "Print intercepted info", IDC_TRACE_INTERCEPTED 42 | MENUITEM "Print Spy internal trace", IDC_TRACE_SPY_BRIEF 43 | MENUITEM "Print Spy detailed trace", IDC_TRACE_SPY_DETAILED 44 | MENUITEM SEPARATOR 45 | MENUITEM "Output to memory buffer", IDC_OUTPUT_MEM, GRAYED 46 | MENUITEM "Output to debug monitor", IDC_OUTPUT_DEBUG 47 | MENUITEM SEPARATOR 48 | MENUITEM "Exit", IDC_OPTIONS_EXIT 49 | END 50 | END 51 | 52 | 53 | ///////////////////////////////////////////////////////////////////////////// 54 | // 55 | // RCDATA 56 | // 57 | 58 | IDR_MENUBAR RCDATA 59 | BEGIN 60 | 0x0065, 0x0005, 0xfffe, 0x9c41, 0x0004, 0x0010, 0x9c43, 0x0000, 0x0000, 61 | 0xfffe, 0x9c44, 0x0004, 0x0010, 0x9c46, 0x0000, 0x0001, 0xfffe, 0x9c47, 62 | 0x0004, 0x0010, 0x9c49, 0x0000, 0x0002, 0xfffe, 0x9c54, 0x0004, 0x0010, 63 | 0x9c54, 0x0000, 0x0003, 0xfffe, 0x9c4c, 0x0004, 0x0018, 0x9c4e, 0x0000, 64 | 0x0004 65 | END 66 | 67 | 68 | #ifdef APSTUDIO_INVOKED 69 | ///////////////////////////////////////////////////////////////////////////// 70 | // 71 | // TEXTINCLUDE 72 | // 73 | 74 | 1 TEXTINCLUDE 75 | BEGIN 76 | "resource.h\0" 77 | END 78 | 79 | 2 TEXTINCLUDE 80 | BEGIN 81 | "#include ""windows.h""\r\n" 82 | "#include \r\n" 83 | "#define I_IMAGENONE (-2)\r\n" 84 | "#define NOMENU 0xFFFF\r\n" 85 | "#define SHMENUBAR RCDATA\r\n" 86 | "\0" 87 | END 88 | 89 | 3 TEXTINCLUDE 90 | BEGIN 91 | "\r\n" 92 | "\0" 93 | END 94 | 95 | #endif // APSTUDIO_INVOKED 96 | 97 | 98 | ///////////////////////////////////////////////////////////////////////////// 99 | // 100 | // String Table 101 | // 102 | 103 | STRINGTABLE 104 | BEGIN 105 | IDS_CAP_START "Start" 106 | IDS_CAP_STOP "Stop" 107 | IDS_CAP_SAVE "Save" 108 | IDS_CAP_OK "OK" 109 | IDS_CAP_OPTIONS "Options" 110 | END 111 | 112 | STRINGTABLE 113 | BEGIN 114 | IDS_CAP_DUMP_APIS "ApiDump" 115 | END 116 | 117 | #endif // English (U.S.) resources 118 | ///////////////////////////////////////////////////////////////////////////// 119 | 120 | 121 | 122 | #ifndef APSTUDIO_INVOKED 123 | ///////////////////////////////////////////////////////////////////////////// 124 | // 125 | // Generated from the TEXTINCLUDE 3 resource. 126 | // 127 | 128 | 129 | ///////////////////////////////////////////////////////////////////////////// 130 | #endif // not APSTUDIO_INVOKED 131 | 132 | -------------------------------------------------------------------------------- /ApiSpy/TrcView.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************** 2 | Module : TrcView.cpp - trace buffer viewer 3 | Written 2000,2003 by Dmitri Leman 4 | for an article in C/C++ journal about a tracing framework. 5 | Purpose: A part of the tracer framework. 6 | ********************************************************************/ 7 | #ifdef TRACE_ //{ 8 | 9 | #if defined WIN32 10 | #include 11 | #include 12 | #include "HTrace.h" 13 | 14 | #elif defined(_WIN32_WCE) 15 | 16 | #include 17 | #include "resource.h" 18 | #include "../common/HTrace.h" 19 | 20 | #elif defined(__linux__) 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include "HTrace.h" 28 | 29 | //This module was ported from WIN32 to ncurses. 30 | //Therefore, I included few declarations, which allows 31 | //some WIN32-specific to compile under linux. 32 | typedef WINDOW * HDC; 33 | typedef WINDOW * HWND; 34 | typedef int BOOL; 35 | #define __int64 long long 36 | typedef struct {int left, top, right, bottom;} RECT; 37 | void DrawText( 38 | WINDOW * p_pWindow, const char * p_pszBuffer, 39 | int p_iNumBytes, RECT * p_pPaintRect, int p_iFlags) 40 | { 41 | int l_iRes = 42 | mvwaddnstr(stdscr, 0,0, p_pszBuffer, p_iNumBytes); 43 | wclrtobot(p_pWindow); 44 | } 45 | static ULONG GetTickCount() 46 | { 47 | clock_t l_Clock = clock(); 48 | return (ULONG)(((__int64)l_Clock) * 1000 / CLOCKS_PER_SEC); 49 | } 50 | #define SB_VERT 1 51 | #define SB_THUMBTRACK 1 52 | #define SB_LINEUP 2 53 | #define SB_LINEDOWN 3 54 | #define SB_PAGEUP 4 55 | #define SB_PAGEDOWN 5 56 | #define SB_TOP 6 57 | #define SB_BOTTOM 7 58 | 59 | #define _snprintf snprintf 60 | #endif 61 | 62 | 63 | static const char s_szCaption[] = "Trace Viewer"; 64 | 65 | static char s_szFullINIPath[_MAX_PATH]; 66 | 67 | #define MAX_ROW_LEN 256 68 | #define NUM_EXTRA_ROWS 2 69 | 70 | struct BufferViewer 71 | { 72 | LocalTraceBufferPointers * m_pBufferPointers; 73 | 74 | HWND m_hWnd; 75 | 76 | #ifdef WIN32 77 | HFONT m_hFont; 78 | int m_iFontHeight; 79 | int m_iFontWidth; 80 | int m_iLogicalWidthChars; 81 | int m_iLogicalWidthPixels; 82 | #endif 83 | 84 | LPTSTR m_pBuffer; 85 | int m_iBufferSize; 86 | int m_iNumLines; 87 | int m_iFirstPaintIndex; 88 | int m_iNumBytesPainted; 89 | int m_iFirstViewPosWhenPainted; 90 | int m_iNumLinesPainted; 91 | int m_iFirstRowLength; 92 | int m_iTotalNumCharsWhenPainted; 93 | int m_iScrollChanged; 94 | int m_iScrollChangedWhenPainted; 95 | 96 | int m_iHorzPos; 97 | int m_iCharShownFirst; 98 | int m_iLineOffset; 99 | bool m_bStickToEnd; 100 | bool m_bMoveToStartNextTime; 101 | 102 | RECT m_ClientRect; 103 | RECT m_PaintRect; 104 | int m_iNumLinesInClientArea; 105 | 106 | BufferViewer(HWND p_hWnd) 107 | { 108 | m_hWnd = p_hWnd; 109 | m_pBufferPointers = NULL; 110 | #ifdef WIN32 111 | m_hFont = 0; 112 | m_iFontHeight = 0; 113 | m_iFontWidth = 0; 114 | m_iLogicalWidthChars = 0; 115 | m_iLogicalWidthPixels = 0; 116 | #endif 117 | m_pBuffer = NULL; 118 | m_iBufferSize = 0; 119 | m_iNumLines = 0; 120 | m_iFirstPaintIndex = -1; 121 | m_iNumBytesPainted = -1; 122 | m_iFirstViewPosWhenPainted = -1; 123 | m_iTotalNumCharsWhenPainted = -1; 124 | m_iNumLinesPainted = 0; 125 | m_iFirstRowLength = 0; 126 | m_iScrollChanged = 0; 127 | m_iScrollChangedWhenPainted = -1; 128 | m_iHorzPos = 0; 129 | m_iCharShownFirst = 0; 130 | m_iLineOffset = 0; 131 | m_bStickToEnd = true; 132 | m_bMoveToStartNextTime = false; 133 | m_iNumLinesInClientArea = 0; 134 | #ifdef __linux__ 135 | m_iInvalidated = 0; 136 | m_iScrollMin = 0; 137 | m_iScrollMax = 0; 138 | m_iScrollPos = 0; 139 | m_pWndStatus = NULL; 140 | m_pWndHelp = NULL; 141 | #endif 142 | } 143 | void PaintBufferWithCopy 144 | ( 145 | HDC p_hDC, 146 | LPCTSTR p_pTraceBuffer, 147 | int p_lBufferSizeChars, 148 | int p_iFirstViewPos, 149 | int p_iLinesOffset, 150 | int p_iDataSizeAfterScrollPos, 151 | int p_iDataSizeBeforeScrollPos 152 | ); 153 | void PaintBuffer 154 | ( 155 | int p_iFirstViewPos, 156 | int p_iLinesOffset, 157 | HDC p_hDC, 158 | RECT * p_pPaintRect 159 | ); 160 | void UpdateScrollPos(); 161 | void OnPaint(); 162 | void OnSizeChanges(); 163 | void OnTimerMessage(); 164 | void OnScrollMessage 165 | ( 166 | int p_nScrollBarType, 167 | int p_nScrollCode, 168 | int p_nPos, 169 | int p_nTrackPos, 170 | int p_nMin, 171 | int p_nMax 172 | ); 173 | #ifdef __linux__ 174 | //Few more routines to allow portions of WIN32 specific 175 | //code to run under ncurses 176 | void InvalidateRect(HWND,RECT*,BOOL) 177 | { 178 | m_iInvalidated++; 179 | } 180 | void GetScrollRange(HWND, int, int * p_piMin,int * p_piMax) 181 | { 182 | *p_piMin = m_iScrollMin; 183 | *p_piMax = m_iScrollMax; 184 | } 185 | void SetScrollRange(HWND, int,int p_iMin, int p_iMax,BOOL) 186 | { 187 | m_iScrollMin = p_iMin; 188 | m_iScrollMax = p_iMax; 189 | } 190 | void SetScrollPos(HWND, int, int p_iPos,BOOL) 191 | { 192 | m_iScrollPos = p_iPos; 193 | } 194 | int m_iInvalidated; 195 | int m_iScrollMin; 196 | int m_iScrollMax; 197 | int m_iScrollPos; 198 | WINDOW * m_pWndStatus; 199 | WINDOW * m_pWndHelp; 200 | #endif 201 | };//struct BufferViewer 202 | 203 | /*------------------------------------------------------------- 204 | 205 | FUNCTION: BufferViewer::PaintBufferWithCopy 206 | 207 | PURPOSE: Worker routine to copy a portion of a trace buffer 208 | to a local display buffer and paint it to the screen. 209 | PARAMETERS: 210 | HDC p_hDC - device context 211 | LPCTSTR p_pTraceBuffer - the whole circular buffer 212 | int p_lBufferSizeChars - total size of the buffer 213 | int p_iFirstViewPos - current scroll position 214 | int p_iLinesOffset - count p_iLinesOffset lines up or down 215 | from the current scroll position to 216 | find the first line to paint. 217 | int p_iDataSizeAfterScrollPos - number of valid bytes in the 218 | buffer before p_iCurByte 219 | int p_iDataSizeBeforeScrollPos - number of valid bytes in the 220 | buffer after p_iCurByte 221 | -------------------------------------------------------------*/ 222 | void BufferViewer::PaintBufferWithCopy 223 | ( 224 | HDC p_hDC, 225 | LPCTSTR p_pTraceBuffer, 226 | int p_lBufferSizeChars, 227 | int p_iFirstViewPos, 228 | int p_iLinesOffset, 229 | int p_iDataSizeAfterScrollPos, 230 | int p_iDataSizeBeforeScrollPos 231 | ) 232 | { 233 | int l_iSize = (m_iNumLinesInClientArea + NUM_EXTRA_ROWS) * 234 | MAX_ROW_LEN; 235 | if(m_iNumLines < m_iNumLinesInClientArea || !m_pBuffer) 236 | { 237 | //The worst uncertainty is the line width. 238 | //We will assume MAX_ROW_LEN = 256 byte line width. 239 | //Hopefully, most of lines will be shorter. 240 | //If most of lines will be longer than 256, 241 | //we will print fewer lines, than fit in window 242 | LPTSTR l_pBuff = (LPTSTR)malloc(l_iSize*sizeof(TCHAR)); 243 | if(l_pBuff == NULL) 244 | { 245 | HTRACE(TG_Error, 246 | _T("ERROR: malloc(%d) failed"), l_iSize); 247 | return; 248 | } 249 | free(m_pBuffer); 250 | m_pBuffer = l_pBuff; 251 | m_iBufferSize = l_iSize; 252 | m_iNumLines = m_iNumLinesInClientArea; 253 | }//if(m_iNumLines < m_iNumLinesInClientArea) 254 | 255 | //Now we need to copy memory from the trace buffer to the 256 | //screen buffer. 257 | //We need to start before the current position to find the 258 | //beginning of the line, which contains the current 259 | //position. 260 | int l_iLookBack = p_iLinesOffset < -1? 261 | (-p_iLinesOffset)*MAX_ROW_LEN : MAX_ROW_LEN; 262 | if(l_iLookBack + p_iDataSizeAfterScrollPos < l_iSize) 263 | { 264 | //If we have not enough data after the scroll point, 265 | //we need to look farther behind to avoid leaving blank 266 | //space (basically this means that the very last line should 267 | //be displayed at the bottom of the screen - not at the top) 268 | l_iLookBack = l_iSize - p_iDataSizeAfterScrollPos; 269 | } 270 | if(l_iLookBack > p_iDataSizeBeforeScrollPos) 271 | l_iLookBack = p_iDataSizeBeforeScrollPos; 272 | 273 | int l_iStartFromByteWithExtra = 274 | (p_iFirstViewPos - l_iLookBack) % p_lBufferSizeChars; 275 | int l_iDisplaySize = p_iDataSizeAfterScrollPos + l_iLookBack; 276 | if(l_iDisplaySize > l_iSize) 277 | l_iDisplaySize = l_iSize; 278 | int l_iLookForward = l_iDisplaySize; 279 | if(l_iStartFromByteWithExtra + l_iLookForward > 280 | p_lBufferSizeChars) 281 | { 282 | l_iLookForward = p_lBufferSizeChars - 283 | l_iStartFromByteWithExtra; 284 | memcpy(m_pBuffer, p_pTraceBuffer + 285 | l_iStartFromByteWithExtra, l_iLookForward*sizeof(TCHAR)); 286 | //The display area continues at the beginning of buffer 287 | memcpy(m_pBuffer + l_iLookForward, p_pTraceBuffer, 288 | (l_iDisplaySize - l_iLookForward)*sizeof(TCHAR)); 289 | } 290 | else 291 | { 292 | memcpy(m_pBuffer, p_pTraceBuffer + 293 | l_iStartFromByteWithExtra, l_iLookForward*sizeof(TCHAR)); 294 | } 295 | 296 | int i; 297 | int l_iNumLines = 0; 298 | int l_iBeginning = l_iLookBack; 299 | 300 | //First count lines after the current byte, which is at the 301 | //position l_iLookBack in the m_pBuffer 302 | int l_iEnd = l_iDisplaySize;//if we will not find newlines 303 | int l_iFirstLineEnd = l_iEnd; 304 | for(i = l_iLookBack; i < l_iDisplaySize; i++) 305 | { 306 | if(m_pBuffer[i] == '\n') 307 | { 308 | l_iEnd = i; 309 | if(l_iNumLines == 0) 310 | { 311 | l_iFirstLineEnd = i; 312 | } 313 | l_iNumLines++; 314 | if(l_iNumLines >= m_iNumLinesInClientArea) 315 | break; 316 | } 317 | } 318 | //Next look back until we find the beginning of the line, 319 | //which the current position belongs to. And look further 320 | //back if we have not enough lines already to fill screen. 321 | int l_iCountLinesBefore = p_iLinesOffset < 0? 322 | -p_iLinesOffset : 1; 323 | for(i = l_iLookBack-1; i >= 0; i--) 324 | { 325 | if(m_pBuffer[i] == '\n') 326 | { 327 | l_iBeginning = i+1; 328 | l_iNumLines++; 329 | if(--l_iCountLinesBefore <= 0 && 330 | l_iNumLines >= m_iNumLinesInClientArea) 331 | break; 332 | l_iFirstLineEnd = i; 333 | } 334 | } 335 | if(i < 0) 336 | {//Didn't find any newlines before the current position. 337 | l_iBeginning = 0; 338 | } 339 | 340 | m_iFirstPaintIndex = l_iBeginning; 341 | m_iNumBytesPainted = l_iEnd - l_iBeginning; 342 | DrawText(p_hDC, m_pBuffer + m_iFirstPaintIndex, 343 | m_iNumBytesPainted, &m_PaintRect, 0); 344 | 345 | m_iCharShownFirst = p_iFirstViewPos - l_iLookBack + l_iBeginning; 346 | m_iLineOffset = 0; 347 | m_iFirstViewPosWhenPainted = m_iCharShownFirst; 348 | m_iNumLinesPainted = l_iNumLines; 349 | m_iFirstRowLength = 1 + l_iFirstLineEnd - l_iBeginning; 350 | }//void BufferViewer::PaintBufferWithCopy 351 | 352 | /*------------------------------------------------------------ 353 | 354 | FUNCTION: BufferViewer::PaintBuffer 355 | 356 | PURPOSE: Performs actual painting of the trace buffer 357 | PARAMETERS: 358 | p_iFirstViewPos - current byte (between 0 and the buffer 359 | size) to be shown at the top of the window (measured 360 | from the initial start of writing) 361 | p_iLinesOffset - count p_iLinesOffset lines up or down 362 | from the current scroll position to 363 | find the first line to paint. 364 | ------------------------------------------------------------*/ 365 | void BufferViewer::PaintBuffer 366 | ( 367 | int p_iFirstViewPos, 368 | int p_iLinesOffset, 369 | HDC p_hDC, 370 | RECT * p_pPaintRect 371 | ) 372 | { 373 | if(!m_pBufferPointers || !m_pBufferPointers->m_pGlobalFooter || 374 | !m_pBufferPointers->m_dwTextAreaSize) 375 | return; 376 | int l_iCharsWritten = 377 | m_pBufferPointers->m_pGlobalFooter->m_dwNumBytesWritten / 378 | sizeof(TCHAR); 379 | int l_iBufferSizeChars = 380 | m_pBufferPointers->m_dwTextAreaSize / sizeof(TCHAR); 381 | 382 | if(p_iFirstViewPos > l_iCharsWritten) 383 | p_iFirstViewPos = l_iCharsWritten; 384 | //don't show empty space 385 | 386 | LPTSTR l_pText = m_pBufferPointers->m_pTextArea; 387 | 388 | //Decide which byte in the trace buffer corresponds to the 389 | //scroll position. This will be the last line to be shown. 390 | 391 | int l_iDataSizeAfterScrollPos= l_iCharsWritten - p_iFirstViewPos; 392 | if(l_iDataSizeAfterScrollPos > l_iBufferSizeChars) 393 | { 394 | //The scroll position is behind the beginning of the 395 | //valid data in the buffer (since the scroll position was 396 | //moved there the data were overwritten). 397 | if(m_iFirstViewPosWhenPainted == p_iFirstViewPos && 398 | m_iFirstPaintIndex >= 0 && m_pBuffer != NULL) 399 | { 400 | //Fortunately, we already have the data in the 401 | //display buffer 402 | DrawText(p_hDC, m_pBuffer + m_iFirstPaintIndex, 403 | m_iNumBytesPainted, p_pPaintRect, 0); 404 | } 405 | else 406 | { 407 | DrawText(p_hDC, _T("Data Lost"), 9, p_pPaintRect, 0); 408 | } 409 | } 410 | else 411 | { 412 | int l_iDataSizeBeforeScrollPos; 413 | if(l_iCharsWritten > l_iBufferSizeChars) 414 | l_iDataSizeBeforeScrollPos = 415 | l_iBufferSizeChars - l_iDataSizeAfterScrollPos; 416 | else 417 | l_iDataSizeBeforeScrollPos = p_iFirstViewPos; 418 | 419 | PaintBufferWithCopy( 420 | p_hDC, l_pText, l_iBufferSizeChars, 421 | p_iFirstViewPos, p_iLinesOffset, 422 | l_iDataSizeAfterScrollPos, l_iDataSizeBeforeScrollPos); 423 | } 424 | m_iTotalNumCharsWhenPainted = l_iCharsWritten; 425 | m_iScrollChangedWhenPainted = m_iScrollChanged; 426 | }//void BufferViewer::PaintBuffer 427 | 428 | #ifdef WIN32 //{ 429 | /*------------------------------------------------------------- 430 | 431 | FUNCTION: BufferViewer::OnPaint 432 | 433 | PURPOSE: Called to paint screen buffer view window 434 | -------------------------------------------------------------*/ 435 | void BufferViewer::OnPaint() 436 | { 437 | PAINTSTRUCT l_Paint; 438 | BeginPaint(m_hWnd, &l_Paint); 439 | FillRect(l_Paint.hdc, &m_ClientRect, 440 | (HBRUSH) GetStockObject(WHITE_BRUSH)); 441 | 442 | if(m_pBufferPointers && m_pBufferPointers->m_pGlobalFooter) 443 | { 444 | HGDIOBJ l_hPrevFont = SelectObject 445 | (l_Paint.hdc, m_hFont); 446 | if(!m_iFontHeight) 447 | { 448 | SIZE l_Size; 449 | m_iFontHeight = GetTextExtentPoint32( 450 | l_Paint.hdc, _T("W"), 4, &l_Size); 451 | m_iFontHeight = l_Size.cy; 452 | m_iFontWidth = l_Size.cx; 453 | m_iLogicalWidthPixels = m_iLogicalWidthChars * 454 | m_iFontWidth; 455 | 456 | OnSizeChanges(); 457 | } 458 | //long l_lVertPos = GetScrollPos(m_hWnd, SB_VERT); 459 | 460 | int l_iOldestCharInBuffer = ((int) 461 | (m_pBufferPointers->m_pGlobalFooter->m_dwNumBytesWritten- 462 | m_pBufferPointers->m_dwTextAreaSize))/(int)sizeof(TCHAR); 463 | if(m_bMoveToStartNextTime && 464 | m_iCharShownFirst < l_iOldestCharInBuffer) 465 | { 466 | m_iCharShownFirst = l_iOldestCharInBuffer; 467 | } 468 | m_bMoveToStartNextTime = false; 469 | SetViewportOrgEx(l_Paint.hdc, -m_iHorzPos, 0, NULL); 470 | 471 | FillRect(l_Paint.hdc, &m_PaintRect, 472 | (HBRUSH) GetStockObject(WHITE_BRUSH)); 473 | PaintBuffer(m_iCharShownFirst, m_iLineOffset, 474 | l_Paint.hdc, &m_PaintRect); 475 | SelectObject(l_Paint.hdc, l_hPrevFont); 476 | } 477 | 478 | EndPaint(m_hWnd, &l_Paint); 479 | 480 | UpdateScrollPos(); 481 | }//void BufferViewer::OnPaint() 482 | 483 | /*------------------------------------------------------------- 484 | 485 | FUNCTION: BufferViewer::OnSizeChanges 486 | 487 | PURPOSE: Called in response to WM_SIZE 488 | -------------------------------------------------------------*/ 489 | void BufferViewer::OnSizeChanges() 490 | { 491 | GetClientRect(m_hWnd, &m_ClientRect); 492 | m_iNumLinesInClientArea = 0; 493 | if(m_iFontHeight > 0) 494 | { 495 | m_iNumLinesInClientArea = 496 | (m_ClientRect.bottom - m_ClientRect.top)/m_iFontHeight; 497 | } 498 | m_PaintRect = m_ClientRect; 499 | m_PaintRect.right = m_ClientRect.right + m_iHorzPos; 500 | InvalidateRect(m_hWnd, NULL, FALSE); 501 | }//void BufferViewer::OnSizeChanges() 502 | #endif//WIN32 } 503 | 504 | /*------------------------------------------------------------- 505 | 506 | FUNCTION: BufferViewer::OnTimerMessage 507 | 508 | PURPOSE: Called in response to WM_TIMER message in the 509 | buffer view window. Calculates a new scroll position and 510 | forces repaint 511 | ------------------------------------------------------------*/ 512 | void BufferViewer::OnTimerMessage() 513 | { 514 | if(!m_pBufferPointers || !m_pBufferPointers->m_pGlobalFooter) 515 | return; 516 | 517 | int l_iCharsWritten = 518 | m_pBufferPointers->m_pGlobalFooter->m_dwNumBytesWritten / 519 | sizeof(TCHAR); 520 | if(m_iTotalNumCharsWhenPainted == l_iCharsWritten && 521 | m_iScrollChangedWhenPainted == m_iScrollChanged) 522 | return;//Nothing new was written since last paint 523 | UpdateScrollPos(); 524 | if(m_iCharShownFirst == m_iFirstViewPosWhenPainted && 525 | m_iNumLinesPainted >= m_iNumLinesInClientArea && 526 | m_iLineOffset == 0) 527 | { 528 | return;//don't repaint the same place again 529 | } 530 | InvalidateRect(m_hWnd, NULL, FALSE); 531 | }//void BufferViewer::OnTimerMessage 532 | 533 | void BufferViewer::UpdateScrollPos() 534 | { 535 | int l_iBufferSizeChars = m_pBufferPointers->m_dwTextAreaSize / 536 | sizeof(TCHAR); 537 | int l_iCharsWritten = 538 | m_pBufferPointers->m_pGlobalFooter->m_dwNumBytesWritten / 539 | sizeof(TCHAR); 540 | 541 | int l_iRange = 0; 542 | int l_iScrollPos = 0; 543 | //We will set the scroll range depending where the 544 | //current viewing point (m_iCharShownFirst) is. If it 545 | //is within the memory buffer, we need to set the range 546 | //to the size of the buffer (or the number of bytes 547 | //written, if the buffer is not full yet). If the 548 | //current viewing point is behind the buffer (the data 549 | //were lost), we need to set the range to the whole 550 | //distance between the newest data and the view point. 551 | 552 | if(l_iCharsWritten < l_iBufferSizeChars) 553 | {//The buffer is not full yet. 554 | l_iRange = l_iCharsWritten; 555 | l_iScrollPos = m_iCharShownFirst; 556 | } 557 | else 558 | {//The buffer is full 559 | int l_iFirstByteInBuffer = 560 | l_iCharsWritten - l_iBufferSizeChars; 561 | if(m_iCharShownFirst < l_iFirstByteInBuffer) 562 | { //The view is behind the oldest data in the 563 | //buffer. Set the range to the whole distance 564 | //between the newest data and the view point. 565 | l_iRange = l_iCharsWritten - m_iCharShownFirst; 566 | l_iScrollPos = 0; 567 | } 568 | else 569 | { 570 | //The view point is within the buffer. 571 | //The range should be equal to the buffer size. 572 | l_iRange = l_iBufferSizeChars; 573 | l_iScrollPos = m_iCharShownFirst - l_iFirstByteInBuffer; 574 | } 575 | } 576 | if(m_bStickToEnd) 577 | { 578 | l_iScrollPos = l_iRange; 579 | m_iCharShownFirst = l_iCharsWritten; 580 | } 581 | if(m_iCharShownFirst > l_iCharsWritten) 582 | { 583 | m_iCharShownFirst = 0;//buffer was reset 584 | m_bStickToEnd = true; 585 | } 586 | 587 | SetScrollRange(m_hWnd, SB_VERT, 0, l_iRange, FALSE); 588 | SetScrollPos(m_hWnd, SB_VERT, l_iScrollPos, TRUE); 589 | }//void BufferViewer::UpdateScrollPos() 590 | 591 | void BufferViewer::OnScrollMessage 592 | ( 593 | int p_nScrollBarType, 594 | int p_nScrollCode, 595 | int p_nPos, 596 | int p_nTrackPos, 597 | int p_nMin, 598 | int p_nMax 599 | ) 600 | { 601 | if(!m_pBufferPointers || !m_pBufferPointers->m_pGlobalFooter) 602 | return; 603 | long l_lCurPos = p_nPos; 604 | long l_lNewPos = p_nPos; 605 | int l_iLineOffset = 0; 606 | bool l_bStickToEnd = m_bStickToEnd, 607 | l_bMoveToStartNextTime = m_bMoveToStartNextTime; 608 | switch(p_nScrollCode) 609 | { 610 | case SB_THUMBTRACK: 611 | l_lNewPos = p_nTrackPos; 612 | if(p_nTrackPos >= p_nMax) 613 | { 614 | l_bStickToEnd = true; 615 | } 616 | break; 617 | case SB_LINEUP: 618 | if(p_nScrollBarType == SB_VERT) 619 | l_lNewPos -= 1; 620 | else 621 | l_lNewPos -= m_iFontWidth; 622 | break; 623 | case SB_LINEDOWN: 624 | if(p_nScrollBarType == SB_VERT) 625 | l_lNewPos += m_iFirstRowLength; 626 | else 627 | l_lNewPos += m_iFontWidth; 628 | break; 629 | case SB_PAGEUP: 630 | if(p_nScrollBarType == SB_VERT) 631 | l_iLineOffset = -m_iNumLinesInClientArea; 632 | else 633 | l_lNewPos -= m_ClientRect.right - m_ClientRect.left - 634 | m_iFontWidth; 635 | break; 636 | case SB_PAGEDOWN: 637 | if(p_nScrollBarType == SB_VERT) 638 | l_lNewPos += m_iNumBytesPainted-1; 639 | else 640 | l_lNewPos += m_ClientRect.right - m_ClientRect.left - 641 | m_iFontWidth; 642 | break; 643 | case SB_TOP: 644 | l_lNewPos = 0; 645 | l_bMoveToStartNextTime = true; 646 | break; 647 | case SB_BOTTOM: 648 | l_lNewPos = p_nMax; 649 | l_bStickToEnd = true; 650 | break; 651 | } 652 | if(l_lNewPos < p_nMin) 653 | l_lNewPos = p_nMin; 654 | else if(l_lNewPos > p_nMax) 655 | l_lNewPos = p_nMax; 656 | 657 | if(p_nScrollBarType == SB_VERT) 658 | { 659 | m_iLineOffset = l_iLineOffset; 660 | int l_iDiffPos = l_lNewPos - l_lCurPos; 661 | if(l_iDiffPos < 0 || l_iLineOffset < 0) 662 | { 663 | l_bStickToEnd = false; 664 | } 665 | m_iCharShownFirst += l_iDiffPos; 666 | m_bStickToEnd = l_bStickToEnd; 667 | m_bMoveToStartNextTime = l_bMoveToStartNextTime; 668 | int l_iOldestCharInBuffer = ((int) 669 | (m_pBufferPointers->m_pGlobalFooter->m_dwNumBytesWritten- 670 | m_pBufferPointers->m_dwTextAreaSize))/(int)sizeof(TCHAR); 671 | if(m_iCharShownFirst < l_iOldestCharInBuffer) 672 | { 673 | m_bMoveToStartNextTime = true; 674 | } 675 | else if(m_iCharShownFirst >= (int) 676 | (m_pBufferPointers->m_pGlobalFooter->m_dwNumBytesWritten/ 677 | sizeof(TCHAR)) && m_iLineOffset >= 0) 678 | { 679 | m_bStickToEnd = true; 680 | } 681 | } 682 | else 683 | { 684 | if(m_iHorzPos == l_lNewPos) 685 | return; 686 | m_iHorzPos = l_lNewPos; 687 | m_PaintRect.right = m_ClientRect.right + m_iHorzPos; 688 | } 689 | SetScrollPos(m_hWnd, p_nScrollBarType, l_lNewPos, TRUE); 690 | InvalidateRect(m_hWnd, NULL, FALSE); 691 | m_iScrollChanged++; 692 | }//void BufferViewer::OnScrollMessage 693 | 694 | #ifdef WIN32 //{ 695 | /*------------------------------------------------------------- 696 | 697 | FUNCTION: WindowProc 698 | 699 | PURPOSE: Window procedure for the trace buffer view window 700 | ------------------------------------------------------------*/ 701 | static LRESULT CALLBACK TraceViewWindowProc 702 | ( 703 | HWND p_hWnd, 704 | UINT p_uMsg, 705 | WPARAM p_wParam, 706 | LPARAM p_lParam 707 | ) 708 | { 709 | HTRACEK((KeyWordAppDebug, _T("View WindowProc %x %x %x %x"), 710 | p_hWnd, p_uMsg, p_wParam, p_lParam )); 711 | 712 | long l_lBufferViewer = GetWindowLong(p_hWnd, 0); 713 | BufferViewer * l_pViewer =(BufferViewer * )l_lBufferViewer; 714 | switch(p_uMsg) 715 | { 716 | case WM_CREATE: 717 | { 718 | SetTimer(p_hWnd, 1, 1000, NULL); 719 | 720 | BufferViewer * l_pViewer =new BufferViewer(p_hWnd); 721 | l_pViewer->m_pBufferPointers = pGetTraceBuffer(); 722 | l_pViewer->m_hFont = 723 | (HFONT)GetStockObject( 724 | #if !defined(_WIN32_WCE) 725 | SYSTEM_FIXED_FONT 726 | #else 727 | SYSTEM_FONT 728 | #endif 729 | ); 730 | 731 | SetWindowLong(p_hWnd, 0, (long)l_pViewer); 732 | 733 | if(l_pViewer->m_pBufferPointers) 734 | { 735 | SetScrollRange(p_hWnd, SB_VERT, 0, 736 | l_pViewer->m_pBufferPointers->m_dwTextAreaSize/ 737 | sizeof(TCHAR), FALSE); 738 | l_pViewer->m_iLogicalWidthChars = 512; 739 | SetScrollRange(p_hWnd, SB_HORZ, 0, 740 | l_pViewer->m_iLogicalWidthChars, FALSE); 741 | } 742 | } 743 | case WM_SIZE: 744 | if(l_pViewer) 745 | l_pViewer->OnSizeChanges(); 746 | break; 747 | case WM_TIMER: 748 | if(l_pViewer) 749 | l_pViewer->OnTimerMessage(); 750 | break; 751 | case WM_VSCROLL: 752 | case WM_HSCROLL: 753 | if(l_pViewer) 754 | { 755 | int l_nScrollBarType = 756 | p_uMsg == WM_VSCROLL? SB_VERT : SB_HORZ; 757 | int l_nScrollCode = (int) LOWORD(p_wParam); 758 | short int l_nPos = (short int) HIWORD(p_wParam); 759 | HWND l_hwndScrollBar = (HWND) p_lParam; 760 | 761 | SCROLLINFO l_ScrollInfo; 762 | memset(&l_ScrollInfo, 0, sizeof(l_ScrollInfo)); 763 | l_ScrollInfo.cbSize = sizeof(l_ScrollInfo); 764 | l_ScrollInfo.fMask = 765 | SIF_TRACKPOS | SIF_POS | SIF_RANGE; 766 | GetScrollInfo(p_hWnd, l_nScrollBarType, &l_ScrollInfo); 767 | long l_lPos = l_ScrollInfo.nPos; 768 | l_pViewer->OnScrollMessage( 769 | l_nScrollBarType, l_nScrollCode, 770 | l_ScrollInfo.nPos, l_ScrollInfo.nTrackPos, 771 | l_ScrollInfo.nMin, l_ScrollInfo.nMax); 772 | } 773 | break; 774 | case WM_PAINT: 775 | if(l_pViewer) 776 | l_pViewer->OnPaint(); 777 | break; 778 | case WM_USER: 779 | KillTimer(p_hWnd, 1); 780 | SetTimer(p_hWnd, 1, p_wParam, NULL); 781 | break; 782 | case WM_USER+1: 783 | if(l_pViewer && l_pViewer->m_pBufferPointers && 784 | l_pViewer->m_pBufferPointers->m_pGlobalFooter) 785 | l_pViewer->m_pBufferPointers->m_pGlobalFooter-> 786 | m_dwNumBytesWritten = 0; 787 | break; 788 | case WM_DESTROY: 789 | KillTimer(p_hWnd, 1); 790 | PostQuitMessage(0); 791 | 792 | if(l_pViewer) 793 | { 794 | l_pViewer->m_pBufferPointers = NULL; 795 | delete l_pViewer; 796 | } 797 | SetWindowLong(p_hWnd, 0, 0); 798 | break; 799 | } 800 | return DefWindowProc(p_hWnd, p_uMsg, p_wParam, p_lParam); 801 | }//LRESULT CALLBACK WindowProc 802 | 803 | void RegisterTraceView(LPCTSTR p_pszClassName) 804 | { 805 | WNDCLASS l_Class; 806 | memset(&l_Class,0,sizeof(l_Class)); 807 | l_Class.lpfnWndProc = TraceViewWindowProc; 808 | l_Class.hCursor = LoadCursor(0,IDC_ARROW); 809 | l_Class.hbrBackground = (HBRUSH)(1 + COLOR_WINDOW); 810 | l_Class.lpszClassName = p_pszClassName; 811 | l_Class.cbWndExtra = 4; 812 | RegisterClass(&l_Class); 813 | } 814 | #endif //#ifdef WIN32 } 815 | #endif //#ifdef TRACE_ } -------------------------------------------------------------------------------- /ApiSpy/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by CeApiSpy.rc 4 | // 5 | #define IDR_MENUBAR 101 6 | #define IDC_START 40001 7 | #define IDS_CAP_START 40003 8 | #define IDC_STOP 40004 9 | #define IDS_CAP_STOP 40006 10 | #define IDC_SAVE 40007 11 | #define IDS_CAP_SAVE 40009 12 | #define IDS_CAP_OK 40011 13 | #define IDC_OPTIONS 40012 14 | #define IDS_CAP_OPTIONS 40014 15 | #define IDC_TRACE_INTERCEPTED 40015 16 | #define IDC_TRACE_SPY_BRIEF 40016 17 | #define IDC_TRACE_SPY_DETAILED 40017 18 | #define IDC_OUTPUT_MEM 40018 19 | #define IDC_OUTPUT_DEBUG 40019 20 | #define IDC_DUMP_APIS 40020 21 | #define IDS_CAP_DUMP_APIS 40020 22 | #define ID_OPTIONS_EXIT 40023 23 | #define ID_OPTIONS_ 40024 24 | #define IDC_OPTIONS_EXIT 40025 25 | 26 | // Next default values for new objects 27 | // 28 | #ifdef APSTUDIO_INVOKED 29 | #ifndef APSTUDIO_READONLY_SYMBOLS 30 | #define _APS_NEXT_RESOURCE_VALUE 102 31 | #define _APS_NEXT_COMMAND_VALUE 40026 32 | #define _APS_NEXT_CONTROL_VALUE 1000 33 | #define _APS_NEXT_SYMED_VALUE 101 34 | #endif 35 | #endif 36 | -------------------------------------------------------------------------------- /ApiSpyDLL/ApiSpyDLL.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 10.00 3 | # Visual Studio 2008 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ApiSpyDLL", "ApiSpyDLL.vcproj", "{CD09CFD6-F74C-46E1-A34D-74DE98F479E3}" 5 | EndProject 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ApiSpy", "..\ApiSpy\ApiSpy.vcproj", "{D0DCE244-7FAF-4495-87E1-37ABB2C2C5CD}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{0D927239-52FC-4740-8838-E953097ECE33}" 9 | ProjectSection(SolutionItems) = preProject 10 | ..\name_wince_syscalls.idc = ..\name_wince_syscalls.idc 11 | EndProjectSection 12 | EndProject 13 | Global 14 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 15 | Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) 16 | Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) = Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) 17 | EndGlobalSection 18 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 19 | {CD09CFD6-F74C-46E1-A34D-74DE98F479E3}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) 20 | {CD09CFD6-F74C-46E1-A34D-74DE98F479E3}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) 21 | {CD09CFD6-F74C-46E1-A34D-74DE98F479E3}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) 22 | {CD09CFD6-F74C-46E1-A34D-74DE98F479E3}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) 23 | {CD09CFD6-F74C-46E1-A34D-74DE98F479E3}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) 24 | {CD09CFD6-F74C-46E1-A34D-74DE98F479E3}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) 25 | {D0DCE244-7FAF-4495-87E1-37ABB2C2C5CD}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) 26 | {D0DCE244-7FAF-4495-87E1-37ABB2C2C5CD}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) 27 | {D0DCE244-7FAF-4495-87E1-37ABB2C2C5CD}.Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Debug|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) 28 | {D0DCE244-7FAF-4495-87E1-37ABB2C2C5CD}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).ActiveCfg = Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) 29 | {D0DCE244-7FAF-4495-87E1-37ABB2C2C5CD}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Build.0 = Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) 30 | {D0DCE244-7FAF-4495-87E1-37ABB2C2C5CD}.Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I).Deploy.0 = Release|Windows Mobile 5.0 Pocket PC SDK (ARMV4I) 31 | EndGlobalSection 32 | GlobalSection(SolutionProperties) = preSolution 33 | HideSolutionNode = FALSE 34 | EndGlobalSection 35 | EndGlobal 36 | -------------------------------------------------------------------------------- /ApiSpyDLL/ApiSpyDLL.vcproj: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 15 | 16 | 17 | 18 | 19 | 26 | 29 | 32 | 35 | 38 | 41 | 53 | 56 | 62 | 65 | 81 | 84 | 87 | 90 | 93 | 96 | 99 | 105 | 107 | 108 | 115 | 118 | 121 | 124 | 127 | 130 | 141 | 144 | 150 | 153 | 170 | 173 | 176 | 179 | 182 | 185 | 188 | 194 | 196 | 197 | 198 | 199 | 200 | 201 | 206 | 209 | 210 | 213 | 214 | 217 | 218 | 219 | 224 | 227 | 228 | 231 | 232 | 235 | 236 | 239 | 240 | 241 | 246 | 247 | 248 | 249 | 250 | 251 | -------------------------------------------------------------------------------- /common/HTrace.h: -------------------------------------------------------------------------------- 1 | /************************************************************** 2 | Module : HTrace.h Declaration of tracing routines. 3 | Written 1998,1999,2000 by Dmitri Leman 4 | Purpose: Tracing framework allows inserting HTRACE and HTRACEK 5 | tracing statements to applications and drivers. 6 | Tracing messages may redirected to various output streams 7 | without rebuilding the whole application. 8 | To enable the trace, define TRACE_ in the compiler settings. 9 | To compile for NT kernel mode driver, add TRACER_NTDRIVER 10 | definition. To compile with Java JNI support, add TRACE_JNI. 11 | This file was compiled using Visual C++ 6.0 for WIN32 and NT 12 | kernel mode, 13 | g++ version egcs-2.91 for Red Hat Linux 6.1 on Pentium 14 | Most of the tracer routines are also callable from C. 15 | **************************************************************/ 16 | #ifndef TRACE_H /*{*/ 17 | #define TRACE_H 18 | 19 | /* 20 | The following are constants for various thread groups used in 21 | the ApiSpy application. 22 | To use the trace in other applications, different groups 23 | should be defined. 24 | */ 25 | enum TraceGroups 26 | { 27 | TG_InterceptedInfo = 1,/*The main output of the Spy -intercepted 28 | functions, parameters, etc. */ 29 | 30 | TG_DebugSpyBrief = 2, /* Debug the Spy itself */ 31 | TG_DebugSpyDetailed = 4, /*Detailed prints from Spy's internals*/ 32 | 33 | TG_PrintAlways = 8, /* Important messages */ 34 | 35 | /*The following are groups for error messages:*/ 36 | TG_MessageBox = 0x1000000,/*errors and warnings*/ 37 | 38 | TG_Error = 0x80000000 /*errors*/ 39 | };/*enum TraceGroups*/ 40 | 41 | 42 | #ifdef __cplusplus 43 | extern "C" { 44 | #else 45 | typedef int bool; 46 | #endif 47 | 48 | #ifdef WIN32 49 | #include 50 | 51 | #else 52 | 53 | #include 54 | typedef unsigned long DWORD; 55 | typedef unsigned long ULONG; 56 | typedef unsigned long * PDWORD; 57 | typedef unsigned long * PULONG; 58 | typedef const char * LPCTSTR; 59 | typedef const char * LPCSTR; 60 | typedef const char * PCSTR; 61 | typedef char * PTSTR; 62 | typedef char * PSTR; 63 | typedef char TCHAR; 64 | #define _tcslen strlen 65 | #define IN 66 | #define OUT 67 | typedef struct 68 | { 69 | int QuadPart; 70 | } LARGE_INTEGER, *PLARGE_INTEGER; 71 | 72 | typedef int HANDLE; 73 | #define INVALID_HANDLE_VALUE -1 74 | 75 | #define _MAX_PATH PATH_MAX 76 | 77 | /* 78 | These are replacement for Windows interlocked routines 79 | for Linux implemented using Pentium inline assembly. 80 | */ 81 | long InterlockedExchangeAdd(long * p_plValue, long p_lAdd); 82 | long InterlockedIncrement(long * p_plValue); 83 | long InterlockedDecrement(long * p_plValue); 84 | 85 | #endif 86 | 87 | /* 88 | The following are keyword to enable tracing of various 89 | routines in the applications and the driver. 90 | */ 91 | #define KeyWordDriverDebug "DrvD" 92 | #define KeyWordAppDebug "AppD" 93 | 94 | /* 95 | The following are constants for various trace output streams. 96 | To add a new method of trace output just add a new constant, 97 | then write a new output routine and add a new row in s_Outputs 98 | array in htrace.cpp. For example one routine may send trace 99 | messages to a remote computer, another - to a database. 100 | After that you can redirect selected trace groups to your 101 | new output stream by calling TraceAssignGroupsToStream 102 | */ 103 | enum TraceOutputs 104 | { 105 | TO_DebugMonitor = 1, 106 | TO_File = 2, 107 | TO_FlushFile = 4,/*this is not a stream, but a command 108 | to flush the file after a message is printed to TO_File*/ 109 | TO_MessageBox = 8, 110 | TO_Console = 0x10, 111 | TO_MemoryBuffer = 0x20, 112 | TO_OutputLog = 0x40, 113 | };/*enum TraceOutputs*/ 114 | 115 | /* 116 | The following is support for the trace memory buffer. 117 | Most of the space in the trace buffer will be filled by actual 118 | trace messages, but it also should keep several integers 119 | used during tracing: buffer size, number of bytes written, 120 | "stop after" threshold, frozen flag, enabled group mask, 121 | enabled keywords and keyword modification counter. 122 | 123 | The purpose of m_dwStopAfterThreshold is to freeze the output 124 | as soon as m_dwNumBytesWritten exceeds its value. Then m_iFrozen 125 | will be set to 1 and no more traces will be added to the buffer. 126 | 127 | We cannot keep integers in the header, because it will prevent 128 | text editors from seeing our trace file as text. Therefore, 129 | we will store size of the buffer as a text string at the 130 | beginning of the buffer and the rest of the integer at the end. 131 | This way text editors will be happy to open the buffer as text. 132 | 133 | Layout of the memory trace buffer: 134 | Header + 0: Signature - 4 bytes 135 | Header + 4: SizeTextAreaHex - 10 byte hexadecimal string 136 | Actual text buffer of size == SizeTextAreaHex 137 | Footer + 0: Number of bytes written - 4 bytes integer 138 | Footer + 4: Threshold to stop - 4 bytes integer 139 | Footer + 8: Frozen or not - 4 bytes integer 140 | Footer + C: Group Mask - 4 bytes integer 141 | Footer + 10: Group Keyword Mask - 256 bytes string 142 | Footer + 110: Keyword modification counter - 4 bytes 143 | */ 144 | #define TRACE_BUFFER_SIGNATURE 0x46425254 /*"TRBF"*/ 145 | struct GlobalTraceBufferHeader/*may be in shared memory*/ 146 | { 147 | ULONG m_dwSignature;/*TRACE_BUFFER_SIGNATURE*/ 148 | char m_cSizeTextArea[12]; 149 | };/*struct GlobalTraceBufferHeader*/ 150 | struct GlobalTraceBufferFooter /*may be in shared memory*/ 151 | { 152 | ULONG m_dwNumBytesWritten; 153 | ULONG m_dwStopAfterThreshold; 154 | ULONG m_dwFrozen; 155 | ULONG m_dwEnabledGroups; 156 | ULONG m_dwEnabledGroupsTotal; 157 | char m_szKeyWordMask[256]; 158 | ULONG m_dwKeyWordModificationCounter; 159 | };/*struct GlobalTraceBufferHeader*/ 160 | struct LocalTraceBufferPointers /*kept local by application*/ 161 | { 162 | struct GlobalTraceBufferHeader * m_pGlobalHeader; 163 | LPTSTR m_pTextArea; 164 | ULONG m_dwTextAreaSize; 165 | struct GlobalTraceBufferFooter * m_pGlobalFooter; 166 | }; 167 | #define TRACE_BUFFER_EXTRA_SIZE \ 168 | (sizeof(GlobalTraceBufferHeader)+\ 169 | sizeof(GlobalTraceBufferFooter)) 170 | 171 | #ifdef TRACE_ /*{*/ 172 | /* 173 | Current implementation does not allow simultaneous modification 174 | of trace parameters by multiple threads. Ideally, a process 175 | should initialize trace from the beginning and, may be, 176 | update trace parameters from a single thread. 177 | Functions, which generate trace, such as HTraceImpl and 178 | OutputTraceString can be called by any thread at any time(after 179 | the trace is initialized by TraceInitialize. 180 | */ 181 | 182 | /* 183 | TraceInitialize should be called once for any process, which 184 | use the trace. TraceUnInitialize should be called before 185 | the process terminates. 186 | In some platforms C++ constructors can be used for this 187 | purpose, but many other platforms lack such support. 188 | */ 189 | bool TraceInitialize(void); 190 | bool TraceUnInitialize(void); 191 | 192 | /* 193 | TraceAssignGroupsToStream is the most important function of 194 | the trace. It allows turning on and off individual group 195 | flags defined in enum TraceGroups for each trace output 196 | specified by constants in enum TraceOutputs, which will 197 | enable/disable and redirect the specified trace groups 198 | for the given output streams. 199 | PARAMETERS: . 200 | p_dwTraceOutputs flags from TraceOutputs. 201 | p_dwNewGroupFlags groups to print 202 | p_dwGroupFlagsToModify which bits can be modified 203 | */ 204 | bool TraceAssignGroupsToStream 205 | ( 206 | ULONG p_dwTraceOutputs, 207 | ULONG p_dwNewGroupFlags, 208 | ULONG p_dwGroupFlagsToModify 209 | 210 | ); 211 | /* 212 | TraceAssignGroupKeyWordToStream is useful when there is not 213 | enough bit positions in 32 bit number to assign for various 214 | trace groups in the program. In such a case string keywords 215 | can be assigned to trace groups. 216 | TraceAssignGroupKeyWordToStream allows assigning 217 | individual group keywords for each trace output 218 | specified by constants in enum TraceOutputs. 219 | PARAMETERS: . 220 | p_dwTraceOutputs flags from TraceOutputs. 221 | char * p_pszGroupKeyWord new keyword mask 222 | */ 223 | bool TraceAssignGroupKeyWordToStream 224 | ( 225 | ULONG p_dwTraceOutputs, 226 | char * p_pszGroupKeyWord 227 | ); 228 | /* 229 | TraceGetAssignedGroupsToStream and 230 | TraceGetAssignedGroupKeyWordsToStream allow to get currently 231 | enabled trace groups for a particular trace output. 232 | PARAMETERS: . 233 | p_dwTraceOutputs flags from TraceOutputs. 234 | */ 235 | ULONG TraceGetAssignedGroupsToStream(ULONG p_dwTraceOutputs); 236 | LPCSTR TraceGetAssignedGroupKeyWordsToStream 237 | (ULONG p_dwTraceOutputs); 238 | 239 | /* 240 | TraceReadWriteSettings allows to read and write 241 | the current trace settings, including group masks and keywords 242 | for some or all output streams to/from system registry or 243 | an INI file under WIN32. This allows defining trace settings 244 | in registry or INI file without modifying the program. 245 | PARAMETERS: . 246 | HKEY p_hKeyRoot root registry key (for example 247 | HKEY_CURRENT_USER). May be NULL - in that case p_pszPath 248 | should be a path to .INI file (if platform supports it). 249 | LPCTSTR p_pszPath if p_hKeyRoot != NULL - registry path 250 | if p_hKeyRoot == NULL - INI file path 251 | bool p_bWrite true to write, false to read 252 | ULONG p_ulOutputsToProcess flags from TraceOutputs - 253 | chose which stream settings to read/write 254 | */ 255 | bool TraceReadWriteSettings(HKEY p_hKeyRoot, LPCTSTR p_pszPath, 256 | bool p_bWrite, ULONG p_ulOutputsToProcess); 257 | 258 | #ifndef TRACER_NTDRIVER 259 | /* 260 | TraceSetOutputToFile enables tracing to a file. Unlike 261 | memory-mapped file, output to a file will directly print 262 | trace messages to a file, 263 | which allows an unlimited size, but may be slower. 264 | This function accepts 2 masks: p_dwNewGroupFlags to decide 265 | which trace statements should be printed to file and 266 | p_dwNewFlushBits to determine which trace statements should 267 | also flush the file. Flushing the file allows to preserve 268 | the trace if an application crashes, but is much slower. 269 | PARAMETERS: . 270 | LPCTSTR p_pszFileName - file name to print traces to 271 | ULONG p_dwNewGroupFlags - groups to print 272 | ULONG p_dwGroupFlagsToModify-trace groups flags to change 273 | ULONG p_dwNewFlushBits - groups which will flush the file 274 | ULONG p_dwFlushBitsToModify - trace flags to change 275 | */ 276 | bool TraceSetOutputToFile 277 | ( 278 | LPCTSTR p_pszFileName, 279 | ULONG p_dwNewGroupFlags, 280 | ULONG p_dwGroupFlagsToModify, 281 | ULONG p_dwNewFlushBits , 282 | ULONG p_dwFlushBitsToModify 283 | ); 284 | LPCTSTR TraceGetCurTraceFileName(); 285 | #endif 286 | 287 | /* 288 | TraceAllocateBuffer - allocate trace buffer of the given size 289 | and enable trace groups for that output. This buffer cannot be 290 | shared with other applications or files. This buffer should be 291 | dumped to a file using TraceDumpBufferToFile before the program 292 | terminates. Other ways to enable trace to a memory buffer are 293 | TraceSetExternalBuffer, TraceAttachToNTDriverBuffer, 294 | TraceUseMemMapFileBuffer 295 | PARAMETERS: . 296 | int p_iSize - size of the buffer text area to allocate 297 | ULONG p_dwNewGroupFlags - groups to print 298 | ULONG p_dwGroupFlagsToModify-trace groups flags to change 299 | */ 300 | bool TraceAllocateBuffer(int p_iSize, 301 | ULONG p_dwNewGroupFlags, ULONG p_dwGroupFlagsToModify); 302 | /* 303 | TraceSetExternalBuffer is used to share trace buffer between 304 | several application. If one application or driver created the 305 | trace buffer in some kind of shared memory, another application 306 | can obtain a pointer to that buffer and call 307 | TraceSetExternalBuffer to start printing it's trace to the same 308 | buffer. A care should be taken with group flags in this case, 309 | because they will affect trace in both applications. 310 | PARAMETERS: . 311 | GlobalTraceBufferHeader* p_pBufferHeader - trace pointers 312 | returned from pGetTraceBuffer 313 | ULONG p_dwNewGroupFlags - groups to print 314 | ULONG p_dwGroupFlagsToModify-trace groups flags to change 315 | */ 316 | bool TraceSetExternalBuffer( 317 | struct GlobalTraceBufferHeader* p_pBufferHeader, 318 | ULONG p_dwNewGroupFlags, ULONG p_dwGroupFlagsToModify); 319 | /* 320 | TraceAttachToNTDriverBuffer is a convenience function, which 321 | requests the shared trace buffer from an NT kernel mode driver, 322 | and calls TraceSetExternalBuffer to share the buffer with the 323 | driver. The driver must process necessary IOCTL requests. 324 | To easiest way to meet these requirements, is to include 325 | HTrace.cpp in the driver and call TraceIoctl 326 | from the driver's dispatch routine, as shown in HTraceD.cpp. 327 | PARAMETERS: 328 | LPCTSTR p_pszDeviceName - name of NT device. This parameter 329 | can be left NULL to use our default name 330 | TRACER_WIN32_FILE_NAME 331 | int p_iIOCTLMapTraceBuffer - NT IOCTL code to map the 332 | buffer. This parameter can be left -1 to use our default 333 | IOCTL_TRACER_MAP_BUFFER 334 | int p_iIOCTLUnMapTraceBuffer - NT IOCTL code to unmap 335 | the buffer. This parameter can be left -1 to use our 336 | default IOCTL_TRACER_MAP_BUFFER 337 | bool p_bDontComplainIfDeviceAbsent - set to true if the 338 | caller expects that the driver may be absent. 339 | ULONG p_dwNewGroupFlags - groups to print 340 | ULONG p_dwGroupFlagsToModify-trace groups flags to change 341 | */ 342 | bool TraceAttachToNTDriverBuffer 343 | ( 344 | LPCTSTR p_pszDeviceName, 345 | int p_iIOCTLMapTraceBuffer, 346 | int p_iIOCTLUnMapTraceBuffer, 347 | bool p_bDontComplainIfDeviceAbsent, 348 | ULONG p_dwNewGroupFlags, ULONG p_dwGroupFlagsToModify 349 | ); 350 | /* 351 | TraceUseMemMapFileBuffer creates a memory mapped file 352 | (or use an existing one) to shared trace buffer between 353 | several applications. 354 | PARAMETERS: 355 | p_pszMemMapFilePath - file path 356 | p_iFileSize - size (for creation) 357 | p_dwNewGroupFlags - groups to print 358 | p_dwGroupFlagsToModify-trace groups flags to change 359 | */ 360 | bool TraceUseMemMapFileBuffer 361 | ( 362 | LPCTSTR p_pszMemMapFilePath, 363 | int p_iFileSize, 364 | ULONG p_dwNewGroupFlags, 365 | ULONG p_dwGroupFlagsToModify 366 | ); 367 | /* 368 | TraceFreeBuffer frees the trace buffer (if it was allocated), 369 | releases memory mapped file or calls NT driver to detach from 370 | the buffer, which was shared by TraceAttachToNTDriverBuffer. 371 | */ 372 | bool TraceFreeBuffer(); 373 | /* 374 | TraceDumpBufferToFile prints the memory buffer to the specified 375 | file. It is usually called before the program terminates. 376 | This function can handle circular buffers. 377 | */ 378 | bool TraceDumpBufferToFile(LPCTSTR p_pszFileName); 379 | 380 | /* 381 | pGetTraceBuffer returns LocalTraceBufferPointers structure, 382 | which keeps pointers to the currently allocated trace buffer 383 | (if any) including header, text area, size and footer. 384 | */ 385 | struct LocalTraceBufferPointers * pGetTraceBuffer(); 386 | 387 | /* 388 | TraceFreezeBufferAfter will freeze output to the trace buffer 389 | after the specified amount of data (measured in percents 390 | from the buffer size). 391 | Common use: 392 | - TraceFreezeBufferAfter(0) to freeze output immediately - 393 | last printed trace will remain the last in the buffer. 394 | - TraceFreezeBufferAfter(50) - last printed trace will be 395 | approximately at the middle of the buffer 396 | - TraceFreezeBufferAfter(100) - last printed trace will be 397 | the first in the trace buffer after freeze. 398 | */ 399 | void TraceFreezeBufferAfter(int p_iPercent); 400 | 401 | /* 402 | TraceEraseBuffer erases the trace buffer by resetting 403 | the "number of bytes written" field of the trace buffer 404 | */ 405 | void TraceEraseBuffer(); 406 | 407 | #ifdef TRACER_NTDRIVER 408 | typedef struct _DRIVER_OBJECT *PDRIVER_OBJECT; 409 | /* 410 | EnableTraceToOutputLog used by NT drivers to enable some trace 411 | groups to be printed to the system log. 412 | */ 413 | bool EnableTraceToOutputLog(PDRIVER_OBJECT p_pDriverObject, 414 | ULONG p_dwNewGroupFlags, ULONG p_dwGroupFlagsToModify); 415 | #endif 416 | 417 | /*Actual trace output routines with group bit masks:*/ 418 | /* 419 | OutputTraceString is the fastest tracing routine.It does no 420 | formatting, it simply copies the specified string to output 421 | streams, which matches the specified group mask. 422 | PARAMETERS: . 423 | 424 | ULONG p_dwMask flags from TraceGroups 425 | LPCSTR p_pszMessage, string 426 | int p_iLen Number of characters in the string 427 | */ 428 | void OutputTraceString(ULONG p_dwMask, LPCTSTR p_pszMessage, 429 | int p_iLen); 430 | /* 431 | HTraceImpl and macro HTRACE are used to format trace message 432 | and print it to streams,which matches the specified group mask. 433 | */ 434 | void HTraceImpl(ULONG p_dwMask, LPCTSTR p_pszFormat, ...); 435 | #define HTRACE HTraceImpl 436 | /* 437 | OutputTraceStringUnconditional disregards group masks 438 | and copies the given string to all output streams, 439 | which has their TO_* constants included in p_dwOutputMask 440 | */ 441 | void OutputTraceStringUnconditional(ULONG p_dwOutputMask, 442 | LPCTSTR p_pszMessage, int p_iLenChars); 443 | 444 | void RegisterTraceView(LPCTSTR p_pszClassName); 445 | 446 | /*Support for keyword masks*/ 447 | #ifdef __cplusplus 448 | class TraceKeywordCheck 449 | { 450 | public: 451 | void Output(char * p_pszKeyWord, LPCTSTR p_pszFormat, 452 | ...); 453 | void CompareKeyWords(const char * p_pszKeyWord); 454 | 455 | ULONG m_dwEnabledStreams; 456 | ULONG m_dwModificationCounter; 457 | };/*class TraceKeywordCheck*/ 458 | 459 | /* 460 | Parameters of HTRACEK must be enclosed in double brackets like: 461 | HTRACEK(("KeyWord", "Format %s %d", "First Param", 123)) 462 | This macro formats the trace messages and prints it to the 463 | output streams, which have keyword masks that matches the 464 | given keyword. 465 | */ 466 | #define HTRACEK(Params) { \ 467 | static TraceKeywordCheck l_Check = {false, 0}; \ 468 | l_Check.Output Params ; \ 469 | } 470 | 471 | #endif /*__cplusplus*/ 472 | 473 | #else /* } TRACE_ {*/ 474 | 475 | #if defined(__cplusplus) && !defined(TRACE_CPP) /* {*/ 476 | /* 477 | The following are empty versions of all functions, 478 | which are used then TRACE_ macro is not defined. 479 | They should be completely optimized out by the compiler, 480 | so the all trace calls can be left in the release version 481 | of the program. 482 | */ 483 | 484 | inline bool TraceInitialize(){return false;}; 485 | inline bool TraceUnInitialize(){return false;}; 486 | 487 | inline bool TraceAssignGroupsToStream 488 | (ULONG p_dwTraceOutputs, ULONG p_dwNewGroupFlags, 489 | ULONG p_dwGroupFlagsToModify) {return false;} 490 | inline bool TraceAssignGroupKeyWordToStream 491 | (ULONG p_dwTraceOutputs, char * p_pszGroupKeyWord) 492 | {return false;} 493 | inline ULONG TraceGetAssignedGroupsToStream 494 | (ULONG p_dwTraceOutputs) {return 0;} 495 | inline LPCSTR TraceGetAssignedGroupKeyWordsToStream 496 | (ULONG p_dwTraceOutputs) {return NULL;}; 497 | inline bool TraceReadWriteSettings 498 | (HKEY p_hKeyRoot, LPCTSTR p_pszPath, 499 | bool p_bWrite, ULONG p_ulOutputsToProcess) 500 | {return false;} 501 | 502 | #ifndef TRACER_NTDRIVER 503 | inline bool TraceSetOutputToFile(LPCTSTR p_pszFileName, 504 | ULONG p_dwNewGroupFlags, ULONG p_dwGroupFlagsToModify, 505 | ULONG p_dwNewFlushBits ,ULONG p_dwFlushBitsToModify) 506 | {return false;} 507 | inline LPCTSTR TraceGetCurTraceFileName(){return NULL;}; 508 | #endif 509 | 510 | inline bool TraceAllocateBuffer(int p_iSize, 511 | ULONG p_dwNewGroupFlags, ULONG p_dwGroupFlagsToModify) 512 | {return false;} 513 | inline bool TraceSetExternalBuffer( 514 | GlobalTraceBufferHeader* p_pBufferHeader, 515 | ULONG p_dwNewGroupFlags, ULONG p_dwGroupFlagsToModify) 516 | {return false;} 517 | inline bool TraceAttachToNTDriverBuffer 518 | ( 519 | LPCSTR p_pszDeviceName, 520 | int p_iIOCTLMapTraceBuffer,int p_iIOCTLUnMapTraceBuffer, 521 | bool p_bDontComplainIfDeviceAbsent, 522 | ULONG p_dwNewGroupFlags, ULONG p_dwGroupFlagsToModify 523 | ){return false;} 524 | inline bool TraceUseMemMapFileBuffer 525 | ( 526 | LPCTSTR p_pszMemMapFilePath, 527 | int p_iFileSize, 528 | ULONG p_dwNewGroupFlags, 529 | ULONG p_dwGroupFlagsToModify 530 | ){return false;} 531 | inline bool TraceFreeBuffer(){return false;} 532 | inline bool TraceDumpBufferToFile(LPCTSTR p_pszFileName) 533 | {return false;} 534 | inline LocalTraceBufferPointers*pGetTraceBuffer(){return NULL;} 535 | 536 | #ifdef TRACER_NTDRIVER 537 | typedef struct _DRIVER_OBJECT *PDRIVER_OBJECT; 538 | inline bool EnableTraceToOutputLog( 539 | PDRIVER_OBJECT p_pDriverObject, ULONG p_dwNewGroupFlags, 540 | ULONG p_dwGroupFlagsToModify) {return false;} 541 | #endif 542 | 543 | /*Actual trace output routines with group bit masks:*/ 544 | inline void OutputTraceString(ULONG p_dwMask, 545 | LPCTSTR p_pszMessage, int p_iLen) {} 546 | inline void HTraceImpl(ULONG p_dwMask, 547 | LPCTSTR p_pszFormat, ...){} 548 | inline void OutputTraceStringUnconditional 549 | (ULONG p_dwOutputMask, LPCSTR p_pszMessage, int p_iLen) {} 550 | inline void RegisterTraceView(LPCTSTR p_pszClassName) {} 551 | inline void Dummy(...){} 552 | #define HTRACE 1 ? (void)0 : HTraceImpl 553 | #define HTRACEK 1 ? (void)0 : Dummy 554 | 555 | #endif /* #if defined(__cplusplus) && !defined(TRACE_CPP) }*/ 556 | #endif/*TRACE_ else }*/ 557 | 558 | /*The following definitions are for communication with NT 559 | driver*/ 560 | #if defined(WIN32) && !defined(TRACER_NTDRIVER) 561 | #include 562 | #endif 563 | 564 | #if defined(WIN32) || defined(TRACER_NTDRIVER) /*{*/ 565 | 566 | #define TRACER_KERNEL_DEVICE_NAME L"\\Device\\HTrcDrv" 567 | #define TRACER_DOS_DEVICE_NAME_A "\\DosDevices\\HTrcDrv" 568 | #define TRACER_DOS_DEVICE_NAME_W L"\\DosDevices\\HTrcDrv" 569 | 570 | #define TRACER_WIN32_FILE_NAME_W L"\\\\.\\HTrcDrv" 571 | #define TRACER_WIN32_FILE_NAME _T("\\\\.\\HTrcDrv") 572 | 573 | /* 574 | Define a random device type and IOCTL codes, which will be used 575 | by our launcher application to call our driver 576 | */ 577 | #define FILE_DEVICE_TRACER 0x83ff 578 | 579 | #define IOCTL_TRACER_CHECK_ACTIVE ((ULONG) CTL_CODE\ 580 | ( FILE_DEVICE_TRACER, 0x01, METHOD_BUFFERED, FILE_ANY_ACCESS )) 581 | #define IOCTL_TRACER_DUMP_TRACE ((ULONG) CTL_CODE\ 582 | ( FILE_DEVICE_TRACER, 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS )) 583 | #define IOCTL_TRACER_MAP_BUFFER ((ULONG) CTL_CODE\ 584 | ( FILE_DEVICE_TRACER, 0x03, METHOD_BUFFERED, FILE_ANY_ACCESS )) 585 | #define IOCTL_TRACER_UNMAP_BUFFER ((ULONG) CTL_CODE\ 586 | ( FILE_DEVICE_TRACER, 0x04, METHOD_BUFFERED, FILE_ANY_ACCESS )) 587 | 588 | #endif /*#if defined(WIN32) || defined(TRACER_NTDRIVER) } */ 589 | 590 | #ifdef TRACER_NTDRIVER/* { */ 591 | /* 592 | The following routines to be used by a NT driver to map, 593 | unmap and print trace buffer to a file 594 | */ 595 | #ifdef TRACE_ /* { */ 596 | /* 597 | TraceIoctl: This function should be called by driver's dispatch 598 | routine to allow the tracer to respond to request for 599 | mapping and unmapping trace buffer and dumping it to a file 600 | 601 | PARAMETERS: . 602 | 603 | IN PDEVICE_OBJECT p_pDeviceObject our device object 604 | IN PIRP p_pIrp request packet 605 | The following are IOCTL codes for tracer requests. 606 | Usually these are IOCTL_TRACER_* defined in HTrace.h, 607 | but the driver may assign different codes. 608 | IN ULONG p_dwIoctlCheckActive - check presence of tracer. 609 | This code will be returned in the output buffer. 610 | IN ULONG p_dwIoctlDumpTrace - dump the content of trace 611 | memory buffer to the file. IOCTL input buffer 612 | has the name of the file. 613 | IN ULONG p_dwIoctlMapBuffer - map the trace memory buffer 614 | to the user space of the current application and 615 | return the address in the IOCTL output buffer. 616 | IN ULONG p_dwIoctlUnMapBuffer - unmap the trace buffer. 617 | The IOCTL input buffer should have the user address, 618 | which was previously returned by p_iIoctlMapBuffer 619 | */ 620 | NTSTATUS TraceIoctl 621 | ( 622 | IN PDEVICE_OBJECT p_pDeviceObject, 623 | IN PIRP p_pIrp, 624 | IN ULONG p_dwIoctlCheckActive, 625 | IN ULONG p_dwIoctlDumpTrace, 626 | IN ULONG p_dwIoctlMapBuffer, 627 | IN ULONG p_dwIoctlUnMapBuffer 628 | ); 629 | /* 630 | MapTraceMemory map the trace buffer to the address context of the 631 | current application and store the new MapMem object into 632 | the given FILE_OBJECT, so we will be able to unmap the 633 | memory when the file is closed. 634 | PARAMETERS: 635 | PFILE_OBJECT p_pFileObject - file object, which was created 636 | specifically for communication with the tracer driver. 637 | Don't try to call this function on other file objects, 638 | because it will overwrite FsContext field. 639 | ULONG *p_pulReturnUserAddress - return the mapped address 640 | */ 641 | NTSTATUS MapTraceMemory(PFILE_OBJECT p_pFileObject, 642 | ULONG *p_pulReturnUserAddress); 643 | /* 644 | UnmapTraceMemory unmaps the trace buffer, which was mapped by 645 | MapTraceMemory. 646 | PARAMETERS: 647 | ULONG p_ulUserAddress - the address, which was 648 | returned by MapTraceMemory 649 | PFILE_OBJECT p_pFileObject - must be the file object, which 650 | was created for communication with the tracer driver and 651 | was used in call to MapTraceMemory. 652 | */ 653 | NTSTATUS UnmapTraceMemory(ULONG p_ulUserAddress, 654 | PFILE_OBJECT p_pFileObject); 655 | #else 656 | inline NTSTATUS TraceIoctl 657 | ( 658 | IN PDEVICE_OBJECT p_pDeviceObject, 659 | IN PIRP p_pIrp, 660 | IN ULONG p_dwIoctlCheckActive, 661 | IN ULONG p_dwIoctlDumpTrace, 662 | IN ULONG p_dwIoctlMapBuffer, 663 | IN ULONG p_dwIoctlUnMapBuffer 664 | ){return STATUS_NOT_IMPLEMENTED;} 665 | inline NTSTATUS MapTraceMemory(PFILE_OBJECT p_pFileObject, 666 | ULONG *p_pulReturnUserAddress) 667 | {return STATUS_NOT_IMPLEMENTED;} 668 | inline NTSTATUS UnmapTraceMemory(ULONG p_ulUserAddress, 669 | PFILE_OBJECT p_pFileObject) 670 | {return STATUS_NOT_IMPLEMENTED;} 671 | #endif /*#ifdef TRACE_ else }*/ 672 | #endif /*#ifdef TRACER_NTDRIVER }*/ 673 | 674 | #ifdef __cplusplus 675 | }/*extern "C"*/ 676 | #endif 677 | 678 | #if defined(TRACE_) && defined WIN32 && !defined(TRACER_NTDRIVER)//{ 679 | #if defined(__cplusplus) /*{*/ 680 | /* 681 | class LocalStringHolder, strGetErrorExplanation and ERR_EXPL 682 | are useful for printing Win32 error messages. 683 | For example : HTRACE(TG_Error, "ERROR: CreateFile failed - %s", 684 | ERR_EXPL(GetLastError()); 685 | 686 | class LocalStringHolder simply keeps a string allocated using 687 | LocalAlloc API function and frees this function in destructor. 688 | */ 689 | class LocalStringHolder 690 | { 691 | public: 692 | LocalStringHolder() 693 | { 694 | m_pszString = m_szDummy; 695 | *m_szDummy = 0; 696 | } 697 | ~LocalStringHolder(){Free();} 698 | LocalStringHolder(const LocalStringHolder & p_rScr) 699 | { 700 | m_pszString = m_szDummy; 701 | *m_szDummy = 0; 702 | StrDup(p_rScr.m_pszString); 703 | } 704 | LocalStringHolder & operator = 705 | (const LocalStringHolder & p_rScr) 706 | { 707 | Free(); 708 | StrDup(p_rScr.m_pszString); 709 | return *this; 710 | } 711 | 712 | void StrDup(PTSTR p_pszStr) 713 | { 714 | Free(); 715 | int l_iSize = (_tcslen(p_pszStr)+1)*sizeof(TCHAR); 716 | m_pszString = (PTSTR)LocalAlloc(LPTR, l_iSize); 717 | if(!m_pszString) 718 | m_pszString = m_szDummy; 719 | else 720 | memcpy(m_pszString, p_pszStr, l_iSize); 721 | }/*void SetStr*/ 722 | 723 | void AdoptStr(PTSTR p_pszStr) 724 | /*p_pszStr must be allocated using LocalAlloc*/ 725 | { 726 | Free(); 727 | m_pszString = p_pszStr; 728 | } 729 | LPCTSTR strGetStr(){return m_pszString;} 730 | void Free() 731 | { 732 | if(m_pszString != m_szDummy) 733 | LocalFree(m_pszString); 734 | m_pszString = m_szDummy; 735 | }/*void Free()*/ 736 | protected: 737 | PTSTR m_pszString; 738 | TCHAR m_szDummy[1]; 739 | };/*class LocalStringHolder*/ 740 | 741 | /* 742 | strGetErrorExplanation takes WIN32 error code and returns 743 | error message 744 | */ 745 | LocalStringHolder strGetErrorExplanation(DWORD p_dwErrCode); 746 | 747 | /* 748 | ERR_EXPL is a convenient macro to be used in printf and 749 | HTRACE calls to print Win32 error messages. 750 | */ 751 | #define ERR_EXPL(ErrorCode) \ 752 | ((LPCTSTR)strGetErrorExplanation(ErrorCode).strGetStr()) 753 | 754 | #endif /*defined(__cplusplus) } */ 755 | #endif /*defined WIN32 && !defined(TRACER_NTDRIVER) }*/ 756 | 757 | #if defined(_WIN32_WCE) 758 | 759 | /* 760 | #undef RETAILMSG 761 | #define RETAILMSG(mask, printf_exp) HTraceImpl(mask, A printf_exp) 762 | 763 | #undef DEBUGZONE 764 | #define DEBUGZONE(n) n 765 | */ 766 | #endif 767 | 768 | 769 | #endif /*TRACE_H }*/ 770 | -------------------------------------------------------------------------------- /common/Interceptors.cpp: -------------------------------------------------------------------------------- 1 | /******************************************************************** 2 | Module : Interceptors.cpp - part of ApiSpyDll implementation 3 | Written 2003 by Dmitri Leman 4 | for an article about CE Api Spy. 5 | Purpose: Contains individual API interceptor routines for 6 | CreateFile, CreateProcess and LoadLibrary APIs. 7 | Function InstallInterceptors is used to install these interceptors. 8 | This file can be modified to monitor additional API routines. 9 | 10 | This file was compiled using eMbedded Visual C++ 3.0 11 | with Pocket PC 2002 SDK and 4.0 with Standard SDK. 12 | ********************************************************************/ 13 | 14 | #include 15 | //Redefinitions for some CE internal structures and undocumented API: 16 | #include "SysDecls.h" 17 | #include "SpyEngine.h" 18 | #include "HTrace.h" 19 | 20 | #pragma data_seg("SH_DATA") 21 | //The following are pointers to the original API routines, 22 | //which our interceptors should invoke. 23 | PFNVOID g_pOrigCreateWindow = NULL; 24 | PFNVOID g_pOrigCreateFile = NULL; 25 | PFNVOID g_pOrigCreateProcess = NULL; 26 | PFNVOID g_pOrigLoadLibrary = NULL; 27 | PFNVOID g_pOrigRegOpenKeyEx = NULL; 28 | 29 | #pragma data_seg() 30 | 31 | LONG HookRegOpenKeyEx( 32 | HKEY p_hKey, 33 | LPCTSTR p_lpSubKey, 34 | DWORD p_ulOptions, 35 | REGSAM p_samDesired, 36 | PHKEY p_phkResult 37 | ) 38 | { 39 | InterlockedIncrement(&g_SpyEngine.m_lNumCalls); 40 | InterlockedIncrement(&g_SpyEngine.m_lNumHooksActive); 41 | 42 | HANDLE l_hCurProc = GetCurrentProcess(); 43 | 44 | DWORD l_dwCurTrace = TraceGetAssignedGroupsToStream((DWORD)-1); 45 | if(l_dwCurTrace & TG_DebugSpyDetailed) 46 | {//Don't make extra calls unless trace is enabled 47 | HTRACE(TG_DebugSpyDetailed, 48 | _T("RegOpenKeyEx enter proc %x owner %x ") 49 | _T("caller %x call %x\r\n"), 50 | GetCurrentProcessId(), GetOwnerProcess(), 51 | GetCallerProcess(), g_pOrigCreateWindow); 52 | } 53 | LONG l_lResult = -1; 54 | //do original call 55 | if(g_pOrigRegOpenKeyEx) 56 | { 57 | l_lResult = ((LONG (*)( 58 | HKEY, LPCTSTR, DWORD, REGSAM, PHKEY))g_pOrigRegOpenKeyEx) 59 | ( 60 | p_hKey, 61 | p_lpSubKey, 62 | p_ulOptions, 63 | p_samDesired, 64 | p_phkResult 65 | ); 66 | } 67 | 68 | if(l_dwCurTrace & TG_InterceptedInfo) 69 | { 70 | //TCHAR needs a copy 71 | LPCWSTR l_pszSubKey = (LPCWSTR)MapPtrToProcess((LPVOID)p_lpSubKey, l_hCurProc); 72 | 73 | HTRACE(TG_InterceptedInfo, 74 | _T("HookRegOpenKeyEx(hKey:0x%08x, name:%x:'%s', opts:0x%08x, sam:0x%08x, hkey:0x%08x) ret 0x%08x err %d\r\n"), 75 | p_hKey, 76 | p_lpSubKey, l_pszSubKey, 77 | p_ulOptions, 78 | p_samDesired, 79 | p_phkResult, 80 | l_lResult, 81 | GetLastError()); 82 | } 83 | InterlockedDecrement(&g_SpyEngine.m_lNumHooksActive); 84 | return l_lResult; 85 | } 86 | 87 | /*------------------------------------------------------------- 88 | FUNCTION: HookCreateWindowW 89 | PURPOSE: Interceptor for CreateWindowW API 90 | Parameters and return value are identical to the documented 91 | CreateFile function. 92 | -------------------------------------------------------------*/ 93 | HANDLE HookCreateWindowW 94 | ( 95 | LPCWSTR p_lpFileName, 96 | DWORD p_dwDesiredAccess, 97 | DWORD p_dwShareMode, 98 | LPSECURITY_ATTRIBUTES p_lpSecurityAttributes, 99 | DWORD p_dwCreationDisposition, 100 | DWORD p_dwFlagsAndAttributes, 101 | HANDLE p_hTemplateFile 102 | ) 103 | { 104 | InterlockedIncrement(&g_SpyEngine.m_lNumCalls); 105 | InterlockedIncrement(&g_SpyEngine.m_lNumHooksActive); 106 | 107 | HANDLE l_hCurProc = GetCurrentProcess(); 108 | 109 | DWORD l_dwCurTrace = 110 | TraceGetAssignedGroupsToStream((DWORD)-1); 111 | if(l_dwCurTrace & TG_DebugSpyDetailed) 112 | {//Don't make extra calls unless trace is enabled 113 | HTRACE(TG_DebugSpyDetailed, 114 | _T("HookCreateFileW enter proc %x owner %x ") 115 | _T("caller %x call %x\r\n"), 116 | GetCurrentProcessId(), GetOwnerProcess(), 117 | GetCallerProcess(), g_pOrigCreateWindow); 118 | } 119 | 120 | HANDLE l_hResult = FALSE; 121 | if(g_pOrigCreateWindow) 122 | { 123 | l_hResult = ((HANDLE (*)( 124 | LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, 125 | DWORD, DWORD, HANDLE))g_pOrigCreateWindow) 126 | ( 127 | p_lpFileName, 128 | p_dwDesiredAccess, 129 | p_dwShareMode, 130 | p_lpSecurityAttributes, 131 | p_dwCreationDisposition, 132 | p_dwFlagsAndAttributes, 133 | p_hTemplateFile 134 | ); 135 | }//if(g_pOrigCreateWindow) 136 | 137 | if(l_dwCurTrace & TG_InterceptedInfo) 138 | { 139 | LPCWSTR l_pszMappedName = (LPCWSTR) 140 | MapPtrToProcess((LPVOID)p_lpFileName, l_hCurProc); 141 | 142 | HTRACE(TG_InterceptedInfo, 143 | _T("HookCreateFileW(%x:%s,%x,%x,%x) ret %x err %d\r\n"), 144 | p_lpFileName, l_pszMappedName, 145 | p_dwDesiredAccess, 146 | p_dwShareMode, 147 | p_dwFlagsAndAttributes, 148 | l_hResult, 149 | GetLastError()); 150 | } 151 | InterlockedDecrement(&g_SpyEngine.m_lNumHooksActive); 152 | return l_hResult; 153 | }//HANDLE HookCreateWindowW 154 | 155 | /*------------------------------------------------------------- 156 | FUNCTION: HookCreateFileW 157 | PURPOSE: Interceptor for CreateFileW API 158 | Parameters and return value are identical to the documented 159 | CreateFile function. 160 | -------------------------------------------------------------*/ 161 | HANDLE HookCreateFileW 162 | ( 163 | LPCWSTR p_lpFileName, 164 | DWORD p_dwDesiredAccess, 165 | DWORD p_dwShareMode, 166 | LPSECURITY_ATTRIBUTES p_lpSecurityAttributes, 167 | DWORD p_dwCreationDisposition, 168 | DWORD p_dwFlagsAndAttributes, 169 | HANDLE p_hTemplateFile 170 | ) 171 | { 172 | InterlockedIncrement(&g_SpyEngine.m_lNumCalls); 173 | InterlockedIncrement(&g_SpyEngine.m_lNumHooksActive); 174 | 175 | HANDLE l_hCurProc = GetCurrentProcess(); 176 | 177 | DWORD l_dwCurTrace = 178 | TraceGetAssignedGroupsToStream((DWORD)-1); 179 | if(l_dwCurTrace & TG_DebugSpyDetailed) 180 | {//Don't make extra calls unless trace is enabled 181 | HTRACE(TG_DebugSpyDetailed, 182 | _T("HookCreateFileW enter proc %x owner %x ") 183 | _T("caller %x call %x\r\n"), 184 | GetCurrentProcessId(), GetOwnerProcess(), 185 | GetCallerProcess(), g_pOrigCreateWindow); 186 | } 187 | 188 | HANDLE l_hResult = FALSE; 189 | if(g_pOrigCreateFile) 190 | { 191 | l_hResult = ((HANDLE (*)( 192 | LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, 193 | DWORD, DWORD, HANDLE))g_pOrigCreateFile) 194 | ( 195 | p_lpFileName, 196 | p_dwDesiredAccess, 197 | p_dwShareMode, 198 | p_lpSecurityAttributes, 199 | p_dwCreationDisposition, 200 | p_dwFlagsAndAttributes, 201 | p_hTemplateFile 202 | ); 203 | }//if(g_pOrigCreateFile) 204 | 205 | if(l_dwCurTrace & TG_InterceptedInfo) 206 | { 207 | LPCWSTR l_pszMappedName = (LPCWSTR) 208 | MapPtrToProcess((LPVOID)p_lpFileName, l_hCurProc); 209 | 210 | HTRACE(TG_InterceptedInfo, 211 | _T("HookCreateFileW(%x:%s,%x,%x,%x) ret %x err %d\r\n"), 212 | p_lpFileName, l_pszMappedName, 213 | p_dwDesiredAccess, 214 | p_dwShareMode, 215 | p_dwFlagsAndAttributes, 216 | l_hResult, 217 | GetLastError()); 218 | } 219 | InterlockedDecrement(&g_SpyEngine.m_lNumHooksActive); 220 | return l_hResult; 221 | }//HANDLE HookCreateFileW 222 | 223 | /*------------------------------------------------------------- 224 | FUNCTION: HookCreateProcessW 225 | PURPOSE: Interceptor for CreateProcessW API 226 | Parameters and return value are identical to the documented 227 | CreateProcess function. 228 | -------------------------------------------------------------*/ 229 | BOOL HookCreateProcessW 230 | ( 231 | LPCWSTR p_lpszImageName, 232 | LPCWSTR p_lpszCommandLine, 233 | LPSECURITY_ATTRIBUTES p_lpsaProcess, 234 | LPSECURITY_ATTRIBUTES p_lpsaThread, 235 | BOOL p_fInheritHandles, 236 | DWORD p_fdwCreate, 237 | LPVOID p_lpvEnvironment, 238 | LPWSTR p_lpszCurDir, 239 | LPSTARTUPINFO p_lpsiStartInfo, 240 | LPPROCESS_INFORMATION p_lppiProcInfo 241 | ) 242 | { 243 | InterlockedIncrement(&g_SpyEngine.m_lNumCalls); 244 | InterlockedIncrement(&g_SpyEngine.m_lNumHooksActive); 245 | 246 | HANDLE l_hCurProc = GetCurrentProcess(); 247 | 248 | DWORD l_dwCurTrace = 249 | TraceGetAssignedGroupsToStream((DWORD)-1); 250 | if(l_dwCurTrace & TG_DebugSpyDetailed) 251 | {//Don't make extra calls unless trace is enabled 252 | HTRACE(TG_DebugSpyDetailed, 253 | _T("HookCreateProcessW enter proc %x owner %x ") 254 | _T("caller %x call %x\r\n"), 255 | GetCurrentProcessId(), GetOwnerProcess(), 256 | GetCallerProcess(), g_pOrigCreateProcess); 257 | } 258 | 259 | LPCWSTR l_pszMappedName = NULL, l_pszMappedLine = NULL; 260 | if(l_dwCurTrace & TG_InterceptedInfo) 261 | { 262 | l_pszMappedName = (LPCWSTR) 263 | MapPtrToProcess((LPVOID)p_lpszImageName, l_hCurProc); 264 | l_pszMappedLine = (LPCWSTR) 265 | MapPtrToProcess((LPVOID)p_lpszCommandLine, l_hCurProc); 266 | HTRACE(TG_InterceptedInfo, 267 | _T("->HookCreateProcessW(%x:%s,%x:%s)\r\n"), 268 | p_lpszImageName, l_pszMappedName, 269 | p_lpszCommandLine, l_pszMappedLine); 270 | } 271 | 272 | BOOL l_bResult = FALSE; 273 | if(g_pOrigCreateProcess) 274 | { 275 | l_bResult = ((BOOL (*)( 276 | LPCWSTR, LPCWSTR, LPSECURITY_ATTRIBUTES, 277 | LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPWSTR, 278 | LPSTARTUPINFO, LPPROCESS_INFORMATION)) 279 | g_pOrigCreateProcess) ( 280 | p_lpszImageName, 281 | p_lpszCommandLine, 282 | p_lpsaProcess, 283 | p_lpsaThread, 284 | p_fInheritHandles, 285 | p_fdwCreate, 286 | p_lpvEnvironment, 287 | p_lpszCurDir, 288 | p_lpsiStartInfo, 289 | p_lppiProcInfo 290 | ); 291 | }//if(g_pOrigCreateProcess) 292 | 293 | if(l_dwCurTrace & TG_InterceptedInfo) 294 | { 295 | HTRACE(TG_InterceptedInfo, 296 | _T("<-HookCreateProcessW(%x:%s,%x:%s)ret %x err %d\r\n"), 297 | p_lpszImageName, l_pszMappedName, 298 | p_lpszCommandLine, l_pszMappedLine, 299 | l_bResult, GetLastError()); 300 | } 301 | InterlockedDecrement(&g_SpyEngine.m_lNumHooksActive); 302 | return l_bResult; 303 | }//BOOL HookCreateProcessW 304 | 305 | /*------------------------------------------------------------- 306 | FUNCTION: HookLoadLibraryW 307 | PURPOSE: Interceptor for LoadLibraryW API 308 | Parameters and return value are identical to the documented 309 | LoadLibraryW function. 310 | -------------------------------------------------------------*/ 311 | HANDLE HookLoadLibraryW 312 | ( 313 | LPCTSTR p_lpszFileName 314 | ) 315 | { 316 | InterlockedIncrement(&g_SpyEngine.m_lNumCalls); 317 | InterlockedIncrement(&g_SpyEngine.m_lNumHooksActive); 318 | 319 | HANDLE l_hCurProc = GetCurrentProcess(); 320 | 321 | DWORD l_dwCurTrace = 322 | TraceGetAssignedGroupsToStream((DWORD)-1); 323 | if(l_dwCurTrace & TG_DebugSpyDetailed) 324 | {//Don't make extra calls unless trace is enabled 325 | HTRACE(TG_DebugSpyDetailed, 326 | _T("HookLoadLibraryW enter proc %x owner %x ") 327 | _T("caller %x call %x\r\n"), 328 | GetCurrentProcessId(), GetOwnerProcess(), 329 | GetCallerProcess(), g_pOrigLoadLibrary); 330 | } 331 | LPCWSTR l_pszMappedName = NULL; 332 | if(l_dwCurTrace & TG_InterceptedInfo) 333 | { 334 | l_pszMappedName = (LPCWSTR) 335 | MapPtrToProcess((LPVOID)p_lpszFileName, l_hCurProc); 336 | 337 | HTRACE(TG_InterceptedInfo, 338 | _T("->HookLoadLibraryW(%x:%s)\r\n"), 339 | p_lpszFileName, l_pszMappedName); 340 | } 341 | 342 | HANDLE l_hResult = FALSE; 343 | if(g_pOrigLoadLibrary) 344 | { 345 | l_hResult = ((HANDLE (*)(LPCTSTR p_lpszFileName)) 346 | g_pOrigLoadLibrary) 347 | (p_lpszFileName); 348 | }//if(g_pOrigLoadLibrary) 349 | 350 | if(l_dwCurTrace & TG_InterceptedInfo) 351 | { 352 | HTRACE(TG_InterceptedInfo, 353 | _T("<-HookLoadLibraryW(%x:%s) ret %x err %d\r\n"), 354 | p_lpszFileName, l_pszMappedName, 355 | l_hResult, GetLastError()); 356 | } 357 | InterlockedDecrement(&g_SpyEngine.m_lNumHooksActive); 358 | return l_hResult; 359 | }//HANDLE HookLoadLibraryW 360 | 361 | /*------------------------------------------------------------- 362 | FUNCTION: InstallInterceptors 363 | PURPOSE: Customizable routine, which is called by the Spy 364 | engine to install individual interceptors. 365 | -------------------------------------------------------------*/ 366 | BOOL InstallInterceptors() 367 | { 368 | //g_pOrigCreateWindow = g_SpyEngine.HookMethod 369 | // (SH_WIN32, CreateWindowW, 370 | // (PFNVOID)HookCreateWindowW); 371 | 372 | HTRACE(TG_DebugSpyBrief, _T("HookRegOpenKeyEx api set #%i, method #%i\r\n"), SH_SHELL, SH32_RegOpenKeyEx); 373 | g_pOrigRegOpenKeyEx = g_SpyEngine.HookMethod 374 | (SH_SHELL, SH32_RegOpenKeyEx, 375 | (PFNVOID)HookRegOpenKeyEx); 376 | 377 | HTRACE(TG_DebugSpyBrief, _T("HookCreateFileW api set #%i, method #%i\r\n"), SH_FILESYS_APIS, FILESYS_CreateFile); 378 | g_pOrigCreateFile = g_SpyEngine.HookMethod 379 | (SH_FILESYS_APIS, FILESYS_CreateFile, 380 | (PFNVOID)HookCreateFileW); 381 | 382 | HTRACE(TG_DebugSpyBrief, _T("HookCreateProcessW api set #%i, method #%i\r\n"), SH_WIN32, W32_CreateProc); 383 | g_pOrigCreateProcess = g_SpyEngine.HookMethod 384 | (SH_WIN32, W32_CreateProc, 385 | (PFNVOID)HookCreateProcessW); 386 | 387 | HTRACE(TG_DebugSpyBrief, _T("HookLoadLibraryW api set #%i, method #%i\r\n"), SH_WIN32, W32_LoadLibraryW); 388 | g_pOrigLoadLibrary = g_SpyEngine.HookMethod 389 | (SH_WIN32, W32_LoadLibraryW, 390 | (PFNVOID)HookLoadLibraryW); 391 | 392 | //test CreateFile hook 393 | HTRACE(TG_InterceptedInfo, _T("Before test CreateFile")); 394 | CreateFile(_T("Test file"), GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); 395 | HTRACE(TG_InterceptedInfo, _T("After test CreateFile")); 396 | 397 | return TRUE; 398 | }//BOOL InstallInterceptors() 399 | -------------------------------------------------------------------------------- /common/SpyControl.h: -------------------------------------------------------------------------------- 1 | /******************************************************************** 2 | Module : SpyControl.h - part of ApiSpyDll implementation 3 | Written 2003 by Dmitri Leman 4 | for an article about CE Api Spy. 5 | Purpose: Contains some common declarations 6 | 7 | This file was compiled using eMbedded Visual C++ 3.0 8 | with Pocket PC 2002 SDK and 4.0 with Standard SDK. 9 | ********************************************************************/ 10 | 11 | #ifndef _SPY_CONTROL_H_ 12 | #define _SPY_CONTROL_H_ 13 | 14 | static const TCHAR s_szApiSpyDll[] = _T("ApiSpyDll.dll"); 15 | static const TCHAR s_szSettingsRegPath[] = _T("Software\\ApiSpy"); 16 | static const TCHAR s_szTraceMapFile[] = _T("HckMap.txt"); 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /common/SpyEngine.h: -------------------------------------------------------------------------------- 1 | /******************************************************************** 2 | Module : SpyEngine.h - part of ApiSpyDll implementation 3 | Written 2003 by Dmitri Leman 4 | for an article about CE Api Spy. 5 | Purpose: Contains declaration of SpyEngine structure. 6 | 7 | This file was compiled using eMbedded Visual C++ 3.0 8 | with Pocket PC 2002 SDK and 4.0 with Standard SDK. 9 | ********************************************************************/ 10 | 11 | #ifndef _SPY_ENGINE_H_ 12 | #define _SPY_ENGINE_H_ 13 | 14 | #include 15 | 16 | //Redefinitions for some CE internal structures and undocumented APIs 17 | #include "SysDecls.h" 18 | 19 | extern BOOL InstallInterceptors(); 20 | 21 | struct CINFO; 22 | 23 | #define NUM_SYSTEM_SETS 32 //size of system API table 24 | 25 | /* 26 | struct HookedAPI holds information for one system API, 27 | which is hooked by us. 28 | */ 29 | struct HookedAPI 30 | { 31 | BOOL m_bUsed; 32 | BOOL m_bSwapped; 33 | int m_iOrigApiSetId; 34 | CINFO * m_pOrigApiSet; 35 | CINFO * m_pOurApiSet; 36 | }; 37 | 38 | /* 39 | struct SpyEngine is the main data of the Spy engine. 40 | Only one static instance exists. 41 | */ 42 | struct SpyEngine 43 | { 44 | //API for custom interceptors: 45 | PFNVOID HookMethod(int p_iAPISetId, int p_iMethodIndex, 46 | PFNVOID p_pHookMethod); 47 | 48 | //Implementation: 49 | 50 | //CE has up to 32 running processes. 51 | //Therefore, reserve 32 PROCESSENTRY32 structures indexed by the 52 | //process slot number. 53 | PROCESSENTRY32 m_Processes[32]; 54 | 55 | //Since we load SpyDll into all running processes, 56 | //we need to keep handles in m_hSpyDllLoaded 57 | HINSTANCE m_hSpyDllLoaded[32]; 58 | 59 | //Address of the memory slot of the ApiSpy process. 60 | DWORD m_dwCurrentProcBase; 61 | 62 | DWORD m_dwOrigThreadId; 63 | 64 | //Pointer to an array of system APIs. 65 | CINFO ** m_pSystemAPISets; 66 | 67 | //Pointers to the kernel Win32 method table 68 | //and extra methods table. 69 | PFNVOID * m_ppWin32Methods; 70 | PFNVOID * m_ppExtraMethods; 71 | 72 | PFNVOID * m_ppHookWin32Methods; 73 | DWORD * m_pdwHookWin32Signatures; 74 | 75 | PFNVOID * m_ppHookExtraMethods; 76 | DWORD * m_pdwHookExtraSignatures; 77 | #define SIZE_EXTRA_TABLE 256 //no way to know the actual size 78 | 79 | HANDLE m_hOurApiHandle; 80 | int m_iNumOurApiMethods; 81 | PFNVOID * m_ppOurApiMethods; 82 | DWORD * m_pdwOurApiSignatures; 83 | 84 | int m_iHookAPISetID; 85 | CINFO * m_pHookAPISet; 86 | 87 | LPTSTR m_pszSpyDllPathInKernelMemory; 88 | 89 | PFNVOID m_pOriginalLoadLibrary; 90 | 91 | BOOL m_bCoredllHooked; 92 | 93 | long m_lNumCalls; 94 | long m_lNumHooksActive; 95 | 96 | //Reserve a table for all system APIs. 97 | HookedAPI m_HookedAPI[NUM_SYSTEM_SETS]; 98 | 99 | BOOL DoStart(); 100 | BOOL DoStop(); 101 | 102 | BOOL CreateDuplicateApi(int p_iAPISetId); 103 | 104 | HINSTANCE LoadHookDllIntoProcess(HANDLE p_hProcess); 105 | BOOL UnloadHookDllInProcess 106 | (HANDLE p_hProcess, HINSTANCE p_hInst); 107 | void LoadHookDllInAllProcesses(); 108 | PFNVOID SetPrivateApiMethod(PFNVOID p_pHookMethod); 109 | 110 | };//struct SpyEngine 111 | 112 | extern SpyEngine g_SpyEngine; 113 | //The only static instance of SpyEngine. 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /common/SysDecls.h: -------------------------------------------------------------------------------- 1 | /******************************************************************** 2 | Module : SpyEngine.h - part of CeApiSpyDll implementation 3 | Written 2003 by Dmitri Leman 4 | for an article about CE Api Spy. 5 | Purpose: Contains redefinitions for some CE internal 6 | structures and undocumented APIs 7 | 8 | This file was compiled using eMbedded Visual C++ 3.0 9 | with Pocket PC 2002 SDK and 4.0 with Standard SDK. 10 | ********************************************************************/ 11 | 12 | #ifndef _SYS_DECLS_H_ 13 | #define _SYS_DECLS_H_ 14 | 15 | /******** Beginning of undocumented functions declarations *******/ 16 | extern "C" 17 | { 18 | //The following functions exported from coredll.dll are documented in 19 | //Platform Builder help and declared in 20 | //PUBLIC\COMMON\OAK\INC\pkfuncs.h, 21 | //but not in SDK, so declare them here: 22 | DWORD __stdcall SetProcPermissions(DWORD); 23 | LPVOID __stdcall MapCallerPtr(LPVOID ptr, DWORD dwLen); 24 | LPVOID __stdcall MapPtrToProcess (LPVOID lpv, HANDLE hProc); 25 | LPVOID __stdcall UnMapPtr(LPVOID lpv); 26 | HANDLE __stdcall GetOwnerProcess (void); 27 | HANDLE __stdcall GetCallerProcess (void); 28 | BOOL __stdcall SetKMode(BOOL fMode); 29 | BOOL __stdcall IsAPIReady(DWORD hAPI); 30 | 31 | //The following are undocumented structures declared in 32 | //PUBLIC\COMMON\OAK\INC\pkfuncs.h, which we have to redeclare here. 33 | //WARNING: undocumented structures and functions may change in the 34 | //future. 35 | struct CALLBACKINFO 36 | { 37 | HANDLE m_hDestinationProcessHandle; 38 | FARPROC m_pFunction; 39 | PVOID m_pFirstArgument; 40 | }; 41 | 42 | //The following undocumented functions exported from coredll.dll 43 | //and declared in PUBLIC\COMMON\OAK\INC\pkfuncs.h, 44 | //but not in SDK, so declare them here: 45 | //WARNING: undocumented structures and functions may change in the 46 | //future. 47 | HANDLE __stdcall CreateAPISet(char acName[4], USHORT cFunctions, 48 | const PFNVOID *ppfnMethods, const DWORD *pdwSig); 49 | BOOL __stdcall RegisterAPISet(HANDLE hASet, DWORD dwSetID); 50 | int __stdcall QueryAPISetID(char *pName); 51 | FARPROC __stdcall GetAPIAddress(int setId, int iMethod); 52 | HLOCAL __stdcall LocalAllocInProcess(UINT uFlags, UINT uBytes, 53 | HPROCESS hProc); 54 | HANDLE __stdcall GetProcFromPtr(LPVOID p); 55 | DWORD __stdcall PerformCallBack4(CALLBACKINFO *pcbi, 56 | DWORD dw1, DWORD dw2, DWORD dw3); 57 | BOOL __stdcall GetRomFileInfo(DWORD type, 58 | LPWIN32_FIND_DATA lpfd, DWORD count); 59 | DWORD __stdcall GetProcessIndexFromID(HANDLE hProc); 60 | LPBYTE __stdcall THCreateSnapshot(DWORD dwFlags, DWORD dwProcID); 61 | 62 | /* 63 | The formula ((0xFFFFFE00-TRAP)/2),x (or ((0xF0010000-TRAP)/4),x on ARM CPUs) lets you 64 | obtain method index (low-order byte) and API index (second byte). Then you use the 65 | API index to get pointer to CINFO from SystemAPISets, and the method index to get 66 | the method address from the method table. Alternatively, you can use method 67 | DumpApis() in CeApiSpy (available electronically) to dump all registered APIs 68 | and their methods. 69 | 70 | storemgr.h: 71 | #define IMPLICIT_CALL(hid, mid) (FIRST_METHOD - ((hid)<