还原SSDT出现乱码 求内核编程高手进来帮忙!!

dengchaozhu 2011-07-13 09:16:23
请耐心看完哈
内存原型为:

kd> u 805C24B5 //双机调试的命令 就是反汇编一个地址
nt!NtOpenProcess+0x21f: 显示该地址在NtOpenProcess+0x21f
805c24b5 75c8 jne nt!NtOpenProcess+0x1e9 (805c247f) //地址 机器码 反汇编
805c24b7 ff75dc push dword ptr [ebp-24h]
805c24ba e88bfefeff call nt!ObOpenObjectByPointer (805b234a)
805c24bf 8bf8 mov edi,eax
805c24c1 8d8548ffffff lea eax,[ebp-0B8h]
805c24c7 50 push eax
805c24c8 e887590200 call nt!SeDeleteAccessState (805e7e54)
805c24cd 8b4dd0 mov ecx,dword ptr [ebp-30h]


我打开某个程序时会修改了这一行
805c24ba e88bfefeff call nt!ObOpenObjectByPointer (805b234a)

修改为
call AA542B17

因为不能直接恢复我想了个办法恢复

办法就是 在call之前jmp到我自己的指令来call ObOpenObjectByPointer
实现绕过call AA542B17:

805c24b7 ff75dc push dword ptr [ebp-24h]
这一行jmp到MyNtOpenProcess

我写了个内联汇编的代码

DWORD dwEditAddress/*保存地址805c24b7*/,dwRetAddress/*因为是jmp所以保存call下一个地址805c24bf*/;
DWORD pObOpenObjectByPointer=NULL;//保存ObOpenObjectByPointer函数地址

__declspec(naked)VOID MyNtOpenProcess()
{
__asm
{
push dword ptr[ebp-24] //恢复指令
push dwRetAddress //push call下一个地址以便遇到ret返回那里
jmp pObOpenObjectByPointer //call nt!ObOpenObjectByPointer (805b234a)

}


}
VOID Hook()
{
UNICODE_STRING Us_ObOpenObjectByPointer;
RtlInitUnicodeString(&Us_ObOpenObjectByPointer,L"ObOpenObjectByPointer");
pObOpenObjectByPointer=(DWORD)MmGetSystemRoutineAddress(&Us_ObOpenObjectByPointer);

DWORD dwNtOpenProcess;
UNICODE_STRING Us_NtOpenProcess;
RtlInitUnicodeString(&Us_NtOpenProcess,L"NtOpenProcess");
dwNtOpenProcess=(DWORD)MmGetSystemRoutineAddress(&Us_NtOpenProcess);//获得NtOpenProcess地址
dwEditAddress=dwNtOpenProcess+0x221; //获得准备修改的地址
KdPrint(("EditAddress=%x\n",dwNtOpenProcessAdd221));
dwRetAddress=dwNtOpenProcess+0x229; //获得返回的地址
KdPrint(("RetAddress=%x\n",dwRetAddress));

__asm
{
//去掉保护
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
//还原NtOpenProcess
mov ebx,dwEditAddress
mov al,0xe9
mov byte ptr[ebx],al //写入jmp指令
lea eax,MyNtOpenProcess //取得函数地址
sub eax,ebx //网上获得的方法当前地址sub要跳转的地址再sub 5
sub eax,5
mov DWORD ptr[ebx+1],eax 写入函数地址
//开启保护
mov eax,cr0
or eax,10000h
mov cr0,eax


}
return;
}


这样我在虚拟机里试过了 可以加载 不蓝屏 但是出现乱码



在本机测试蓝屏。。。

不知何解。。。求高手帮忙看看我哪里错了?
...全文
425 50 打赏 收藏 转发到动态 举报
写回复
用AI写文章
50 条回复
切换为时间正序
请发表友善的回复…
发表回复
A买点 2013-12-10
  • 打赏
  • 举报
回复
还有同胞在没,我也遇见这问题了
dengchaozhu 2011-07-15
  • 打赏
  • 举报
回复
[Quote=引用 45 楼 lactoferrin 的回复:]
你反汇编的位置不对
[/Quote]


再问 你看 44楼得反汇编代码 第3和第4行代码 2行一共是6字节

而 jmp MyNtOpenProcess是5字节

如果我在第三行 修改为 jmp MyNtOpenProcess 第4行会剩下一个字节出来

将这字节怎么处理才不会影响代码的执行呢? NOP掉吗?
dengchaozhu 2011-07-15
  • 打赏
  • 举报
回复
[Quote=引用 41 楼 lactoferrin 的回复:]
mov eax,dword ptr [hook!dwRetAddress (f7cf161c)]
是把dwRetAddress 的值放到eax
lea eax,dwRetAddress 才是取地址
[/Quote]
列宁同志.....我有点想吐血了。。
我查出虚拟机崩溃的原因了
你能在下面代码看出吗
kd> u nt!NtOpenProcess+0x21e
nt!NtOpenProcess+0x21e:
805c24b4 ff75c8 push dword ptr [ebp-38h]
805c24b7 ff75dc push dword ptr [ebp-24h]
805c24ba e88bfefeff call nt!ObOpenObjectByPointer (805b234a)
805c24bf 8bf8 mov edi,eax
805c24c1 8d8548ffffff lea eax,[ebp-0B8h]
805c24c7 50 push eax
805c24c8 e887590200 call nt!SeDeleteAccessState (805e7e54)
805c24cd 8b4dd0 mov ecx,dword ptr [ebp-30h]
kd> u nt!NtOpenProcess+0x21f
nt!NtOpenProcess+0x21f:
805c24b5 75c8 jne nt!NtOpenProcess+0x1e9 (805c247f)
805c24b7 ff75dc push dword ptr [ebp-24h]
805c24ba e88bfefeff call nt!ObOpenObjectByPointer (805b234a)
805c24bf 8bf8 mov edi,eax
805c24c1 8d8548ffffff lea eax,[ebp-0B8h]
805c24c7 50 push eax
805c24c8 e887590200 call nt!SeDeleteAccessState (805e7e54)
805c24cd 8b4dd0 mov ecx,dword ptr [ebp-30h]
Lactoferrin 2011-07-15
  • 打赏
  • 举报
回复
你反汇编的位置不对
dengchaozhu 2011-07-15
  • 打赏
  • 举报
回复
[Quote=引用 47 楼 lactoferrin 的回复:]
nop is ok
[/Quote]
不过加载几秒后蓝屏不知道为什么呢
dengchaozhu 2011-07-15
  • 打赏
  • 举报
回复
[Quote=引用 47 楼 lactoferrin 的回复:]
nop is ok
[/Quote]
哦 谢谢列宁同志的耐心教导
Lactoferrin 2011-07-15
  • 打赏
  • 举报
回复
nop is ok
dengchaozhu 2011-07-14
  • 打赏
  • 举报
回复
修改的代码:

DWORD dwEditCodeAddress,dwRetAddress,dwJneAddress,dwObOpenObjectByPointer;


__declspec(naked)VOID MyNtOpenProcess()
{
__asm
{

jne 805C247Fh //不是很清楚为什么jne dwJneAddress 通不过编译
push dword ptr[ebp-24] //仿照NtOpenProcess里的指令
push dwRetAddress //push返回地址
jmp pObOpenObjectByPointer //调用函数

}


}
VOID Hook()
{
UNICODE_STRING Us_ObOpenObjectByPointer,Us_NtOpenProcess;
DWORD dwNtOpenProcess;

RtlInitUnicodeString(&Us_ObOpenObjectByPointer,L"ObOpenObjectByPointer");

dwObOpenObjectByPointer=(DWORD)MmGetSystemRoutineAddress(&Us_ObOpenObjectByPointer);//取得ObOpenObjectByPointer函数地址



RtlInitUnicodeString(&Us_NtOpenProcess,L"NtOpenProcess");

dwNtOpenProcess=(DWORD)MmGetSystemRoutineAddress(&Us_NtOpenProcess);//取得NtOpenProcess函数地址

dwEditCodeAddress=dwNtOpenProcess+0x21f; //NtOpenProcess+0x21f是要修改的地址


dwRetAddress=dwNtOpenProcess+0x229; //这个是当ObOpenObjectByPointer遇到ret时返回的地址



dwJneAddress =dwNtOpenProcess+0x1e9;//这个是jne跳转的地址

__asm
{
//去掉保护
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
//还原NtOpenProcess
mov ebx,dwEditCodeAddress
mov al,0xe9
mov byte ptr[ebx],al //往要修改的地址里写入jmp
lea eax,MyNtOpenProcess
sub eax,ebx
sub eax,5
mov DWORD ptr[ebx+1],eax //写入jmp的函数地址
//开启保护
mov eax,cr0
or eax,10000h
mov cr0,eax


}
return;
}


加载驱动前 这块内存为:

805c24b5 75c8            jne     nt!NtOpenProcess+0x1e9 (805c247f)
805c24b7 ff75dc push dword ptr [ebp-24h]
805c24ba e88bfefeff call nt!ObOpenObjectByPointer (805b234a)
805c24bf 8bf8 mov edi,eax

加载驱动后
805c24b5 e956bb3977      jmp     Hook!MyNtOpenProcess (f795e010)
805c24ba e88bfefeff call nt!ObOpenObjectByPointer (805b234a)
805c24bf 8bf8 mov edi,eax

是成功jmp到我的函数了 我跟进 f795e010里看了

f795e010 0f8500000000    jne     Hook!MyNtOpenProcess+0x6 (f795e016)
f795e016 ff75e8 push dword ptr [ebp-18h]
f795e019 ff351c0096f7 push dword ptr [Hook!dwRetAddress (f796001c)]
f795e01f ff25240096f7 jmp dword ptr [Hook!dwObOpenObjectByPointer (f7960024)]

为什么地址全错了呢
push dword ptr [Hook!dwRetAddress (f796001c)]
dwRetAddress明明是我 dwJneAddress =dwNtOpenProcess+0x1e9; 得来的
还有 jmp dwObOpenObjectByPointer 也是我计算出来的
不说 第一条指令 jne 我已经写了明确的地址 jne 805C247Fh 它也给我跳到f795e016去了

很不解额。。。
Lactoferrin 2011-07-14
  • 打赏
  • 举报
回复
为什么不能直接恢复?
你可以用ZwQuerySystemInformation得到内核的文件名,然后从这个文件中取得原始数据
NtOpenProcess是导出的
dengchaozhu 2011-07-14
  • 打赏
  • 举报
回复
[Quote=引用 41 楼 lactoferrin 的回复:]
mov eax,dword ptr [hook!dwRetAddress (f7cf161c)]
是把dwRetAddress 的值放到eax
lea eax,dwRetAddress 才是取地址
[/Quote]

je hook!MyNtOpenProcess+0x8 (f7cf1b88)
jne hook!MyNtOpenProcess+0x8 (f7cf1b88)
这样是对的吗
dengchaozhu 2011-07-14
  • 打赏
  • 举报
回复
[Quote=引用 41 楼 lactoferrin 的回复:]
mov eax,dword ptr [hook!dwRetAddress (f7cf161c)]
是把dwRetAddress 的值放到eax
lea eax,dwRetAddress 才是取地址
[/Quote]
哦,那jne 呢 我都把地址写出了 反汇编怎么还是错的?
Lactoferrin 2011-07-14
  • 打赏
  • 举报
回复
mov eax,dword ptr [hook!dwRetAddress (f7cf161c)]
是把dwRetAddress 的值放到eax
lea eax,dwRetAddress 才是取地址
dengchaozhu 2011-07-14
  • 打赏
  • 举报
回复
[Quote=引用 38 楼 lactoferrin 的回复:]
f7cf4618是pObOpenObjectByPointer这个变量的地址
[/Quote]
还是不对

	__asm
{
je a

jne 0x805c247f //jne dwJneAddress 通不过编译
a:
push dword ptr[ebp-0x24] //仿照NtOpenProcess里的指令
mov eax,dwRetAddress
push eax //push返回地址
mov eax,0x805b234a
jmp eax //调用函数


}

f7cf1b80 7406            je      hook!MyNtOpenProcess+0x8 (f7cf1b88)
f7cf1b82 0f8500000000 jne hook!MyNtOpenProcess+0x8 (f7cf1b88)
f7cf1b88 ff75dc push dword ptr [ebp-24h]
f7cf1b8b a11c16cff7 mov eax,dword ptr [hook!dwRetAddress (f7cf161c)]
f7cf1b90 50 push eax
f7cf1b91 b84a235b80 mov eax,offset nt!ObOpenObjectByPointer (805b234a)
f7cf1b96 ffe0 jmp eax


怎么会这样啊 mov eax,dwJneAddress 取的是它的地址 不是它的值
dengchaozhu 2011-07-14
  • 打赏
  • 举报
回复
[Quote=引用 38 楼 lactoferrin 的回复:]
f7cf4618是pObOpenObjectByPointer这个变量的地址
[/Quote]

我乌龙

我想call pObOpenObjectByPointer这变量里面的值呢

这变量里面存放着函数地址啊
Lactoferrin 2011-07-14
  • 打赏
  • 举报
回复
f7cf4618是pObOpenObjectByPointer这个变量的地址
dengchaozhu 2011-07-14
  • 打赏
  • 举报
回复
[Quote=引用 36 楼 lactoferrin 的回复:]
地址哪里不对了f7bccb80 是你的代码的地址
KdPrint(("Address=%x",dwJneAddress));出来的是dwJneAddress的值,两者没关系
[/Quote]

....

我再想问下

就拿call这里来说吧 你看看 0楼的反汇编代码那里

805c24ba e88bfefeff call nt!ObOpenObjectByPointer (805b234a)

这是系统原来的代码

他是 call ObOpenObjectByPointer函数 805b234a 是这函数的地址吧

在看 32楼得C++代码那里 :

pObOpenObjectByPointer=(DWORD)MmGetSystemRoutineAddress(&Us_ObOpenObjectByPointer);

//获得 ObOpenObjectByPointer函数地址 我KdPrint出来看了 这地址是805b234a

你再看32楼的反汇编代码 最后一行

call dword ptr [hook!pObOpenObjectByPointer (f7cf4618)]

它是在call f7cf4618 这个地址 这个地址是怎么来的呢?






Lactoferrin 2011-07-14
  • 打赏
  • 举报
回复
地址哪里不对了f7bccb80 是你的代码的地址
KdPrint(("Address=%x",dwJneAddress));出来的是dwJneAddress的值,两者没关系
dengchaozhu 2011-07-14
  • 打赏
  • 举报
回复
[Quote=引用 34 楼 lactoferrin 的回复:]
jne 0x805c247f
换成jmp 0x805c247f
[/Quote]
这个有什么关系啊

你知道这是为什么吗 地址怎么全不对

全都是f7bcc开头的

我获取地址时 KdPrint 出来看 是对的啊

Lactoferrin 2011-07-14
  • 打赏
  • 举报
回复
jne 0x805c247f
换成jmp 0x805c247f
dengchaozhu 2011-07-14
  • 打赏
  • 举报
回复
上面搞错了

是少一个mov的:

f7bccb80 7406            je      hook!MyNtOpenProcess+0x8 (f7bccb88)
f7bccb82 0f8500000000 jne hook!MyNtOpenProcess+0x8 (f7bccb88)
f7bccb88 ff75dc push dword ptr [ebp-24h]
f7bccb8b ff351cc6bcf7 push dword ptr [hook!dwRetAddress (f7bcc61c)]
f7bccb91 ff2518c6bcf7 jmp dword ptr [hook!pObOpenObjectByPointer (f7bcc618)]
加载更多回复(30)

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧