-
-
[旧帖] [求助]关于内核函数ntoskrnl!MmGetPhysicalAddress 0.00雪花
-
2007-12-19 12:42 6196
-
前两天买了本黑防,看到了一片关于调用门进ring0的文章。其实文章没什么很新的,进ring0也是用的别人的老代码(好像最初是在看雪上看到的~~~~!)关于这个代码,以前也用过好几次,但没有深究~~~惭愧啊~~然后呢?一看,这个技术都快普及了,再不搞懂我就崩溃了!!!
话归正题,今天我想讨论的是ntoskrnl!MmGetPhysicalAddress这个内核级的函数(只要是我有点东西没搞懂,详请高手帮忙~)
我也没有用kd调了,直接用了前人的好东西:
kd> u nt!MmGetPhysicalAddress l 30
ntoskrnl!MmGetPhysicalAddress:
801374e0 56 push esi
801374e1 8b742408 mov esi,[esp+0×8]
801374e5 33d2 xor edx,edx
801374e7 81fe00000080 cmp esi,0×80000000
801374ed 722c jb ntoskrnl!MmGetPhysicalAddress+0×2b (8013751b)
801374ef 81fe000000a0 cmp esi,0xa0000000
801374f5 7324 jnb ntoskrnl!MmGetPhysicalAddress+0×2b (8013751b)
801374f7 39153ce71780 cmp [ntoskrnl!MmKseg2Frame (8017e73c)],edx
801374fd 741c jz ntoskrnl!MmGetPhysicalAddress+0×2b (8013751b)
801374ff 8bc6 mov eax,esi
80137501 c1e80c shr eax,0xc
80137504 25ffff0100 and eax,0×1ffff
80137509 6a0c push 0xc
8013750b 59 pop ecx
8013750c e8d3a7fcff call ntoskrnl!_allshl (80101ce4)
80137511 81e6ff0f0000 and esi,0xfff
80137517 03c6 add eax,esi
80137519 eb17 jmp ntoskrnl!MmGetPhysicalAddress+0×57 (80137532)
8013751b 8bc6 mov eax,esi
8013751d c1e80a shr eax,0xa
80137520 25fcff3f00 and eax,0×3ffffc
80137525 2d00000040 sub eax,0×40000000
8013752a 8b00 mov eax,[eax]
8013752c a801 test al,0×1
8013752e 7506 jnz ntoskrnl!MmGetPhysicalAddress+0×44 (80137536)
80137530 33c0 xor eax,eax
80137532 5e pop esi
80137533 c20400 ret 0×4
好,开始分析~~~
801374e0 56 push esi ;典型的函数调用开头~~~
801374e1 8b742408 mov esi,[esp+0×8]
801374e5 33d2 xor edx,edx
801374e7 81fe00000080 cmp esi,0×80000000
801374ed 722c jb ntoskrnl!MmGetPhysicalAddress+0×2b (8013751b) ;一个地址判断而已
801374ef 81fe000000a0 cmp esi,0xa0000000 ;超过了0×80000000到0xa0000000
801374f5 7324 jnb ntoskrnl!MmGetPhysicalAddress+0×2b (8013751b) ;就跳到8013751b
801374f7 39153ce71780 cmp [ntoskrnl!MmKseg2Frame (8017e73c)],edx ;这个MmKseg2Frame 是干什么的不懂
801374fd 741c jz ntoskrnl!MmGetPhysicalAddress+0×2b (8013751b) ;也没有查,因为不是我想讨论的重点~~
重头戏上场了~~~
801374ff 8bc6 mov eax,esi ;把虚拟地址给eax
80137501 c1e80c shr eax,0xc ;右移12位
80137504 25ffff0100 and eax,0×1ffff ;与17个1做and操作
80137509 6a0c push 0xc
8013750b 59 pop ecx ;让ecx为12
8013750c e8d3a7fcff call ntoskrnl!_allshl (80101ce4) ;左移12位,实际上_allshl的作用是我猜的,不知对不对?
80137511 81e6ff0f0000 and esi,0xfff ;让虚拟地址和12个1做and
80137517 03c6 add eax,esi ;请他们相加,然后返回~~~
80137519 eb17 jmp ntoskrnl!MmGetPhysicalAddress+0×57 (80137532)
不知道,我上面的分析对否~~~?
好,我继续说。假设我上面是对的,那么举个例子:
一个地址000aaaaaaaaaaaaaaaaabbbbbbbbbbbb
右移12位得到000000000000000aaaaaaaaaaaaaaaaa和1ffff做and结果不变还是000000000000000aaaaaaaaaaaaaaaaa
然后我左移12位000aaaaaaaaaaaaaaaaa000000000000
接着又把esi与fff做and得到00000000000000000000bbbbbbbbbbbb
最后相加返回不又是000aaaaaaaaaaaaaaaaabbbbbbbbbbbb
这不是没有变~~~~我晕了!!!
我说清楚点按汇编来看32位的地址只是把高3位的置0了,而后29位都没变~~~
但是~~~~
这个轻量级版本的MmGetPhysicalAddress() 中
PHYSICAL_MEMORY MyGetPhysicalAddress(void *BaseAddress) {
if (BaseAddress < 0x80000000 || BaseAddress >= 0xA0000000) {
return(BaseAddress & 0xFFFF000);
}
return(BaseAddress & 0x1FFFF000);
}
0x1FFFF000这个掩码虚拟地址,把高3位和低12位都置零了,然后返回,和我汇编分析的不同
汇编的是000aaaaaaaaaaaaaaaaabbbbbbbbbbbb
这个代码得到的是000aaaaaaaaaaaaaaaaa000000000000
所以我很迷惑~~~
请大家帮忙解释下!!!
话归正题,今天我想讨论的是ntoskrnl!MmGetPhysicalAddress这个内核级的函数(只要是我有点东西没搞懂,详请高手帮忙~)
我也没有用kd调了,直接用了前人的好东西:
kd> u nt!MmGetPhysicalAddress l 30
ntoskrnl!MmGetPhysicalAddress:
801374e0 56 push esi
801374e1 8b742408 mov esi,[esp+0×8]
801374e5 33d2 xor edx,edx
801374e7 81fe00000080 cmp esi,0×80000000
801374ed 722c jb ntoskrnl!MmGetPhysicalAddress+0×2b (8013751b)
801374ef 81fe000000a0 cmp esi,0xa0000000
801374f5 7324 jnb ntoskrnl!MmGetPhysicalAddress+0×2b (8013751b)
801374f7 39153ce71780 cmp [ntoskrnl!MmKseg2Frame (8017e73c)],edx
801374fd 741c jz ntoskrnl!MmGetPhysicalAddress+0×2b (8013751b)
801374ff 8bc6 mov eax,esi
80137501 c1e80c shr eax,0xc
80137504 25ffff0100 and eax,0×1ffff
80137509 6a0c push 0xc
8013750b 59 pop ecx
8013750c e8d3a7fcff call ntoskrnl!_allshl (80101ce4)
80137511 81e6ff0f0000 and esi,0xfff
80137517 03c6 add eax,esi
80137519 eb17 jmp ntoskrnl!MmGetPhysicalAddress+0×57 (80137532)
8013751b 8bc6 mov eax,esi
8013751d c1e80a shr eax,0xa
80137520 25fcff3f00 and eax,0×3ffffc
80137525 2d00000040 sub eax,0×40000000
8013752a 8b00 mov eax,[eax]
8013752c a801 test al,0×1
8013752e 7506 jnz ntoskrnl!MmGetPhysicalAddress+0×44 (80137536)
80137530 33c0 xor eax,eax
80137532 5e pop esi
80137533 c20400 ret 0×4
好,开始分析~~~
801374e0 56 push esi ;典型的函数调用开头~~~
801374e1 8b742408 mov esi,[esp+0×8]
801374e5 33d2 xor edx,edx
801374e7 81fe00000080 cmp esi,0×80000000
801374ed 722c jb ntoskrnl!MmGetPhysicalAddress+0×2b (8013751b) ;一个地址判断而已
801374ef 81fe000000a0 cmp esi,0xa0000000 ;超过了0×80000000到0xa0000000
801374f5 7324 jnb ntoskrnl!MmGetPhysicalAddress+0×2b (8013751b) ;就跳到8013751b
801374f7 39153ce71780 cmp [ntoskrnl!MmKseg2Frame (8017e73c)],edx ;这个MmKseg2Frame 是干什么的不懂
801374fd 741c jz ntoskrnl!MmGetPhysicalAddress+0×2b (8013751b) ;也没有查,因为不是我想讨论的重点~~
重头戏上场了~~~
801374ff 8bc6 mov eax,esi ;把虚拟地址给eax
80137501 c1e80c shr eax,0xc ;右移12位
80137504 25ffff0100 and eax,0×1ffff ;与17个1做and操作
80137509 6a0c push 0xc
8013750b 59 pop ecx ;让ecx为12
8013750c e8d3a7fcff call ntoskrnl!_allshl (80101ce4) ;左移12位,实际上_allshl的作用是我猜的,不知对不对?
80137511 81e6ff0f0000 and esi,0xfff ;让虚拟地址和12个1做and
80137517 03c6 add eax,esi ;请他们相加,然后返回~~~
80137519 eb17 jmp ntoskrnl!MmGetPhysicalAddress+0×57 (80137532)
不知道,我上面的分析对否~~~?
好,我继续说。假设我上面是对的,那么举个例子:
一个地址000aaaaaaaaaaaaaaaaabbbbbbbbbbbb
右移12位得到000000000000000aaaaaaaaaaaaaaaaa和1ffff做and结果不变还是000000000000000aaaaaaaaaaaaaaaaa
然后我左移12位000aaaaaaaaaaaaaaaaa000000000000
接着又把esi与fff做and得到00000000000000000000bbbbbbbbbbbb
最后相加返回不又是000aaaaaaaaaaaaaaaaabbbbbbbbbbbb
这不是没有变~~~~我晕了!!!
我说清楚点按汇编来看32位的地址只是把高3位的置0了,而后29位都没变~~~
但是~~~~
这个轻量级版本的MmGetPhysicalAddress() 中
PHYSICAL_MEMORY MyGetPhysicalAddress(void *BaseAddress) {
if (BaseAddress < 0x80000000 || BaseAddress >= 0xA0000000) {
return(BaseAddress & 0xFFFF000);
}
return(BaseAddress & 0x1FFFF000);
}
0x1FFFF000这个掩码虚拟地址,把高3位和低12位都置零了,然后返回,和我汇编分析的不同
汇编的是000aaaaaaaaaaaaaaaaabbbbbbbbbbbb
这个代码得到的是000aaaaaaaaaaaaaaaaa000000000000
所以我很迷惑~~~
请大家帮忙解释下!!!
阿里云助力开发者!2核2G 3M带宽不限流量!6.18限时价,开 发者可享99元/年,续费同价!
赞赏
他的文章
看原图