BehaviorMon.c
上传用户:xuemeng126
上传日期:2022-07-05
资源大小:454k
文件大小:84k
源码类别:

系统编程

开发平台:

Visual C++

  1. //////////////////////////////////////////////////////////////////////////
  2. //头文件
  3. #include "ntddk.h"
  4. #include "stdio.h" 
  5. #include "ntifs.h"
  6. #include "BehaviorMon.h"
  7. //from regmon
  8. #include "stdarg.h" 
  9. #include "IoctlCmd.h" 
  10. #include "ksecdd.h"
  11. #include "ntsec.h"
  12. #include "regsys.h"
  13. #include "reglib.h" 
  14. #pragma comment(lib,"regmlib.lib")
  15. #pragma comment(lib,"ksecdd.lib")
  16. //宏定义
  17. #define SYSNAME "System"
  18. #define NT_PROCNAMELEN 16 
  19. #define ObjectNameInformation (1)
  20. #define STATUS_INFO_LEN_MISMATCH       0xC0000004
  21. #define DELAYTIME -10
  22. //类型定义
  23. typedef unsigned long DWORD;
  24. //typedef void* PVOID;
  25. //结构体定义
  26. struct SYS_SERVICE_TABLE { 
  27. void **ServiceTable; 
  28. unsigned long CounterTable; 
  29. unsigned long ServiceLimit; 
  30. void **ArgumentsTable; 
  31. }; 
  32. //保存被hook的nativeAPI函数信息
  33. typedef struct {
  34. const char * nativeAPIname;//函数名称
  35. ULONG Index;//在描述符表中的代号
  36. ULONG RealCallee;//真正的地址
  37. ULONG proxyfunadd;//代理函数地址
  38. BOOL  hooked;
  39. }HOOKED_API_INFO;
  40. HOOKED_API_INFO hook_API_info[100];
  41. int hook_num=0;
  42. //交互缓冲区,驱动往里写,前台往出读,做显示
  43. typedef struct{
  44. char IsRead;
  45. char ProcessName[32];
  46. char NativeAPIName[32];
  47. char ProcessFullName[512];
  48. char Behavior[1024];
  49. char Result[64];
  50. char Time[16];
  51. }LOG_BEHAVIOR,* PLOG_BEHAVIOR;
  52. int curr_write_pointer=0;
  53. BOOL can_use_curr_write_pointer=TRUE;
  54. DWORD LOG_BEHAVIOR_NUM=10;
  55. PLOG_BEHAVIOR plog_behavior;
  56. //////////////////////////////////////////////////////////////////////////
  57. //常量
  58. const WCHAR devicename[]=L"\Device\BehaviorMon";
  59. const WCHAR devicelink[]=L"\DosDevices\BEHAVIORMON"; 
  60. // Is registry hooked? 
  61. BOOLEAN Hooked = FALSE;
  62. //ProcessName在EPROCESS结构体中的偏移量,不同操作系统不同
  63. //xp:0x174 2k:0x1fc
  64. ULONG ProcessNameOffset;
  65. //事件
  66. KEVENT event; 
  67. //真正NativeAPI函数的地址
  68. ULONG Index,RealCallee;
  69. //与前台的交换缓冲区
  70. //char*plog_behavior;
  71. char*tmp;
  72. int i=0;
  73. int goornot=0;
  74. //windows系统服务描述符表
  75. extern struct SYS_SERVICE_TABLE *KeServiceDescriptorTable; 
  76. PVOID                   *KeServiceTablePointers;
  77. SERVICE_HOOK_DESCRIPTOR *HookDescriptors;
  78. //要监控的程序全路径
  79. char processname_G[1024];
  80. //
  81. // Full path name lookaside 
  82. //
  83. //非分页内存
  84. PAGED_LOOKASIDE_LIST  FullPathLookaside;
  85. //
  86. // Lenghs of rootkeys (filled in at init). This table allows us to translate 
  87. // path names into better-known forms. Current user is treated specially since
  88. // its not a full match.
  89. //
  90. ROOTKEY CurrentUser[2] = {
  91. { "\\REGISTRY\USER\S", "HKCU", 0 },
  92. { "HKU\S", "HKCU", 0 }
  93. };
  94. ROOTKEY RootKey[NUMROOTKEYS] = {
  95. { "\\REGISTRY\USER", "HKU", 0 },
  96. { "\\REGISTRY\MACHINE\SYSTEM\CURRENTCONTROLSET\HARDWARE PROFILES\CURRENT", 
  97. "HKCC", 0 },
  98. { "\\REGISTRY\MACHINE\SOFTWARE\CLASSES", "HKCR", 0 },
  99. { "\\REGISTRY\MACHINE", "HKLM", 0 }
  100. };
  101. //
  102. // This is a hash table for keeping names around for quick lookup.
  103. //
  104. PHASH_ENTRY             HashTable[NUMHASH];
  105. //
  106. // Mutex for hash table accesses
  107. //
  108. KMUTEX                  HashMutex;
  109. //
  110. // Data structure for storing messages we generate
  111. //
  112. PLOG_BUF                Log           = NULL;
  113. ULONG                   Sequence      = 0;
  114. LARGE_INTEGER           StartTime;
  115. KMUTEX                  LogMutex;
  116. //
  117. // Maximum amount of data we will grab for buffered unread data
  118. //
  119. ULONG                   NumLog        = 0;
  120. ULONG                   MaxLog        = MAXMEM/LOGBUFSIZE;
  121. //
  122. // Global error string
  123. //
  124. CHAR                    errstring[256];
  125. //
  126. // A unicode string constant for the "default" value
  127. //
  128. #define DEFAULTNAMELEN  (9*sizeof(WCHAR))
  129. WCHAR                   DefaultValueString[] = L"(Default)";
  130. UNICODE_STRING          DefaultValue = {
  131.     DEFAULTNAMELEN,
  132. DEFAULTNAMELEN,
  133. DefaultValueString
  134. };
  135. //======================================================================
  136. //                   B U F F E R  R O U T I N E S 
  137. //======================================================================
  138. //----------------------------------------------------------------------
  139. //
  140. // ApplyNameFilter
  141. //
  142. // If the name matches the exclusion mask, we do not log it. Else if
  143. // it doesn't match the inclusion mask we do not log it. 
  144. //
  145. //----------------------------------------------------------------------
  146. BOOLEAN
  147. ApplyFilters( 
  148.  PCHAR fullname 
  149.  )
  150. {
  151. return TRUE;
  152. }
  153. //----------------------------------------------------------------------
  154. //
  155. // RegmonFreeLog
  156. //
  157. // Frees all the data output buffers that we have currently allocated.
  158. //
  159. //----------------------------------------------------------------------
  160. VOID 
  161. RegmonFreeLog(
  162.   VOID
  163.   )
  164. {
  165. PLOG_BUF      next;
  166. //
  167. // Just traverse the list of allocated output buffers
  168. //
  169. while( Log ) {
  170. next = Log->Next;
  171. ExFreePool( Log );
  172. Log = next;
  173. }
  174. }       
  175. //----------------------------------------------------------------------
  176. //
  177. // RegmonNewLog
  178. //
  179. // Called when the current buffer has filled up. This moves us to the
  180. // pre-allocated buffer and then allocates another buffer.
  181. //
  182. //----------------------------------------------------------------------
  183. VOID 
  184. RegmonNewLog( 
  185.  VOID 
  186.  )
  187. {
  188. PLOG_BUF prev = Log, newLog; 
  189. //
  190. // If we have maxed out or haven't accessed the current Log
  191. // just return
  192. //
  193. if( MaxLog == NumLog ) {
  194. Log->Len = 0;
  195. return; 
  196. }
  197. //
  198. // See if we can re-use a Log
  199. //
  200. if( !Log->Len ) {
  201. return;
  202. }
  203. //
  204. // Move to the next buffer and allocate another one
  205. //
  206. newLog = ExAllocatePool( PagedPool, sizeof(*Log) );
  207. if( newLog ) { 
  208. //
  209. // Allocation was successful so add the buffer to the list
  210. // of allocated buffers and increment the buffer count.
  211. //
  212. Log   = newLog;
  213. Log->Len  = 0;
  214. Log->Next = prev;
  215. NumLog++;
  216. } else {
  217. //
  218. // The allocation failed - just reuse the current buffer
  219. //
  220. Log->Len = 0;
  221. }
  222. }
  223. //----------------------------------------------------------------------
  224. //
  225. // RegmonOldestLog
  226. //
  227. // Goes through the linked list of storage buffers and returns the 
  228. // oldest one.
  229. //
  230. //----------------------------------------------------------------------
  231. PLOG_BUF 
  232. RegmonOldestLog( 
  233. VOID 
  234. )
  235. {
  236. PLOG_BUF  ptr = Log, prev = NULL;
  237. //
  238. // Traverse the list
  239. //
  240. while( ptr->Next ) {
  241. ptr = (prev = ptr)->Next;
  242. }
  243. //
  244. // Remove the buffer from the list
  245. //
  246. if( prev ) {
  247. prev->Next = NULL;    
  248. NumLog--;
  249. }
  250. return ptr;
  251. }
  252. //----------------------------------------------------------------------
  253. //
  254. // RegmonResetLog
  255. //
  256. // When a GUI is no longer communicating with us, but we can't unload,
  257. // we reset the storage buffers.
  258. //
  259. //----------------------------------------------------------------------
  260. VOID
  261. RegmonResetLog(
  262.    VOID
  263.    )
  264. {
  265. PLOG_BUF  current, next;
  266. MUTEX_ACQUIRE( LogMutex );
  267. //
  268. // Traverse the list of output buffers
  269. //
  270. current = Log->Next;
  271. while( current ) {
  272. //
  273. // Free the buffer
  274. //
  275. next = current->Next;
  276. ExFreePool( current );
  277. current = next;
  278. }
  279. // 
  280. // Move the output pointer in the buffer that's being kept
  281. // the start of the buffer.
  282. // 
  283. NumLog = 1;
  284. Log->Len = 0;
  285. Log->Next = NULL;
  286. MUTEX_RELEASE( LogMutex );
  287. }
  288. //----------------------------------------------------------------------
  289. //
  290. // LogRecord
  291. //
  292. // Add a new string to Log, if it fits. 
  293. //
  294. //----------------------------------------------------------------------
  295. VOID 
  296. LogRecord( 
  297.   const char * format, 
  298.   ... 
  299.   )
  300. PENTRY          Entry;
  301. ULONG           len;
  302. va_list         arg_ptr;
  303. static CHAR     text[MAXPATHLEN + MAXDATALEN + MAXPROCNAMELEN + MAXERRORLEN];
  304. #define A (&format)
  305. //KdPrint(( (char *)format, A[1], A[2], A[3], A[4], A[5], A[6] ));
  306. //KdPrint(( "n" ));
  307. #undef A
  308. //
  309. // only do this if a GUI is active
  310. //
  311. //if( !GUIActive ) return;
  312. //
  313. // Lock the buffer pool
  314. //
  315. MUTEX_ACQUIRE( LogMutex );
  316. //
  317. // Sprint the string to get the length
  318. //
  319. va_start( arg_ptr, format );
  320. len = vsprintf( text, format, arg_ptr );
  321. va_end( arg_ptr );    
  322. //
  323. // Only log it if it passes the filters
  324. //
  325. if( ApplyFilters( text )) {
  326. //
  327. // Get a sequence numnber
  328. //
  329. InterlockedIncrement( &Sequence );
  330. //
  331. // ULONG align for Alpha
  332. //
  333. len += 4; len &=  0xFFFFFFFC; // +1 to include null terminator and +3 to allign on longword
  334. //
  335. // See if its time to switch to extra buffer
  336. //
  337. if( Log->Len + len + sizeof(*Entry) + 1 >= LOGBUFSIZE ) {
  338. RegmonNewLog();
  339. }
  340. //
  341. // Log the sequence number so that 
  342. // a call's result can be paired with its
  343. // initial data collected when it was made.
  344. //
  345. Entry = (void *)(Log->Data+Log->Len);
  346. Entry->seq = Sequence;
  347. KeQuerySystemTime( &Entry->time );
  348. Entry->perftime = KeQueryPerformanceCounter( NULL );
  349. Entry->perftime.QuadPart -= StartTime.QuadPart;
  350. memcpy( Entry->text, text, len );
  351. //
  352. // Log the length of the string, plus 1 for the terminating
  353. // NULL  
  354. //   
  355. Log->Len += ((ULONG) (Entry->text - (PCHAR) Entry )) + len;
  356. }
  357. //
  358. // Release the buffer pool
  359. //
  360. MUTEX_RELEASE( LogMutex );
  361. }
  362. VOID 
  363. RegmonHashCleanup(
  364.   VOID
  365.   )
  366. {
  367. PHASH_ENTRY             hashEntry, nextEntry;
  368. ULONG                   i;
  369. MUTEX_ACQUIRE( HashMutex );    
  370. //
  371. // First free the hash table entries
  372. //       
  373. for( i = 0; i < NUMHASH; i++ ) {
  374. hashEntry = HashTable[i];
  375. while( hashEntry ) {
  376. nextEntry = hashEntry->Next;
  377. ExFreePool( hashEntry->FullPathName );
  378. ExFreePool( hashEntry );
  379. hashEntry = nextEntry;
  380. }
  381. HashTable[i] = NULL;
  382. }
  383. MUTEX_RELEASE( HashMutex );
  384. }
  385. //----------------------------------------------------------------------
  386. // 
  387. // Minimum
  388. //
  389. // Returns min of two numbers
  390. //
  391. //----------------------------------------------------------------------
  392. ULONG
  393. Minimum( 
  394. ULONG Value1, 
  395. ULONG Value2
  396. )
  397. {       
  398. return Value1 < Value2 ? Value1 : Value2;
  399. }
  400. //////////////////////////////////////////////////////////////////////////
  401. //功能函数
  402. //----------------------------------------------------------------------
  403. //
  404. // ErrorString
  405. //
  406. // Returns the string form of an error code.
  407. //
  408. //----------------------------------------------------------------------
  409. PCHAR 
  410. ErrorString( 
  411. NTSTATUS retval 
  412. )
  413. //
  414. // Passed filter, so log it
  415. //
  416. switch( retval ) {
  417. case STATUS_BUFFER_TOO_SMALL:
  418. return "BUFTOOSMALL";
  419. case STATUS_SUCCESS:
  420. return "SUCCESS";
  421. case STATUS_KEY_DELETED:
  422. return "KEYDELETED";
  423. case STATUS_REGISTRY_IO_FAILED:
  424. return "IOFAILED";
  425. case STATUS_REGISTRY_CORRUPT:
  426. return "CORRUPT";
  427. case STATUS_NO_MEMORY:
  428. return "OUTOFMEM";
  429. case STATUS_ACCESS_DENIED:
  430. return "ACCDENIED";
  431. case STATUS_NO_MORE_ENTRIES:
  432. return "NOMORE";
  433. case STATUS_OBJECT_NAME_NOT_FOUND:
  434. return "NOTFOUND";
  435. case STATUS_BUFFER_OVERFLOW:
  436. return "BUFOVRFLOW";
  437. case STATUS_OBJECT_PATH_SYNTAX_BAD:
  438. return "SYNTAXERR";
  439. case STATUS_OBJECT_NAME_COLLISION:
  440. return "NAMECOLLISION";
  441. case STATUS_REPARSE:
  442. return "REPARSE";
  443. case STATUS_BAD_IMPERSONATION_LEVEL:
  444. return "BADIMPERSONATION";
  445. default:
  446. sprintf(errstring, "%x", retval );
  447. return errstring;
  448. }
  449. }
  450. //----------------------------------------------------------------------
  451. //
  452. // ConverToUpper
  453. //
  454. // Obvious.
  455. //
  456. //----------------------------------------------------------------------
  457. VOID 
  458. ConvertToUpper( 
  459.    PCHAR Dest, 
  460.    PCHAR Source, 
  461.    ULONG Len 
  462.    )
  463. {
  464. ULONG   i;
  465. for( i = 0; i < Len; i++ ) {
  466. if( Source[i] >= 'a' && Source[i] <= 'z' ) {
  467. Dest[i] = Source[i] - 'a' + 'A';
  468. } else {
  469. Dest[i] = Source[i];
  470. }
  471. if( Source[i] == 0 ) return;
  472. }
  473. }
  474. //----------------------------------------------------------------------
  475. //
  476. // GetPointer
  477. //
  478. // Translates a handle to an object pointer. In a build for .NET
  479. // server we simply return the passed object pointer so as to 
  480. // avoid having to modify the code further.
  481. //
  482. //----------------------------------------------------------------------
  483. POBJECT 
  484. GetPointer( 
  485.    HANDLE KeyOrHandle 
  486.    )
  487. {
  488. POBJECT         pKey = NULL;
  489. //POBJECT_HANDLE_INFORMATION info=0;
  490. //
  491. // Ignore null handles.
  492. //
  493. if( !KeyOrHandle ) return NULL;
  494. //
  495. // Get the pointer the handle refers to.
  496. //
  497. #ifdef WNET
  498. pKey = KeyOrHandle;
  499. #else
  500. //
  501. // Make sure that we're not going to access
  502. // the kernel handle table from a non-system process
  503. //
  504. if( (LONG)(ULONG_PTR) KeyOrHandle < 0 &&
  505. ExGetPreviousMode() != KernelMode ) {
  506. return NULL;
  507. }
  508. //  ObReferenceObjectByHandle( KeyOrHandle, KEY_READ, NULL, KernelMode, &pKey, NULL );
  509. //  if( !pKey ) return NULL;
  510.     if( !NT_SUCCESS( ObReferenceObjectByHandle( KeyOrHandle, 0, NULL, KernelMode, &pKey, NULL ))) {
  511.         //KdPrint(("Error %x getting key pointern"));
  512.         pKey = NULL;
  513.     } 
  514. #endif
  515. return pKey;
  516. }
  517. //----------------------------------------------------------------------
  518. //
  519. // ReleasePointer
  520. //
  521. // Dereferences the object.
  522. //
  523. //----------------------------------------------------------------------
  524. VOID 
  525. ReleasePointer( 
  526.    POBJECT object 
  527.    )
  528. {
  529. #ifndef WNET
  530. if( object ) ObDereferenceObject( object );
  531. #endif
  532. }
  533. //----------------------------------------------------------------------
  534. //
  535. // GetProcessNameOffset
  536. //
  537. // In an effort to remain version-independent, rather than using a
  538. // hard-coded into the KPEB (Kernel Process Environment Block), we
  539. // scan the KPEB looking for the name, which should match that
  540. // of the GUI process
  541. //
  542. //----------------------------------------------------------------------
  543. //这个函数不知道为什么,我在xp上没成功,但在2k上成功了
  544. ULONG 
  545. GetProcessNameOffset(
  546.  VOID
  547.  )
  548. {
  549. PEPROCESS       curproc;
  550. int             i;
  551. curproc = PsGetCurrentProcess();
  552. //
  553. // Scan for 12KB, hopping the KPEB never grows that big!
  554. //
  555. for( i = 0; i < 3*PAGE_SIZE; i++ ) {
  556. if( !strncmp( SYSNAME, (char *) curproc + i, strlen(SYSNAME) )) {
  557. return i;
  558. }
  559. }
  560. //
  561. // Name not found - oh, well
  562. //
  563. return 0;
  564. }
  565. //----------------------------------------------------------------------
  566. //
  567. // GetProcess
  568. //
  569. // Uses undocumented data structure offsets to obtain the name of the
  570. // currently executing process.
  571. // 获取当前进程的程序名和pid
  572. //----------------------------------------------------------------------
  573. char *
  574. GetProcess( 
  575.    char * Name 
  576.    )
  577. {
  578. PEPROCESS       curproc;
  579. char            *nameptr;
  580. ULONG           i;
  581. //
  582. // We only try and get the name if we located the name offset
  583. // 
  584. //ProcessNameOffset=0x1fc; //2k
  585. if( ProcessNameOffset ) {
  586. //
  587. // Get a pointer to the current process block
  588. //
  589. curproc = PsGetCurrentProcess();
  590. //
  591. // Dig into it to extract the name. Make sure to leave enough room
  592. // in the buffer for the appended process ID.
  593. //
  594. nameptr   = (char *) curproc + ProcessNameOffset;
  595. strncpy( Name, nameptr, NT_PROCNAMELEN-1 );
  596. Name[NT_PROCNAMELEN-1] = 0; 
  597. sprintf( Name + strlen(Name), ":%d", (ULONG) PsGetCurrentProcessId()); 
  598. } else {
  599. strcpy( Name, "???");
  600. }
  601. return Name;
  602. }
  603. //----------------------------------------------------------------------
  604. //
  605. // GetProcess
  606. //
  607. // Uses undocumented data structure offsets to obtain the name of the
  608. // currently executing process.
  609. // 获取当前进程的程序名
  610. //----------------------------------------------------------------------
  611. char *
  612. GetProcess_noid( 
  613. char * Name 
  614. )
  615. {
  616. PEPROCESS       curproc;
  617. char            *nameptr;
  618. ULONG           i;
  619. //
  620. // We only try and get the name if we located the name offset
  621. // 
  622. //ProcessNameOffset=0x1fc; //2k
  623. if( ProcessNameOffset ) {
  624. //
  625. // Get a pointer to the current process block
  626. //
  627. curproc = PsGetCurrentProcess();
  628. //
  629. // Dig into it to extract the name. Make sure to leave enough room
  630. // in the buffer for the appended process ID.
  631. //
  632. nameptr   = (char *) curproc + ProcessNameOffset;
  633. strncpy( Name, nameptr, NT_PROCNAMELEN-1 );
  634. Name[NT_PROCNAMELEN-1] = 0; 
  635. //sprintf( Name + strlen(Name), ":%d", (ULONG) PsGetCurrentProcessId()); 
  636. } else {
  637. strcpy( Name, "???");
  638. }
  639. return Name;
  640. }
  641. //----------------------------------------------------------------------
  642. //
  643. // GetCurrentProcessFileName
  644. //
  645. // 获得当前进程对应PE文件的完整路径 
  646. // 返回PCWSTR类型
  647. //----------------------------------------------------------------------
  648. PCWSTR GetCurrentProcessFileName()
  649. {
  650. DWORD dwAddress = (DWORD)PsGetCurrentProcess();
  651. DWORD dwAddress1 ;
  652. if(KeGetCurrentIrql() != PASSIVE_LEVEL)
  653. return NULL;
  654. if(dwAddress == 0 || dwAddress == 0xFFFFFFFF)
  655. return NULL;
  656. dwAddress += 0x1B0;
  657. if((dwAddress = *(DWORD*)dwAddress) == 0) return 0;
  658. dwAddress += 0x10;
  659. if((dwAddress = *(DWORD*)dwAddress) == 0) return 0;
  660. dwAddress1=dwAddress;//20000
  661. dwAddress += 0x3C;
  662. if((dwAddress = *(DWORD*)dwAddress) == 0) return 0;
  663. if(dwAddress<dwAddress1)
  664. dwAddress=dwAddress+dwAddress1;
  665. //KdPrint(("Current Process Full Path Name: %wsn",  (PCWSTR)dwAddress)); 
  666. return (PCWSTR)dwAddress;
  667. }  
  668. //----------------------------------------------------------------------
  669. //
  670. // GetCurrentProcessFileName
  671. //
  672. // 获得当前进程的PE文件的全名
  673. // 返回到processfullname_c中
  674. //----------------------------------------------------------------------
  675. void GetCurrentProcessFileFullName(char * processfullname_c)
  676. {
  677. PCWSTR processfullname_pcwstr;
  678. PUNICODE_STRING processfullname_u;
  679. ANSI_STRING processfullname_a;
  680. processfullname_pcwstr=GetCurrentProcessFileName();
  681. if(processfullname_pcwstr)
  682. {
  683. processfullname_u = ExAllocatePool( PagedPool, MAXPATHLEN*sizeof(WCHAR)+2*sizeof(ULONG));
  684. if( !processfullname_u ) { 
  685. //
  686. // Out of memory
  687. //  
  688. return;
  689. processfullname_u->MaximumLength = MAXPATHLEN*sizeof(WCHAR);
  690. RtlInitUnicodeString(processfullname_u,processfullname_pcwstr);
  691. processfullname_a.Length=0;
  692. if(processfullname_u->Length!=0)
  693. RtlUnicodeStringToAnsiString(&processfullname_a,processfullname_u,1);
  694. if(processfullname_a.Length!=0)
  695. {
  696. strncpy(processfullname_c,processfullname_a.Buffer,processfullname_a.Length);
  697. processfullname_c[processfullname_a.Length]='';
  698. }
  699. ExFreePool( processfullname_u );
  700. if(&processfullname_a)
  701. RtlFreeAnsiString(&processfullname_a); 
  702. }
  703. }
  704. //----------------------------------------------------------------------
  705. //
  706. // GetKeyFullName
  707. //
  708. // Returns the full pathname of a key, if we can obtain one, else
  709. // returns a handle.
  710. //
  711. //----------------------------------------------------------------------
  712. VOID 
  713. GetKeyFullName( 
  714.    HANDLE hKey, 
  715.    PUNICODE_STRING lpszSubKeyVal, 
  716.    PCHAR fullname //输出的fullname
  717.    )
  718. {
  719. PHASH_ENTRY             hashEntry;
  720. POBJECT                 pKey = NULL;
  721. CHAR                    tmpkey[16];
  722. ANSI_STRING             keyname;
  723. PCHAR                   tmpname;
  724. PCHAR                   cmpname;
  725. PCHAR                   nameptr;
  726. PUNICODE_STRING         fullUniName;
  727. ULONG                   actualLen;
  728. int                     i;
  729. POBJECT_NAME_INFORMATION      keyNameInformation=0;
  730. //
  731. // If the fullname buffer is NULL, bail now
  732. //
  733. if( !fullname ) return;
  734. //
  735. // Allocate a temporary buffer
  736. //
  737. cmpname = ExAllocatePool( PagedPool, MAXROOTLEN );
  738. tmpname = ExAllocateFromPagedLookasideList( &FullPathLookaside );
  739. if( !tmpname || !cmpname ) {
  740. //
  741. // Not enough memory for a buffer
  742. //
  743. if( cmpname ) ExFreePool( cmpname );
  744. if( tmpname ) ExFreeToPagedLookasideList( &FullPathLookaside, tmpname );
  745. strcpy( fullname, "<INSUFFICIENT MEMORY>");
  746. return;
  747. }
  748. //
  749. // Translate the hkey into a pointer
  750. //
  751. fullname[0] = 0;
  752. tmpname[0] = 0;
  753. //
  754. // Is it a valid handle?
  755. //
  756. if( pKey = GetPointer( hKey )) {
  757. //
  758. // See if we find the key in the hash table
  759. //
  760. ReleasePointer( pKey );
  761. MUTEX_ACQUIRE( HashMutex );
  762. hashEntry = HashTable[ HASHOBJECT( pKey ) ];
  763. while( hashEntry && hashEntry->Object != pKey ) {
  764. hashEntry = hashEntry->Next;
  765. }
  766. if( hashEntry ) {
  767. strcpy( tmpname, hashEntry->FullPathName );
  768. MUTEX_RELEASE( HashMutex );
  769. } else {
  770. //
  771. // We will only get here if key was created before we loaded - ask the Configuration
  772. // Manager what the name of the key is.
  773. //
  774. MUTEX_RELEASE( HashMutex );
  775. if( pKey ) {
  776. fullUniName = ExAllocatePool( PagedPool, MAXPATHLEN*sizeof(WCHAR)+2*sizeof(ULONG));
  777. if( !fullUniName ) {
  778. //
  779. // Out of memory
  780. //
  781. strcpy( fullname, "<INSUFFICIENT MEMORY>" );
  782. ExFreePool( cmpname );
  783. ExFreeToPagedLookasideList( &FullPathLookaside, tmpname );
  784. return;
  785. }
  786. // NTKERNELAPI
  787. // NTSTATUS
  788. // ObQueryNameString (
  789. //     IN PVOID                        Object,
  790. //     OUT POBJECT_NAME_INFORMATION    ObjectNameInfo,
  791. //     IN ULONG                        Length,
  792. //     OUT PULONG                      ReturnLength
  793. // );
  794. fullUniName->MaximumLength = MAXPATHLEN*sizeof(WCHAR);
  795. //&keyNameInformation->Name=fullUniName;
  796. if( NT_SUCCESS(ObQueryNameString( pKey, fullUniName, MAXPATHLEN, &actualLen ) )) {
  797. //fullUniName=&keyNameInformation->Name;
  798. if( NT_SUCCESS( RtlUnicodeStringToAnsiString( &keyname, fullUniName, TRUE ))) { 
  799. if( keyname.Buffer[0] ) {
  800. strcpy( tmpname, "\" );
  801. strncat( tmpname, keyname.Buffer, Minimum( keyname.Length, MAXPATHLEN -2 ));
  802. }
  803. RtlFreeAnsiString( &keyname );
  804. }
  805. }
  806. ExFreePool( fullUniName );
  807. }
  808. }
  809. }
  810. //
  811. // Append subkey and value, if they are there
  812. //
  813. try {
  814. if( lpszSubKeyVal ) {
  815. keyname.Buffer = NULL;
  816. if( NT_SUCCESS( RtlUnicodeStringToAnsiString( &keyname, lpszSubKeyVal, TRUE ))) {
  817. if( keyname.Buffer[0] ) {
  818. //
  819. // See if this is an absolute rather than relative path, which 
  820. // can be the case on Open/Create when the Registry callback API
  821. // is used (.NET Server and higher)
  822. //
  823. ConvertToUpper( cmpname, keyname.Buffer, strlen("\REGISTRY")+1);
  824. if( !strncmp( cmpname, "\REGISTRY", strlen("\REGISTRY"))) {
  825. strcpy( tmpname, "\" );
  826. } else {
  827. strcat( tmpname, "\" );
  828. }
  829. strncat( tmpname, keyname.Buffer, Minimum( keyname.Length, MAXPATHLEN - 1 - strlen(tmpname) ));
  830. }
  831. RtlFreeAnsiString( &keyname );
  832. }
  833. }
  834. } except( EXCEPTION_EXECUTE_HANDLER ) {
  835. if( keyname.Buffer ) RtlFreeAnsiString( &keyname );
  836. strcat( tmpname, "*** Invalid Name ****" );
  837. }
  838. //
  839. // See if it matches current user
  840. //
  841. for( i = 0; i < 2; i++ ) {
  842. ConvertToUpper( cmpname, tmpname, CurrentUser[i].RootNameLen );
  843. if( !strncmp( cmpname, CurrentUser[i].RootName,
  844. CurrentUser[i].RootNameLen )) {
  845. //  KdPrint(( " CurrentUser(%d) %s ==> %sn", i, 
  846. //  tmpname, CurrentUser[i].RootName ));
  847. //
  848. // Its current user. Process to next slash
  849. //
  850. nameptr = tmpname + CurrentUser[i].RootNameLen;
  851. while( *nameptr && *nameptr != '\' ) nameptr++;
  852. strcpy( fullname, CurrentUser[i].RootShort );
  853. #if 0
  854. cmpname = nameptr - sizeof(USER_CLASSES);
  855. ConvertToUpper (cmpname, cmpname, sizeof(USER_CLASSES));
  856. if (!strncmp( cmpname, USER_CLASSES, sizeof(USER_CLASSES))) {
  857. strcat (fullname, "\Software\Classes");
  858. }
  859. #endif
  860. strcat( fullname, nameptr );
  861. ExFreePool( cmpname );
  862. ExFreeToPagedLookasideList( &FullPathLookaside, tmpname );
  863. return;
  864. }
  865. }     
  866. //
  867. // Now, see if we can translate a root key name
  868. //
  869. for( i = 0; i < NUMROOTKEYS; i++ ) {
  870. ConvertToUpper( cmpname, tmpname, RootKey[i].RootNameLen );
  871. if( !strncmp( cmpname, RootKey[i].RootName, 
  872. RootKey[i].RootNameLen )) {
  873. nameptr = tmpname + RootKey[i].RootNameLen;
  874. strcpy( fullname, RootKey[i].RootShort );
  875. strcat( fullname, nameptr );
  876. ExFreePool( cmpname );
  877. ExFreeToPagedLookasideList( &FullPathLookaside, tmpname );
  878. return;
  879. }
  880. }
  881. //
  882. // No translation
  883. //
  884. strcpy( fullname, tmpname );
  885. ExFreeToPagedLookasideList( &FullPathLookaside, tmpname );
  886. ExFreePool( cmpname );
  887. }
  888. //----------------------------------------------------------------------
  889. //
  890. // GetFileFullName
  891. //
  892. // Returns the full pathname of a file, if we can obtain one, else
  893. // returns a handle.
  894. // 获取一个注册项的全名
  895. //----------------------------------------------------------------------
  896. VOID 
  897. GetFileFullName( 
  898. POBJECT_ATTRIBUTES ObjectAttributes,
  899. PCHAR fullname //输出的fullname
  900. )
  901. {
  902. ANSI_STRING             filefullname_a;
  903. filefullname_a.Length=0;
  904. RtlUnicodeStringToAnsiString(&filefullname_a,ObjectAttributes->ObjectName,1);
  905. if(filefullname_a.Length==0)
  906. {
  907. return;
  908. }
  909. strncpy(fullname,filefullname_a.Buffer,Minimum(filefullname_a.Length,1023)); 
  910. fullname[Minimum(filefullname_a.Length,1023)]=''; 
  911. if(&filefullname_a)
  912. RtlFreeAnsiString(&filefullname_a); 
  913. }
  914. //----------------------------------------------------------------------
  915. //
  916. // GetFileFullName
  917. //
  918. // Returns the full pathname of a file, if we can obtain one, else
  919. // returns a handle.
  920. // 获取一个注册项的全名
  921. //----------------------------------------------------------------------
  922. VOID 
  923. GetFileFullNamebyFileHandle_forSection( 
  924. HANDLE FileHandle,
  925. char   *filefullname_c
  926. )
  927. {
  928. //文件相关的变量 
  929. PFILE_OBJECT file=0; 
  930. ANSI_STRING filefullname_a; 
  931. POBJECT_NAME_INFORMATION      fileNameInformation; 
  932. POBJECT_HANDLE_INFORMATION info=0;
  933. ULONG retSize;  
  934. ObReferenceObjectByHandle(FileHandle,0,0,KernelMode,&file,info);
  935. if(!file)return;
  936. filefullname_a.Length=0;
  937. RtlUnicodeStringToAnsiString(&filefullname_a,&file->FileName,1);
  938. if(filefullname_a.Length==0)
  939. {
  940. return;
  941. }
  942. strncpy(filefullname_c,filefullname_a.Buffer,Minimum(filefullname_a.Length,1023)); 
  943. filefullname_c[Minimum(filefullname_a.Length,1023)]=''; 
  944. if(&filefullname_a)
  945. RtlFreeAnsiString(&filefullname_a); 
  946. }
  947. //----------------------------------------------------------------------
  948. //
  949. // GetFileFullNamebyFileHandle
  950. //
  951. // Returns the full pathname of a file, if we can obtain one, else
  952. // returns a handle.
  953. // 获取一个注册项的全名
  954. //----------------------------------------------------------------------
  955. VOID 
  956. GetFileFullNamebyFileHandle_QueryNameString( 
  957. HANDLE filehandle,
  958. char   *filefullname_c
  959. )
  960. {
  961. //文件相关的变量 
  962. PFILE_OBJECT file=0; 
  963. ANSI_STRING filefullname_a; 
  964. POBJECT_NAME_INFORMATION      fileNameInformation; 
  965. POBJECT_HANDLE_INFORMATION info=0;
  966. ULONG retSize;
  967. PUNICODE_STRING filefullname_u;
  968. //经由文件句柄得到文件名 
  969. ObReferenceObjectByHandle(filehandle,0,0,KernelMode,&file,info);
  970. if(!file)return; 
  971. // 得到的文件路径是 DeviceHarddiskVolum1.... 
  972. filefullname_u = ExAllocatePool( PagedPool, MAXPATHLEN*sizeof(WCHAR)+2*sizeof(ULONG));
  973. if( !filefullname_u ) {
  974. //
  975. // Out of memory
  976. // 
  977. return;
  978. filefullname_u->MaximumLength = MAXPATHLEN*sizeof(WCHAR);
  979. ObQueryNameString(file, filefullname_u, 1024, &retSize); 
  980. filefullname_a.Length=0;
  981. RtlUnicodeStringToAnsiString(&filefullname_a,filefullname_u,1);
  982. if(filefullname_a.Length==0)
  983. {
  984. return;
  985. }
  986. strncpy(filefullname_c,filefullname_a.Buffer,Minimum(filefullname_a.Length,1023)); 
  987. filefullname_c[Minimum(filefullname_a.Length,1023)]=''; 
  988. if(&filefullname_a)
  989. RtlFreeAnsiString(&filefullname_a); 
  990. ExFreePool( filefullname_u );
  991. }
  992. //----------------------------------------------------------------------
  993. //
  994. // GetFileFullNamebyFileHandle
  995. //
  996. // Returns the full pathname of a file, if we can obtain one, else
  997. // returns a handle.
  998. // 获取一个注册项的全名
  999. //----------------------------------------------------------------------
  1000. VOID 
  1001. GetFileFullNamebyFileHandle( 
  1002. HANDLE filehandle,
  1003. char   *filefullname_c
  1004. )
  1005. {
  1006. //文件相关的变量 
  1007. PFILE_OBJECT file=0;
  1008. PFILE_OBJECT relatedfile=0; ANSI_STRING filefullname_a; 
  1009. PUNICODE_STRING filefullname_u;
  1010. int relatedfilelength;
  1011. POBJECT_NAME_INFORMATION      fileNameInformation;
  1012. POBJECT_HANDLE_INFORMATION info=0;
  1013. ULONG retSize;
  1014. //经由文件句柄得到文件名 
  1015. ObReferenceObjectByHandle(filehandle,0,0,KernelMode,&file,info);
  1016. if(!file)return; 
  1017. filefullname_u = ExAllocatePool( PagedPool, MAXPATHLEN*sizeof(WCHAR)+2*sizeof(ULONG));
  1018. if( !filefullname_u ) { 
  1019. //
  1020. // Out of memory
  1021. //  
  1022. return;
  1023. filefullname_u->MaximumLength = MAXPATHLEN*sizeof(WCHAR);
  1024. //先得到盘符
  1025. RtlVolumeDeviceToDosName(file->DeviceObject,filefullname_u);
  1026. RtlUnicodeStringToAnsiString(&filefullname_a,filefullname_u,1);
  1027. strncpy(filefullname_c,filefullname_a.Buffer,filefullname_a.Length); 
  1028. filefullname_c[filefullname_a.Length]='';
  1029. relatedfilelength=filefullname_a.Length;
  1030. //相对路径
  1031. relatedfile=file->RelatedFileObject;
  1032. RtlUnicodeStringToAnsiString(&filefullname_a,&relatedfile->FileName,1);
  1033. strncat(filefullname_c,filefullname_a.Buffer,filefullname_a.Length); 
  1034. filefullname_c[relatedfilelength+filefullname_a.Length]='';
  1035. relatedfilelength+=filefullname_a.Length;
  1036. //文件名
  1037. RtlUnicodeStringToAnsiString(&filefullname_a,&file->FileName,1);
  1038. strcat(filefullname_c,"\");
  1039. strncat(filefullname_c,filefullname_a.Buffer,filefullname_a.Length);
  1040. filefullname_c[relatedfilelength+filefullname_a.Length+1]='';
  1041. ExFreePool( filefullname_u );
  1042. if(&filefullname_a)
  1043. RtlFreeAnsiString(&filefullname_a);
  1044. }
  1045. //----------------------------------------------------------------------
  1046. //
  1047. // GetFullName
  1048. //
  1049. // Returns the full pathname of a file, if we can obtain one, else
  1050. // returns a handle.
  1051. // 获取一个注册项的全名
  1052. //----------------------------------------------------------------------
  1053. NTSTATUS   GetFullName(HANDLE     KeyHandle,char   *fullname)   
  1054. {   
  1055. NTSTATUS   ns;   
  1056. PVOID   pKey=NULL,pFile=NULL;   
  1057. UNICODE_STRING                   fullUniName;   
  1058. ANSI_STRING                           akeyname;   
  1059. ULONG   actualLen;   
  1060. UNICODE_STRING   dosName;   
  1061. fullUniName.Buffer=NULL;   
  1062. fullUniName.Length=0;   
  1063. fullname[0]=0x00;   
  1064. ns=   ObReferenceObjectByHandle(   KeyHandle,   0,   NULL,   KernelMode,   &pKey,   NULL   )   ;   
  1065. if(   !NT_SUCCESS(ns))   return   ns;   
  1066. fullUniName.Buffer   =   ExAllocatePool(   PagedPool,   MAXPATHLEN*2);//1024*2   
  1067. fullUniName.MaximumLength   =   MAXPATHLEN*2;   
  1068. __try   
  1069. {   
  1070. pFile=(PVOID)*(ULONG   *)((char   *)pKey+20);   
  1071. pFile=(PVOID)*(ULONG   *)((char   *)pFile);   
  1072. pFile=(PVOID)*(ULONG   *)((char   *)pFile+36);   
  1073. ObReferenceObjectByPointer(pFile,   0,   NULL,   KernelMode);   
  1074. RtlVolumeDeviceToDosName(((PFILE_OBJECT)pFile)->DeviceObject,&dosName);     
  1075. RtlCopyUnicodeString(&fullUniName,   &dosName);   
  1076. RtlAppendUnicodeStringToString(&fullUniName,&((PFILE_OBJECT)pFile)->FileName);   
  1077. ObDereferenceObject(pFile);   
  1078. ObDereferenceObject(pKey   );   
  1079. RtlUnicodeStringToAnsiString(   &akeyname,   &fullUniName,   TRUE   );   
  1080. if(akeyname.Length<MAXPATHLEN)     
  1081. {   
  1082. memcpy(fullname,akeyname.Buffer,akeyname.Length);   
  1083. fullname[akeyname.Length]=0x00;   
  1084. }   
  1085. else   
  1086. {   
  1087. memcpy(fullname,akeyname.Buffer,MAXPATHLEN);   
  1088. fullname[MAXPATHLEN-1]=0x00;   
  1089. }   
  1090. RtlFreeAnsiString(   &akeyname   );   
  1091. ExFreePool(dosName.Buffer);   
  1092. ExFreePool(   fullUniName.Buffer   );   
  1093. return   STATUS_SUCCESS;   
  1094. }   
  1095. __except(1)   
  1096. {   
  1097. if(fullUniName.Buffer)   ExFreePool(   fullUniName.Buffer     );   
  1098. if(pKey)   ObDereferenceObject(pKey   );   
  1099. return   STATUS_SUCCESS;   
  1100. }   
  1101. void GetRealCallee(char * hookedfunname)
  1102. {
  1103. int i;
  1104. for(i=0;i<hook_num;i++)
  1105. {
  1106. if(strcmp(hook_API_info[i].nativeAPIname,hookedfunname)==0)
  1107. {
  1108. RealCallee=hook_API_info[i].RealCallee;
  1109. break;
  1110. }
  1111. }
  1112. }
  1113. NTSTATUS 
  1114. NTAPI
  1115. HookNtRestoreKey( 
  1116.  IN HANDLE               KeyHandle,
  1117.  IN HANDLE               FileHandle,
  1118.  IN ULONG                RestoreOption )
  1119. {
  1120. //函数名称
  1121. char hookedfunname[32]="NtRestoreKey";
  1122. NTSTATUS  ntstatus;
  1123. //key相关的变量
  1124. char keyfullname_c[1024]="???";
  1125. //行为Behavior相关变量
  1126. CHAR behavior[1024]="???";
  1127. //进程相关的变量
  1128. CHAR processname[32]="???";//进程名称
  1129. CHAR processfullname_c[512]="???";//进程全名
  1130. //-------------------------------------------------------------------
  1131. //输出函数地址
  1132. GetRealCallee(hookedfunname);
  1133. //获得函数返回结果
  1134. _asm{
  1135. push RestoreOption
  1136. push FileHandle
  1137. push KeyHandle
  1138. call RealCallee
  1139. mov ntstatus,eax
  1140. //获取进程的全名
  1141. GetCurrentProcessFileFullName(processfullname_c);
  1142. //监控要监控的程序 
  1143. if(strcmp(processfullname_c,processname_G)!=0)
  1144. {
  1145. return ntstatus;
  1146. //  //经由文件句柄得到文件名
  1147. //  GetFileFullNamebyFileHandle(FileHandle,filefullname_c);
  1148. //经由key句柄获得key全名
  1149. GetKeyFullName(KeyHandle,NULL,keyfullname_c);
  1150. //--------------------------------------------------------------------------
  1151. strcpy(behavior,"导入键"");
  1152. strcat(behavior,keyfullname_c);
  1153. strcat(behavior,""");
  1154. //这里要进行操作系统判断,不同的操作系统这个地址不同
  1155. //ProcessNameOffset=0x1FC; //2k
  1156. ProcessNameOffset=0x174;  //xp 
  1157. //------------------------------------------------------------------
  1158. LogRecord( "%st%st%st%st%s", GetProcess(processname),hookedfunname,
  1159. processfullname_c, ErrorString( ntstatus ), behavior );
  1160. //------------------------------------------------------------------
  1161. return ntstatus;
  1162. }
  1163. NTSTATUS 
  1164. NTAPI
  1165. HookNtOpenKey( 
  1166.   OUT PHANDLE             pKeyHandle,
  1167.   IN ACCESS_MASK          DesiredAccess,
  1168.   IN POBJECT_ATTRIBUTES   ObjectAttributes )
  1169. {
  1170. //函数名称
  1171. char hookedfunname[32]="NtOpenKey";
  1172. NTSTATUS ntstatus;
  1173. //key相关的变量 
  1174. char keyfullname_c[1024]="???";
  1175. //行为Behavior相关变量
  1176. CHAR behavior[1024]="???";
  1177. //进程相关的变量
  1178. CHAR processname[32]="???";//进程名称
  1179. CHAR processfullname_c[512]="???";//进程全名
  1180. //-------------------------------------------------------------------
  1181. //必须放考前一点,否则不能及时得到RealCallee
  1182. //输出函数地址
  1183. GetRealCallee(hookedfunname);
  1184. //获得函数返回结果
  1185. _asm{
  1186. push ObjectAttributes
  1187. push DesiredAccess
  1188. push pKeyHandle
  1189. call RealCallee
  1190. mov ntstatus,eax
  1191. //获取进程的全名
  1192. GetCurrentProcessFileFullName(processfullname_c);
  1193. //监控要监控的程序 
  1194. if(strcmp(processfullname_c,processname_G)!=0)
  1195. {
  1196. return ntstatus;
  1197. GetKeyFullName( ObjectAttributes->RootDirectory, ObjectAttributes->ObjectName, keyfullname_c );
  1198. strcpy(behavior,"打开键"");  
  1199. strcat(behavior,keyfullname_c);
  1200. strcat(behavior,"""); 
  1201.  
  1202. //这里要进行操作系统判断,不同的操作系统这个地址不同
  1203. //ProcessNameOffset=0x1FC; //2k
  1204. ProcessNameOffset=0x174;  //xp
  1205. //------------------------------------------------------------------
  1206. LogRecord( "%st%st%st%st%s", GetProcess(processname),hookedfunname,
  1207. processfullname_c, ErrorString( ntstatus ), behavior );
  1208. //------------------------------------------------------------------
  1209.  
  1210. return ntstatus;
  1211. }
  1212. NTSTATUS 
  1213. NTAPI
  1214. HookNtCreateKey( 
  1215. OUT PHANDLE             pKeyHandle,
  1216. IN ACCESS_MASK          DesiredAccess,
  1217. IN POBJECT_ATTRIBUTES   ObjectAttributes,
  1218. IN ULONG                TitleIndex,
  1219. IN PUNICODE_STRING      Class OPTIONAL,
  1220. IN ULONG                CreateOptions,
  1221. OUT PULONG              Disposition OPTIONAL )
  1222. {
  1223. //函数名称
  1224. char hookedfunname[32]="NtCreateKey";
  1225. NTSTATUS ntstatus;
  1226. //key相关的变量
  1227. char keyfullname_c[1024]="???";
  1228. //行为Behavior相关变量
  1229. CHAR behavior[1024]="???";
  1230. //进程相关的变量
  1231. CHAR processname[32];//进程名称
  1232. CHAR processfullname_c[512]="???";//进程全名
  1233. //-------------------------------------------------------------------
  1234. //输出函数地址
  1235. GetRealCallee(hookedfunname);
  1236. //获得函数返回结果
  1237. _asm{
  1238. push Disposition
  1239. push CreateOptions
  1240. push Class
  1241. push TitleIndex 
  1242. push ObjectAttributes
  1243. push DesiredAccess
  1244. push pKeyHandle
  1245. call RealCallee
  1246. mov ntstatus,eax
  1247. //获取进程的全名
  1248. GetCurrentProcessFileFullName(processfullname_c);
  1249. //监控要监控的程序 
  1250. if(strcmp(processfullname_c,processname_G)!=0)
  1251. {
  1252. return ntstatus;
  1253. GetKeyFullName( ObjectAttributes->RootDirectory, ObjectAttributes->ObjectName, keyfullname_c );
  1254. strcpy(behavior,"创建键"");  
  1255. strcat(behavior,keyfullname_c);
  1256. strcat(behavior,"""); 
  1257.  
  1258. //这里要进行操作系统判断,不同的操作系统这个地址不同
  1259. //ProcessNameOffset=0x1FC; //2k
  1260. ProcessNameOffset=0x174;  //xp
  1261. //------------------------------------------------------------------
  1262. LogRecord( "%st%st%st%st%s", GetProcess(processname),hookedfunname,
  1263. processfullname_c, ErrorString( ntstatus ), behavior );
  1264. //------------------------------------------------------------------
  1265.  
  1266.    
  1267. return ntstatus;
  1268. }
  1269. NTSTATUS 
  1270. NTAPI
  1271. HookNtQueryValueKey( 
  1272. IN HANDLE               KeyHandle,
  1273. IN PUNICODE_STRING      ValueName,
  1274. IN KEY_VALUE_INFORMATION_CLASS  KeyValueInformationClass,
  1275. OUT PVOID               KeyValueInformation,
  1276. IN ULONG                KeyValueInformationLength,
  1277. OUT PULONG              ResultLength )
  1278. {
  1279. //函数名称
  1280. char hookedfunname[32]="NtQueryValueKey";
  1281. NTSTATUS ntstatus;
  1282. //key相关的变量
  1283. char keyfullname_c[1024]="???";
  1284. PUNICODE_STRING         valueName;
  1285. //行为Behavior相关变量
  1286. CHAR behavior[1024]="???";
  1287. //进程相关的变量
  1288. CHAR processname[32];//进程名称
  1289. CHAR processfullname_c[512]="???";//进程全名
  1290. if( !ValueName || !ValueName->Length ) valueName = &DefaultValue;
  1291.     else                                   valueName = ValueName;
  1292. GetKeyFullName(KeyHandle,valueName,keyfullname_c);
  1293. //-------------------------------------------------------------------
  1294. //输出函数地址
  1295. GetRealCallee(hookedfunname);
  1296. //获得函数返回结果
  1297. _asm{
  1298. push ResultLength
  1299. push KeyValueInformationLength
  1300. push KeyValueInformation 
  1301. push KeyValueInformationClass 
  1302. push ValueName
  1303. push KeyHandle 
  1304. call RealCallee
  1305. mov ntstatus,eax
  1306. //获取进程的全名
  1307. GetCurrentProcessFileFullName(processfullname_c);
  1308. //监控要监控的程序 
  1309. if(strcmp(processfullname_c,processname_G)!=0)
  1310. {
  1311. return ntstatus;
  1312. //这里分析具体的行为---------------------------------------------------
  1313. //经由key句柄获得key全名
  1314. strcpy(behavior,"查询键值"");
  1315. strcat(behavior,keyfullname_c); 
  1316. strcat(behavior,""");
  1317.  
  1318. //这里要进行操作系统判断,不同的操作系统这个地址不同
  1319. //ProcessNameOffset=0x1FC; //2k
  1320. ProcessNameOffset=0x174;  //xp 
  1321. //------------------------------------------------------------------
  1322. LogRecord( "%st%st%st%st%s", GetProcess(processname),hookedfunname,
  1323. processfullname_c, ErrorString( ntstatus ), behavior );
  1324. //------------------------------------------------------------------
  1325.  
  1326.    
  1327. return ntstatus;
  1328. }
  1329. NTSTATUS 
  1330. NTAPI
  1331. HookNtQueryKey( 
  1332.    IN HANDLE               KeyHandle,
  1333.    IN KEY_INFORMATION_CLASS KeyInformationClass,
  1334.    OUT PVOID               KeyInformation,
  1335.    IN ULONG                KeyInformationLength,
  1336.    OUT PULONG              ResultLength )
  1337. {
  1338. //函数名称
  1339. char hookedfunname[32]="NtQueryKey";
  1340. NTSTATUS ntstatus;
  1341. //key相关的变量
  1342. char keyfullname_c[1024]="???";
  1343. //行为Behavior相关变量
  1344. CHAR behavior[1024]="???";
  1345. //进程相关的变量
  1346. CHAR processname[32];//进程名称
  1347. CHAR processfullname_c[512]="???";//进程全名
  1348. //-------------------------------------------------------------------
  1349. //输出函数地址
  1350. GetRealCallee(hookedfunname);
  1351. //获得函数返回结果
  1352. _asm{
  1353. push ResultLength
  1354. push KeyInformationLength
  1355. push KeyInformation 
  1356. push KeyInformationClass 
  1357. push KeyHandle 
  1358. call RealCallee
  1359. mov ntstatus,eax
  1360. //获取进程的全名
  1361. GetCurrentProcessFileFullName(processfullname_c);
  1362. //监控要监控的程序 
  1363. if(strcmp(processfullname_c,processname_G)!=0)
  1364. {
  1365. return ntstatus;
  1366. //这里分析具体的行为-----------------------------------------------
  1367. //经由key句柄获得key全名
  1368. GetKeyFullName(KeyHandle,NULL,keyfullname_c);
  1369. strcpy(behavior,"查询键"");
  1370. strcat(behavior,keyfullname_c); 
  1371. strcat(behavior,""");
  1372.  
  1373. //这里要进行操作系统判断,不同的操作系统这个地址不同
  1374. //ProcessNameOffset=0x1FC; //2k
  1375. ProcessNameOffset=0x174;  //xp
  1376. //------------------------------------------------------------------
  1377. LogRecord( "%st%st%st%st%s", GetProcess(processname),hookedfunname,
  1378. processfullname_c, ErrorString( ntstatus ), behavior );
  1379. //------------------------------------------------------------------
  1380.  
  1381.    
  1382. return ntstatus;
  1383. }
  1384. NTSTATUS 
  1385. NTAPI
  1386. HookNtDeleteKey( 
  1387. IN HANDLE               KeyHandle )
  1388. {
  1389. //函数名称
  1390. char hookedfunname[32]="NtDeleteKey";
  1391. NTSTATUS ntstatus;
  1392. //key相关的变量
  1393. char keyfullname_c[1024]="???";
  1394. //行为Behavior相关变量
  1395. CHAR behavior[1024]="???";
  1396. //进程相关的变量
  1397. CHAR processname[32];//进程名称
  1398. CHAR processfullname_c[512]="???";//进程全名
  1399. //-------------------------------------------------------------------
  1400. //输出函数地址
  1401. GetRealCallee(hookedfunname);
  1402. //获得函数返回结果
  1403. _asm{
  1404. push KeyHandle 
  1405. call RealCallee
  1406. mov ntstatus,eax
  1407. //获取进程的全名
  1408. GetCurrentProcessFileFullName(processfullname_c);
  1409. //监控要监控的程序 
  1410. if(strcmp(processfullname_c,processname_G)!=0)
  1411. {
  1412. return ntstatus;
  1413. //这里分析具体的行为-----------------------------------------------
  1414. //经由key句柄获得key全名
  1415. GetKeyFullName(KeyHandle,NULL,keyfullname_c);
  1416. strcpy(behavior,"删除键"");
  1417. strcat(behavior,keyfullname_c); 
  1418. strcat(behavior,""");
  1419.  
  1420. //这里要进行操作系统判断,不同的操作系统这个地址不同
  1421. //ProcessNameOffset=0x1FC; //2k
  1422. ProcessNameOffset=0x174;  //xp
  1423. //------------------------------------------------------------------
  1424. LogRecord( "%st%st%st%st%s", GetProcess(processname),hookedfunname,
  1425. processfullname_c, ErrorString( ntstatus ), behavior );
  1426. //------------------------------------------------------------------
  1427.  
  1428.    
  1429. return ntstatus;
  1430. }
  1431. NTSTATUS 
  1432. NTAPI
  1433. HookNtDeleteValueKey( 
  1434.  IN HANDLE               KeyHandle,
  1435.  IN PUNICODE_STRING      ValueName )
  1436. {
  1437. //函数名称
  1438. char hookedfunname[32]="NtDeleteValueKey";
  1439. NTSTATUS ntstatus;
  1440. //key相关的变量
  1441. char keyfullname_c[1024]="???";
  1442. //行为Behavior相关变量
  1443. CHAR behavior[1024]="???";
  1444. //进程相关的变量
  1445. CHAR processname[32];//进程名称
  1446. CHAR processfullname_c[512]="???";//进程全名
  1447. //-------------------------------------------------------------------
  1448. //输出函数地址
  1449. GetRealCallee(hookedfunname);
  1450. //获得函数返回结果
  1451. _asm{
  1452. push ValueName
  1453. push KeyHandle
  1454. call RealCallee
  1455. mov ntstatus,eax
  1456. //获取进程的全名
  1457. GetCurrentProcessFileFullName(processfullname_c);
  1458. //监控要监控的程序 
  1459. if(strcmp(processfullname_c,processname_G)!=0)
  1460. {
  1461. return ntstatus;
  1462. //这里分析具体的行为-----------------------------------------------
  1463. //经由key句柄获得key全名
  1464. GetKeyFullName(KeyHandle,NULL,keyfullname_c);
  1465. strcpy(behavior,"删除键值"");
  1466. strcat(behavior,keyfullname_c); 
  1467. strcat(behavior,""");
  1468.  
  1469. //这里要进行操作系统判断,不同的操作系统这个地址不同
  1470. //ProcessNameOffset=0x1FC; //2k
  1471. ProcessNameOffset=0x174;  //xp
  1472. //------------------------------------------------------------------
  1473. LogRecord( "%st%st%st%st%s", GetProcess(processname),hookedfunname,
  1474. processfullname_c, ErrorString( ntstatus ), behavior );
  1475. //------------------------------------------------------------------
  1476.  
  1477.    
  1478. return ntstatus;
  1479. }
  1480. NTSTATUS 
  1481. NTAPI
  1482. HookNtSetValueKey( 
  1483.   IN HANDLE               KeyHandle,
  1484.   IN PUNICODE_STRING      ValueName,
  1485.   IN ULONG                TitleIndex OPTIONAL,
  1486.   IN ULONG                ValueType,
  1487.   IN PVOID                Data,
  1488.   IN ULONG                DataSize )
  1489. {
  1490. //函数名称
  1491. char hookedfunname[32]="NtSetValueKey";
  1492. NTSTATUS ntstatus;
  1493. //key相关的变量
  1494. char keyfullname_c[1024]="???";
  1495. //行为Behavior相关变量
  1496. CHAR behavior[1024]="???";
  1497. //进程相关的变量
  1498. CHAR processname[32];//进程名称
  1499. CHAR processfullname_c[512]="???";//进程全名
  1500. //-------------------------------------------------------------------
  1501. //输出函数地址
  1502. GetRealCallee(hookedfunname); 
  1503. //获得函数返回结果
  1504. _asm{
  1505. push DataSize 
  1506. push Data
  1507. push ValueType
  1508. push TitleIndex
  1509. push ValueName
  1510. push KeyHandle
  1511. call RealCallee
  1512. mov ntstatus,eax
  1513. //获取进程的全名
  1514. GetCurrentProcessFileFullName(processfullname_c);
  1515. //监控要监控的程序 
  1516. if(strcmp(processfullname_c,processname_G)!=0)
  1517. {
  1518. return ntstatus;
  1519. //这里分析具体的行为-----------------------------------------------
  1520. //经由key句柄获得key全名
  1521. GetKeyFullName(KeyHandle,NULL,keyfullname_c);
  1522. strcpy(behavior,"设置键值"");
  1523. strcat(behavior,keyfullname_c); 
  1524. strcat(behavior,""");
  1525.  
  1526. //这里要进行操作系统判断,不同的操作系统这个地址不同
  1527. //ProcessNameOffset=0x1FC; //2k
  1528. ProcessNameOffset=0x174;  //xp
  1529. //------------------------------------------------------------------
  1530. LogRecord( "%st%st%st%st%s", GetProcess(processname),hookedfunname,
  1531. processfullname_c, ErrorString( ntstatus ), behavior );
  1532. //------------------------------------------------------------------
  1533.  
  1534.    
  1535. return ntstatus;
  1536. }
  1537. NTSTATUS 
  1538. NTAPI
  1539. HookNtEnumerateKey( 
  1540.    IN HANDLE               KeyHandle,
  1541.    IN ULONG                Index,
  1542.    IN KEY_INFORMATION_CLASS KeyInformationClass,
  1543.    OUT PVOID               KeyInformation,
  1544.    IN ULONG                KeyInformationLength,
  1545.    OUT PULONG              ResultLength )
  1546. {
  1547. //函数名称
  1548. char hookedfunname[32]="NtEnumerateKey";
  1549. NTSTATUS ntstatus;
  1550. //key相关的变量
  1551. char keyfullname_c[1024]="???";
  1552. //行为Behavior相关变量
  1553. CHAR behavior[1024]="???";
  1554. //进程相关的变量
  1555. CHAR processname[32];//进程名称
  1556. CHAR processfullname_c[512]="???";//进程全名
  1557. //-------------------------------------------------------------------
  1558. //输出函数地址
  1559. GetRealCallee(hookedfunname);  
  1560. //获得函数返回结果
  1561. _asm{
  1562. push ResultLength 
  1563. push KeyInformationLength
  1564. push KeyInformation
  1565. push KeyInformationClass
  1566. push Index
  1567. push KeyHandle
  1568. call RealCallee
  1569. mov ntstatus,eax
  1570. //获取进程的全名
  1571. GetCurrentProcessFileFullName(processfullname_c);
  1572. //监控要监控的程序 
  1573. if(strcmp(processfullname_c,processname_G)!=0)
  1574. {
  1575. return ntstatus;
  1576. //这里分析具体的行为-----------------------------------------------
  1577. //经由key句柄获得key全名
  1578. GetKeyFullName(KeyHandle,NULL,keyfullname_c);
  1579. strcpy(behavior,"枚举键"");
  1580. strcat(behavior,keyfullname_c); 
  1581. strcat(behavior,""");
  1582.  
  1583. //这里要进行操作系统判断,不同的操作系统这个地址不同
  1584. //ProcessNameOffset=0x1FC; //2k
  1585. ProcessNameOffset=0x174;  //xp
  1586. //------------------------------------------------------------------
  1587. LogRecord( "%st%st%st%st%s", GetProcess(processname),hookedfunname,
  1588. processfullname_c, ErrorString( ntstatus ), behavior );
  1589. //------------------------------------------------------------------
  1590.  
  1591.    
  1592. return ntstatus;
  1593. }
  1594. NTSTATUS 
  1595. NTAPI
  1596. HookNtEnumerateValueKey( 
  1597. IN HANDLE               KeyHandle,
  1598. IN ULONG                Index,
  1599. IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass ,
  1600. OUT PVOID               KeyValueInformation,
  1601. IN ULONG                KeyValueInformationLength,
  1602. OUT PULONG              ResultLength )
  1603. {
  1604. //函数名称
  1605. char hookedfunname[32]="NtEnumerateValueKey";
  1606. NTSTATUS ntstatus;
  1607. //key相关的变量
  1608. char keyfullname_c[1024]="???";
  1609. //行为Behavior相关变量
  1610. CHAR behavior[1024]="???";
  1611. //进程相关的变量
  1612. CHAR processname[32];//进程名称
  1613. CHAR processfullname_c[512]="???";//进程全名
  1614. //-------------------------------------------------------------------
  1615. //输出函数地址
  1616. GetRealCallee(hookedfunname);   
  1617. //获得函数返回结果
  1618. _asm{
  1619. push ResultLength 
  1620. push KeyValueInformationLength
  1621. push KeyValueInformation
  1622. push KeyValueInformationClass 
  1623. push Index
  1624. push KeyHandle
  1625. call RealCallee
  1626. mov ntstatus,eax
  1627. //获取进程的全名
  1628. GetCurrentProcessFileFullName(processfullname_c);
  1629. //监控要监控的程序 
  1630. if(strcmp(processfullname_c,processname_G)!=0)
  1631. {
  1632. return ntstatus;
  1633. //这里分析具体的行为-----------------------------------------------
  1634. //经由key句柄获得key全名
  1635. GetKeyFullName(KeyHandle,NULL,keyfullname_c);
  1636. strcpy(behavior,"枚举键值"");
  1637. strcat(behavior,keyfullname_c); 
  1638. strcat(behavior,""");
  1639.  
  1640. //这里要进行操作系统判断,不同的操作系统这个地址不同
  1641. //ProcessNameOffset=0x1FC; //2k
  1642. ProcessNameOffset=0x174;  //xp
  1643. //------------------------------------------------------------------
  1644. LogRecord( "%st%st%st%st%s", GetProcess(processname),hookedfunname,
  1645. processfullname_c, ErrorString( ntstatus ), behavior );
  1646. //------------------------------------------------------------------
  1647.  
  1648.    
  1649. return ntstatus;
  1650. }
  1651. NTSTATUS 
  1652. NTAPI
  1653. HookNtOpenFile( 
  1654.    OUT PHANDLE             FileHandle,
  1655.    IN ACCESS_MASK          DesiredAccess,
  1656.    IN POBJECT_ATTRIBUTES   ObjectAttributes,
  1657.    OUT PIO_STATUS_BLOCK    IoStatusBlock,
  1658.    IN ULONG                ShareAccess,
  1659.    IN ULONG                OpenOptions )
  1660. {
  1661. //函数名称
  1662. char hookedfunname[32]="NtOpenFile";
  1663. NTSTATUS ntstatus;
  1664.  
  1665. //文件相关的变量
  1666. char filefullname_c[1024]="???";
  1667. //key相关的变量
  1668. char keyfullname_c[1024]="???";
  1669. //行为Behavior相关变量
  1670. CHAR behavior[1024]="???";
  1671. //进程相关的变量
  1672. CHAR processname[32];//进程名称
  1673. CHAR processfullname_c[512]="???";//进程全名
  1674. //-------------------------------------------------------------------
  1675. //输出函数地址
  1676. GetRealCallee(hookedfunname); 
  1677. //获得函数返回结果
  1678. _asm{
  1679. push OpenOptions 
  1680. push ShareAccess
  1681. push IoStatusBlock
  1682. push ObjectAttributes
  1683. push DesiredAccess
  1684. push FileHandle
  1685. call RealCallee
  1686. mov ntstatus,eax
  1687. //获取进程的全名
  1688. GetCurrentProcessFileFullName(processfullname_c);
  1689. //监控要监控的程序 
  1690. if(strcmp(processfullname_c,processname_G)!=0)
  1691. {
  1692. return ntstatus;
  1693. //这里分析具体的行为---------------------------------------
  1694. GetFileFullName(ObjectAttributes,filefullname_c);
  1695. strcpy(behavior,"打开文件"");
  1696. strcat(behavior,filefullname_c); 
  1697. strcat(behavior,""");
  1698.  
  1699. //这里要进行操作系统判断,不同的操作系统这个地址不同
  1700. //ProcessNameOffset=0x1FC; //2k
  1701. ProcessNameOffset=0x174;  //xp
  1702. //------------------------------------------------------------------
  1703. LogRecord( "%st%st%st%st%s", GetProcess(processname),hookedfunname,
  1704. processfullname_c, ErrorString( ntstatus ), behavior );
  1705. //------------------------------------------------------------------
  1706.  
  1707.    
  1708. return ntstatus;
  1709. }
  1710. NTSTATUS 
  1711. NTAPI
  1712. HookNtWriteFile( 
  1713. IN HANDLE               FileHandle,
  1714. IN HANDLE               Event OPTIONAL,
  1715. IN PIO_APC_ROUTINE      ApcRoutine OPTIONAL,
  1716. IN PVOID                ApcContext OPTIONAL,
  1717. OUT PIO_STATUS_BLOCK    IoStatusBlock,
  1718. IN PVOID                Buffer,
  1719. IN ULONG                BufferLength,
  1720. IN PLARGE_INTEGER       ByteOffset OPTIONAL,
  1721. IN PULONG               Key OPTIONAL )
  1722. {
  1723. //函数名称
  1724. char hookedfunname[32]="NtWriteFile";
  1725. NTSTATUS ntstatus;
  1726. //文件相关的变量
  1727. char filefullname_c[1024]="???";
  1728. //key相关的变量
  1729. char keyfullname_c[1024]="???";
  1730. //行为Behavior相关变量
  1731. CHAR behavior[1024]="???";
  1732. //进程相关的变量
  1733. CHAR processname[32];//进程名称
  1734. CHAR processfullname_c[512]="???";//进程全名
  1735. //-------------------------------------------------------------------
  1736. //输出函数地址
  1737. GetRealCallee(hookedfunname); 
  1738. //获得函数返回结果
  1739. _asm{
  1740. push Key 
  1741. push ByteOffset 
  1742. push BufferLength 
  1743. push Buffer 
  1744. push IoStatusBlock
  1745. push ApcContext
  1746. push ApcRoutine
  1747. push Event
  1748. push FileHandle
  1749. call RealCallee
  1750. mov ntstatus,eax
  1751. //获取进程的全名
  1752. GetCurrentProcessFileFullName(processfullname_c);
  1753. //监控要监控的程序 
  1754. if(strcmp(processfullname_c,processname_G)!=0)
  1755. {
  1756. return ntstatus;
  1757. //这里分析具体的行为------------------------------------------------
  1758. //经由文件句柄得到文件名
  1759. GetFileFullNamebyFileHandle_QueryNameString(FileHandle,filefullname_c); 
  1760. //--------------------------------------------------------------------------
  1761. strcpy(behavior,"写入文件"");
  1762. strcat(behavior,filefullname_c); 
  1763. strcat(behavior,""");
  1764.  
  1765. //这里要进行操作系统判断,不同的操作系统这个地址不同
  1766. //ProcessNameOffset=0x1FC; //2k
  1767. ProcessNameOffset=0x174;  //xp
  1768. //------------------------------------------------------------------
  1769. LogRecord( "%st%st%st%st%s", GetProcess(processname),hookedfunname,
  1770. processfullname_c, ErrorString( ntstatus ), behavior );
  1771. //------------------------------------------------------------------
  1772.  
  1773.    
  1774. return ntstatus;
  1775. }
  1776. NTSTATUS 
  1777. NTAPI
  1778. HookNtCreateFile( 
  1779.  OUT PHANDLE             FileHandle,
  1780.  IN ACCESS_MASK          DesiredAccess,
  1781.  IN POBJECT_ATTRIBUTES   ObjectAttributes,
  1782.  OUT PIO_STATUS_BLOCK    IoStatusBlock,
  1783.  IN PLARGE_INTEGER       AllocationSize OPTIONAL,
  1784.  IN ULONG                FileAttributes,
  1785.  IN ULONG                ShareAccess,
  1786.  IN ULONG                CreateDisposition,
  1787.  IN ULONG                CreateOptions,
  1788.  IN PVOID                EaBuffer OPTIONAL,
  1789.  IN ULONG                EaLength )
  1790. {
  1791. //函数名称
  1792. char hookedfunname[32]="NtCreateFile";
  1793. NTSTATUS ntstatus;
  1794. //文件相关的变量
  1795. char filefullname_c[1024]="???"; 
  1796. //key相关的变量
  1797. char keyfullname_c[1024]="???";
  1798. //行为Behavior相关变量
  1799. CHAR behavior[1024]="???";
  1800. //进程相关的变量
  1801. CHAR processname[32];//进程名称
  1802. CHAR processfullname_c[512]="???";//进程全名
  1803. //-------------------------------------------------------------------
  1804. //输出函数地址
  1805. GetRealCallee(hookedfunname); 
  1806. //获得函数返回结果
  1807. _asm{
  1808. push EaLength
  1809. push EaBuffer
  1810. push CreateOptions 
  1811. push CreateDisposition 
  1812. push ShareAccess 
  1813. push FileAttributes 
  1814. push AllocationSize
  1815. push IoStatusBlock
  1816. push ObjectAttributes
  1817. push DesiredAccess
  1818. push FileHandle
  1819. call RealCallee
  1820. mov ntstatus,eax
  1821. }  
  1822. //获取进程的全名
  1823. GetCurrentProcessFileFullName(processfullname_c);
  1824. //监控要监控的程序 
  1825. if(strcmp(processfullname_c,processname_G)!=0)
  1826. {
  1827. return ntstatus;
  1828. //这里分析具体的行为------------------------------------------------
  1829. //经由文件句柄得到文件名
  1830. //??????????????????函数有问题//??????????????????
  1831. //GetFileFullNamebyFileHandle_QueryNameString(FileHandle,filefullname_c); 
  1832. //--------------------------------------------------------------------------
  1833. strcpy(behavior,"创建文件"");
  1834. strcat(behavior,filefullname_c); 
  1835. strcat(behavior,""");
  1836.  
  1837. //这里要进行操作系统判断,不同的操作系统这个地址不同
  1838. //ProcessNameOffset=0x1FC; //2k
  1839. ProcessNameOffset=0x174;  //xp
  1840. //------------------------------------------------------------------
  1841. LogRecord( "%st%st%st%st%s", GetProcess(processname),hookedfunname,
  1842. processfullname_c, ErrorString( ntstatus ), behavior );
  1843. //------------------------------------------------------------------
  1844.  
  1845.    
  1846. return ntstatus;
  1847. }
  1848. NTSTATUS 
  1849. NTAPI
  1850. HookNtCreateProcess( 
  1851. OUT PHANDLE           ProcessHandle,
  1852. IN ACCESS_MASK        DesiredAccess,
  1853. IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
  1854. IN HANDLE             ParentProcess,
  1855. IN BOOLEAN            InheritObjectTable,
  1856. IN HANDLE             SectionHandle OPTIONAL,
  1857. IN HANDLE             DebugPort OPTIONAL,
  1858. IN HANDLE             ExceptionPort OPTIONAL )
  1859. {
  1860. //函数名称
  1861. char hookedfunname[32]="NtCreateProcess";
  1862. NTSTATUS ntstatus;
  1863. //key相关的变量
  1864. char keyfullname_c[1024]="???";
  1865. //行为Behavior相关变量
  1866. CHAR behavior[1024]="???";
  1867. //进程相关的变量
  1868. CHAR processname[32];//进程名称
  1869. CHAR processfullname_c[512]="???";//进程全名
  1870. WORD InheritObjectTable_W;
  1871. //-------------------------------------------------------------------
  1872. InheritObjectTable_W=InheritObjectTable;
  1873. //输出函数地址
  1874. GetRealCallee(hookedfunname);  
  1875. //获得函数返回结果
  1876. _asm{ 
  1877. push ExceptionPort 
  1878. push DebugPort 
  1879. push SectionHandle  
  1880. push InheritObjectTable_W
  1881. push ParentProcess
  1882. push ObjectAttributes
  1883. push DesiredAccess
  1884. push ProcessHandle
  1885. call RealCallee
  1886. mov ntstatus,eax
  1887. }  
  1888. //获取进程的全名
  1889. GetCurrentProcessFileFullName(processfullname_c);
  1890. //监控要监控的程序 
  1891. if(strcmp(processfullname_c,processname_G)!=0)
  1892. {
  1893. return ntstatus;
  1894. //这里分析具体的行为?????????????????????????????????????????????????
  1895. strcpy(behavior,"创建进程""); 
  1896. strcat(behavior,""");
  1897.  
  1898. //这里要进行操作系统判断,不同的操作系统这个地址不同
  1899. //ProcessNameOffset=0x1FC; //2k
  1900. ProcessNameOffset=0x174;  //xp
  1901. //------------------------------------------------------------------
  1902. LogRecord( "%st%st%st%st%s", GetProcess(processname),hookedfunname,
  1903. processfullname_c, ErrorString( ntstatus ), behavior );
  1904. //------------------------------------------------------------------
  1905.  
  1906.    
  1907. return ntstatus;
  1908. }
  1909. NTSTATUS 
  1910. NTAPI
  1911. HookNtCreateProcessEx(  
  1912.   OUT PHANDLE ProcessHandle,
  1913.   IN ACCESS_MASK DesiredAccess,
  1914.   IN POBJECT_ATTRIBUTES ObjectAttributes,
  1915.   IN HANDLE InheritFromProcessHandle,
  1916.   IN ULONG CreateFlags,
  1917.   IN HANDLE SectionHandle OPTIONAL,
  1918.   IN HANDLE DebugObject OPTIONAL,
  1919.   IN HANDLE ExceptionPort OPTIONAL,
  1920.   IN ULONG JobMemberLevel)
  1921. {
  1922. //函数名称
  1923. char hookedfunname[32]="NtCreateProcessEx";
  1924. NTSTATUS ntstatus;
  1925. //key相关的变量
  1926. char keyfullname_c[1024]="???";
  1927. //行为Behavior相关变量
  1928. CHAR behavior[1024]="???";
  1929. //进程相关的变量
  1930. CHAR processname[32];//进程名称
  1931. CHAR processfullname_c[512]="???";//进程全名
  1932. //-------------------------------------------------------------------
  1933. //输出函数地址
  1934. GetRealCallee(hookedfunname);  
  1935. //获得函数返回结果
  1936. _asm{ 
  1937. push JobMemberLevel 
  1938. push ExceptionPort 
  1939. push DebugObject  
  1940. push SectionHandle
  1941. push CreateFlags
  1942. push InheritFromProcessHandle
  1943. push ObjectAttributes
  1944. push DesiredAccess
  1945. push ProcessHandle
  1946. call RealCallee
  1947. mov ntstatus,eax
  1948. }  
  1949. //获取进程的全名
  1950. GetCurrentProcessFileFullName(processfullname_c);
  1951. //监控要监控的程序 
  1952. if(strcmp(processfullname_c,processname_G)!=0)
  1953. {
  1954. return ntstatus;
  1955. //这里分析具体的行为?????????????????????????????????????????????????
  1956. strcpy(behavior,"创建进程""); 
  1957. strcat(behavior,""");
  1958.  
  1959. //这里要进行操作系统判断,不同的操作系统这个地址不同
  1960. //ProcessNameOffset=0x1FC; //2k
  1961. ProcessNameOffset=0x174;  //xp
  1962. //------------------------------------------------------------------
  1963. LogRecord( "%st%st%st%st%s", GetProcess(processname),hookedfunname,
  1964. processfullname_c, ErrorString( ntstatus ), behavior );
  1965. //------------------------------------------------------------------
  1966. return ntstatus;
  1967. }
  1968. NTSTATUS 
  1969. NTAPI
  1970. HookNtCreateSection( 
  1971. OUT PHANDLE             SectionHandle,
  1972. IN ULONG                DesiredAccess,
  1973. IN POBJECT_ATTRIBUTES   ObjectAttributes OPTIONAL,
  1974. IN PLARGE_INTEGER       MaximumSize OPTIONAL,
  1975. IN ULONG                PageAttributess,
  1976. IN ULONG                SectionAttributes,
  1977. IN HANDLE               FileHandle OPTIONAL )
  1978. {
  1979. //函数名称
  1980. char hookedfunname[32]="NtCreateSection";
  1981. NTSTATUS ntstatus;
  1982. //文件相关的变量
  1983. char filefullname_c[1024]="???";
  1984. //key相关的变量
  1985. char keyfullname_c[1024]="???";
  1986. //行为Behavior相关变量
  1987. CHAR behavior[1024]="???";
  1988. //进程相关的变量
  1989. CHAR processname[32];//进程名称
  1990. CHAR processfullname_c[512]="???";//进程全名
  1991. //-------------------------------------------------------------------
  1992. //输出函数地址
  1993. GetRealCallee(hookedfunname);  
  1994. //获得函数返回结果
  1995. _asm{  
  1996. push FileHandle 
  1997. push SectionAttributes  
  1998. push PageAttributess
  1999. push MaximumSize
  2000. push ObjectAttributes
  2001. push DesiredAccess
  2002. push SectionHandle
  2003. call RealCallee
  2004. mov ntstatus,eax
  2005. }  
  2006. //获取进程的全名
  2007. GetCurrentProcessFileFullName(processfullname_c);
  2008. //监控要监控的程序 
  2009. if(strcmp(processfullname_c,processname_G)!=0)
  2010. {
  2011. return ntstatus;
  2012. //这里分析具体的行为?????????????????????????????????????????????????
  2013. //经由文件句柄得到文件名 
  2014. GetFileFullNamebyFileHandle_forSection(FileHandle,filefullname_c);
  2015. strcpy(behavior,"创建Section为文件"");
  2016. strcat(behavior,filefullname_c); 
  2017. strcat(behavior,""");
  2018.  
  2019. //这里要进行操作系统判断,不同的操作系统这个地址不同
  2020. //ProcessNameOffset=0x1FC; //2k
  2021. ProcessNameOffset=0x174;  //xp
  2022. //------------------------------------------------------------------
  2023. LogRecord( "%st%st%st%st%s", GetProcess(processname),hookedfunname,
  2024. processfullname_c, ErrorString( ntstatus ), behavior );
  2025. //------------------------------------------------------------------
  2026.  
  2027.    
  2028. return ntstatus;
  2029. }
  2030. NTSTATUS 
  2031. NTAPI
  2032. HookNtOpenThread( 
  2033.  OUT PHANDLE             ThreadHandle,
  2034.  IN ACCESS_MASK          AccessMask,
  2035.  IN POBJECT_ATTRIBUTES   ObjectAttributes,
  2036.  IN PCLIENT_ID           ClientId )
  2037. {
  2038. //函数名称
  2039. char hookedfunname[32]="NtOpenThread";
  2040. NTSTATUS ntstatus;
  2041. //key相关的变量
  2042. char keyfullname_c[1024]="???";
  2043. //行为Behavior相关变量
  2044. CHAR behavior[1024]="???";
  2045. //进程相关的变量
  2046. CHAR processname[32];//进程名称
  2047. CHAR processfullname_c[512]="???";//进程全名
  2048. //-------------------------------------------------------------------
  2049. //输出函数地址
  2050. GetRealCallee(hookedfunname);  
  2051. //获得函数返回结果
  2052. _asm{  
  2053. push ClientId
  2054. push ObjectAttributes
  2055. push AccessMask
  2056. push ThreadHandle
  2057. call RealCallee
  2058. mov ntstatus,eax
  2059. }  
  2060. //获取进程的全名
  2061. GetCurrentProcessFileFullName(processfullname_c);
  2062. //监控要监控的程序 
  2063. if(strcmp(processfullname_c,processname_G)!=0)
  2064. {
  2065. return ntstatus;
  2066. //这里分析具体的行为?????????????????????????????????????????????????
  2067. strcpy(behavior,"打开线程""); 
  2068. strcat(behavior,""");
  2069.  
  2070. //这里要进行操作系统判断,不同的操作系统这个地址不同
  2071. //ProcessNameOffset=0x1FC; //2k
  2072. ProcessNameOffset=0x174;  //xp
  2073. //------------------------------------------------------------------
  2074. LogRecord( "%st%st%st%st%s", GetProcess(processname),hookedfunname,
  2075. processfullname_c, ErrorString( ntstatus ), behavior );
  2076. //------------------------------------------------------------------
  2077.  
  2078. return ntstatus;
  2079. }
  2080. NTSTATUS 
  2081. NTAPI
  2082. HookNtCreateThread( 
  2083.    OUT PHANDLE             ThreadHandle,
  2084.    IN ACCESS_MASK          DesiredAccess,
  2085.    IN POBJECT_ATTRIBUTES   ObjectAttributes OPTIONAL,
  2086.    IN HANDLE               ProcessHandle,
  2087.    OUT PCLIENT_ID          ClientId,
  2088.    IN PCONTEXT             ThreadContext,
  2089.    IN PINITIAL_TEB         InitialTeb,
  2090.    IN BOOLEAN              CreateSuspended )
  2091. {
  2092. //函数名称
  2093. char hookedfunname[32]="NtCreateThread";
  2094. NTSTATUS ntstatus;
  2095. //key相关的变量
  2096. char keyfullname_c[1024]="???";
  2097. //行为Behavior相关变量
  2098. CHAR behavior[1024]="???";
  2099. //进程相关的变量
  2100. CHAR processname[32];//进程名称
  2101. CHAR processfullname_c[512]="???";//进程全名
  2102. WORD CreateSuspended_W;
  2103. //-------------------------------------------------------------------
  2104. CreateSuspended_W=CreateSuspended;
  2105. //输出函数地址
  2106. GetRealCallee(hookedfunname);  
  2107. //获得函数返回结果
  2108. _asm{ 
  2109. push CreateSuspended_W 
  2110. push InitialTeb 
  2111. push ThreadContext  
  2112. push ClientId
  2113. push ProcessHandle
  2114. push ObjectAttributes
  2115. push DesiredAccess
  2116. push ThreadHandle
  2117. call RealCallee
  2118. mov ntstatus,eax
  2119. }  
  2120. //获取进程的全名
  2121. GetCurrentProcessFileFullName(processfullname_c);
  2122. //监控要监控的程序 
  2123. if(strcmp(processfullname_c,processname_G)!=0)
  2124. {
  2125. return ntstatus;
  2126. //这里分析具体的行为?????????????????????????????????????????????????
  2127. strcpy(behavior,"创建线程""); 
  2128. strcat(behavior,""");
  2129.  
  2130. //这里要进行操作系统判断,不同的操作系统这个地址不同
  2131. //ProcessNameOffset=0x1FC; //2k
  2132. ProcessNameOffset=0x174;  //xp
  2133. //------------------------------------------------------------------
  2134. LogRecord( "%st%st%st%st%s", GetProcess(processname),hookedfunname,
  2135. processfullname_c, ErrorString( ntstatus ), behavior );
  2136. //------------------------------------------------------------------
  2137.  
  2138. return ntstatus;
  2139. }
  2140. NTSTATUS 
  2141. NTAPI
  2142. HookNtOpenProcess( 
  2143.   OUT PHANDLE             ProcessHandle,
  2144.   IN ACCESS_MASK          AccessMask,
  2145.   IN POBJECT_ATTRIBUTES   ObjectAttributes,
  2146.   IN PCLIENT_ID           ClientId )
  2147. {
  2148. //函数名称
  2149. char hookedfunname[32]="NtOpenProcess";
  2150. NTSTATUS ntstatus;
  2151. //key相关的变量
  2152. char keyfullname_c[1024]="???";
  2153. //行为Behavior相关变量
  2154. CHAR behavior[1024]="???";
  2155. //进程相关的变量
  2156. CHAR processname[32];//进程名称
  2157. CHAR processfullname_c[512]="???";//进程全名
  2158. //-------------------------------------------------------------------
  2159. //输出函数地址
  2160. GetRealCallee(hookedfunname);   
  2161. //获得函数返回结果
  2162. _asm{ 
  2163. push ClientId
  2164. push ObjectAttributes
  2165. push AccessMask
  2166. push ProcessHandle
  2167. call RealCallee
  2168. mov ntstatus,eax
  2169. }  
  2170. //获取进程的全名
  2171. GetCurrentProcessFileFullName(processfullname_c);
  2172. //监控要监控的程序 
  2173. if(strcmp(processfullname_c,processname_G)!=0)
  2174. {
  2175. return ntstatus;
  2176. //这里分析具体的行为?????????????????????????????????????????????????
  2177. strcpy(behavior,"打开进程""); 
  2178. strcat(behavior,""");
  2179. //这里要进行操作系统判断,不同的操作系统这个地址不同
  2180. //ProcessNameOffset=0x1FC; //2k
  2181. ProcessNameOffset=0x174;  //xp
  2182. //------------------------------------------------------------------
  2183. LogRecord( "%st%st%st%st%s", GetProcess(processname),hookedfunname,
  2184. processfullname_c, ErrorString( ntstatus ), behavior );
  2185. //------------------------------------------------------------------
  2186.  
  2187.    
  2188. return ntstatus;
  2189. }
  2190. NTSTATUS 
  2191. NTAPI
  2192. HookNtOpenSection( 
  2193.   OUT PHANDLE             SectionHandle,
  2194.   IN ACCESS_MASK          DesiredAccess,
  2195.   IN POBJECT_ATTRIBUTES   ObjectAttributes )
  2196. {
  2197. //函数名称
  2198. char hookedfunname[32]="NtOpenSection";
  2199. NTSTATUS ntstatus;
  2200. //文件相关的变量
  2201. ANSI_STRING filefullname_a;
  2202. char filefullname_c[1024]="???";
  2203. //key相关的变量
  2204. char keyfullname_c[1024]="???";
  2205. //行为Behavior相关变量
  2206. CHAR behavior[1024]="???";
  2207. //进程相关的变量
  2208. CHAR processname[32];//进程名称
  2209. CHAR processfullname_c[512]="???";//进程全名
  2210. //-------------------------------------------------------------------
  2211. //输出函数地址
  2212. GetRealCallee(hookedfunname);   
  2213. //获得函数返回结果
  2214. _asm{  
  2215. push ObjectAttributes
  2216. push DesiredAccess
  2217. push SectionHandle
  2218. call RealCallee
  2219. mov ntstatus,eax
  2220. }  
  2221. //获取进程的全名
  2222. GetCurrentProcessFileFullName(processfullname_c);
  2223. //监控要监控的程序 
  2224. if(strcmp(processfullname_c,processname_G)!=0)
  2225. {
  2226. return ntstatus;
  2227. //这里分析具体的行为?????????????????????????????????????????????????
  2228. RtlUnicodeStringToAnsiString( &filefullname_a, ObjectAttributes->ObjectName, TRUE );
  2229. if(filefullname_a.Length!=0)
  2230. {
  2231. strncpy(filefullname_c,filefullname_a.Buffer,Minimum(filefullname_a.Length,1023)); 
  2232. filefullname_c[Minimum(filefullname_a.Length,1023)]=''; 
  2233. }
  2234. strcpy(behavior,"打开Section""); 
  2235. strcat(behavior,filefullname_c);
  2236. strcat(behavior,""");
  2237.  
  2238. //这里要进行操作系统判断,不同的操作系统这个地址不同
  2239. //ProcessNameOffset=0x1FC; //2k
  2240. ProcessNameOffset=0x174;  //xp
  2241. //------------------------------------------------------------------
  2242. LogRecord( "%st%st%st%st%s", GetProcess(processname),hookedfunname,
  2243. processfullname_c, ErrorString( ntstatus ), behavior );
  2244. //------------------------------------------------------------------
  2245.  
  2246. return ntstatus;
  2247. }
  2248. NTSTATUS 
  2249. NTAPI
  2250. HookNtCreateSymbolicLinkObject( 
  2251.    OUT PHANDLE             pHandle,
  2252.    IN ACCESS_MASK          DesiredAccess,
  2253.    IN POBJECT_ATTRIBUTES   ObjectAttributes,
  2254.    IN PUNICODE_STRING      DestinationName )
  2255. {
  2256. //函数名称
  2257. char hookedfunname[32]="NtCreateSymbolicLinkObject";
  2258. NTSTATUS ntstatus;
  2259. //key相关的变量
  2260. char keyfullname_c[1024]="???";
  2261. //行为Behavior相关变量
  2262. CHAR behavior[1024]="???";
  2263. //进程相关的变量
  2264. CHAR processname[32];//进程名称
  2265. CHAR processfullname_c[512]="???";//进程全名
  2266. //-------------------------------------------------------------------
  2267. //输出函数地址
  2268. GetRealCallee(hookedfunname);    
  2269. //获得函数返回结果
  2270. _asm{  
  2271. push DestinationName
  2272. push ObjectAttributes
  2273. push DesiredAccess
  2274. push pHandle
  2275. call RealCallee
  2276. mov ntstatus,eax
  2277. }  
  2278. //获取进程的全名
  2279. GetCurrentProcessFileFullName(processfullname_c);
  2280. //监控要监控的程序 
  2281. if(strcmp(processfullname_c,processname_G)!=0)
  2282. {
  2283. return ntstatus;
  2284. //这里分析具体的行为?????????????????????????????????????????????????
  2285. strcpy(behavior,"创建符号链接""); 
  2286. strcat(behavior,"""); 
  2287. //这里要进行操作系统判断,不同的操作系统这个地址不同
  2288. //ProcessNameOffset=0x1FC; //2k
  2289. ProcessNameOffset=0x174;  //xp
  2290. //------------------------------------------------------------------
  2291. LogRecord( "%st%st%st%st%s", GetProcess(processname),hookedfunname,
  2292. processfullname_c, ErrorString( ntstatus ), behavior );
  2293. //------------------------------------------------------------------
  2294.  
  2295.    
  2296. return ntstatus;
  2297. }
  2298. NTSTATUS 
  2299. NTAPI
  2300. HookNtSetSystemTime( 
  2301. IN PLARGE_INTEGER       SystemTime,
  2302. OUT PLARGE_INTEGER      PreviousTime OPTIONAL )
  2303. {
  2304. //函数名称
  2305. char hookedfunname[32]="NtSetSystemTime";
  2306. NTSTATUS ntstatus;
  2307. //key相关的变量
  2308. char keyfullname_c[1024]="???";
  2309. //行为Behavior相关变量
  2310. CHAR behavior[1024]="???";
  2311. //进程相关的变量
  2312. CHAR processname[32];//进程名称
  2313. CHAR processfullname_c[512]="???";//进程全名
  2314. //-------------------------------------------------------------------
  2315. //输出函数地址
  2316. GetRealCallee(hookedfunname);    
  2317. //获得函数返回结果
  2318. _asm{   
  2319. push PreviousTime
  2320. push SystemTime
  2321. call RealCallee
  2322. mov ntstatus,eax
  2323. }  
  2324. //获取进程的全名
  2325. GetCurrentProcessFileFullName(processfullname_c);
  2326. //监控要监控的程序 
  2327. if(strcmp(processfullname_c,processname_G)!=0)
  2328. {
  2329. return ntstatus;
  2330. //这里分析具体的行为?????????????????????????????????????????????????
  2331. strcpy(behavior,"设置系统时间""); 
  2332. strcat(behavior,"""); 
  2333.  
  2334. //这里要进行操作系统判断,不同的操作系统这个地址不同
  2335. //ProcessNameOffset=0x1FC; //2k
  2336. ProcessNameOffset=0x174;  //xp
  2337. //------------------------------------------------------------------
  2338. LogRecord( "%st%st%st%st%s", GetProcess(processname),hookedfunname,
  2339. processfullname_c, ErrorString( ntstatus ), behavior );
  2340. //------------------------------------------------------------------
  2341.  
  2342.    
  2343. return ntstatus;
  2344. }
  2345. //////////////////////////////////////////////////////////////////////////
  2346. //驱动控制相关
  2347. void unhook()
  2348. {
  2349. ULONG a,base;
  2350. int i=0;
  2351. for(i=0;i<hook_num;i++)
  2352. {
  2353. if(hook_API_info[i].hooked)
  2354. {
  2355. Index=hook_API_info[i].Index;
  2356. RealCallee=hook_API_info[i].RealCallee;
  2357. //unhook dispatch table
  2358. a=4*Index+(ULONG)KeServiceDescriptorTable->ServiceTable;
  2359. base=(ULONG)MmMapIoSpace(MmGetPhysicalAddress((void*)a),4,0);
  2360. //恢复ssdt中的函数地址
  2361. _asm
  2362. {
  2363. mov eax,base
  2364. mov ebx,RealCallee
  2365. mov dword ptr[eax],ebx
  2366. }
  2367. tmp=(char*)base;
  2368. MmUnmapIoSpace(tmp,4);
  2369. hook_API_info[i].hooked=FALSE;
  2370. }
  2371. }
  2372. }
  2373. //////////////////////////////////////////////////////////////////////////
  2374. //IRP派遣例程——IRP_MJ_DEVICE_CONTROL 
  2375. //driver->MajorFunction[IRP_MJ_DEVICE_CONTROL]=DrvDispatch;
  2376. NTSTATUS DrvDispatch(IN PDEVICE_OBJECT device,IN PIRP Irp)
  2377. {
  2378. UCHAR*buff=0; ULONG a,base;
  2379. int offsetbuff=0;
  2380. DWORD numHookAPI=0;
  2381. CHAR nativeAPIname[64];
  2382. int i=0;
  2383. int j=0;
  2384. PIO_STATUS_BLOCK IoStatus;
  2385. BOOLEAN               retval = FALSE;
  2386. PLOG_BUF              old;
  2387. BOOLEAN               logMutexReleased;
  2388. PIO_STACK_LOCATION      irpStack;
  2389. PVOID                   inputBuffer;
  2390. PVOID                   outputBuffer;
  2391. ULONG                   inputBufferLength;
  2392. ULONG                   outputBufferLength;
  2393. PIO_STACK_LOCATION loc;
  2394. ULONG                   ioControlCode;
  2395. irpStack = IoGetCurrentIrpStackLocation (Irp);
  2396. inputBuffer             = Irp->AssociatedIrp.SystemBuffer;
  2397. inputBufferLength       = irpStack->Parameters.DeviceIoControl.InputBufferLength;
  2398. outputBuffer            = Irp->AssociatedIrp.SystemBuffer;
  2399. outputBufferLength      = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
  2400. loc=IoGetCurrentIrpStackLocation(Irp);//获得IRP Stack
  2401. ioControlCode           = irpStack->Parameters.DeviceIoControl.IoControlCode;
  2402. //使buff指向controlbuff
  2403. buff=(UCHAR*)Irp->AssociatedIrp.SystemBuffer; 
  2404. //
  2405. // Its a message from our GUI!
  2406. //
  2407. IoStatus=&Irp->IoStatus;
  2408. IoStatus->Status      = STATUS_SUCCESS; // Assume success
  2409. IoStatus->Information = 0;              // Assume nothing returned
  2410. //
  2411. // See if the output buffer is really a user buffer that we
  2412. // can just dump data into.
  2413. //
  2414. if( IOCTL_TRANSFER_TYPE(ioControlCode) == METHOD_NEITHER ) {
  2415. outputBuffer = Irp->UserBuffer;
  2416. }
  2417. switch(ioControlCode)
  2418. {
  2419. case IOCTL_BEHAVIORMON_HOOK://hook Native API function
  2420. offsetbuff=0;
  2421. //获得要Hook的NativeAPI函数的个数
  2422. numHookAPI=(DWORD)buff[8];
  2423. offsetbuff+=12;
  2424. //hook
  2425. for(i=0;i<(int)numHookAPI;i++)
  2426. {
  2427. //获得要Hook的NativeAPI函数的name
  2428. strcpy(nativeAPIname,buff+offsetbuff);
  2429. offsetbuff+=strlen(nativeAPIname);
  2430. offsetbuff+=1;
  2431. //获得要Hook的NativeAPI函数的Index
  2432. memmove(&Index,buff+offsetbuff,4);//读出从前台输入的SSDT函数服务Index
  2433. offsetbuff+=4;
  2434. //将上面得到的信息放在对应的Hook_API_Info中
  2435. for(j=0;j<hook_num;j++)
  2436. {
  2437. if(strcmp(nativeAPIname,hook_API_info[j].nativeAPIname)==0)
  2438. {
  2439. break;
  2440. }
  2441. }
  2442. if(j==hook_num)
  2443. {
  2444. continue;
  2445. }
  2446. //获得该函数的真实地址,并开始Hook
  2447. a=4*Index+(ULONG)KeServiceDescriptorTable->ServiceTable;
  2448. //把正确的SSDT函数调用地址先备份到base中
  2449. base=(ULONG)MmMapIoSpace(MmGetPhysicalAddress((void*)a),4,0);
  2450. a=hook_API_info[j].proxyfunadd;
  2451. _asm
  2452. {
  2453. mov eax,base//把正确的SSDT函数调用地址复制到eax中
  2454. mov ebx,dword ptr[eax]//使ebx=eax
  2455. mov RealCallee,ebx//RealCallee=eax
  2456. mov ebx,a//使ebx指向HookRegRestoreKey()函数
  2457. mov dword ptr[eax],ebx//把SSDT中的正确的函数调用地址改为HookRegRestoreKey()函数所在的地址!!!
  2458. //将上面得到的信息放在对应的Hook_API_Info中 
  2459. hook_API_info[j].Index=Index;
  2460. hook_API_info[j].RealCallee=RealCallee; 
  2461. hook_API_info[j].hooked=TRUE;
  2462. tmp=(char*)base;
  2463. MmUnmapIoSpace(tmp,4);
  2464. }
  2465. //获取与用户的交互缓冲区,buff中第一个DW就是其地址
  2466. memmove(&a,buff,4);
  2467. plog_behavior=(PLOG_BEHAVIOR)MmMapIoSpace(MmGetPhysicalAddress((void*)a),LOG_BEHAVIOR_NUM*sizeof(LOG_BEHAVIOR),0);
  2468. break;
  2469. case IOCTL_BEHAVIORMON_PROC:
  2470. //设置要监控的程序全路径
  2471. strcpy(processname_G,buff);
  2472. break;
  2473. case IOCTL_BEHAVIORMON_UNHOOK:
  2474. unhook();
  2475. break;
  2476. case IOCTL_BEHAVIORMON_GETSTATS:
  2477. //
  2478. // Probe the output buffer
  2479. //
  2480. try {                 
  2481. ProbeForWrite( outputBuffer,
  2482. outputBufferLength,
  2483. sizeof( UCHAR ));
  2484. } except( EXCEPTION_EXECUTE_HANDLER ) {
  2485. IoStatus->Status = STATUS_INVALID_PARAMETER;
  2486. return FALSE;
  2487. }            
  2488. MUTEX_ACQUIRE( LogMutex );
  2489. if( LOGBUFSIZE > outputBufferLength )  {
  2490. //
  2491. // Output buffer isn't big enough
  2492. //
  2493. MUTEX_RELEASE( LogMutex );
  2494. IoStatus->Status = STATUS_INVALID_PARAMETER;
  2495. return FALSE;
  2496. } else if( Log->Len  ||  Log->Next ) {
  2497. //
  2498. // Switch to a new Log
  2499. //
  2500. RegmonNewLog();
  2501. //
  2502. // Fetch the oldest to give to user
  2503. //
  2504. old = RegmonOldestLog();
  2505. if( old != Log ) {
  2506. logMutexReleased = TRUE;
  2507. MUTEX_RELEASE( LogMutex );
  2508. } else {
  2509. logMutexReleased = FALSE;
  2510. }
  2511. //
  2512. // Copy it
  2513. //
  2514. memcpy( outputBuffer, old->Data, old->Len );
  2515. //
  2516. // Return length of copied info
  2517. //
  2518. IoStatus->Information = old->Len;
  2519. //
  2520. // Deallocate buffer - unless its the last one
  2521. //
  2522. if( logMutexReleased ) {
  2523. ExFreePool( old );
  2524. } else {
  2525. Log->Len = 0;
  2526. MUTEX_RELEASE( LogMutex );
  2527. }
  2528. } else {
  2529. //
  2530. // No unread data
  2531. //
  2532. MUTEX_RELEASE( LogMutex );
  2533. IoStatus->Information = 0;
  2534. }
  2535. break;
  2536. case IOCTL_BEHAVIORMON_ZEROSTATS: 
  2537. //
  2538. // Zero contents of buffer
  2539. // 
  2540. MUTEX_ACQUIRE( LogMutex );
  2541. while( Log->Next )  {
  2542. //
  2543. // Free all but the first output buffer
  2544. //
  2545. old = Log->Next;
  2546. Log->Next = old->Next;
  2547. ExFreePool( old );
  2548. NumLog--;
  2549. }
  2550. //
  2551. // Set the output pointer to the start of the output buffer
  2552. //
  2553. Log->Len = 0;
  2554. //
  2555. // Reset sequence and relative start time
  2556. //
  2557. Sequence = 0;
  2558. StartTime = KeQueryPerformanceCounter( NULL );
  2559. MUTEX_RELEASE( LogMutex );
  2560. break;
  2561. default:
  2562. break;
  2563. Irp->IoStatus.Status=0;
  2564. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  2565. return 0;
  2566. }
  2567. // nothing special
  2568. NTSTATUS DrvCreateClose(IN PDEVICE_OBJECT device,IN PIRP Irp)
  2569. {
  2570. Irp->IoStatus.Information=0;
  2571. Irp->IoStatus.Status=0;
  2572. IoCompleteRequest(Irp,IO_NO_INCREMENT);
  2573. return 0;
  2574. }
  2575. // nothing special -just a cleanup
  2576. void DrvUnload(IN PDRIVER_OBJECT driver)
  2577. {
  2578. UNICODE_STRING devlink;
  2579. ULONG a,base;
  2580. int i=0;
  2581. for(i=0;i<hook_num;i++)
  2582. {
  2583. if(hook_API_info[i].hooked)
  2584. {
  2585. Index=hook_API_info[i].Index;
  2586. RealCallee=hook_API_info[i].RealCallee;
  2587. //unhook dispatch table
  2588. a=4*Index+(ULONG)KeServiceDescriptorTable->ServiceTable;
  2589. base=(ULONG)MmMapIoSpace(MmGetPhysicalAddress((void*)a),4,0);
  2590. //恢复ssdt中的函数地址
  2591. _asm
  2592. {
  2593. mov eax,base
  2594. mov ebx,RealCallee
  2595. mov dword ptr[eax],ebx
  2596. }
  2597. tmp=(char*)base;
  2598. MmUnmapIoSpace(tmp,4);
  2599. hook_API_info[i].hooked=FALSE;
  2600. }
  2601. }
  2602. MmUnmapIoSpace(plog_behavior,LOG_BEHAVIOR_NUM*sizeof(LOG_BEHAVIOR));
  2603. RtlInitUnicodeString(&devlink,devicelink);
  2604. IoDeleteSymbolicLink(&devlink);
  2605. IoDeleteDevice(driver->DeviceObject);
  2606. //
  2607. // Now we can free any memory we have outstanding
  2608. //
  2609. RegmonHashCleanup();
  2610. RegmonFreeLog(); 
  2611. ExDeletePagedLookasideList( &FullPathLookaside );
  2612. }
  2613. //****************************************************************************
  2614. //驱动程序的入口点,相当于c语言的main函数,它在驱动程序被加载进内存的时候调用
  2615. //第一个重要的任务——就是要设定驱动程序对象的几个函数指针;
  2616. /*
  2617. pDriverObj->DriverUnload = DriverUnload;//卸载函数
  2618. pDriverObj->MajorFunction[IRP_MJ_CREATE] =
  2619. pDriverObj->MajorFunction[IRP_MJ_CLOSE] =
  2620. pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverDispatch;//派遣函数
  2621. */
  2622. //第二个重要的任务——就是要创建设备对象并为其建立符号连接;
  2623. /*
  2624. NTKERNELAPI
  2625. NTSTATUS
  2626. IoCreateDevice(
  2627. IN PDRIVER_OBJECT DriverObject,
  2628. IN ULONG DeviceExtensionSize,
  2629. IN PUNICODE_STRING DeviceName OPTIONAL,
  2630. IN DEVICE_TYPE DeviceType,
  2631. IN ULONG DeviceCharacteristics,
  2632. IN BOOLEAN Exclusive,
  2633. OUT PDEVICE_OBJECT *DeviceObject
  2634. );
  2635. //例子:
  2636. IoCreateDevice( pDriverObj,
  2637. 0,
  2638. &deviceName,
  2639. FILE_DEVICE_UNKNOWN,
  2640. FILE_DEVICE_SECURE_OPEN,
  2641. true,
  2642. &pDeviceObj ); //创建设备对象
  2643. IoCreateSymbolicLink( &linkName, &deviceName );   //建立符号连接
  2644. */
  2645. //DriverEntry just creates our device - nothing special here
  2646. NTSTATUS DriverEntry(IN PDRIVER_OBJECT driver,IN PUNICODE_STRING path)
  2647. {
  2648. PDEVICE_OBJECT devobject=0;//设备对象
  2649. UNICODE_STRING devlink,devname;//设备链接,设备名称
  2650. ULONG a,b; 
  2651. RtlInitUnicodeString(&devname,devicename);
  2652. RtlInitUnicodeString(&devlink,devicelink);
  2653. //初始化要监控的程序全路径
  2654. processname_G[0]='X';
  2655. processname_G[1]='X';
  2656. processname_G[2]='X';
  2657. processname_G[3]='';
  2658. //初始化哈希表,存放注册表全名
  2659. MUTEX_INIT( HashMutex );
  2660. MUTEX_INIT( LogMutex );
  2661. //
  2662. // Initialize a lookaside for key names
  2663. //
  2664. ExInitializePagedLookasideList( &FullPathLookaside, NULL, NULL,
  2665. 0, MAXPATHLEN, 'mgeR', 256 );
  2666. //
  2667. // Allocate the initial output buffer
  2668. //
  2669. Log = ExAllocatePool( PagedPool, sizeof(*Log) );
  2670. if( !Log ) {  
  2671. RtlInitUnicodeString(&devlink,devicelink);
  2672. IoDeleteSymbolicLink(&devlink);
  2673. IoDeleteDevice(driver->DeviceObject);
  2674. return STATUS_INSUFFICIENT_RESOURCES;
  2675. }
  2676. Log->Len  = 0;
  2677. Log->Next = NULL;
  2678. NumLog = 1;
  2679. //
  2680. // Initialize rootkey lengths
  2681. //
  2682. for( i = 0; i < NUMROOTKEYS; i++ ) {
  2683. RootKey[i].RootNameLen = strlen( RootKey[i].RootName );
  2684. }
  2685. for( i = 0; i < 2; i++ ) {
  2686. CurrentUser[i].RootNameLen = strlen( CurrentUser[i].RootName );
  2687. }
  2688. //创建设备+创建符号链接
  2689. IoCreateDevice(driver,2048,&devname,FILE_DEVICE_UNKNOWN,0,TRUE,&devobject);
  2690. IoCreateSymbolicLink(&devlink,&devname);
  2691. //设定驱动程序对象的几个函数指针
  2692. driver->MajorFunction[IRP_MJ_DEVICE_CONTROL]=DrvDispatch;//派遣函数
  2693. driver->MajorFunction[IRP_MJ_CREATE]=DrvCreateClose;
  2694. driver->MajorFunction[IRP_MJ_CLOSE]=DrvCreateClose;
  2695. driver->DriverUnload=DrvUnload;//卸载函数
  2696. ProcessNameOffset = GetProcessNameOffset();
  2697. //初始化Hook_API_Info
  2698. //NtRestoreKey
  2699. hook_API_info[hook_num].nativeAPIname="NtRestoreKey";
  2700. hook_API_info[hook_num].proxyfunadd=(ULONG)&HookNtRestoreKey;
  2701. hook_API_info[hook_num].hooked=FALSE;
  2702. hook_num++;
  2703. //NtOpenKey 
  2704. hook_API_info[hook_num].nativeAPIname="NtOpenKey";
  2705. hook_API_info[hook_num].proxyfunadd=(ULONG)&HookNtOpenKey;
  2706. hook_API_info[hook_num].hooked=FALSE;
  2707. hook_num++; 
  2708. //NtCreateKey 
  2709. hook_API_info[hook_num].nativeAPIname="NtCreateKey";
  2710. hook_API_info[hook_num].proxyfunadd=(ULONG)&HookNtCreateKey;
  2711. hook_API_info[hook_num].hooked=FALSE;
  2712. hook_num++;
  2713. //NtQueryValueKey 
  2714. hook_API_info[hook_num].nativeAPIname="NtQueryValueKey";
  2715. hook_API_info[hook_num].proxyfunadd=(ULONG)&HookNtQueryValueKey;
  2716. hook_API_info[hook_num].hooked=FALSE;
  2717. hook_num++;
  2718. //NtQueryKey 
  2719. hook_API_info[hook_num].nativeAPIname="NtQueryKey";
  2720. hook_API_info[hook_num].proxyfunadd=(ULONG)&HookNtQueryKey;
  2721. hook_API_info[hook_num].hooked=FALSE;
  2722. hook_num++;
  2723. //NtDeleteKey 
  2724. hook_API_info[hook_num].nativeAPIname="NtDeleteKey";
  2725. hook_API_info[hook_num].proxyfunadd=(ULONG)&HookNtDeleteKey;
  2726. hook_API_info[hook_num].hooked=FALSE;
  2727. hook_num++;
  2728. //NtDeleteValueKey 
  2729. hook_API_info[hook_num].nativeAPIname="NtDeleteValueKey";
  2730. hook_API_info[hook_num].proxyfunadd=(ULONG)&HookNtDeleteValueKey;
  2731. hook_API_info[hook_num].hooked=FALSE;
  2732. hook_num++;
  2733. //NtSetValueKey 
  2734. hook_API_info[hook_num].nativeAPIname="NtSetValueKey";
  2735. hook_API_info[hook_num].proxyfunadd=(ULONG)&HookNtSetValueKey;
  2736. hook_API_info[hook_num].hooked=FALSE;
  2737. hook_num++;
  2738. //NtEnumerateKey 
  2739. hook_API_info[hook_num].nativeAPIname="NtEnumerateKey";
  2740. hook_API_info[hook_num].proxyfunadd=(ULONG)&HookNtEnumerateKey;
  2741. hook_API_info[hook_num].hooked=FALSE;
  2742. hook_num++;
  2743. //NtEnumerateValueKey 
  2744. hook_API_info[hook_num].nativeAPIname="NtEnumerateValueKey";
  2745. hook_API_info[hook_num].proxyfunadd=(ULONG)&HookNtEnumerateValueKey;
  2746. hook_API_info[hook_num].hooked=FALSE;
  2747. hook_num++;
  2748. //NtOpenFile 
  2749. hook_API_info[hook_num].nativeAPIname="NtOpenFile";
  2750. hook_API_info[hook_num].proxyfunadd=(ULONG)&HookNtOpenFile;
  2751. hook_API_info[hook_num].hooked=FALSE;
  2752. hook_num++;
  2753. //NtWriteFile 
  2754. hook_API_info[hook_num].nativeAPIname="NtWriteFile";
  2755. hook_API_info[hook_num].proxyfunadd=(ULONG)&HookNtWriteFile;
  2756. hook_API_info[hook_num].hooked=FALSE;
  2757. hook_num++;
  2758. //  //NtCreateFile 
  2759. //  hook_API_info[hook_num].nativeAPIname="NtCreateFile";
  2760. //  hook_API_info[hook_num].proxyfunadd=(ULONG)&HookNtCreateFile;
  2761. //  hook_API_info[hook_num].hooked=FALSE;
  2762. //  hook_num++;
  2763. //NtCreateProcess 
  2764. hook_API_info[hook_num].nativeAPIname="NtCreateProcess";
  2765. hook_API_info[hook_num].proxyfunadd=(ULONG)&HookNtCreateProcess;
  2766. hook_API_info[hook_num].hooked=FALSE;
  2767. hook_num++;
  2768. //NtCreateProcessEx 
  2769. hook_API_info[hook_num].nativeAPIname="NtCreateProcessEx";
  2770. hook_API_info[hook_num].proxyfunadd=(ULONG)&HookNtCreateProcessEx;
  2771. hook_API_info[hook_num].hooked=FALSE;
  2772. hook_num++;
  2773. //NtCreateSection 
  2774. hook_API_info[hook_num].nativeAPIname="NtCreateSection";
  2775. hook_API_info[hook_num].proxyfunadd=(ULONG)&HookNtCreateSection;
  2776. hook_API_info[hook_num].hooked=FALSE;
  2777. hook_num++;
  2778. //NtOpenThread 
  2779. hook_API_info[hook_num].nativeAPIname="NtOpenThread";
  2780. hook_API_info[hook_num].proxyfunadd=(ULONG)&HookNtOpenThread;
  2781. hook_API_info[hook_num].hooked=FALSE;
  2782. hook_num++;
  2783. //NtCreateThread 
  2784. hook_API_info[hook_num].nativeAPIname="NtCreateThread";
  2785. hook_API_info[hook_num].proxyfunadd=(ULONG)&HookNtCreateThread;
  2786. hook_API_info[hook_num].hooked=FALSE;
  2787. hook_num++;
  2788. //NtOpenProcess 
  2789. hook_API_info[hook_num].nativeAPIname="NtOpenProcess";
  2790. hook_API_info[hook_num].proxyfunadd=(ULONG)&HookNtOpenProcess;
  2791. hook_API_info[hook_num].hooked=FALSE;
  2792. hook_num++;
  2793. //NtOpenSection 
  2794. hook_API_info[hook_num].nativeAPIname="NtOpenSection";
  2795. hook_API_info[hook_num].proxyfunadd=(ULONG)&HookNtOpenSection;
  2796. hook_API_info[hook_num].hooked=FALSE;
  2797. hook_num++;
  2798. //NtCreateSymbolicLinkObject 
  2799. hook_API_info[hook_num].nativeAPIname="NtCreateSymbolicLinkObject";
  2800. hook_API_info[hook_num].proxyfunadd=(ULONG)&HookNtCreateSymbolicLinkObject;
  2801. hook_API_info[hook_num].hooked=FALSE;
  2802. hook_num++;
  2803. //NtSetSystemTime 
  2804. hook_API_info[hook_num].nativeAPIname="NtSetSystemTime";
  2805. hook_API_info[hook_num].proxyfunadd=(ULONG)&HookNtSetSystemTime;
  2806. hook_API_info[hook_num].hooked=FALSE;
  2807. hook_num++; 
  2808. return 0;
  2809. }