inline-hook和object双HOOK联合调用拒绝WIN打开服务
看标题其实很简单我也没有找到比较合适的标题,所以各位大牛们别嘲笑小弟就好,
原理很简单,其实就是找到个和对象有关的系统频繁调用的函数实现双HOOK就行啦,
我选折ObCreateObject函数下手,关于OBJECTHOOK的文章参考一下我的前篇科普篇
http://bbs.pediy.com/showthread.php?t=128161
我们先看下ObCreateObject函数原型先
NTSTATUS
ObCreateObject (
__in KPROCESSOR_MODE ProbeMode, // 决定是否要验证参数
__in POBJECT_TYPE ObjectType, // 对象类型指针
__in POBJECT_ATTRIBUTES ObjectAttributes, // 对象的属性, 最终会转化成ObAllocateObject需要的OBJECT_CREATE_INFORMATION结构
__in KPROCESSOR_MODE OwnershipMode, // 内核对象?用户对象?
__inout_opt PVOID ParseContext, // 这参数没用
__in ULONG ObjectBodySize, // 对象体大小
__in ULONG PagedPoolCharge, //
__in ULONG NonPagedPoolCharge, //
__out PVOID *Object // 接收对象体的指针
)
这里面有1个结构和一个对象对我们比较有用ObjectAttributes和ObjectType
ObjectType那那个科普帖已经介绍了,下面简单介绍一下这个结构
_OBJECT_ATTRIBUTES { ULONG Length;//结构长
HANDLE RootDirectory; //对象所在目录
PUNICODE_STRING ObjectName; //对象名
ULONG Attributes; //属性标志
PVOID SecurityDescriptor;
PVOID SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
这里面最重要还是ObjectType
直接上代码吧,太乱 因为是笔记 #include<ntddk.h>
#include<windef.h>
VOID Hook();
VOID WPOFF();
VOID WPON();
typedef struct _OBJECT_TYPE_INITIALIZER {
USHORT Length;
BOOLEAN UseDefaultObject;
BOOLEAN CaseInsensitive;
ULONG InvalidAttributes;
GENERIC_MAPPING GenericMapping;
ULONG ValidAccessMask;
BOOLEAN SecurityRequired;
BOOLEAN MaintainHandleCount;
BOOLEAN MaintainTypeList;
POOL_TYPE PoolType;
ULONG DefaultPagedPoolCharge;
ULONG DefaultNonPagedPoolCharge;
PVOID DumpProcedure;
PVOID OpenProcedure;
PVOID CloseProcedure;
PVOID DeleteProcedure;
PVOID ParseProcedure;
PVOID SecurityProcedure;
PVOID QueryNameProcedure;
PVOID OkayToCloseProcedure;
} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER; typedef struct _OBJECT_TYPE {
ERESOURCE Mutex;
LIST_ENTRY TypeList;
UNICODE_STRING Name;
PVOID DefaultObject;
ULONG Index;
ULONG TotalNumberOfObjects;
ULONG TotalNumberOfHandles;
ULONG HighWaterNumberOfObjects;
ULONG HighWaterNumberOfHandles;
OBJECT_TYPE_INITIALIZER TypeInfo;
#ifdef POOL_TAGGING
ULONG Key;
#endif
} OBJECT_TYPE, *POBJECT_TYPE;
typedef struct _OBJECT_CREATE_INFORMATION {
ULONG Attributes;
HANDLE RootDirectory;
PVOID ParseContext;
KPROCESSOR_MODE ProbeMode;
ULONG PagedPoolCharge;
ULONG NonPagedPoolCharge;
ULONG SecurityDescriptorCharge;
PSECURITY_DESCRIPTOR SecurityDescriptor;
PSECURITY_QUALITY_OF_SERVICE SecurityQos;
SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
} OBJECT_CREATE_INFORMATION, *POBJECT_CREATE_INFORMATION; typedef struct _OBJECT_HEADER {
LONG PointerCount;
union {
LONG HandleCount;
PSINGLE_LIST_ENTRY SEntry;
};
POBJECT_TYPE Type;
UCHAR NameInfoOffset;
UCHAR HandleInfoOffset;
UCHAR QuotaInfoOffset;
UCHAR Flags;
union
{
POBJECT_CREATE_INFORMATION ObjectCreateInfo;
PVOID QuotaBlockCharged;
};
PSECURITY_DESCRIPTOR SecurityDescriptor;
QUAD Body;
} OBJECT_HEADER, *POBJECT_HEADER;
POBJECT_TYPE pType= NULL;
POBJECT_HEADER addrs=NULL;
PVOID OldParseProcedure = NULL;
BYTE *pAddrs=NULL;
ULONG Ret=0;
ULONG hookaddr=0;
NTSTATUS NewParseProcedure(IN PVOID ParseObject,
IN PVOID ObjectType,
IN OUT PACCESS_STATE AccessState,
IN KPROCESSOR_MODE AccessMode,
IN ULONG Attributes,
IN OUT PUNICODE_STRING CompleteName,
IN OUT PUNICODE_STRING RemainingName,
IN OUT PVOID Context OPTIONAL,
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
OUT PVOID *Object)
{
NTSTATUS Status;
KdPrint(("object is hook\n"));
__asm
{
push eax
push Object
push SecurityQos
push Context
push RemainingName
push CompleteName
push Attributes
movzx eax, AccessMode
push eax
push AccessState
push ObjectType
push ParseObject
call OldParseProcedure
mov Status, eax
pop eax
}
return Status;
}
VOID Hook1()
{
_asm{
pushf
pusha
mov eax,pType
cmp eax,0
jz ggdd //空就跳
add eax,0x9c
cmp [eax],0 //打开服务为空就跳
jz ggdd
mov eax,[eax]
cmp eax,NewParseProcedure // 已经HOOK了就跳
jz ggdd
mov OldParseProcedure,eax
mov ebx,NewParseProcedure
mov eax,pType
add eax,0x9c
mov [eax],ebx
ggdd:
popa
popf
} }
__declspec(naked) void __stdcall MyHook()
{
_asm{
push eax
mov eax,[ebp+0xc] //获取ObjectType
mov pType,eax
call [hookaddr]
pop eax
push ecx
push ebx
push esi
push edi
jmp [Ret]
}
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
NTSTATUS status;
hookaddr=(ULONG)Hook1;
Hook();
return STATUS_SUCCESS;
}
VOID Hook()
{
ULONG ObjAddrs,jmpAddrs;
UNICODE_STRING name;
KIRQL Irql;
char code[5]={0xe9,0,0,0,0};
RtlInitUnicodeString(&name,L"ObCreateObject");
pAddrs=(BYTE*)MmGetSystemRoutineAddress(&name);
if(pAddrs==NULL)
{
DbgPrint("pAaddrs is NULL\n");
}
DbgPrint("pAaddrs is:%08X\n",pAddrs);
ObjAddrs=(ULONG)pAddrs;
ObjAddrs=ObjAddrs+6;
Ret=ObjAddrs+5;
DbgPrint("pAaddrs is:%08X\n",ObjAddrs);
DbgPrint("Ret is:%08X\n",Ret);
jmpAddrs=(ULONG)MyHook-ObjAddrs-5;
*(ULONG*)(code+1)=jmpAddrs;
WPOFF();
Irql=KeRaiseIrqlToDpcLevel();
RtlCopyMemory(ObjAddrs,code,5);
KeLowerIrql(Irql);
WPON();
}
VOID WPOFF()
{
__asm
{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
}
VOID WPON()
{
__asm
{
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
}
以上代码有危险性,因为比较极端,请大家在虚拟机上运行 我的测试环境是 windows_xp_professional_with_service_pack_3
1.有如下症状所有文件不能打开,右键选中打开的选项消失。如果需要分析工具请先运行再加载驱动
2.所有驱动不能加载,包括任务管理器 CMD 不能打开
3.无法关机和重启。
希望大家不要把代码运用到恶意程序上,其实也没多少技术含量,只是比较极端而已。如有BUG
欢迎大牛们指正,共同学习 共同进步嘛
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
上传的附件: