您的位置:首页 > 运维架构

SSDT的例子2-NtOpenProcess

2016-10-20 22:43 316 查看

前言

看人家的工程中,都不是直接返回STATUS_ACCESS_DENIED.
在MyNtOpenProcess直接返回STATUS_ACCESS_DENIED并不会影响打开进程.


试验记录

#include <Ntddk.h>
#include <stdlib.h>
#include <stdio.h>

typedef char CHAR;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef unsigned int size_t;
typedef unsigned long DWORD;

#define MAXBYTE 0xff
#define MAKEDWORD(L, H) (((WORD)((DWORD_PTR)(L) & 0xffff)) | ((DWORD)((WORD)((DWORD_PTR)(H) & 0xffff))) << 16)

#pragma pack(push)
#pragma pack(1)

typedef struct _SYSTEM_SERVICE_TABLE {
PVOID   ServiceTableBase;        //这个指向系统服务函数地址表
PULONG  ServiceCounterTableBase;
ULONG   NumberOfService;         //服务函数的个数,NumberOfService*4 就是整个地址表的大小
ULONG   ParamTableBase;
} SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE;

typedef struct _SERVICE_DESCRIPTOR_TABLE {
SYSTEM_SERVICE_TABLE   ntoskrnel;  //ntoskrnl.exe的服务函数
SYSTEM_SERVICE_TABLE   win32k;     //win32k.sys的服务函数,(gdi.dll/user.dll的内核支持)
SYSTEM_SERVICE_TABLE   NotUsed1;
SYSTEM_SERVICE_TABLE   NotUsed2;
} SYSTEM_DESCRIPTOR_TABLE, *PSYSTEM_DESCRIPTOR_TABLE;

#pragma pack(pop)

extern PSYSTEM_DESCRIPTOR_TABLE KeServiceDescriptorTable;
SYSTEM_SERVICE_TABLE* g_pSST = NULL;

// typedef NTSTATUS (__stdcall *PFN_ZwOpenProcess)(
//               __out PHANDLE  ProcessHandle,
//               __in ACCESS_MASK  DesiredAccess,
//               __in POBJECT_ATTRIBUTES  ObjectAttributes,
//               __in_opt PCLIENT_ID  ClientId
//               );

// PFN_ZwOpenProcess g_pfn = NULL;

DWORD g_dwSsdtFunIndexAddr_NtOpenProcess = 0;
DWORD g_dwPfnNtOpenProcessOrg = 0;

// naked 函数内不能初始化变量
// 在裸函数内使用的变量必须在函数外定义
DWORD g_dwAddrJmp_MyNtOpenProcess = 0x805c22a0;
const DWORD g_dw_STATUS_ERR = STATUS_ACCESS_DENIED;
__declspec(naked) NTSTATUS __stdcall MyNtOpenProcess(PHANDLE ProcessHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PCLIENT_ID ClientId)
{
/**
kd> u 805C2296
nt!NtOpenProcess:
805c2296 68c4000000      push    0C4h
805c229b 68a8aa4d80      push    offset nt!ObWatchHandles+0x25c (804daaa8)
// 用 __asm + _emit, 在InlineHook函数后,可以跳到任意地址
// 但是call指令有重定位问题, 如果不修正, 只能在call之前打住

// 跳到这
805c22a0 e86b6cf7ff      call    nt!_SEH_prolog (80538f10)

805c22a5 33f6            xor     esi,esi
805c22a7 8975d4          mov     dword ptr [ebp-2Ch],esi
805c22aa 33c0            xor     eax,eax
805c22ac 8d7dd8          lea     edi,[ebp-28h]
805c22af ab              stos    dword ptr es:[edi]
*/
__asm {
// 这里可以用int 3来调试
// int 3

// 68c4000000
// 805c2296 68c4000000      push    0C4h

_emit 0x68
_emit 0xc4
_emit 0x00
_emit 0x00
_emit 0x00

// 68a8aa4d80
// 805c229b 68a8aa4d80      push    offset nt!ObWatchHandles+0x25c (804daaa8)
_emit 0x68
_emit 0xa8
_emit 0xaa
_emit 0x4d
_emit 0x80

// e86b6cf7ff
// 805c22a0 e86b6cf7ff      call    nt!_SEH_prolog (80538f10)
// f8dc841a e86b6cf7ff      call    f8d3f08a
// call 指令涉及到重定位了, opcode一模一样也不是相同的反汇编指令
// 怪不得人家只跳过前10个字节
//         _emit 0xe8
//         _emit 0x6b
//         _emit 0x6c
//         _emit 0xf7
//         _emit 0xff

pushf
pusha
}
// do my hook task
// 调用 KdPrint 可以正常打印
KdPrint(("MyNtOpenProcess : don't allow open process ^_^\r\n"));
__asm {
popa
popf

// 对函数入口10字节的2个push进行平栈
pop eax
pop eax

// 返回
// 返回其他值(不是STATUS_SUCCESS), 进程还是会打开
// 不管返回什么值, 进程还是会被打开
// 可能不能Hook这个API.
// 先丢这里, 以后再玩. SSDT Hook已经成功了
mov eax, g_dw_STATUS_ERR
ret

// jmp g_dwAddrJmp_MyNtOpenProcess
}
// return STATUS_SUCCESS;
// return 0;
}

void fnHook_SSDT()
{
DWORD dwAddr = 0;

do {
if (NULL == KeServiceDescriptorTable) {
break;
}

g_pSST = &KeServiceDescriptorTable->ntoskrnel;

if (NULL == g_pSST) {
break;
}

KdPrint(("g_pSST = %p\r\n", g_pSST));

if (NULL == g_pSST->ServiceTableBase) {
break;
}

KdPrint(("g_pSST->ServiceTableBase = %p\r\n", g_pSST->ServiceTableBase));
// 0x7a is OpenProcess Index On SSDT
dwAddr = (DWORD)g_pSST->ServiceTableBase + 0x7a * sizeof(DWORD);

if (0 == dwAddr) {
break;
}

// 要换的就是g_dwSsdtFunIndexAddr_NtOpenProcess地址中的内容
g_dwSsdtFunIndexAddr_NtOpenProcess = dwAddr;
KdPrint(("g_dwSsdtFunIndexAddr_NtOpenProcess = %p\r\n", g_dwSsdtFunIndexAddr_NtOpenProcess));
g_dwPfnNtOpenProcessOrg = *((DWORD*)(g_dwSsdtFunIndexAddr_NtOpenProcess));
KdPrint(("g_dwPfnNtOpenProcessOrg = %p\r\n", g_dwPfnNtOpenProcessOrg));
/**
>> DriverEntry
g_pSST = 80553FA0
g_pSST->ServiceTableBase = 80502B8C
g_dwSsdtFunIndexAddr_NtOpenProcess = 80502D74
g_dwPfnNtOpenProcessOrg = 805C2296

kd> u 805C2296
nt!NtOpenProcess:
805c2296 68c4000000      push    0C4h
805c229b 68a8aa4d80      push    offset nt!ObWatchHandles+0x25c (804daaa8)
805c22a0 e86b6cf7ff      call    nt!_SEH_prolog (80538f10)
805c22a5 33f6            xor     esi,esi
805c22a7 8975d4          mov     dword ptr [ebp-2Ch],esi
805c22aa 33c0            xor     eax,eax
805c22ac 8d7dd8          lea     edi,[ebp-28h]
805c22af ab              stos    dword ptr es:[edi]
*/
__asm { //去掉内存保护
cli
mov  eax, cr0
and  eax, not 10000h
mov  cr0, eax
}
*((DWORD*)(g_dwSsdtFunIndexAddr_NtOpenProcess)) = (DWORD)MyNtOpenProcess;
__asm { //恢复内存保护
mov  eax, cr0
or   eax, 10000h
mov  cr0, eax
sti
}
KdPrint(("Hook By MyNtOpenProcess = %p\r\n", MyNtOpenProcess));
} while (0);
}

void fnUnHook_SSDT()
{
__asm { //去掉内存保护
cli
mov  eax, cr0
and  eax, not 10000h
mov  cr0, eax
}
*((DWORD*)(g_dwSsdtFunIndexAddr_NtOpenProcess)) = (DWORD)g_dwPfnNtOpenProcessOrg;
__asm { //恢复内存保护
mov  eax, cr0
or   eax, 10000h
mov  cr0, eax
sti
}
KdPrint(("UnHook By g_dwPfnNtOpenProcessOrg = %p\r\n", g_dwPfnNtOpenProcessOrg));
}

VOID fnDrvUnLoad(__in struct _DRIVER_OBJECT* DriverObject)
{
KdPrint((">> fnDrvUnLoad"));
fnUnHook_SSDT();
}

NTSTATUS fnDrvDisPatch(__in struct _DEVICE_OBJECT* DeviceObject, __inout struct _IRP* Irp)
{
KdPrint((">> fnDrvDisPatch"));
return STATUS_SUCCESS;
}

NTSTATUS DriverEntry(__in struct _DRIVER_OBJECT*  DriverObject, __in PUNICODE_STRING  RegistryPath)
{
KdPrint((">> DriverEntry"));
DriverObject->DriverUnload = fnDrvUnLoad;
DriverObject->MajorFunction[IRP_MJ_CREATE] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_CREATE_NAMED_PIPE] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_READ] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_WRITE] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_QUERY_EA] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_SET_EA] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_CREATE_MAILSLOT] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_POWER] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CHANGE] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_QUERY_QUOTA] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_SET_QUOTA] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_PNP] = fnDrvDisPatch;
DriverObject->MajorFunction[IRP_MJ_MAXIMUM_FUNCTION] = fnDrvDisPatch;
fnHook_SSDT();
return STATUS_SUCCESS;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: