:p:我知道写出这个来,很可能没多长时间就失效了:eek:。但是我还是要写出来,帮助一下那些和我一样在不停得探索的童鞋们。。。
有些东西,你学一遍不懂。学两遍可能就会懵懂,3遍可能就懂了。。。。
光问别人,不好。也得共享一些东西。:D:
其实就是HOOK kddisabledebugger 这个函数。但是要对某P的几个全局变量做点手脚。
某P是这样获取地址的。
Kddisabledebugger ===(17b6c+2c) xor 17b68
Kddebuggerenabled ===(17b6c+28) xor 17b68
其中他在一个地方会这样
while ( kddeuggerenabled)
{
kddisabledebugger();
}
我们没法改变某P的代码:3:他现在是有效验?。但是我们可以改变某P的数据或者寄存器的数。
对17b6c+28 这个地方进行操作。让某P经过计算之后得到的kddebuggerenabled值为0.那么他就可以不用无限循环了。
第二。某P会在一个地方将kidebugroutine 的值复为:KdpStub。对此,我只需要在kddisabledebugger里面讲存储kdpstub的地址改为KdpTrap。那么,某P就会一直讲kidebugroutine的值复为kdptrap。
为了防止一直写入会造成系统崩溃什么的。我只在第一次调用的时候,进行这些修改。以后调用直接ret。
哦了。以上就是我的方法。
另外我还有点想法,请教一下:
1,能不能HOOK一个函数,windows操作系统线程调用不是轮询吗?当他调用到这个调用kddisabledebugger这个线程的时候,就将kddebuggerenabled,kidebugroutine的值设为某P想要的那样,然后当windows跳到别的线程的时候,再改回来?这样可以?
2,重载内核,我还能用windbg调试吗?我知道重载内核直接passtp了。但是如果我调试别的呢?
3,虚拟地址映射物理地址可否做些手脚呢?
呵呵。我知道的东西太少了。还得再学习。先共享上面那个方法吧。鄙人语言表达能力基本没有。还望见谅。
某P调用kddisabledebugger的代码自己补贴了哈
有些东西,你学一遍不懂。学两遍可能就会懵懂,3遍可能就懂了。。。。
光问别人,不好。也得共享一些东西。:D:
代码:
ULONG clearaddr1=0;
ULONG clearaddr2=0;
ULONG KiDebugRoutineaddr=0;
ULONG returnaddr2=0;
ULONG calltimes=0;
typedef unsigned char byte;
void my_kddisabledebugger();
VOID MY_PloadImageNotifyRoutine(IN PUNICODE_STRING FullImageName,IN HANDLE ProcessId,IN PIMAGE_INFO ImageInfo)
{
if (NULL!=wcsstr(FullImageName->Buffer,L"TesSafe.sys"))
{
KdPrint(("要加载的内存映像名称为%ws,进程ID=%x,映像基地址=%x,映像大小=%x\r\n",FullImageName->Buffer,ProcessId,ImageInfo->ImageBase,ImageInfo->ImageSize));
_asm int 3;
clearaddr1=(ULONG)ImageInfo->ImageBase+0x17b6c;
clearaddr2=(ULONG)ImageInfo->ImageBase+0x13268;
KiDebugRoutineaddr=*PULONG((ULONG)KdDisableDebugger+0x4a);
returnaddr2=(ULONG)ImageInfo->ImageBase+0x7008;
WPOFF();
byte jmpcode[6];
jmpcode[0]=0x90;
jmpcode[1]=0xe9;
*(ULONG*)(jmpcode+2)=(ULONG)my_kddisabledebugger-((ULONG)KdDisableDebugger+1+5);
RtlCopyMemory((PVOID)KdDisableDebugger,jmpcode,6);
WPON();
}
}
void showhookkddisabledeguggermessage()
{
KdPrint(("tp还在调用kddisabledebugger,当前线程ID=%d\r\n",PsGetCurrentThreadId()));
}
void _declspec (naked) my_kddisabledebugger()
{
showhookkddisabledeguggermessage();
//将第一个数改为39f1 //17b68
//读取KiDebugRoutine里面的数值,付给13268
__asm
{
mov eax,calltimes
cmp eax,0
jne return3
mov eax,clearaddr1
mov eax,[eax]
mov edi,[eax+0x28]
sub edi,1
mov [eax+0x28],edi
mov edi,[esp]
cmp edi,returnaddr2
jne return2
sub esi,1
return2:
mov edi,[KiDebugRoutineaddr]
mov edi,[edi]
mov eax,clearaddr2
mov [eax],edi
lea eax,calltimes
mov edi,calltimes
add edi,1
mov [eax],edi
return3:
ret
}
}
某P是这样获取地址的。
Kddisabledebugger ===(17b6c+2c) xor 17b68
Kddebuggerenabled ===(17b6c+28) xor 17b68
其中他在一个地方会这样
while ( kddeuggerenabled)
{
kddisabledebugger();
}
我们没法改变某P的代码:3:他现在是有效验?。但是我们可以改变某P的数据或者寄存器的数。
对17b6c+28 这个地方进行操作。让某P经过计算之后得到的kddebuggerenabled值为0.那么他就可以不用无限循环了。
第二。某P会在一个地方将kidebugroutine 的值复为:KdpStub。对此,我只需要在kddisabledebugger里面讲存储kdpstub的地址改为KdpTrap。那么,某P就会一直讲kidebugroutine的值复为kdptrap。
为了防止一直写入会造成系统崩溃什么的。我只在第一次调用的时候,进行这些修改。以后调用直接ret。
哦了。以上就是我的方法。
另外我还有点想法,请教一下:
1,能不能HOOK一个函数,windows操作系统线程调用不是轮询吗?当他调用到这个调用kddisabledebugger这个线程的时候,就将kddebuggerenabled,kidebugroutine的值设为某P想要的那样,然后当windows跳到别的线程的时候,再改回来?这样可以?
2,重载内核,我还能用windbg调试吗?我知道重载内核直接passtp了。但是如果我调试别的呢?
3,虚拟地址映射物理地址可否做些手脚呢?
呵呵。我知道的东西太少了。还得再学习。先共享上面那个方法吧。鄙人语言表达能力基本没有。还望见谅。
某P调用kddisabledebugger的代码自己补贴了哈