标签:
本文讲 用inline hook的方式修改NtOpenKey函数的一个小例子, 自己的学习笔记
hook 计算机里面一般是指 挂钩某函数,也可以是替换掉原来的函数。
inline hook 是直接在以前的函数替里面修改指令,用一个跳转或者其他指令来达到挂钩的目的。 这是相对普通的hook来说,因为普通的hook只是修改函数的调用地址,而不是在原来的函数体里面做修改。
一般来说 普通的hook比较稳定使用。 inline hook 更加高级一点,一般也跟难以被发现。所以很多人比如病毒制作者都比较推崇inline hook。
SSDT的全称是System Services Descriptor Table,系统服务描述符表
一般来说此表与链接系统内核的API密切相关,对此有一项应用就是杀毒软件的主动防御,当然病毒也可以通过修改主动防御的SSDT来绕过杀软的主动防御。SSDT hook一般是用来隐藏进程运行程序的,前面已经讲了。
先用PCHunter查看下NtOpenKey的序号
1. hook 内核函数NtOpenKey, 把 函数开头的前5个字节的指令 改成 call xxxxxxxx
2. 把前5个字节的指令 替换成 call 相对偏移, 实现跳转到 newNtOpenKey
公式: 相对偏移 = hook后函数地址 - 原函数地址 -指令长度
机器码: E8 XXXXXXXX
3. 完成 newNtOpenKey 函数
void FilterNtOpenKey()
{
KdPrint(("%s",(char*)PsGetCurrentProcess()+0x16c));
}
void NewNtOpenKey()
{
__asm{
call FilterNtOpenKey
pop eax
mov edi,edi
push ebp
mov ebp,esp
jmp g_jmp_orig_ntopenkey
}
}
完整代码
1 #include "ntddk.h" 2 //windbg命令: 3 //dd KeServiceDescriptorTable 4 //dt _EPROCESS 5 extern "C" 6 { 7 8 void PageProtectOn() 9 { 10 __asm{//恢复内存保护 11 mov eax,cr0 12 or eax,10000h 13 mov cr0,eax 14 sti 15 } 16 } 17 void PageProtectOff() 18 { 19 __asm{//去掉内存保护 20 cli 21 mov eax,cr0 22 and eax,not 10000h 23 mov cr0,eax 24 } 25 } 26 27 #pragma pack(1) 28 typedef struct ServiceDescriptorEntry { 29 unsigned int *ServiceTableBase; 30 unsigned int *ServiceCounterTableBase; //仅适用于checked build版本 31 unsigned int NumberOfServices; 32 unsigned char *ParamTableBase; 33 } ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t; 34 #pragma pack() 35 __declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable; 36 37 NTSTATUS PsLookupProcessByProcessId(IN HANDLE ProcessId, OUT PEPROCESS *Process); 38 39 ULONG g_ntopenprocess; 40 ULONG g_ntocreatesection; 41 42 typedef NTSTATUS (*NTOPENPROCESS) ( 43 __out PHANDLE ProcessHandle, 44 __in ACCESS_MASK DesiredAccess, 45 __in POBJECT_ATTRIBUTES ObjectAttributes, 46 __in_opt PCLIENT_ID ClientId); 47 48 typedef NTSTATUS (*NtCreateSection)( 49 OUT PHANDLE SectionHandle , 50 IN ACCESS_MASK DesiredAccess , 51 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, 52 IN PLARGE_INTEGER MaximumSize OPTIONAL, 53 IN ULONG SectionPageProtection , 54 IN ULONG AllocationAttributes , 55 IN HANDLE FileHandle OPTIONAL); 56 57 58 59 NTSTATUS IoQueryFileDosDeviceName(IN PFILE_OBJECT FileObject,OUT POBJECT_NAME_INFORMATION *ObjectNameInformation ); 60 61 NTSTATUS NewNtCreateSection( 62 OUT PHANDLE SectionHandle , 63 IN ACCESS_MASK DesiredAccess , 64 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, 65 IN PLARGE_INTEGER MaximumSize OPTIONAL, 66 IN ULONG SectionPageProtection , 67 IN ULONG AllocationAttributes , 68 IN HANDLE FileHandle OPTIONAL 69 ) 70 { 71 ULONG isrun =1; 72 PFILE_OBJECT FileObject; 73 POBJECT_NAME_INFORMATION wcFilePath; 74 if (SectionPageProtection & (PAGE_EXECUTE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE|PAGE_EXECUTE_WRITECOPY) ){ 75 if (NT_SUCCESS(ObReferenceObjectByHandle(FileHandle,0,NULL,KernelMode,(PVOID *)(&FileObject),NULL))) 76 { 77 if (IoQueryFileDosDeviceName(FileObject,&wcFilePath)==STATUS_SUCCESS) 78 { 79 ExFreePool(wcFilePath); 80 wchar_t wstr[260]=L""; 81 wcscpy(wstr, wcFilePath->Name.Buffer); 82 _wcslwr(wstr); 83 DbgPrint("[TrueCell] %ws\r\n",wstr); 84 if (wcsstr(wstr, L"360safe.exe")!=0) 85 { 86 ObDereferenceObject(FileObject); 87 return STATUS_UNSUCCESSFUL; 88 } 89 } 90 ObDereferenceObject(FileObject); 91 } 92 } 93 return ((NtCreateSection)g_ntocreatesection)(SectionHandle,DesiredAccess,ObjectAttributes,MaximumSize,SectionPageProtection,AllocationAttributes,FileHandle); 94 } 95 96 97 NTSTATUS NewNtOpenProcess ( 98 __out PHANDLE ProcessHandle, 99 __in ACCESS_MASK DesiredAccess, 100 __in POBJECT_ATTRIBUTES ObjectAttributes, 101 __in_opt PCLIENT_ID ClientId) 102 { 103 NTSTATUS status; 104 PEPROCESS process_obj; 105 char strpname[30]="calc.exe"; 106 HANDLE ProcessId=(HANDLE)(ClientId->UniqueProcess); 107 if (!MmIsAddressValid(strpname))return FALSE; 108 if (ProcessId==0) return FALSE; 109 status = PsLookupProcessByProcessId(ProcessId,&process_obj); 110 if (!NT_SUCCESS(status)){ 111 KdPrint(("error code:%X---ProcessId:%d",status,ProcessId)); 112 return FALSE; 113 } 114 char sname[15]=""; 115 strcpy(sname, (char*)process_obj+0x16c); 116 _strlwr(sname); 117 if (strstr(strpname, sname)!=0) 118 { 119 ObDereferenceObject(process_obj); 120 return STATUS_UNSUCCESSFUL; 121 } 122 ObDereferenceObject(process_obj); 123 124 return ((NTOPENPROCESS)g_ntopenprocess)(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId); 125 } 126 127 128 NTSTATUS HookNtFun() 129 { 130 NTSTATUS status; 131 status = STATUS_SUCCESS; 132 133 PageProtectOff(); 134 135 g_ntopenprocess = KeServiceDescriptorTable.ServiceTableBase[190]; 136 KeServiceDescriptorTable.ServiceTableBase[190] = (unsigned int)NewNtOpenProcess; 137 138 g_ntocreatesection = KeServiceDescriptorTable.ServiceTableBase[84];//84 139 KeServiceDescriptorTable.ServiceTableBase[84] = (unsigned int)NewNtCreateSection; 140 PageProtectOn(); 141 return status; 142 } 143 VOID UnHookNtFun() 144 { 145 PageProtectOff(); 146 KeServiceDescriptorTable.ServiceTableBase[190] = (unsigned int)g_ntopenprocess; 147 KeServiceDescriptorTable.ServiceTableBase[84] = (unsigned int)g_ntocreatesection; 148 PageProtectOn(); 149 } 150 VOID MyUnload(PDRIVER_OBJECT pDriverObject) 151 { 152 UnHookNtFun(); 153 } 154 NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject,PUNICODE_STRING Reg_Path) 155 { 156 HookNtFun(); 157 pDriverObject->DriverUnload = MyUnload; 158 return STATUS_SUCCESS; 159 } 160 161 }
标签:
原文地址:http://www.cnblogs.com/mayingkun/p/5151539.html