-
-
[原创]逆向分析MmIsAddressValid函数2-9-9-12分页
-
发表于: 2023-8-12 12:05 2972
-
1、逆向分析XP系统2-9-9-12分页模式下,内核文件ntkrnlpa.exe中的MmIsAddressValid函数
2、总结3点
3、错误修复:
Exported entry 685. MmIsAddressValid
.text:0043C928
.text:0043C928 ; =============== S U B R O U T I N E =======================================
.text:0043C928
.text:0043C928 ; Attributes: bp-based frame
.text:0043C928
.text:0043C928 ;
BOOLEAN
__stdcall MmIsAddressValid(
PVOID
VirtualAddress)
.text:0043C928
public
_MmIsAddressValid@4
.text:0043C928 _MmIsAddressValid@4 proc near ; CODE XREF: IopIsAddressRangeValid(x,x)+2F↑p
.text:0043C928 ; IopGetMaxValidMemorySize(x,x)+29↑p
.text:0043C928 ; IoSetDumpRange(x,x,x,x)+56↑p
.text:0043C928 ; IoFreeDumpRange(x,x,x,x)+4C↑p
.text:0043C928 ; IopWriteDriverList(x,x,x,x)+8F↑p
.text:0043C928 ; IopInvokeDumpIoCallbacks(x,x,x)+56↑p
.text:0043C928 ; IopInvokeDumpIoCallbacks(x,x,x)+AB↑p
.text:0043C928 ; sub_41B7E6+13↑p
.text:0043C928 ; KeCapturePersistentThreadState(x,x,x,x,x,x,x,x)+49A↑p
.text:0043C928 ; IopInvokeSecondaryDumpDataCallbacks(x,x,x,x,x,x,x,x,x)+BA↑p
.text:0043C928 ; IopInvokeSecondaryDumpDataCallbacks(x,x,x,x,x,x,x,x,x)+120↑p
.text:0043C928 ; KiPcToFileHeader(x,x,x,x)+2C↑p
.text:0043C928 ; KiDumpParameterImages(x,x,x,x)+7A↑p
.text:0043C928 ; KiScanBugCheckCallbackList()+3C↑p
.text:0043C928 ; KiInvokeBugCheckEntryCallbacks()+50↑p ...
.text:0043C928
.text:0043C928 var_8= dword ptr -8
.text:0043C928 var_4= dword ptr -4
.text:0043C928 VirtualAddress= dword ptr 8
.text:0043C928
.text:0043C928 mov edi, edi
.text:0043C92A push ebp
.text:0043C92B mov ebp, esp
.text:0043C92D push ecx
.text:0043C92E push ecx
.text:0043C92F mov ecx, [ebp+VirtualAddress] ; 取出线性地址
.text:0043C932 push esi
.text:0043C933 mov eax, ecx
.text:0043C935 shr eax, 12h ; 线性地址右移18位,移除了12位物理页偏移和PTI的低6位
.text:0043C938 mov esi, 3FF8h ; 0000 0000 0000 0000 0011 1111 1111 1000
.text:0043C93D and eax, esi ; 与运算后,保留了2位PDPTI和9位PDI。最后3位为0的作用:1.移除PTI的高3位。2.PDI<<3。3.POPTI<<12
.text:0043C93F sub eax, 3FA00000h ; 运算结果 eax = 0xC0600000 + PDPTI*4KB + PDI*8
.text:0043C944 mov edx, [eax] ; edx = PDE低4字节
.text:0043C946 mov eax, [eax+4] ; eax = PDE高4字节
.text:0043C949 mov [ebp+var_4], eax ; 局部变量1 = PDE高4字节
.text:0043C94C mov eax, edx ; eax = PDE低4字节
.text:0043C94E push edi
.text:0043C94F and eax, 1 ; 取出PDE低4字节中的P位
.text:0043C952 xor edi, edi ; edi = 0
.text:0043C954 or eax, edi ; 判断P位是否为0
.text:0043C956 jz
short
loc_43C9B9 ;
if
P==0,则
return
0
.text:0043C956
.text:0043C958 mov edi, 80h ; 1000 0000
.text:0043C95D and edx, edi ; 取出PDE低4字节中的PS位
.text:0043C95F push 0
.text:0043C961 mov [ebp+var_8], edx ; 局部变量2 = PDE低4字节中的PS位
.text:0043C964 pop eax ; eax = 0
.text:0043C965 jz
short
loc_43C96B ; PS位 == 0,跳转到判断小页代码
.text:0043C965
.text:0043C967 test eax, eax ; 判断eax==0
.text:0043C969 jz
short
loc_43C9BD ;
if
PS位 == 1, 则
return
1
.text:0043C969
.text:0043C96B
.text:0043C96B loc_43C96B: ; CODE XREF: MmIsAddressValid(x)+3D↑j
.text:0043C96B shr ecx, 9 ; 线性地址右移9位。
.text:0043C96E and ecx, 7FFFF8h ; 7FFFF8 = 0000 0000 0111 1111 1111 1111 1111 1000
.text:0043C96E ; 与运算后,保留2位PDPTI<<21,9位PDI<<12,9位PTI<<3
.text:0043C974 mov eax, [ecx-3FFFFFFCh] ; ecx-3FFFFFFC = 0xC0000000 + PDPTI*2MB + PDI*4KB + PTI*8; eax = PTE高4字节
.text:0043C97A sub ecx, 40000000h
.text:0043C980 mov edx, [ecx] ; edx = PTE低4字节
.text:0043C982 mov [ebp+var_4], eax ; 局部变量1 = PTE高4字节
.text:0043C985 push ebx
.text:0043C986 mov eax, edx ; eax = PTE低4字节
.text:0043C988 xor ebx, ebx ; ebx = 0
.text:0043C98A and eax, 1 ; 取出PTE低4字节中的P位
.text:0043C98D or eax, ebx ; 判断P位是否为0
.text:0043C98F pop ebx
.text:0043C990 jz
short
loc_43C9B9 ;
if
P == 0, 则
return
0
.text:0043C990
.text:0043C992 and edx, edi ; 判断PTE低4字节中的PAT位
.text:0043C994 push 0
.text:0043C996 mov [ebp+var_8], edx ; 局部变量2 = PAT位
.text:0043C999 pop eax
.text:0043C99A jz
short
loc_43C9BD ;
if
PAT == 0, 则
return
1
.text:0043C99A
.text:0043C99C test eax, eax
.text:0043C99E jnz
short
loc_43C9BD ; 下面代码是PAT == 1的情况
.text:0043C99E
.text:0043C9A0 and ecx, esi ; PTE的低4字节线性地址 and 0000 0000 0000 0000 0011 1111 1111 1000
.text:0043C9A2 mov ecx, [ecx-3FA00000h]
.text:0043C9A8 mov eax, 81h
.text:0043C9AD and ecx, eax
.text:0043C9AF xor edx, edx
.text:0043C9B1 cmp ecx, eax
.text:0043C9B3 jnz
short
loc_43C9BD
.text:0043C9B3
.text:0043C9B5 test edx, edx
.text:0043C9B7 jnz
short
loc_43C9BD
.text:0043C9B7
.text:0043C9B9
.text:0043C9B9 loc_43C9B9: ; CODE XREF: MmIsAddressValid(x)+2E↑j
.text:0043C9B9 ; MmIsAddressValid(x)+68↑j
.text:0043C9B9 xor al, al
.text:0043C9BB jmp
short
loc_43C9BF
.text:0043C9BB
.text:0043C9BD ; ---------------------------------------------------------------------------
.text:0043C9BD
.text:0043C9BD loc_43C9BD: ; CODE XREF: MmIsAddressValid(x)+41↑j
.text:0043C9BD ; MmIsAddressValid(x)+72↑j
.text:0043C9BD ; MmIsAddressValid(x)+76↑j
.text:0043C9BD ; MmIsAddressValid(x)+8B↑j
.text:0043C9BD ; MmIsAddressValid(x)+8F↑j
.text:0043C9BD mov al, 1
.text:0043C9BD
.text:0043C9BF
.text:0043C9BF loc_43C9BF: ; CODE XREF: MmIsAddressValid(x)+93↑j
.text:0043C9BF pop edi
.text:0043C9C0 pop esi
.text:0043C9C1 leave
.text:0043C9C2 retn 4
.text:0043C9C2
.text:0043C9C2 _MmIsAddressValid@4 endp
Exported entry 685. MmIsAddressValid
.text:0043C928
.text:0043C928 ; =============== S U B R O U T I N E =======================================
.text:0043C928
.text:0043C928 ; Attributes: bp-based frame
.text:0043C928
.text:0043C928 ;
BOOLEAN
__stdcall MmIsAddressValid(
PVOID
VirtualAddress)
.text:0043C928
public
_MmIsAddressValid@4
.text:0043C928 _MmIsAddressValid@4 proc near ; CODE XREF: IopIsAddressRangeValid(x,x)+2F↑p
.text:0043C928 ; IopGetMaxValidMemorySize(x,x)+29↑p
.text:0043C928 ; IoSetDumpRange(x,x,x,x)+56↑p
.text:0043C928 ; IoFreeDumpRange(x,x,x,x)+4C↑p
.text:0043C928 ; IopWriteDriverList(x,x,x,x)+8F↑p
.text:0043C928 ; IopInvokeDumpIoCallbacks(x,x,x)+56↑p
.text:0043C928 ; IopInvokeDumpIoCallbacks(x,x,x)+AB↑p
.text:0043C928 ; sub_41B7E6+13↑p
.text:0043C928 ; KeCapturePersistentThreadState(x,x,x,x,x,x,x,x)+49A↑p
.text:0043C928 ; IopInvokeSecondaryDumpDataCallbacks(x,x,x,x,x,x,x,x,x)+BA↑p
.text:0043C928 ; IopInvokeSecondaryDumpDataCallbacks(x,x,x,x,x,x,x,x,x)+120↑p
.text:0043C928 ; KiPcToFileHeader(x,x,x,x)+2C↑p
.text:0043C928 ; KiDumpParameterImages(x,x,x,x)+7A↑p
.text:0043C928 ; KiScanBugCheckCallbackList()+3C↑p
.text:0043C928 ; KiInvokeBugCheckEntryCallbacks()+50↑p ...
.text:0043C928
.text:0043C928 var_8= dword ptr -8
.text:0043C928 var_4= dword ptr -4
.text:0043C928 VirtualAddress= dword ptr 8
.text:0043C928
.text:0043C928 mov edi, edi
.text:0043C92A push ebp
.text:0043C92B mov ebp, esp
.text:0043C92D push ecx
.text:0043C92E push ecx
.text:0043C92F mov ecx, [ebp+VirtualAddress] ; 取出线性地址
.text:0043C932 push esi
.text:0043C933 mov eax, ecx
.text:0043C935 shr eax, 12h ; 线性地址右移18位,移除了12位物理页偏移和PTI的低6位
.text:0043C938 mov esi, 3FF8h ; 0000 0000 0000 0000 0011 1111 1111 1000
.text:0043C93D and eax, esi ; 与运算后,保留了2位PDPTI和9位PDI。最后3位为0的作用:1.移除PTI的高3位。2.PDI<<3。3.POPTI<<12
.text:0043C93F sub eax, 3FA00000h ; 运算结果 eax = 0xC0600000 + PDPTI*4KB + PDI*8
.text:0043C944 mov edx, [eax] ; edx = PDE低4字节
.text:0043C946 mov eax, [eax+4] ; eax = PDE高4字节
.text:0043C949 mov [ebp+var_4], eax ; 局部变量1 = PDE高4字节
.text:0043C94C mov eax, edx ; eax = PDE低4字节
.text:0043C94E push edi
.text:0043C94F and eax, 1 ; 取出PDE低4字节中的P位
.text:0043C952 xor edi, edi ; edi = 0
.text:0043C954 or eax, edi ; 判断P位是否为0
.text:0043C956 jz
short
loc_43C9B9 ;
if
P==0,则
return
0
.text:0043C956
.text:0043C958 mov edi, 80h ; 1000 0000
.text:0043C95D and edx, edi ; 取出PDE低4字节中的PS位
.text:0043C95F push 0
.text:0043C961 mov [ebp+var_8], edx ; 局部变量2 = PDE低4字节中的PS位
.text:0043C964 pop eax ; eax = 0
.text:0043C965 jz
short
loc_43C96B ; PS位 == 0,跳转到判断小页代码
.text:0043C965
.text:0043C967 test eax, eax ; 判断eax==0
.text:0043C969 jz
short
loc_43C9BD ;
if
PS位 == 1, 则
return
1
.text:0043C969
.text:0043C96B
.text:0043C96B loc_43C96B: ; CODE XREF: MmIsAddressValid(x)+3D↑j
.text:0043C96B shr ecx, 9 ; 线性地址右移9位。
.text:0043C96E and ecx, 7FFFF8h ; 7FFFF8 = 0000 0000 0111 1111 1111 1111 1111 1000
.text:0043C96E ; 与运算后,保留2位PDPTI<<21,9位PDI<<12,9位PTI<<3
.text:0043C974 mov eax, [ecx-3FFFFFFCh] ; ecx-3FFFFFFC = 0xC0000000 + PDPTI*2MB + PDI*4KB + PTI*8; eax = PTE高4字节
.text:0043C97A sub ecx, 40000000h
.text:0043C980 mov edx, [ecx] ; edx = PTE低4字节
.text:0043C982 mov [ebp+var_4], eax ; 局部变量1 = PTE高4字节
.text:0043C985 push ebx
.text:0043C986 mov eax, edx ; eax = PTE低4字节
.text:0043C988 xor ebx, ebx ; ebx = 0
.text:0043C98A and eax, 1 ; 取出PTE低4字节中的P位
.text:0043C98D or eax, ebx ; 判断P位是否为0
.text:0043C98F pop ebx
.text:0043C990 jz
short
loc_43C9B9 ;
if
P == 0, 则
return
0
.text:0043C990
.text:0043C992 and edx, edi ; 判断PTE低4字节中的PAT位
.text:0043C994 push 0
.text:0043C996 mov [ebp+var_8], edx ; 局部变量2 = PAT位
.text:0043C999 pop eax
.text:0043C99A jz
short
loc_43C9BD ;
if
PAT == 0, 则
return
1
.text:0043C99A
.text:0043C99C test eax, eax
.text:0043C99E jnz
short
loc_43C9BD ; 下面代码是PAT == 1的情况
.text:0043C99E
.text:0043C9A0 and ecx, esi ; PTE的低4字节线性地址 and 0000 0000 0000 0000 0011 1111 1111 1000
.text:0043C9A2 mov ecx, [ecx-3FA00000h]
.text:0043C9A8 mov eax, 81h
.text:0043C9AD and ecx, eax
.text:0043C9AF xor edx, edx
.text:0043C9B1 cmp ecx, eax
.text:0043C9B3 jnz
short
loc_43C9BD
.text:0043C9B3
.text:0043C9B5 test edx, edx
.text:0043C9B7 jnz
short
loc_43C9BD
.text:0043C9B7
.text:0043C9B9
.text:0043C9B9 loc_43C9B9: ; CODE XREF: MmIsAddressValid(x)+2E↑j
.text:0043C9B9 ; MmIsAddressValid(x)+68↑j
.text:0043C9B9 xor al, al
.text:0043C9BB jmp
short
loc_43C9BF
.text:0043C9BB
.text:0043C9BD ; ---------------------------------------------------------------------------
.text:0043C9BD
.text:0043C9BD loc_43C9BD: ; CODE XREF: MmIsAddressValid(x)+41↑j
.text:0043C9BD ; MmIsAddressValid(x)+72↑j
.text:0043C9BD ; MmIsAddressValid(x)+76↑j
.text:0043C9BD ; MmIsAddressValid(x)+8B↑j
.text:0043C9BD ; MmIsAddressValid(x)+8F↑j
.text:0043C9BD mov al, 1
.text:0043C9BD
.text:0043C9BF
.text:0043C9BF loc_43C9BF: ; CODE XREF: MmIsAddressValid(x)+93↑j
.text:0043C9BF pop edi
.text:0043C9C0 pop esi
.text:0043C9C1 leave
.text:0043C9C2 retn 4
.text:0043C9C2
.text:0043C9C2 _MmIsAddressValid@4 endp
1. (PDE)线性地址>>18 & 3FF8h - 3FA00000h
.text:0043C935 shr eax, 12h ; 线性地址右移18位,移除了12位物理页偏移和PTI的低6位
.text:0043C938 mov esi, 3FF8h ; 3FF8h = 0000 0000 0000 0000 0011 1111 1111 1000
.text:0043C93D and eax, esi ; 与运算后,保留了2位PDPTI和9位PDI和3位0
3FF8h 最后3位为0的作用:1.移除PTI剩余的高3位。2.PDI<<3 == PDI*8。3.PDPTI<<12 == PDPTI*4KB
eax = PDPTI*4KB + PDI*8
.text:0043C93F sub eax, 3FA00000h ; 运算结果 eax = 0xC0600000 + PDPTI*4KB + PDI*8
2. (PTE)线性地址>>9 & 7FFFF8h - 3FFFFFFCh
.text:0043C96B shr ecx, 9 ; 线性地址右移9位,移除了12位物理页偏移的低9位
.text:0043C96E and ecx, 7FFFF8h ; 7FFFF8 = 0000 0000 0111 1111 1111 1111 1111 1000
.text:0043C96E ; 与运算后,保留2位PDPTI,9位PDI,9位PTI,3位0
7FFFF8h 最后3位为0的作用:
1.移除物理页偏移的高3位。2.PDPTI<<21 == PDPTI*2MB。3.PDI<<12 == PDI*4KB。4.PTI<<3 == PTI*8
.text:0043C974 mov eax, [ecx-3FFFFFFCh] ; PTE高4字节的线性地址 = ecx-3FFFFFFC = 0xC0000000 + PDPTI*2MB + PDI*4KB + PTI*8
.text:0043C97A sub ecx, 40000000h
.text:0043C980 mov edx, [ecx]
上面两条指令等价于 <==> mov edx, [ecx - 3FFFFFFCh - 4]
为什么 [ecx-3FFFFFFCh]是PTE高4字节,[ecx - 3FFFFFFCh - 4] 是PTE低4字节?
首先,当前数据是按照小尾方式存储的,即高字节存储在高地址。
其次,PTE是由8个字节组成,前4个字节是低位,存储在低地址。后4个字节是高位,存在高地址。
-3FFFFFFCh == 0xC0000004,-40000000h == 0xC0000000
所以,[ecx-3FFFFFFCh]是PTE高4字节,[ecx - 3FFFFFFCh - 4] 是PTE低4字节
3.对比分析我的C源码解析PTE线性地址和内核文件中MmIsAddressValid函数有何区别
我的c源码:
// 拆分变量x的线性地址 2-9-9-12分页
int
lineAddress = (
int
)ptr_x;
int
PDPTI_x = lineAddress >> 30;
int
PDI_x = (lineAddress & 0x3FE00000) >> 21;
int
PTI_x = (lineAddress & 0x1FF000) >> 12;
int
offset_x = lineAddress & 0xFFF;
// 获取变量x的pPTE
pPET_x = 0xC0000000 + PDPTI_x * (2 << 21) + PDI_x * (2 << 12) + PTI_x * 8;
MmIsAddressValid函数中的源码:
PDE = 线性地址>>18 & 3FF8h - 3FA00000h
PTE = 线性地址>>9 & 7FFFF8h - 3FFFFFFCh
由此可见,该内核函数全是按位操作和减法运算,性能上要优于我们的C代码。
1. (PDE)线性地址>>18 & 3FF8h - 3FA00000h
.text:0043C935 shr eax, 12h ; 线性地址右移18位,移除了12位物理页偏移和PTI的低6位
.text:0043C938 mov esi, 3FF8h ; 3FF8h = 0000 0000 0000 0000 0011 1111 1111 1000
.text:0043C93D and eax, esi ; 与运算后,保留了2位PDPTI和9位PDI和3位0
3FF8h 最后3位为0的作用:1.移除PTI剩余的高3位。2.PDI<<3 == PDI*8。3.PDPTI<<12 == PDPTI*4KB
eax = PDPTI*4KB + PDI*8
.text:0043C93F sub eax, 3FA00000h ; 运算结果 eax = 0xC0600000 + PDPTI*4KB + PDI*8
赞赏
他的文章
- [原创]未导出函数PspTerminateProcess关闭360 5428
- [原创]超详细的3环和0环断链隐藏分析 13706
- [原创]2-9-9-12分页 4114
- [原创]底层分析C++虚函数、this、多态 10726
- [原创]逆向分析MmIsAddressValid函数2-9-9-12分页 2973
看原图
赞赏
雪币:
留言: