能力值:
( LV2,RANK:10 )
|
-
-
2 楼
google “Inline Hook”
|
能力值:
( LV4,RANK:50 )
|
-
-
3 楼
cr0 寄存器没修改,代码段只读不可写
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
能说得详细点么
|
能力值:
( LV5,RANK:70 )
|
-
-
5 楼
LZ的问题在于没有仔细看IofCallDriver,一起看看:
kd> u IofCallDriver
nt!IofCallDriver:
804eefea ff2500c65480 jmp dword ptr [nt!pIofCallDriver (8054c600)]
IofCallDriver这里的ff25是jmp到一个指针变量所保存的值里去,也就是说不是jmp到8054c600,而是jmp到这里:
kd> dd 8054c600 l1
8054c600 804eefb2
kd> u 804eefb2
nt!IopfCallDriver:
804eefb2 fe4a23 dec byte ptr [edx+23h]
804eefb5 8a4223 mov al,byte ptr [edx+23h]
804eefb8 84c0 test al,al
804eefba 7f0e jg nt!IopfCallDriver+0x18 (804eefca)
804eefbc 6a00 push 0
804eefbe 6a00 push 0
804eefc0 6a00 push 0
804eefc2 52 push edx
同样,LZ写进入的值也不能直接是你的MyIoCallDriver,而应该做如下修改:
if(hook)
{
oldcallerbody=(PMY_IOFCALLDRIVER_FP)(*(PLONG)(addr+2));
oldcallerbody=(PMY_IOFCALLDRIVER_FP)(*(ULONG*)oldcallerbody);
static PMY_IOFCALLDRIVER_FP newcallerbody = newCaller;
InterlockedExchange((PLONG)(addr+2),(LONG)&newcallerbody);
return oldcallerbody;
}
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
相对跳转问题吧
|
能力值:
( LV4,RANK:50 )
|
-
-
7 楼
[QUOTE=星逝;1225301]LZ的问题在于没有仔细看IofCallDriver,一起看看:
kd> u IofCallDriver
nt!IofCallDriver:
804eefea ff2500c65480 jmp dword ptr [nt!pIofCallDriver (8054c600)]
IofCa...[/QUOTE]
话说这个问题修改了以后还蓝屏,还用了全局的,也用过ExAllocatePoolWithTag申请不分页内存,呼呼,Hook在windbg下查看完全OK,F9依旧蓝屏,哎~~~
|
能力值:
( LV4,RANK:50 )
|
-
-
8 楼
我去啊,你DriverEntry都没return success,难怪蓝屏了,驱动都没加载成功,而跳转被修改了,函数MyIoCallDriver 不可读
|
能力值:
( LV4,RANK:50 )
|
-
-
9 楼
#include<ntddk.h>
typedef NTSTATUS (FASTCALL* PMY_IOFCALLDRIVER_FP)(IN PDEVICE_OBJECT,IN OUT PIRP);
typedef unsigned char BYTE;
static PMY_IOFCALLDRIVER_FP* oldcallerbody = NULL;
PMY_IOFCALLDRIVER_FP* jmp_addr = NULL;
VOID DriverUnload(IN PDRIVER_OBJECT pDriverObject);
PMY_IOFCALLDRIVER_FP XP_HOOK_IoCallDriver(PMY_IOFCALLDRIVER_FP* newCaller,BOOLEAN hook)
{
UNICODE_STRING funName;
BYTE *addr;
RtlInitUnicodeString(&funName,L"IofCallDriver");
addr=MmGetSystemRoutineAddress(&funName);
if(hook)
{
oldcallerbody = (PMY_IOFCALLDRIVER_FP*)(*(PLONG)(addr+2));
__asm{
cli
mov eax,cr0
push eax
and eax,not 10000h
mov cr0,eax
}
InterlockedExchange((PLONG)(addr+2), newCaller);
__asm{
pop eax
mov cr0,eax
sti
}
return oldcallerbody;
}
else
{
if (oldcallerbody!=NULL)
{
__asm{
cli
mov eax,cr0
push eax
and eax,not 10000h
mov cr0,eax
}
InterlockedExchange((PLONG)(addr+2),oldcallerbody);
__asm{
pop eax
mov cr0,eax
sti
}
return oldcallerbody;
}
}
}
NTSTATUS FASTCALL MyIoCallDriver(IN PDEVICE_OBJECT pDev,IN OUT PIRP pIrp )
{
DbgPrint("Hook Is called \n");
return (*oldcallerbody)(pDev,pIrp);
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN IN PUNICODE_STRING pReg_Path)
{
PMY_IOFCALLDRIVER_FP pfn = MyIoCallDriver;
// 方法一:自己申请内存
// jmp_addr = (PMY_IOFCALLDRIVER_FP*)ExAllocatePoolWithTag(NonPagedPoolCacheAligned, sizeof(PMY_IOFCALLDRIVER_FP), 'KNUJ');
// *jmp_addr = MyIoCallDriver;
// XP_HOOK_IoCallDriver(jmp_addr, TRUE);
// 方法二:全局变量
jmp_addr = MyIoCallDriver;
XP_HOOK_IoCallDriver(&jmp_addr, TRUE);
pDriverObject->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
VOID DriverUnload(IN PDRIVER_OBJECT pDriverObject)
{
// 这里反正第一个参数没用,就取地址吧
XP_HOOK_IoCallDriver(&jmp_addr, FALSE);
// ExFreePoolWithTag(jmp_addr, 'KNUJ');
DbgPrint("close hook \n");
}
|
能力值:
( LV5,RANK:70 )
|
-
-
10 楼
我试过了,不会蓝。DriverEntry里没return应该是LZ copy代码疏忽了,编译器肯定是编不过的。
|
能力值:
( LV4,RANK:50 )
|
-
-
11 楼
额,好吧,我这编译通过了 ,也无情的蓝了,win7 x64 sp1 ,7600的wdk 用 x86 checked。平时写代码还有强转来强转去的,这次这么干脆过了
.text:0001058C mov _jmp_addr, eax
.text:00010591 mov eax, _jmp_addr
.text:00010596 mov dword ptr [eax], offset MyIoCallDriver(x,x)
.text:0001059C push 1 ; hook
.text:0001059E mov ecx, _jmp_addr
.text:000105A4 push ecx ; newCaller
.text:000105A5 call XP_HOOK_IoCallDriver(x,x)
.text:000105A5
.text:000105AA mov edx, [ebp+pDriverObject]
.text:000105AD mov dword ptr [edx+34h], offset DriverUnload(x)
.text:000105B4 mov esp, ebp
.text:000105B6 pop ebp
.text:000105B7 retn 8
.text:000105B7
.text:000105B7 __stdcall DriverEntry(x, x) endp
结果就这样,eax 最后返回了 自己申请的内存地址
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
[QUOTE=星逝;1225301]LZ的问题在于没有仔细看IofCallDriver,一起看看:
kd> u IofCallDriver
nt!IofCallDriver:
804eefea ff2500c65480 jmp dword ptr [nt!pIofCallDriver (8054c600)]
IofCa...[/QUOTE]
能请教你个问题么,我把驱动编译之后,实际上文件中存在的是机器码,然后我通过InterLockedExchange这个函数修改之后,也是直接修改机器码是不是?还是修改汇编代码?
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
[QUOTE=星逝;1225301]LZ的问题在于没有仔细看IofCallDriver,一起看看:
kd> u IofCallDriver
nt!IofCallDriver:
804eefea ff2500c65480 jmp dword ptr [nt!pIofCallDriver (8054c600)]
IofCa...[/QUOTE]
你好改成这样当跟踪到红色这一句就蓝了,我的系统是XP DDK 为 7600
PMY_IOFCALLDRIVER_FP XP_HOOK_IoCallDriver(PMY_IOFCALLDRIVER_FP newCaller,BOOLEAN hook)
{
UNICODE_STRING funName;
BYTE *addr;
static PMY_IOFCALLDRIVER_FP newcallerbody=NULL;
RtlInitUnicodeString(&funName,L"IofCallDriver");
addr=MmGetSystemRoutineAddress(&funName);
if(hook)
{
oldcallerbody=(PMY_IOFCALLDRIVER_FP)(*(PLONG)(addr+2));
newcallerbody=newCaller;
InterlockedExchange((PLONG)(addr+2),(LONG)&newcallerbody);
return oldcallerbody;
}
else
{
if (oldcallerbody!=NULL)
{
InterlockedExchange((PLONG)(addr+2),oldcallerbody);
return oldcallerbody;
}
}
}
|
能力值:
( LV4,RANK:50 )
|
-
-
14 楼
见Intel手册卷三,应该是第3章内存管理里面有详细说明。
上面很清楚的标记了CR0第16位是写保护位,如果为1的时候代码内存是不能写的,一写就蓝屏,必须把它清零先
9L代码不是可以运行了么~~~~~~~~~~~~~~
|
能力值:
( LV5,RANK:70 )
|
-
-
15 楼
你是用命令行编译的吗?
|
能力值:
( LV5,RANK:70 )
|
-
-
16 楼
是直接修改机器码,也可以说修改了汇编代码,因为汇编代码只是机器码的一种等价表示,就如中文的你好用英文表示为hello一样。
|
能力值:
( LV5,RANK:70 )
|
-
-
17 楼
要具体看了,提供下源码我试下?
|
能力值:
( LV4,RANK:50 )
|
-
-
18 楼
wdk自带的命令行编译的。
LZ贴的就是完整代码,你不是说你试过了么?
|
能力值:
( LV5,RANK:70 )
|
-
-
19 楼
我是VS+DDKWizard生成的,DriverEntry部分没用LZ的,所以是有return的。
|
能力值:
( LV5,RANK:60 )
|
-
-
20 楼
目测没有去掉写保护.
|
能力值:
( LV2,RANK:10 )
|
-
-
21 楼
以下是完整代码,去除读写保护之后,InterLockedExchange就不蓝屏了,不过执行HOOK函数就蓝了
#include<ntddk.h>
typedef NTSTATUS (FASTCALL* PMY_IOFCALLDRIVER_FP)(IN PDEVICE_OBJECT,IN OUT PIRP);
typedef unsigned char BYTE;
static PMY_IOFCALLDRIVER_FP oldcallerbody=NULL;
//static PMY_IOFCALLDRIVER_FP newcallerbody=NULL;
VOID DriverUnload(IN PDRIVER_OBJECT pDriverObject);
PMY_IOFCALLDRIVER_FP XP_HOOK_IoCallDriver(PMY_IOFCALLDRIVER_FP newCaller,BOOLEAN hook)
{
UNICODE_STRING funName;
BYTE *addr;
static PMY_IOFCALLDRIVER_FP newcallerbody=NULL;
RtlInitUnicodeString(&funName,L"IofCallDriver");
addr=MmGetSystemRoutineAddress(&funName);
if(hook)
{
oldcallerbody=(PMY_IOFCALLDRIVER_FP)(*(PLONG)(addr+2));
newcallerbody=newCaller;
__asm{
cli
mov eax,cr0
push eax
and eax,not 10000h
mov cr0,eax
}
InterlockedExchange((PLONG)(addr+2),(LONG)&newcallerbody);
__asm{
pop eax
mov cr0,eax
sti
}
return oldcallerbody;
}
else
{
if (oldcallerbody!=NULL)
{
__asm{
cli
mov eax,cr0
push eax
and eax,not 10000h
mov cr0,eax
}
newcallerbody=oldcallerbody;
InterlockedExchange((PLONG)(addr+2),&oldcallerbody);
__asm{
pop eax
mov cr0,eax
sti
}
return oldcallerbody;
}
}
}
NTSTATUS FASTCALL MyIoCallDriver(IN PDEVICE_OBJECT pDev,IN OUT PIRP pIrp )
{
DbgPrint("Hook Is called \n");
return (*oldcallerbody)(pDev,pIrp);
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN IN PUNICODE_STRING pReg_Path)
{
PMY_IOFCALLDRIVER_FP pfn=MyIoCallDriver;
XP_HOOK_IoCallDriver(MyIoCallDriver,TRUE);
pDriverObject->DriverUnload=DriverUnload;
return STATUS_SUCCESS;
}
VOID DriverUnload(IN PDRIVER_OBJECT pDriverObject)
{
XP_HOOK_IoCallDriver(MyIoCallDriver,FALSE);
DbgPrint("close hook \n");
}
|
能力值:
( LV5,RANK:70 )
|
-
-
22 楼
仔细对比下我或者瀚海云烟贴出来的代码,目测现在的问题在oldcallerbody的定义,瀚海云烟的定义如下:static PMY_IOFCALLDRIVER_FP* oldcallerbody = NULL;
|
|
|