小弟从上周开始发奋学习内核知识,书到了,电脑也到了,再也没有理由偷懒了,终于决定学习。
这几天学习学到了不少知识,看了好久的书,翻阅了看雪很多帖子。
先后学习了 SSDT HOOK 、InlineHook ,为了记录一下自己的学习,也为以后查阅,所以写一篇记录文章。
第一例:SSDT HOOK NtOpenProcess 保护calc.exe 程序
typedef struct _KSERVICE_TABLE_DESCRIPTORSTRUCT
{
PULONG ServiceTableBase; // SSDT (System Service Dispatch Table)的基地址
PULONG ServiceCounterTableBase; // 用于 checked builds, 包含 SSDT 中每个服务被调用的次数
ULONG NumberOfService; // 服务函数的个数, NumberOfService * 4 就是整个地址表的大小
ULONG ParamTableBase; // SSPT(System Service Parameter Table)的基地址
} KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;
ULONG OldNtOpenProcessAddr;
extern "C" PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable;
typedef NTSTATUS (__stdcall *NewNtOpenProcess)(
__out PHANDLE ProcessHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__in_opt PCLIENT_ID ClientId
);
NewNtOpenProcess _NewNtOpenProcess;
extern "C" NTSTATUS
PsLookupProcessByProcessId(
__in HANDLE ProcessId,
__deref_out PEPROCESS *Process
);
extern "C" UCHAR *
PsGetProcessImageFileName(
__in PEPROCESS Process
);
/**************************SSDT HOOK NtOpenProcess Start***********************/
NTSTATUS
MyNtOpenProcess (
__out PHANDLE ProcessHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__in_opt PCLIENT_ID ClientId
)
{
PEPROCESS _eprocess;
NTSTATUS _ntReturn;
_ntReturn=_NewNtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
if(NT_SUCCESS(_ntReturn))
{
_ntReturn=PsLookupProcessByProcessId(ClientId->UniqueProcess,&_eprocess);
if(NT_SUCCESS(_ntReturn))
{
char *ProcessName=(char *)PsGetProcessImageFileName(_eprocess);
if(MmIsAddressValid(ProcessName))
{
DbgPrint("%s",ProcessName);
if(!strcmp(ProcessName,"calc.exe"))
{
_ntReturn=STATUS_ACCESS_DENIED;
}
}
}
ObDereferenceObject(_eprocess);
}
return _ntReturn;
}
void HookNtOpenProcess()
{
OldNtOpenProcessAddr=GetSSDTStartAddr(122);
_NewNtOpenProcess=(NewNtOpenProcess)OldNtOpenProcessAddr;
POFF();
KeServiceDescriptorTable->ServiceTableBase[122]=(ULONG)MyNtOpenProcess;
PON();
}
void UnHookNtOpenProcess()
{
POFF();
KeServiceDescriptorTable->ServiceTableBase[122]=OldNtOpenProcessAddr;
PON();
}
/**************************SSDT HOOK NtOpenProcess End*************************/
/**************************SSDT InlineHook NtOpenProcess Start *************************/
BYTE OldData[5]={0};
BYTE JmpData[5]={0xE9,0,0,0,0};
ULONG InLineHookOldAddress;
ULONG JmpRetAddr;
NewNtOpenProcess _InLineHookNewNtOpenProcess;
__declspec(naked) NTSTATUS InLineHookFun(...)
{
_asm
{
push 0xc4
jmp JmpRetAddr;
}
}
NTSTATUS
InlineHookNtOpenProcess (
__out PHANDLE ProcessHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__in_opt PCLIENT_ID ClientId
)
{
PEPROCESS _eprocess;
NTSTATUS _ntReturn;
_InLineHookNewNtOpenProcess=(NewNtOpenProcess)InLineHookFun;
_ntReturn=_InLineHookNewNtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
if(NT_SUCCESS(_ntReturn))
{
_ntReturn=PsLookupProcessByProcessId(ClientId->UniqueProcess,&_eprocess);
if(NT_SUCCESS(_ntReturn))
{
char *ProcessName=(char *)PsGetProcessImageFileName(_eprocess);
if(MmIsAddressValid(ProcessName))
{
DbgPrint("%s",ProcessName);
if(!strcmp(ProcessName,"calc.exe"))
{
_ntReturn=STATUS_ACCESS_DENIED;
}
}
}
ObDereferenceObject(_eprocess);
}
return _ntReturn;
}
void InLineHookNtOpenProcess()
{
InLineHookOldAddress=GetSSDTStartAddr(122);
JmpRetAddr=InLineHookOldAddress+5;
RtlCopyMemory(OldData,(VOID *)InLineHookOldAddress,5);
*(PULONG)(&JmpData[1])=(ULONG)InlineHookNtOpenProcess-InLineHookOldAddress-5;
POFF();
RtlCopyMemory((VOID *)InLineHookOldAddress,JmpData,5);
PON();
}
void InLineUnHookNtOpenProcess()
{
POFF();
RtlCopyMemory((VOID *)InLineHookOldAddress,OldData,5);
PON();
}
/**************************SSDT InlineHook NtOpenProcess End *************************/
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课