流沙团
TLB实验
2018-3-27 流沙团


0x001 实验环境



xp3



2-9-9-12 分页环境







0x002 时间代码



// 20180327_01.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdio.h>
#include <windows.h>

DWORD zero, one, two;

__declspec(naked)
void MountPageOnNull() {
__asm {
push ebp
mov ebp, esp
sub esp, 0x100
push ebx
push esi
push edi
}

DWORD* pPTE; // 保存目标线性地址的 PTE 线性地址
DWORD* pNullPTE; // 0 地址的 PTE 线性地址
pNullPTE = (DWORD*)0xc0000000;

// 挂上 0x50000000 所在位置
pPTE = (DWORD*)(0xc0000000 + ((0x50000000 >> 9) & 0x7ffff8));
*pNullPTE = *pPTE;

zero = *(DWORD*)0;

// 挂上 0x60000000 所在位置
pPTE = (DWORD*)(0xc0000000 + ((0x60000000 >> 9) & 0x7ffff8));
*pNullPTE = *pPTE;

one = *(DWORD*)0;

// 刷新 TLB
__asm {
mov eax, cr3
mov cr3, eax
}

// 再次读取 0 地址位置的数据
two = *(DWORD*)0;



__asm {
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
iretd
}
}

// 外壳包裹函数
__declspec(naked)
void MyMountPageOnNull() {
__asm {
int 0x20
ret
}
}

int main(int argc, char* argv[])
{
DWORD* x = (DWORD*)VirtualAlloc((LPVOID)0x50000000, 4, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
DWORD* y = (DWORD*)VirtualAlloc((LPVOID)0x60000000, 4, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

*x = 0x12345678;
*y = 0x87654321;

if (x != (DWORD*)0x50000000 || y != (DWORD*)0x60000000) {
printf("Error alloc!\n");
return -1;
}

MyMountPageOnNull();

printf("1. 读 0 地址数据:\n");
printf("*NULL = 0x%08x\n\n", zero);

printf("2. 给 0 地址重新挂上物理页\n\n");


printf("3. 重新读取 0 地址数据:\n");
printf("*NULL = 0x%08x\n\n", one);

printf("4. 刷新 TLB \n\n");

printf("5. 再次读取 0 地址数据:\n");
printf("*NULL = 0x%08x\n", two);


return 0;
}



0x003 实验步骤






  1. 在 main 函数起始位置下断点,在 VC6.0 中观察到函数 MountPageOnNull的函数地址,在我的环境里是 0x00401030。





  2. 构造中断门描述符 0040ee00`00081030





  3. 中断到 WinDbg 中去,执行以下命令安装中断门


    kd> eq 8003f500 0040ee00`00081030



    • 1







  4. 在 WinDbg 中执行命令g 回到 xp 系统中。





  5. 继续执行 VC6.0 中的程序。






0x004 实验结果



360截图20180327114818692.jpg

















发表评论:
昵称

邮件地址 (选填)

个人主页 (选填)

内容