哎,虽然之前已经有人帮过我,但一个问题解决又出现一个问题,我才戳啦,
下面是关键代码
//driver.h
typedef PCHAR PBYTE; //不想在一个一个替换了,so...
typedef NTSTATUS (__fastcall *PIOFCALLDRIVER)(PDEVICE_OBJECT,PIRP);
//driver.cpp
ULONG g_uCR0; //保存我们修改CRP寄存器之前的它的值
KSPIN_LOCK SDTSpinLock;
PIOFCALLDRIVER g_nativeIofCallDriver; //保存系统的IofCallDriver的地址
NTSTATUS FASTCALL MyIofCallDriver(IN PDEVICE_OBJECT,IN OUT PIRP); //我们的IofCallDriver;
PIOFCALLDRIVER HookIofCallDriver(IN PIOFCALLDRIVER,
IN BOOLEAN ); //Hook IofCallDriver or unhook
VOID WPOFF(); //
VOID WPON(); //
#pragma PAGEDCODE
VOID WPOFF()
{
ULONG uAttr;
_asm
{
push eax;
mov eax, cr0;
mov uAttr, eax;
and eax, 0FFFEFFFFh; // CR0 16 BIT = 0
mov cr0, eax;
pop eax;
cli
};
g_uCR0=uAttr;
}
VOID WPON()
{
_asm
{
sti
push eax;
mov eax, g_uCR0; //恢復原有 CR0 屬性
mov cr0, eax;
pop eax;
};
}
#pragma LOCKEDCODE
NTSTATUS FASTCALL MyIofCallDriver(IN PDEVICE_OBJECT pDevObj,IN OUT PIRP pIrp)
{
DbgPrint("HDM:This is MyIofCallDriver! You succeed!\n");
NTSTATUS status=STATUS_SUCCESS;
status=g_nativeIofCallDriver(pDevObj,pIrp);
return status;
}
#pragma PAGEDCODE
//
//当hookOrUnhook为TRUE时,IofCallDriver为我们的替换函数的地址
//当hookOrUnhook为FALSE时,则为系统IofCallDriver的地址
//无论是hook or unhook,当函数成功时,返回系统IofCallDriver的地址,否则返回NULL
PIOFCALLDRIVER HookIofCallDriver(IN PIOFCALLDRIVER IofCallDriver,
IN BOOLEAN hookOrUnhook)
{
DbgPrint("HDM:Enter HookIofCallDriver\n");
UNICODE_STRING functionName;
PBYTE address=NULL; //通过调用MmGetSystemRoutineAddress得到的IofCallDriver的入口地址
PBYTE nativeIofCallDriver=NULL; //IofCallDriver执行体的地址
RtlInitUnicodeString(&functionName,L"IofCallDriver");
//得到IofCallDriver的入口地址
address=(PBYTE)MmGetSystemRoutineAddress(&functionName);
if (address==NULL)
{
return NULL;
}
if (hookOrUnhook)
{
/*
kd> u IofCallDriver
nt!IofCallDriver:
804ef130 ff2580d25480 jmp dword ptr [nt!pIofCallDriver (8054d280)]
804ef136 cc int 3
804ef137 cc int 3
804ef138 cc int 3
804ef139 cc int 3
804ef13a cc int 3
804ef13b cc int 3
nt!IoCheckQuerySetFileInformation:
804ef13c 8bff mov edi,edi
注意,上面jmp指令的寻址方式为段间间接远转移,具体格式如下
格式:JMP DWORD PTR OPR
执行的操作:
(EIP)←(EA)
(CS)←(EA+4)
其中EA由OPR的寻址方式确定,根据寻址方式确定EA后,把指定存储单元的字内容送到
IP或EIP寄存器,并把下一个字的内容送到CS,这样就实现了段间跳转
*/
nativeIofCallDriver=(PBYTE)(*(PLONG)(*(PLONG)(address+2)));
KIRQL OldIrql;
KeAcquireSpinLock( &SDTSpinLock, &OldIrql );
WPOFF();
InterlockedExchange((PLONG)(*(PLONG)(address+2)),(LONG)IofCallDriver);
WPON();
KeReleaseSpinLock( &SDTSpinLock, OldIrql );
}
else
{
if (IofCallDriver)
{
KIRQL OldIrql;
KeAcquireSpinLock( &SDTSpinLock, &OldIrql );
WPOFF();
InterlockedExchange((PLONG)(*(PLONG)(address+2)),(LONG)IofCallDriver);
WPON();
KeReleaseSpinLock( &SDTSpinLock, OldIrql );
nativeIofCallDriver=(PBYTE)IofCallDriver;
}
else
{
return NULL;
}
}
DbgPrint("HDM:Leave HookIofCallDriver\n");
return (PIOFCALLDRIVER)nativeIofCallDriver;
}
#pragma INITCODE
NTSTATUS CreateDevice (
IN PDRIVER_OBJECT pDriverObject)
{
NTSTATUS status=STATUS_SUCCESS;
PDEVICE_OBJECT pDevObj;
PDEVICE_EXTENSION pDevExt;
//创建设备名称
UNICODE_STRING devName;
RtlInitUnicodeString(&devName,L"\\Device\\XPHookIofCallDriver");
//创建设备
status = IoCreateDevice( pDriverObject,
sizeof(DEVICE_EXTENSION),
&(UNICODE_STRING)devName,
FILE_DEVICE_UNKNOWN,
0, TRUE,
&pDevObj );
if (!NT_SUCCESS(status))
return status;
pDevObj->Flags |= DO_BUFFERED_IO;
pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
pDevExt->pDevice = pDevObj;
pDevExt->ustrDeviceName = devName;
//创建符号链接
UNICODE_STRING symLinkName;
RtlInitUnicodeString(&symLinkName,L"\\??\\XPHookIofCallDriver");
pDevExt->ustrSymLinkName = symLinkName;
status = IoCreateSymbolicLink( &symLinkName,&devName );
if (!NT_SUCCESS(status))
{
IoDeleteDevice( pDevObj );
return status;
}
g_nativeIofCallDriver=HookIofCallDriver(MyIofCallDriver,TRUE);
if (g_nativeIofCallDriver==NULL)
{
IoDeleteDevice(pDevObj);
IoDeleteSymbolicLink(&symLinkName);
status=STATUS_UNSUCCESSFUL;
}
return status;
}
问题就是调用HookIofCallDriver成功后,接下来就会不停的进入MyIofCallDriver,电脑几乎不反应了,
先先向帮助我的人表示感谢了
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
上传的附件: