忘了是去年什么时候写的了,今年可能有变化。
#include "Shadow_hook.h"
#pragma INITCODE
extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT driver_object,PUNICODE_STRING u_string)
{
_GetVersion(driver_object);
Hook_NtCreateMutant();
NTSTATUS status=STATUS_SUCCESS;
driver_object->MajorFunction[IRP_MJ_CREATE]=DispatchIrp;
driver_object->MajorFunction[IRP_MJ_READ]=DispatchIrp;
driver_object->MajorFunction[IRP_MJ_WRITE]=DispatchIrp;
driver_object->MajorFunction[IRP_MJ_CLOSE]=DispatchIrp;
driver_object->MajorFunction[IRP_MJ_DEVICE_CONTROL]=DispatchIrp;
driver_object->DriverUnload=DrvierUnLoad;
PDEVICEEXTENSION pdevex;
UNICODE_STRING device_string;
RtlInitUnicodeString(&device_string,_device_name);
PDEVICE_OBJECT device_object;
status=IoCreateDevice(driver_object,sizeof(pdevex),&device_string,FILE_DEVICE_UNKNOWN,0,FALSE,&device_object);
if(!NT_SUCCESS(status))
{
KdPrint(("创建设备失败!\n"));
return status;
}
KdPrint(("创建设备成功!\n"));
device_object->Flags |= DO_BUFFERED_IO;
pdevex=(PDEVICEEXTENSION)device_object->DeviceExtension;
pdevex->device_name=device_string;
pdevex->device_object=device_object;
UNICODE_STRING symbol_name;
RtlInitUnicodeString(&symbol_name,_symbolic_name);
pdevex->device_symbolic=symbol_name;
status=IoCreateSymbolicLink(&symbol_name,&device_string);
if(!NT_SUCCESS(status))
{
KdPrint(("创建符号链接失败!\n"));
IoDeleteDevice(device_object);
return status;
}
KdPrint(("创建符号链接成功!\n"));
return STATUS_SUCCESS;
}
#pragma PAGEDCODE
VOID DrvierUnLoad(PDRIVER_OBJECT driver)
{
PDEVICE_OBJECT deviceobject;
UNICODE_STRING symbolname;
RtlInitUnicodeString(&symbolname,_symbolic_name);
IoDeleteSymbolicLink(&symbolname);
IoDeleteDevice(driver->DeviceObject);
// deviceobject=driver->DeviceObject;
// while(deviceobject!=NULL)
// {
// PDEVICEEXTENSION deviceex=(PDEVICEEXTENSION)deviceobject->DeviceExtension;
// UNICODE_STRING symbolname=deviceex->device_symbolic;
// IoDeleteSymbolicLink(&symbolname);
// deviceobject=deviceobject->NextDevice;
// IoDeleteDevice(deviceex->device_object);
// }
KdPrint(("删除设备成功!\n"));
UnHook_NtCreateMutant();
}
#pragma PAGEDCODE
NTSTATUS DispatchIrp(PDEVICE_OBJECT device_object,PIRP irp)
{
NTSTATUS status;
ULONG uin;
ULONG uout;
ULONG ucontrol;
PIO_STACK_LOCATION stirp=IoGetCurrentIrpStackLocation(irp);
ULONG irpindex=stirp->MajorFunction;
switch(irpindex)
{
case IRP_MJ_DEVICE_CONTROL:
status=STATUS_SUCCESS;
uin=stirp->Parameters.DeviceIoControl.InputBufferLength;
uout=stirp->Parameters.DeviceIoControl.OutputBufferLength;
ucontrol=stirp->Parameters.DeviceIoControl.IoControlCode;
switch(ucontrol)
{
case Un_hook:
Hook_NtUserSendInput();
KdPrint(("与应用程序通讯成功,所以地址已打印到调试器中……\n"));
break;
case function_unhook:
Get_NtCreateThread();
Get_NtProtectVirtualMemory();
Get_NtQueueAcpThread();
Get_NtTerminateProcess();
Get_NtWirteVirtualMemory();
Get_ObCheckObjectAccess();
break;
}
break;
case IRP_MJ_CREATE:
break;
case IRP_MJ_READ:
break;
case IRP_MJ_WRITE:
break;
case IRP_MJ_CLOSE:
break;
}
irp->IoStatus.Status=STATUS_SUCCESS;
irp->IoStatus.Information=0;
IoCompleteRequest(irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
//----------------------------------------------------------------------------------
#pragma once
#include "Shadow_.h"
#define Version_2008 60
DWORD KeServiceDescriptorTableShadow=0;
//-----------------------------------
int inxp_NtUserSendInput=0;
int inxp_NtUserQuerySendMessage=0;
int in_NtCreateThreadEx=0;
int in_NtCreateThread=0;
int in_NtProtectVirtualMemory=0;
int in_NtQueueApcThread=0;
int in_TerminateProcess=0;
int in_NtWriteVirtualMemory=0;
int in_NtCreateMutant=0;
//--------------------------------
ULONG push_NtCreateThread;
ULONG push_NtProtectVirtualMemory;
ULONG push_NtWriteVirtualMemory;
ULONG addr_ObCheckObjectAccess; //ObCheckObjectAccess的地址
ULONG addr_NtCreateMutant;
//--------------------------
typedef struct _ServiceDescriptorTable
{
PVOID ServiceTableBase; //System Service Dispatch Table 的基地址
PVOID ServiceCounterTable;
//包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。
unsigned int NumberOfServices;//由 ServiceTableBase 描述的服务的数目。
PVOID ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表
}*PServiceDescriptorTable;
extern "C" extern PServiceDescriptorTable KeServiceDescriptorTable;
#pragma pack(1)
typedef struct _bycode
{
BYTE data[3];
ULONG addr;
}bycode,*pbycode;
typedef struct _push_code
{
BYTE push;
ULONG addr;
BYTE retn;
}push_code,*ppush_code;
typedef struct _bytecode
{
BYTE push;
ULONG addr;
BYTE push1;
ULONG addr1;
}bytecode,*pbytecode;
typedef struct _bytecode1
{
BYTE push;
BYTE pushaddr;
BYTE push1;
ULONG pushaddr1;
}bytecode1,*pbytecode1;
typedef struct _bytecode2
{
BYTE mov[2];
BYTE push;
BYTE mov1[2];
BYTE push1;
}bytecode2,*pbytecode2;
#pragma pack()
KIRQL kirql;
#pragma PAGEDCODE
VOID PAGED_Open()
{
__asm
{
push eax
mov eax,cr0
and eax,not 10000h
mov cr0,eax
pop eax
}
kirql=KeRaiseIrqlToDpcLevel();
}
#pragma PAGEDCODE
VOID PAGED_Exit()
{
KeLowerIrql(kirql);
__asm
{
push eax
mov eax,cr0
or eax,10000h
mov cr0,eax
pop eax
}
}
#pragma PAGEDCODE
VOID __stdcall _GetVersion(PDRIVER_OBJECT driver)
{
ULONG MajorVerion,MinVersion,BulidViersion;
PsGetVersion(&MajorVerion,&MinVersion,&BulidViersion,NULL);
ULONG uas=MajorVerion*10+MinVersion;
switch(uas)
{
case Version_2008:
KdPrint(("当前操作系统是:Server 2008\n"));
KeServiceDescriptorTableShadow=(DWORD)KeServiceDescriptorTable+0x40;
inxp_NtUserSendInput=0x20D;
inxp_NtUserQuerySendMessage=0x1F7;
in_NtCreateThreadEx=0x17E;
in_NtCreateThread=0x4E;
in_NtProtectVirtualMemory=0xD2;
in_NtQueueApcThread=0xFF;
in_TerminateProcess=0x14E;
in_NtWriteVirtualMemory=0x166;
in_NtCreateMutant=0x43;
break;
default:
driver->DriverUnload=DrvierUnLoad;
break;
}
}
#pragma PAGEDCODE
ULONG Get_KeServiceDescriptorTableShadow_addr(int index)
{
KdPrint(("获取Shadow SSDT地址信息.\n"));
DWORD Shadow_addr=KeServiceDescriptorTableShadow;
Shadow_addr+=0x10;
DWORD Shadow_sl=Shadow_addr+8; //shadow函数的数量
DWORD get_sl=*((PDWORD)Shadow_sl);
KdPrint(("Shadow表的地址为: addr=%x 数量=%x\n",Shadow_addr,get_sl));
PDWORD Fun_addr=PDWORD(Shadow_addr);
Fun_addr=PDWORD(*Fun_addr);
//for(DWORD i=0;i<get_sl;i++)
//{
// KdPrint(("当前函数ID=%d,函数地址=%x\n",i,*Fun_addr));
// Fun_addr++;
//}
Fun_addr+=index;
KdPrint(("当前ID=%d,函数地址=%x\n",index,*Fun_addr));
return *Fun_addr;
}
#pragma PAGEDCODE
ULONG GetSsdt_addr(int index)
{
ULONG* addr_funtion,getfuntion,funtion;
getfuntion=(ULONG)KeServiceDescriptorTable->ServiceTableBase;
KdPrint(("当前KeServiceDescriptorTable表的地址为:%x\n",getfuntion));
addr_funtion=(PULONG)(getfuntion+index*4);
funtion=*addr_funtion;
KdPrint(("当前函数序号index=%d 函数地址:%x\n",index,funtion));
return funtion;
}
#pragma PAGEDCODE
ULONG* GetSSdt_this(int index)
{
ULONG* addr_funtion,x_funtion;
x_funtion=(ULONG)KeServiceDescriptorTable->ServiceTableBase;
addr_funtion=(ULONG*)(x_funtion+index*4);
return addr_funtion;
}
pbycode _pbycode;
#pragma PAGEDCODE
void Hook_NtUserSendInput()
{
ULONG addr_NtUserQuerSendMessage=Get_KeServiceDescriptorTableShadow_addr(inxp_NtUserQuerySendMessage);
__asm
{
push eax
mov eax,addr_NtUserQuerSendMessage
add eax,3
mov eax,[eax]
sub eax,0xbf8 ;__safe_se_handler_table的首地址
add eax,0xc18
mov addr_NtUserQuerSendMessage,eax
pop eax
}
KdPrint(("NtUserSendInput的第二个push地址为:%x\n",addr_NtUserQuerSendMessage));
ULONG addr_NtUserSendInput=Get_KeServiceDescriptorTableShadow_addr(inxp_NtUserSendInput);
_pbycode=(pbycode)addr_NtUserSendInput;
PAGED_Open();
_pbycode->data[0]=0x6A;
_pbycode->data[1]=0x18;
_pbycode->data[2]=0x68;
_pbycode->addr=addr_NtUserQuerSendMessage;
PAGED_Exit();
}
bytecode bytecode_NtCreateThread;
pbytecode pbytecode_NtCreateThread;
#pragma PAGEDCODE
VOID Get_NtCreateThread()
{
ULONG u_NtCreateThreadEx=GetSsdt_addr(in_NtCreateThreadEx);
__asm
{
push eax
mov eax,u_NtCreateThreadEx
add eax,5
mov eax,[eax+1]
mov push_NtCreateThread,eax
pop eax
}
push_NtCreateThread=push_NtCreateThread-0x5010+0x2A98;
KdPrint(("NtCreateThread的第二个push地址为:%x\n",push_NtCreateThread));
ULONG u_NtCreateThread=GetSsdt_addr(in_NtCreateThread);
pbytecode_NtCreateThread=(pbytecode)u_NtCreateThread;
bytecode_NtCreateThread.push=pbytecode_NtCreateThread->push;
bytecode_NtCreateThread.addr=pbytecode_NtCreateThread->addr;
bytecode_NtCreateThread.push1=pbytecode_NtCreateThread->push1;
bytecode_NtCreateThread.addr1=pbytecode_NtCreateThread->addr1;
PAGED_Open();
pbytecode_NtCreateThread->push=0x68;
pbytecode_NtCreateThread->addr=0x308;
pbytecode_NtCreateThread->push1=0x68;
pbytecode_NtCreateThread->addr1=push_NtCreateThread;
PAGED_Exit();
}
bytecode1 bytecode_NtProtectVirtualMemory;
pbytecode1 pbytecode_NtProtectVirtualMemory;
#pragma PAGEDCODE
VOID Get_NtProtectVirtualMemory()
{
push_NtProtectVirtualMemory=push_NtCreateThread-0x2a98+0x6758;
ULONG u_NtProtectVirtualMemory=GetSsdt_addr(in_NtProtectVirtualMemory);
pbytecode_NtProtectVirtualMemory=(pbytecode1)u_NtProtectVirtualMemory;
bytecode_NtProtectVirtualMemory.push=pbytecode_NtProtectVirtualMemory->push;
bytecode_NtProtectVirtualMemory.pushaddr=pbytecode_NtProtectVirtualMemory->pushaddr;
bytecode_NtProtectVirtualMemory.push1=pbytecode_NtProtectVirtualMemory->push1;
bytecode_NtProtectVirtualMemory.pushaddr1=pbytecode_NtProtectVirtualMemory->pushaddr1;
PAGED_Open();
pbytecode_NtProtectVirtualMemory->push=0x6a;
pbytecode_NtProtectVirtualMemory->pushaddr=0x38;
pbytecode_NtProtectVirtualMemory->push1=0x68;
pbytecode_NtProtectVirtualMemory->pushaddr1=push_NtProtectVirtualMemory;
PAGED_Exit();
}
bytecode2 bytecode_NtQueueApcThread;
pbytecode2 pbytecode_NtQueueApcThread;
#pragma PAGEDCODE
VOID Get_NtQueueAcpThread()
{
ULONG u_NtQueueApcThread=GetSsdt_addr(in_NtQueueApcThread);
pbytecode_NtQueueApcThread=(pbytecode2)u_NtQueueApcThread;
bytecode_NtQueueApcThread.mov[0]=pbytecode_NtQueueApcThread->mov[0];
bytecode_NtQueueApcThread.mov[1]=pbytecode_NtQueueApcThread->mov[1];
bytecode_NtQueueApcThread.push=pbytecode_NtQueueApcThread->push;
bytecode_NtQueueApcThread.mov1[0]=pbytecode_NtQueueApcThread->mov1[0];
bytecode_NtQueueApcThread.mov1[1]=pbytecode_NtQueueApcThread->mov1[1];
bytecode_NtQueueApcThread.push1=pbytecode_NtQueueApcThread->push1;
PAGED_Open();
pbytecode_NtQueueApcThread->mov[0]=0x8B;
pbytecode_NtQueueApcThread->mov[1]=0xff;
pbytecode_NtQueueApcThread->push=0x55;
pbytecode_NtQueueApcThread->mov1[0]=0x8B;
pbytecode_NtQueueApcThread->mov1[1]=0xEC;
pbytecode_NtQueueApcThread->push1=0x51;
PAGED_Exit();
}
bytecode2 bytecode_NtTerminateProcess;
pbytecode2 pbytecode_NtTerminteProcess;
#pragma PAGEDCODE
VOID Get_NtTerminateProcess()
{
ULONG u_NtTerminateProcess=GetSsdt_addr(in_TerminateProcess);
pbytecode_NtTerminteProcess=(pbytecode2)u_NtTerminateProcess;
bytecode_NtTerminateProcess.mov[0]=pbytecode_NtTerminteProcess->mov[0];
bytecode_NtTerminateProcess.mov[1]=pbytecode_NtTerminteProcess->mov[1];
bytecode_NtTerminateProcess.push=pbytecode_NtTerminteProcess->push;
bytecode_NtTerminateProcess.mov1[0]=pbytecode_NtTerminteProcess->mov1[0];
bytecode_NtTerminateProcess.mov1[1]=pbytecode_NtTerminteProcess->mov1[1];
bytecode_NtTerminateProcess.push1=pbytecode_NtTerminteProcess->push1;
PAGED_Open();
pbytecode_NtTerminteProcess->mov[0]=0x8B;
pbytecode_NtTerminteProcess->mov[1]=0xff;
pbytecode_NtTerminteProcess->push=0x55;
pbytecode_NtTerminteProcess->mov1[0]=0x8B;
pbytecode_NtTerminteProcess->mov1[1]=0xEC;
pbytecode_NtTerminteProcess->push1=0x83;
PAGED_Exit();
}
bytecode1 bytecode_NtWriteVirtualMemory;
pbytecode1 pbytecode_NtWriteVirtualMemory;
#pragma PAGEDCODE
VOID Get_NtWirteVirtualMemory()
{
push_NtWriteVirtualMemory=push_NtProtectVirtualMemory-0x6758+0x5668;
ULONG u_NtWriteVirtualMemory=GetSsdt_addr(in_NtWriteVirtualMemory);
pbytecode_NtWriteVirtualMemory=(pbytecode1)u_NtWriteVirtualMemory;
bytecode_NtWriteVirtualMemory.push=pbytecode_NtWriteVirtualMemory->push;
bytecode_NtWriteVirtualMemory.pushaddr=pbytecode_NtWriteVirtualMemory->pushaddr;
bytecode_NtWriteVirtualMemory.push1=pbytecode_NtWriteVirtualMemory->push1;
bytecode_NtWriteVirtualMemory.pushaddr1=pbytecode_NtWriteVirtualMemory->pushaddr1;
PAGED_Open();
pbytecode_NtWriteVirtualMemory->push=0x6A;
pbytecode_NtWriteVirtualMemory->pushaddr=0x18;
pbytecode_NtWriteVirtualMemory->push1=0x68;
bytecode_NtWriteVirtualMemory.pushaddr1=push_NtWriteVirtualMemory;
PAGED_Exit();
}
bytecode2 bytecode_ObCheckObjectAccess;
pbytecode2 pbytecode_ObCheckObjectAccess;
#pragma PAGEDCODE
VOID Get_ObCheckObjectAccess()
{
ULONG u_NtWiteVirtualMemory=GetSsdt_addr(in_NtWriteVirtualMemory);
BYTE* _bp=(BYTE*)u_NtWiteVirtualMemory;
while(1)
{
if((*(_bp-11)==0xFF)&&(*(_bp-5)==0x6A)&&(*(_bp-3)==0xFF)&&(*(_bp)==0xE8)&&(*(_bp+5)==0x89)&&(*(_bp+8)==0x85))
{
break;
}
_bp++;
}
ULONG u_temp=(ULONG)_bp;
ULONG call_addr;
__asm
{
push eax
push ebx
mov eax,u_temp
mov ebx,[eax+1]
add eax,ebx
add eax,5
mov call_addr,eax
pop ebx
pop eax
}
_bp=(BYTE*)call_addr;
while(1)
{
if((*(_bp-9)==0x89)&&(*(_bp-6)==0x89)&&(*(_bp-3)==0x89)&&(*(_bp)==0xE8)&&(*(_bp+5)==0x3B)&&(*(_bp+7)==0x7D))
{
break;
}
_bp++;
}
ULONG u_ObCheckObjectAccess=(ULONG)_bp-0x27;
pbytecode_ObCheckObjectAccess=(pbytecode2)u_ObCheckObjectAccess;
bytecode_ObCheckObjectAccess.mov[0]=pbytecode_ObCheckObjectAccess->mov[0];
bytecode_ObCheckObjectAccess.mov[1]=pbytecode_ObCheckObjectAccess->mov[1];
bytecode_ObCheckObjectAccess.push=pbytecode_ObCheckObjectAccess->push;
bytecode_ObCheckObjectAccess.mov1[0]=pbytecode_ObCheckObjectAccess->mov1[0];
bytecode_ObCheckObjectAccess.mov1[1]=pbytecode_ObCheckObjectAccess->mov1[1];
bytecode_ObCheckObjectAccess.push1=pbytecode_ObCheckObjectAccess->push1;
PAGED_Open();
pbytecode_ObCheckObjectAccess->mov[0]=0x8B;
pbytecode_ObCheckObjectAccess->mov[1]=0xFF;
pbytecode_ObCheckObjectAccess->push=0x55;
pbytecode_ObCheckObjectAccess->mov1[0]=0x8B;
pbytecode_ObCheckObjectAccess->mov1[1]=0xEC;
pbytecode_ObCheckObjectAccess->push1=0x83;
PAGED_Exit();
}
extern "C"
typedef
NTSYSAPI
NTSTATUS
(__stdcall* nt_NtCreateMutant)(
OUT PHANDLE MutantHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN BOOLEAN InitialOwner
);
nt_NtCreateMutant* ntNtCreateMutant;
#pragma PAGEDCODE
extern "C"
NTSTATUS
__stdcall My_NtCreateMutant(
OUT PHANDLE MutantHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN BOOLEAN InitialOwner)
{
if(ObjectAttributes!=NULL && ObjectAttributes->ObjectName!=NULL && ObjectAttributes->ObjectName->Buffer!=NULL)
{
KdPrint(("互斥体名为:%wZ\r\n",ObjectAttributes->ObjectName));
UNICODE_STRING Mutant_name_Create;
RtlInitUnicodeString(&Mutant_name_Create,L"Global\\MutexDragonNest");
if(ObjectAttributes && RtlEqualUnicodeString(&Mutant_name_Create,ObjectAttributes->ObjectName,FALSE))
{
return STATUS_SUCCESS;
}
}
return ((NTSTATUS(NTAPI*)(PHANDLE,ACCESS_MASK,POBJECT_ATTRIBUTES,BOOLEAN))ntNtCreateMutant)(MutantHandle,DesiredAccess,ObjectAttributes,InitialOwner);
}
#pragma PAGEDCODE
VOID Hook_NtCreateMutant()
{
ULONG* un_NtOpenMutant;
un_NtOpenMutant=GetSSdt_this(in_NtCreateMutant);
addr_NtCreateMutant=GetSsdt_addr(in_NtCreateMutant);
KdPrint(("当前系统NtOpenMutant的地址为:%x\n",addr_NtCreateMutant));
ntNtCreateMutant=(nt_NtCreateMutant*)addr_NtCreateMutant;
PAGED_Open();
*un_NtOpenMutant=(ULONG)My_NtCreateMutant;
PAGED_Exit();
}
#pragma PAGEDCODE
void UnHook_NtCreateMutant()
{
ULONG ntcreatemutant;
ntcreatemutant=(ULONG)KeServiceDescriptorTable->ServiceTableBase+in_NtCreateMutant*4;
PAGED_Open();
*((ULONG*)ntcreatemutant)=(ULONG)addr_NtCreateMutant;
PAGED_Exit();
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)