home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l430 / 1.ddi / CHAP5.ZIP / STEALCDR.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-11  |  5.3 KB  |  227 lines

  1. /*
  2.     STEALCDR.C -- Circumventing FileCdr to hook file system events
  3.  
  4.     Copyright (c) Dave Maxey 1992
  5.     
  6.     From Chapter 5 of "Undocumented Windows" (Addison-Wesley 1992)
  7.     by Andrew Schulman, Dave Maxey and Matt Pietrek
  8.  
  9.     Build using: WINIOBC STEALCDR HANDLES (for Borland C++ v3.00)
  10.                  WINIOMS STEALCDR HANDLES (for Microsoft C/SDK)
  11. */
  12.  
  13. #include <windows.h>
  14. #include <toolhelp.h>
  15. #include <dos.h>
  16. #include "wmhandlr.h"
  17. #include "winio.h"
  18. #include "handles.h"
  19.  
  20.  
  21. #define WM_FILESYSCHANGE        0x0034
  22.  
  23. //extern FARPROC FAR PASCAL FileCdr(FARPROC lpfnFileSysChangeNotifyProc);
  24. void GetSetFileCdr(BOOL bSet, FARPROC *lpfn, HANDLE *ph);
  25. BOOL IsATask(HANDLE h);
  26. WORD far *GetTHH(void);
  27.  
  28. FARPROC lpfnCallbackPrev = NULL;
  29. FARPROC lpfnCallbackOurs;
  30. HANDLE hTaskPrev = NULL;
  31. HANDLE hTaskOurs;
  32. LPVOID lpTHH;
  33.  
  34. typedef struct { BYTE byAction; LPSTR szAction; } ACTION;
  35. ACTION action[] = {
  36.     { 0x3C, "Create file" },
  37.     { 0x41, "Delete file" },
  38.     { 0x56, "Rename file/directory" },
  39.     { 0x5A, "Create unique file" },
  40.     { 0x43, "Get/set file attrs" },
  41.     { 0x57, "Set file date/time" },
  42.     { 0x5B, "Create new file" },
  43.     { 0x39, "Create directory" },
  44.     { 0x3A, "Delete directory" },
  45.     { 0x6C, "Extended open" },
  46.     { 0, 0 } };
  47.  
  48.  
  49. #define THH_OFS_FILECDR_30        0x0185
  50. #define THH_OFS_FILECDR_31        0x00FE
  51.  
  52. void GetSetFileCdr(BOOL bSet, FARPROC *lpfn, HANDLE *ph)
  53.     {
  54.     LPVOID lp = lpTHH;
  55.     
  56.     (DWORD) lp += (GetVersion() >= 0x0a03) ? THH_OFS_FILECDR_31
  57.         : THH_OFS_FILECDR_30;
  58.     
  59.     if (bSet)
  60.         {
  61.         *((FARPROC FAR *) lp)++ = *lpfn;
  62.         *((HANDLE FAR *) lp) = *ph;
  63.         }
  64.     else
  65.         {
  66.         *lpfn = *((FARPROC FAR *) lp)++;
  67.         *ph = *((HANDLE FAR *) lp);
  68.         }
  69.     }
  70.  
  71.  
  72.  
  73. void PutBackPrev(HWND hwnd)
  74.     {
  75.     // Deinstall our callback function and reinstall whoever was
  76.     // there before if they are still there
  77.     if (! IsATask(hTaskPrev))
  78.         {
  79.         lpfnCallbackPrev = NULL;
  80.         hTaskPrev = NULL;
  81.         }
  82.     GetSetFileCdr(TRUE, &lpfnCallbackPrev, &hTaskPrev);
  83.  
  84.     FreeProcInstance(lpfnCallbackOurs);
  85.     }
  86.  
  87.  
  88. long fsc_handler(HWND hwnd, WORD wMsg, WORD wParam, DWORD lParam)
  89.     {
  90.     printf("WM_FILESYSCHANGE %Fs, l=%08X\n",
  91.         action[wParam].szAction, lParam);
  92.     return 0;
  93.     }
  94.  
  95.  
  96. char *GetModuleNameFromTask(HANDLE handle)
  97.     {
  98.     TASKENTRY   te;
  99.     static char name[40];
  100.  
  101.     te.dwSize = sizeof(te);
  102.     if ( TaskFindHandle(&te, handle) )
  103.         {
  104.         lstrcpy(name, te.szModule);
  105.         return name;
  106.         }
  107.  
  108.     lstrcpy(name, "**UNKNOWN**");
  109.     return name;
  110.     }
  111.  
  112. void FAR PASCAL _export FileSysChange(WORD wActionCode, LPSTR lpszFilestring)
  113.     {
  114.     int i;
  115.     static char buf[128];
  116.     
  117.     // Locate string representation of action code
  118.     for (i = 0; action[i].byAction; i++)
  119.         if (HIBYTE(wActionCode) == action[i].byAction) break;
  120.     
  121.     // We can't call anything that will use vsprintf, since it
  122.     // relies on SS == DS which is not true in SMALL model
  123.     wsprintf(buf,
  124.         action[i].byAction ? "Module %s, %s: %s" : "Module %s, %04lX: %s",
  125.         (LPSTR) GetModuleNameFromTask(GetCurrentTask()),
  126.         action[i].byAction ? action[i].szAction : (DWORD) wActionCode,
  127.         lpszFilestring);
  128.     puts(buf);
  129.     
  130.     // Trying to be generous, but may backfire
  131.     if (lpfnCallbackPrev)
  132.         if (IsATask(hTaskPrev))
  133.             (*lpfnCallbackPrev)(wActionCode, lpszFilestring);
  134.         else
  135.             {
  136.             lpfnCallbackPrev = NULL;
  137.             hTaskPrev = NULL;
  138.             }
  139.     }
  140.  
  141.  
  142. int main()
  143.     {
  144.     winio_about("STEALCDR"
  145.         "\nCircumventing FileCdr to hook file system events"
  146.         "\n\nFrom Chapter 5 of"
  147.         "\n\"Undocumented Windows\" (Addison-Wesley, 1992)"
  148.         "\nby Andrew Schulman, David Maxey and Matt Pietrek"
  149.         );
  150.     
  151.     lpfnCallbackOurs = MakeProcInstance((FARPROC) FileSysChange, __hInst);
  152.     hTaskOurs = GetCurrentTask();
  153.     
  154.     if (! (lpTHH = GetTHH()))
  155.         fail("Could not locate KERNEL's DGROUP.");
  156.     
  157.     GetSetFileCdr(FALSE, &lpfnCallbackPrev, &hTaskPrev);
  158.     if (lpfnCallbackPrev != NULL)
  159.         printf("Someone already had FileCdr!\n");
  160.     
  161.     printf("Installing our callback function.\n");
  162.     GetSetFileCdr(TRUE, &lpfnCallbackOurs, &hTaskOurs);
  163.  
  164.     wmhandler_set(__hMainWnd, WM_FILESYSCHANGE, (WMHANDLER) fsc_handler);
  165.     
  166.     winio_onclose(__hMainWnd, (DESTROY_FUNC) PutBackPrev);
  167.     return 0;
  168.     }
  169.  
  170.  
  171. #define TDB_SIGNATURE            0x4454
  172. #define TDB_OFS_SIGNATURE        0xFA
  173.  
  174. BOOL IsATask(HANDLE h)
  175.     {
  176.     WORD wLen = 0;
  177.     
  178.     // Is handle a valid selector
  179.     _asm mov bx, [h];
  180.     _asm or bx, bx;
  181.     _asm jz done;
  182.     _asm lsl ax, bx
  183.     _asm jnz done;
  184.     _asm mov [wLen], ax;
  185. done:    
  186.     if (!wLen || (wLen < TDB_OFS_SIGNATURE + 2))
  187.         return FALSE;
  188.     
  189.     return *((WORD far *) MK_FP(h, TDB_OFS_SIGNATURE)) == TDB_SIGNATURE;
  190.     }
  191.  
  192.  
  193. #define THH_OFS                    0x10
  194.  
  195. #define NEMAGIC                    0x454E
  196.  
  197. #define MAGIC(lpNEhdr)            *((WORD FAR *) &lpNEhdr[0])
  198. #define DGROUP(lpNEhdr)            *((WORD FAR *) &lpNEhdr[0x0e])
  199. #define SEGTAB(lpNEhdr)            *((WORD FAR *) &lpNEhdr[0x22])
  200.  
  201. typedef struct {
  202.     WORD ns_sector, ns_cbseg, ns_flags, ns_minalloc, ns_seg;
  203.     } SEG;
  204.  
  205. WORD far *GetTHH(void)
  206.     {
  207.     HANDLE hMod;
  208.     BYTE far *nehdr;
  209.     SEG far *segtab;
  210.     WORD dgroup;
  211.  
  212.     if (GetVersion() >= 0x0a03)
  213.         return (WORD far *)
  214.             GetProcAddress(GetModuleHandle("KERNEL"), "THHOOK"); 
  215.         
  216.     nehdr = MK_FP(hMod = GetModuleHandle("KERNEL"), 0);
  217.     
  218.     if (MAGIC(nehdr) != NEMAGIC) return 0;
  219.     
  220.     segtab = MK_FP(hMod, SEGTAB(nehdr));
  221.     dgroup = DGROUP(nehdr);
  222.     
  223.     return MK_FP(segtab[dgroup - 1].ns_seg, THH_OFS);
  224.     }
  225.  
  226.  
  227.