#include <ntddk.h>
/*
功能:替换进程对象的OpenProcedure函数.
本代码只适宜于windows server 2008 r2 64位系统.
打开系统任务管理器总是CPU占用率100%.
*/
/*
1: kd> vertarget
Windows 7 Kernel Version 7601 (Service Pack 1) MP (2 procs) Free x64
Product: Server, suite: Enterprise TerminalServer SingleUserTS
Built by: 7601.18205.amd64fre.win7sp1_gdr.130708-1532
Machine Name:
Kernel base = 0xfffff800`01603000 PsLoadedModuleList = 0xfffff800`018466d0
Debug session time: Tue Aug 27 10:19:43.173 2013 (UTC + 8:00)
System Uptime: 0 days 0:02:44.876
1: kd> dq PsProcessType
fffff800`018b0020 fffffa80`03c8fde0 00000040`00026161
fffff800`018b0030 fffffa80`03cc3040 fffffa80`03c2ffc0
fffff800`018b0040 a1db3ffe`00010001 fffffa80`03cdc8a0
fffff800`018b0050 fffffa80`03c8fc90 00000001`00000000
fffff800`018b0060 00000000`000fdd3e 00000040`00000000
fffff800`018b0070 fffffa80`03c01c00 00000000`00000004
fffff800`018b0080 fffff683`ffffff78 0000000f`00000001
fffff800`018b0090 00026161`00000200 00000000`0013ffff
1: kd> dt _object_type fffffa80`03c8fde0
nt!_OBJECT_TYPE
+0x000 TypeList : _LIST_ENTRY [ 0xfffffa80`03c8fde0 - 0xfffffa80`03c8fde0 ]
+0x010 Name : _UNICODE_STRING "Process"
+0x020 DefaultObject : (null)
+0x028 Index : 0x7 ''
+0x02c TotalNumberOfObjects : 0x26
+0x030 TotalNumberOfHandles : 0xc7
+0x034 HighWaterNumberOfObjects : 0x29
+0x038 HighWaterNumberOfHandles : 0xc8
+0x040 TypeInfo : _OBJECT_TYPE_INITIALIZER
+0x0b0 TypeLock : _EX_PUSH_LOCK
+0x0b8 Key : 0x636f7250
+0x0c0 CallbackList : _LIST_ENTRY [ 0xfffff8a0`02a511a0 - 0xfffff8a0`02a511a0 ]
1: kd> dt _OBJECT_TYPE_INITIALIZER fffffa80`03c8fde0+40
nt!_OBJECT_TYPE_INITIALIZER
+0x000 Length : 0x70
+0x002 ObjectTypeFlags : 0x4a 'J'
+0x002 CaseInsensitive : 0y0
+0x002 UnnamedObjectsOnly : 0y1
+0x002 UseDefaultObject : 0y0
+0x002 SecurityRequired : 0y1
+0x002 MaintainHandleCount : 0y0
+0x002 MaintainTypeList : 0y0
+0x002 SupportsObjectCallbacks : 0y1
+0x002 CacheAligned : 0y0
+0x004 ObjectTypeCode : 0
+0x008 InvalidAttributes : 0xb0
+0x00c GenericMapping : _GENERIC_MAPPING
+0x01c ValidAccessMask : 0x1fffff
+0x020 RetainAccess : 0x101000
+0x024 PoolType : 0 ( NonPagedPool )
+0x028 DefaultPagedPoolCharge : 0x1000
+0x02c DefaultNonPagedPoolCharge : 0x528
+0x030 DumpProcedure : (null)
+0x038 OpenProcedure : 0xfffff800`0194bca0 long nt!PspProcessOpen+0
+0x040 CloseProcedure : 0xfffff800`01932fd0 void nt!PspProcessClose+0
+0x048 DeleteProcedure : 0xfffff800`01932280 void nt!PspProcessDelete+0
+0x050 ParseProcedure : (null)
+0x058 SecurityProcedure : 0xfffff800`01963cd0 long nt!SeDefaultObjectMethod+0
+0x060 QueryNameProcedure : (null)
+0x068 OkayToCloseProcedure : (null)
1: kd> uf nt!PspProcessOpen
nt!PspProcessOpen:
fffff800`0194bca0 488b4c2428 mov rcx,qword ptr [rsp+28h]
fffff800`0194bca5 80fa01 cmp dl,1
fffff800`0194bca8 7516 jne nt!PspProcessOpen+0x20 (fffff800`0194bcc0)
nt!PspProcessOpen+0xa:
fffff800`0194bcaa 410fbaa03c0400000b bt dword ptr [r8+43Ch],0Bh
fffff800`0194bcb3 720b jb nt!PspProcessOpen+0x20 (fffff800`0194bcc0)
nt!PspProcessOpen+0x15:
fffff800`0194bcb5 410fbaa13c0400000b bt dword ptr [r9+43Ch],0Bh
fffff800`0194bcbe 7211 jb nt!PspProcessOpen+0x31 (fffff800`0194bcd1)
nt!PspProcessOpen+0x20:
fffff800`0194bcc0 8b01 mov eax,dword ptr [rcx]
fffff800`0194bcc2 0fbae00a bt eax,0Ah
fffff800`0194bcc6 7306 jae nt!PspProcessOpen+0x2e (fffff800`0194bcce)
nt!PspProcessOpen+0x28:
fffff800`0194bcc8 0fbae80c bts eax,0Ch
fffff800`0194bccc 8901 mov dword ptr [rcx],eax
nt!PspProcessOpen+0x2e:
fffff800`0194bcce 33c0 xor eax,eax
fffff800`0194bcd0 c3 ret
nt!PspProcessOpen+0x31:
fffff800`0194bcd1 f701fee70f00 test dword ptr [rcx],0FE7FEh
fffff800`0194bcd7 74e7 je nt!PspProcessOpen+0x20 (fffff800`0194bcc0)
nt!PspProcessOpen+0x39:
fffff800`0194bcd9 b8220000c0 mov eax,0C0000022h
fffff800`0194bcde c3 ret
那些结构就不定义了,直接使用硬编码.
*/
unsigned __int64 g_old = 0;
/*
关于函数原型的说明:
有处理函数的,可以用IDA分析(32位的已经分析出,64位的需要自己分析.).
没有处理函数的,一个想法是可以任意的,另一个想法是任意的如何获取数据信息呢?
关于参数的个数,我猜是宁多勿少,还有一个调用后的平衡问题,有无此问题?
我这里分析的不一定正确.
*/
typedef NTSTATUS (*PspProcessOpen)(unsigned __int64 arg1,unsigned __int64 arg2,unsigned __int64 arg3,unsigned __int64 arg4,
unsigned __int64 arg5,unsigned __int64 arg6,unsigned __int64 arg7,unsigned __int64 arg8,unsigned __int64 arg9);
PspProcessOpen g_pPspProcessOpen;
long MyPspProcessOpen(unsigned __int64 arg1,unsigned __int64 arg2,unsigned __int64 arg3,unsigned __int64 arg4,
unsigned __int64 arg5,unsigned __int64 arg6,unsigned __int64 arg7,unsigned __int64 arg8
,unsigned __int64 arg9)//,unsigned __int64 arg10
/*
PspProcessOpen显示的是long类型,但是经分析是NTSTATUS类型的,这其实是一致的.
VOID
typedef
(*OB_OPEN_METHOD)(
IN OB_OPEN_REASON OpenReason,
IN PEPROCESS Process,
IN PVOID Object,
IN ACCESS_MASK GrantedAccess,
IN ULONG HandleCount OPTIONAL
)//摘自wdk的说明文档.
一是前四个参数分析通过四个寄存器传递:RCX、RDX、R8、R9,如果还有更多的参数,才通过椎栈传递。
二是调用者负责椎栈空间的分配与回收。
外加一个返回地址留空间
在Win2000和XP Vista系统下各个函数的参数有可能不一样,比如OpenProcedure 在2000下是8个参数,XP和Vista下是9个参数。
根据反汇编:mov rcx,qword ptr [rsp+28h]
得出,至少有5个参数,再加会上默认的4个,所以至少有九个参数.
*/
{
//KdBreakPoint();//DbgBreakPoint()
KdPrint(("MyPspProcessOpen is called!\n"));
/*
在这里能做点啥呢?
参数的类型代表的函数都不知道,只有分析汇编了.
*/
return g_pPspProcessOpen(arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9);//如果参数个数过少会蓝屏的,arg10
}
VOID DriverUnload(PDRIVER_OBJECT DriverObject)
/*
恢复.
*/
{
unsigned __int64 x = 0;
x = *(unsigned __int64 *)PsProcessType;
x = (x + 0x40);
x += 0x38;
*(unsigned __int64 *)x = g_old;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
unsigned __int64 x = 0;
unsigned __int64 * * Procedure[9];
KdBreakPoint();//DbgBreakPoint()
DriverObject->DriverUnload = DriverUnload;
x = *(unsigned __int64 *)PsProcessType;
x = (x + 0x40);
g_old = *(unsigned __int64 *)(x + 0x38);
x += 0x38;
*(unsigned __int64 *)x = MyPspProcessOpen;
g_pPspProcessOpen = g_old;
return STATUS_SUCCESS;
}
/*
验证一下:
0: kd> dt _OBJECT_TYPE_INITIALIZER fffffa80`03c8fde0+40
nt!_OBJECT_TYPE_INITIALIZER
+0x000 Length : 0x70
+0x002 ObjectTypeFlags : 0x4a 'J'
+0x002 CaseInsensitive : 0y0
+0x002 UnnamedObjectsOnly : 0y1
+0x002 UseDefaultObject : 0y0
+0x002 SecurityRequired : 0y1
+0x002 MaintainHandleCount : 0y0
+0x002 MaintainTypeList : 0y0
+0x002 SupportsObjectCallbacks : 0y1
+0x002 CacheAligned : 0y0
+0x004 ObjectTypeCode : 0
+0x008 InvalidAttributes : 0xb0
+0x00c GenericMapping : _GENERIC_MAPPING
+0x01c ValidAccessMask : 0x1fffff
+0x020 RetainAccess : 0x101000
+0x024 PoolType : 0 ( NonPagedPool )
+0x028 DefaultPagedPoolCharge : 0x1000
+0x02c DefaultNonPagedPoolCharge : 0x528
+0x030 DumpProcedure : (null)
+0x038 OpenProcedure : 0xfffff880`048010e0 long test!MyPspProcessOpen+0
+0x040 CloseProcedure : 0xfffff800`01932fd0 void nt!PspProcessClose+0
+0x048 DeleteProcedure : 0xfffff800`01932280 void nt!PspProcessDelete+0
+0x050 ParseProcedure : (null)
+0x058 SecurityProcedure : 0xfffff800`01963cd0 long nt!SeDefaultObjectMethod+0
+0x060 QueryNameProcedure : (null)
+0x068 OkayToCloseProcedure : (null)
听说此方法可以过64位Windows的PG机制,可是在开启调试的机器上总是出现:Fatal System Error: 0x00000109.
made by correy
made at 2013.08.27
email:kouleguan at hotmail dot com
homepage:http://correy.webs.com
*/
没有评论:
发表评论