• 一、保护模式


    一、保护模式

    1.1.双机调试

    1.添加debug调试模式

    2.虚拟机设置

    \\.\pipe\com1

    3.windbg

    -y SRV*D:\mysymbol*http://msdl.microsoft.com/download/symbols -b -k com:port=\\.\pipe\com1,baud=115200,pipe

    4.加载符号表

    lm    		 #查看符号有没有下载成功
    
    ld * 		 #加载所有符号表

    1.2.段选择子和段描述符

    windbg

    r gdtr
    
    #d:查看内存   db:一字节  dw:两字节  dd:四字节  dq:八字节
    dq 80b97000   
    
    dq 80b97000 L40   #查看多少项
    
    eq #修改

    段选择子

    ds:0023

    #0023拆分二进制 0000000000100 0 11
    
    RPL:11  			  ->请求特权级别为3
    Ti:0				  ->查找GDT表
    index:0000000000100    ->索引为4,查找GDT表索引为4的段描述符

    段描述符

    段描述符:00cff300`0000ffff

    二进制:00000000 1100 1111 1 11 1 0011 00000000

    P

    P=1:有效
    P=0:无效

    S

    S=0:表示系统段
    S=1:表示代码段或者数据段

    Type

    D/B

    #1.Type为代码段时,这个标志被称为D标志
    D/B为1:表示默认为32位的地址
    D/B为0:表示默认为16位的地址
    
    #2.Type为普通数据段时,这个标志被称为B标志;分为堆栈段和向下扩展的数据段两种情况
    堆栈段
    D/B为1:使用的是32位的栈指针(ESP)
    D/B为0:使用的是16位的栈指针(SP)
    
    向下扩展的数据段
    D/B为1:段地址上限为FFFFFFFF
    D/B为0:段地址上限为FFFFF

    G

    粒度标志
    G=0:段限长以字节为单位
    G=1:段限长以4KB为单位

    AVL和21位

    AVL:  可以被系统软件使用
    21位: 保留,设置位0

    RPL, DPL和CPL

    权限

    RPL:请求的特权级
    DPL:描述符特权级
    CPL:当前特权级

    1.3.调用门

    当段描述符的S标志位0,该描述符为系统描述符

      调用门

     Offset in Segment

    函数的逻辑地址

    Segment Selector

    目标代码段的段选择子(提权)

    Param Count

    参数个数

    调用门实验

    1.vs2008属性修改

    链接器->常规—>启用增量链接->改成“否”
    链接器->高级—>随机基址->改成“禁用”

    2.代码

    // 1.调用门.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include <Windows.h> 
    
    typedef int (__cdecl *DbgPrintX)(_In_z_ _Printf_format_string_ const char * _Format, ...);
    DbgPrintX DbgPrint = NULL;
    char * strtest = "abcdefghijklmn\r\n";
    
    //裸函数
    void _declspec(naked)test()
    {
    	__asm
    	{
    		push fs;
    		push 0x30;
    		pop fs;
    		mov eax,[strtest];
    		push eax;
    		call DbgPrint;
    		add esp,4;   //__cdecl外平栈,压入一个参数
    		pop fs;
    		retf;
    	}
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	char bufcode []= {0,0,0,0,0x48,0};
    	DbgPrint = (DbgPrintX)0x83e2241f;   //u nt!DbgPrint的地址
    	printf("function addr = %x\r\n",test);   //00401000
    
    	system("pause");
    
    	__asm
    	{
    		call fword ptr bufcode;
    	}
    
    	system("pause");
    	return 0;
    }

     打开DebugView,证明已经提权成功

     3.windbg构建调用门描述符

     #函数地址00401000,cs=0008 其它位固定写法
     
    0040EC00`00081000   #构建调用门
    
    r gdtr
    dq 80b97000
    eq 80b97048 0040EC00`00081000

    4.堆栈变化

    #无参 
    
    返回地址
    cs
    esp
    ss
    
    #有参  
    返回地址
    cs
    参数1
    参数2
    esp
    ss

    1.4.中断门

    中断门描述符

    中断门在idt表里面,构建一个类似int 3 功能的中断门描述符

    eq 80b97500 0040ee00`00081000  #构建中断门

    代码

    
    #include "stdafx.h"
    #include <Windows.h> 
    
    void _declspec(naked)test()
    {
    	__asm
    	{
    		int 3;
    		iretd;    //中断门用iretd返回
    	}
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	
    	printf("%x\r\n",test);   //00401000
    	system("pause");
    
    	__asm
    	{
    		int 32;
    		push 0x3b;
    		pop fs;
    	}
        
    	return 0;
    }

     查看堆栈变化dds esp

    #向堆栈中压入五个值
    返回地址
    CS
    EFLAG的IF位
    ESP
    SS

    中断门影响的Eflags位

    中断门会把 VM TF IF NT 四个位置0
    efl = 46

    1.5.劫持int 3

    1.把idt表中int 3位置处的段选择子0008改为0048(找我们自己构建的段描述符)

    2.构建gdt48位置的段描述符

    #base = 函数地址 - int 3的段偏移 
    48位置的base = 00401000 - 83e86c60 = 7C57A3A0

    3.DbgPrint的地址

    4.代码

    // 3.int3劫持.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include <Windows.h>
    
    typedef int (__cdecl *DbgPrintProc)(_In_z_ _Printf_format_string_ const char * _Format, ...);
    DbgPrintProc DbgPrint = NULL;
    char * datouyu = NULL;
    
    void _declspec(naked)test()
    {
    	__asm
    	{
    		sub esp,8;
    		lea eax,haha;
    		mov [esp],eax;
    		mov [esp+4],0x8;
    		jmp fword ptr [esp];
    haha:
    		add esp,8;
    		push fs;
    		push 0x30;
    		pop fs;
    		mov eax,[datouyu];
    		push eax;
    		call DbgPrint;
    		add esp,4
    		pop fs;
    		mov eax,0x83e86c60  ;  //int 3地址
    		jmp eax;
    
    	}
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	printf("%x\r\n",test);   //00401000
    	DbgPrint = (DbgPrintProc)0x83e5741f; //u nt!DbgPrint的地址
    	datouyu = (char *)malloc(30);
    	memset(datouyu,0,30);
    	memcpy(datouyu,"datouyu!\r\n",strlen("datouyu!\r\n"));
    
    	system("pause");
    
    		__asm
    	{
    		int 3;
    
    	}
    	system("pause");
    	return 0;
    }

    1.6.陷进门

    陷进门描述符

    构建陷进门

    eq 80b97500 0040ef00`00081000

    代码

    // 4.陷进门.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include <Windows.h>
    
    int eflags = 0;
    
    void _declspec(naked)test()
    {
    	__asm
    	{
    		pushfd;
    		pop eax;
    		mov [eflags],eax;
    		push fs;
    		push 0x30;
    		pop fs;
    		int 3;
    		pop fs;
    		iretd;
    	}
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	eflags = 0;
    	printf("%x\r\n",test);   //00401000
    	system("pause");
    
    	__asm
    	{
    		int 32;
    	}
        printf("%x\r\n",eflags);
    	system("pause");
    	return 0;
    }

     中断门影响的Eflags位

    陷进门会把 VM TF NT 三个位 置0
    efl = 246

    1.7.任务段

    1.TSS

    2.TSS描述符

    3.操作系统默认的tr为28

     4.查看TSS结构

    kd> dt _KTSS
    ntdll!_KTSS
       +0x000 Backlink         : Uint2B
       +0x002 Reserved0        : Uint2B
       +0x004 Esp0             : Uint4B
       +0x008 Ss0              : Uint2B
       +0x00a Reserved1        : Uint2B
       +0x00c NotUsed1         : [4] Uint4B
       +0x01c CR3              : Uint4B
       +0x020 Eip              : Uint4B
       +0x024 EFlags           : Uint4B
       +0x028 Eax              : Uint4B
       +0x02c Ecx              : Uint4B
       +0x030 Edx              : Uint4B
       +0x034 Ebx              : Uint4B
       +0x038 Esp              : Uint4B
       +0x03c Ebp              : Uint4B
       +0x040 Esi              : Uint4B
       +0x044 Edi              : Uint4B
       +0x048 Es               : Uint2B
       +0x04a Reserved2        : Uint2B
       +0x04c Cs               : Uint2B
       +0x04e Reserved3        : Uint2B
       +0x050 Ss               : Uint2B
       +0x052 Reserved4        : Uint2B
       +0x054 Ds               : Uint2B
       +0x056 Reserved5        : Uint2B
       +0x058 Fs               : Uint2B
       +0x05a Reserved6        : Uint2B
       +0x05c Gs               : Uint2B
       +0x05e Reserved7        : Uint2B
       +0x060 LDT              : Uint2B
       +0x062 Reserved8        : Uint2B
       +0x064 Flags            : Uint2B
       +0x066 IoMapBase        : Uint2B
       +0x068 IoMaps           : [1] _KiIoAccessMap
       +0x208c IntDirectionMap  : [32] UChar

    Previous Task Link存放的是上一个任务的段选择子

    5.在gdt表48位置构建任务段

    eq 80b97048 0000e940`503020ac     #TSS地址为00405030   limit为20ac

    6.代码

    // 5.任务段.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include <Windows.h>
    
    struct _KiIoAccessMap
    {
        UCHAR DirectionMap[32];                                                 //0x0
        UCHAR IoMap[8196];                                                      //0x20
    }; 
    
    typedef struct _KTSS
    {
        USHORT Backlink;                                                        //0x0
        USHORT Reserved0;                                                       //0x2
        ULONG Esp0;                                                             //0x4
        USHORT Ss0;                                                             //0x8
        USHORT Reserved1;                                                       //0xa
        ULONG NotUsed1[4];                                                      //0xc
        ULONG CR3;                                                              //0x1c
        ULONG Eip;                                                              //0x20
        ULONG EFlags;                                                           //0x24
        ULONG Eax;                                                              //0x28
        ULONG Ecx;                                                              //0x2c
        ULONG Edx;                                                              //0x30
        ULONG Ebx;                                                              //0x34
        ULONG Esp;                                                              //0x38
        ULONG Ebp;                                                              //0x3c
        ULONG Esi;                                                              //0x40
        ULONG Edi;                                                              //0x44
        USHORT Es;                                                              //0x48
        USHORT Reserved2;                                                       //0x4a
        USHORT Cs;                                                              //0x4c
        USHORT Reserved3;                                                       //0x4e
        USHORT Ss;                                                              //0x50
        USHORT Reserved4;                                                       //0x52
        USHORT Ds;                                                              //0x54
        USHORT Reserved5;                                                       //0x56
        USHORT Fs;                                                              //0x58
        USHORT Reserved6;                                                       //0x5a
        USHORT Gs;                                                              //0x5c
        USHORT Reserved7;                                                       //0x5e
        USHORT LDT;                                                             //0x60
        USHORT Reserved8;                                                       //0x62
        USHORT Flags;                                                           //0x64
        USHORT IoMapBase;                                                       //0x66
        struct _KiIoAccessMap IoMaps[1];                                        //0x68
        UCHAR IntDirectionMap[32];                                              //0x208c
    }KTSS; 
    
    KTSS tss={0}; 
    
    //申请栈空间
    char bufEsp0[0x2000]={0};
    char bufEsp3[0x2000]={0};
    
    void __declspec(naked) test()
    {
    	__asm
    	{
    		int 3;
    		pushfd;
    		pop eax;
    		or eax,0x4000;   //int 3会把efl的NT位置0,所有这里需要手动把Eflags的NT位置1
    		push eax;
    		popfd;
    		iretd;
    	}
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	//tss.
    	memset(bufEsp0,0,0x2000);
    	memset(bufEsp3,0,0x2000);
    
    	tss.Esp0 = (ULONG)bufEsp0 + 0x1FF0;  //堆栈是从大地址往小地址方向
    	tss.Esp = (ULONG)bufEsp3 + 0x1FF0;
    	tss.Ss0 = 0x10;
    	tss.Ss = 0x10;
    	tss.Cs = 0x8;
    	tss.Ds = 0x23;
    	tss.Es = 0x23;
    	tss.Fs = 0x30;
    	tss.EFlags = 2;
    	tss.Eip = (ULONG)test;
    	tss.IoMapBase = 0x20ac;
    
    	printf("%x\r\n",sizeof(tss));
    	printf("请输入的你的CR3:");
    	DWORD dwCr3 = 0;
    	scanf("%x",&dwCr3);   //输入CR3地址,!process 0 0 查看当前调试程序的cr3
    	tss.CR3 = dwCr3;
    
    	printf("%x\r\n",&tss);   //tss任务段地址
    	system("pause");
    	
    	char bufcode[]={0,0,0,0,0x48,0};   //执行构建的任务段,执行完需要手动修复cr3
    	
    	__asm
    	{
    		call fword ptr bufcode;
    	}
    	system("pause");
    	return 0;
    }

    7.手动修复cr3,使程序能正常返回。执行到打印TSS地址那里,然后进windbg手动修复cr3

    dg 28
    dt _KTSS 801e4000
    ed 801e4000+1c 7edae7a0

    1.8.任务门

    1.任务门

    16-31位是任务段的选择子

    2.代码

    // 6.任务门.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include <Windows.h>
    
    struct _KiIoAccessMap
    {
        UCHAR DirectionMap[32];                                                 //0x0
        UCHAR IoMap[8196];                                                      //0x20
    }; 
    
    typedef struct _KTSS
    {
        USHORT Backlink;                                                        //0x0
        USHORT Reserved0;                                                       //0x2
        ULONG Esp0;                                                             //0x4
        USHORT Ss0;                                                             //0x8
        USHORT Reserved1;                                                       //0xa
        ULONG NotUsed1[4];                                                      //0xc
        ULONG CR3;                                                              //0x1c
        ULONG Eip;                                                              //0x20
        ULONG EFlags;                                                           //0x24
        ULONG Eax;                                                              //0x28
        ULONG Ecx;                                                              //0x2c
        ULONG Edx;                                                              //0x30
        ULONG Ebx;                                                              //0x34
        ULONG Esp;                                                              //0x38
        ULONG Ebp;                                                              //0x3c
        ULONG Esi;                                                              //0x40
        ULONG Edi;                                                              //0x44
        USHORT Es;                                                              //0x48
        USHORT Reserved2;                                                       //0x4a
        USHORT Cs;                                                              //0x4c
        USHORT Reserved3;                                                       //0x4e
        USHORT Ss;                                                              //0x50
        USHORT Reserved4;                                                       //0x52
        USHORT Ds;                                                              //0x54
        USHORT Reserved5;                                                       //0x56
        USHORT Fs;                                                              //0x58
        USHORT Reserved6;                                                       //0x5a
        USHORT Gs;                                                              //0x5c
        USHORT Reserved7;                                                       //0x5e
        USHORT LDT;                                                             //0x60
        USHORT Reserved8;                                                       //0x62
        USHORT Flags;                                                           //0x64
        USHORT IoMapBase;                                                       //0x66
        struct _KiIoAccessMap IoMaps[1];                                        //0x68
        UCHAR IntDirectionMap[32];                                              //0x208c
    }KTSS; 
    
    KTSS tss={0}; 
    
    //申请栈空间
    char bufEsp0[0x2000]={0};
    char bufEsp3[0x2000]={0};
    
    void __declspec(naked) test()
    {
    	__asm
    	{
    		int 3;
    		pushfd;
    		pop eax;
    		or eax,0x4000;   //int 3会把efl的NT位置0,所有这里需要手动把Eflags的NT位置1
    		push eax;
    		popfd;
    		iretd;
    	}
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	//tss.
    	memset(bufEsp0,0,0x2000);
    	memset(bufEsp3,0,0x2000);
    
    	tss.Esp0 = (ULONG)bufEsp0 + 0x1FF0;  //堆栈是从大地址往小地址方向
    	tss.Esp = (ULONG)bufEsp3 + 0x1FF0;
    	tss.Ss0 = 0x10;
    	tss.Ss = 0x10;
    	tss.Cs = 0x8;
    	tss.Ds = 0x23;
    	tss.Es = 0x23;
    	tss.Fs = 0x30;
    	tss.EFlags = 2;
    	tss.Eip = (ULONG)test;
    	tss.IoMapBase = 0x20ac;
    
    	printf("%x\r\n",sizeof(tss));
    	printf("请输入的你的CR3:");
    	DWORD dwCr3 = 0;
    	scanf("%x",&dwCr3);   //输入CR3地址,!process 0 0 查看当前调试程序的cr3
    	tss.CR3 = dwCr3;
    
    	printf("%x\r\n",&tss);   //tss任务段地址
    	system("pause");
    	
    	//char bufcode[]={0,0,0,0,0x48,0};   //执行构建的任务段,执行完需要手动修复cr3
    	
    	__asm
    	{
    		//call fword ptr bufcode;
    		int 32
    	}
    	system("pause");
    	return 0;
    }

    3.构建任务门和调用门

    r gdtr
    dq gdtr
    eq 80b97048 0000e940`50300068   #48位置构建调用门
    
    r idtr
    dq rdtr
    eq 80b97500 0000e500`00480000   #500位置构建任务门

     

    4.修复cr3

    1.9.101012分页

    1.9.1.开启101012分页

    1.打开EasyBCD工具

    添加新条目--名称--添加新条目

    高级设置-->高级-->PAE改为禁用,不执行改为常关

    高级设置-->开发-->勾上在内核调试模式下运行windows

    2.kernel区分

    #C:\Windows\System32
    ntoskrnl.exe:101012分页使用的内核
    ntkrnlpa.exe:29912分页使用的内核

    1.9.2.拆分线性地址

    1.用ce搜索记事本内本,得到线性地址0032E310

    2.拆分线性地址

    #线性地址:0032E310
    0000 0000 0011 0010 1110  0011 0001 0000     #二进制,从后面12位往前拆
    
    #第一个10位,在最前面补两个0,偏移0
    0000 0000 0000   			
    #第二个10位,在最前面补两个0,偏移位32E
    0011 0010 1110   
    #12位,页内偏移310
    0011 0001 0000       

    3.windbg查看物理地址

    #1.查看记事本的cr3
    !process 0 0   查看notepad cr3= 2ce48000
    
    #2.第一个10
    !dd 2ce48000+0*4    #得到地址5bd87867
    
    #3.第二10
    5bd87867 把后面三位去掉补000, 结果:5bd87000
    
    !dd 5bd87000 +32E*4      #得到地址71d34867
    
    #4.12位
    71d34867 把后面三位去掉补000, 结果:71d34000
    
    !db 71d34000+310      #得到物理地址对应的内存数据

    实验

    1.9.3.PDT,PDE,PTT,PTE

    物理页结构

    cr3:是页目录表基址
    PDT:页目录表。每一个元素称为页目录项PDE,总共4K大小。4个字节组成一个元素,总共1024个PDE
    PDE:页目录表项。每个页目录表项指向一个页表PTT
    PTT:页表。每一个元素称为页表项PTE,总共4k大小。4个字节组成一个元素,总共1024个PTE
    PTE:页表项。页表项指向的才是真正的物理页

    1.10.零地址

    实验目的:把A进程的物理页挂到B进程的0地址上,通过远程线程跑起来

    1.0地址执行代码.cpp

    // 07.0地址执行代码.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include <Windows.h>
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	int*x =  NULL;
    	PVOID mem = VirtualAlloc(0,0x100,MEM_COMMIT,PAGE_EXECUTE_READWRITE);  //申请内存
    
    	printf("%x\r\n	",mem);  
    	char bufcode[]=
    	{
    		//硬编码
    		0x6A,0,
    		0x6A,0,
    		0x6A,0,
    		0x6A,0,
    		0xb8,0,0,0,0,
    		0xff,0xd0,
    		0xc2,4,0
    		
    	};
    
    	char user32[]={'u','s','e','r','3','2','.','d','l','l',0};
    	char MessageBoxAA[]={"MessageBoxA"};
    
    	HMODULE hmodule = LoadLibraryA(user32);
    	ULONG messageBox = (ULONG)GetProcAddress(hmodule,MessageBoxAA);
    	*(PULONG)&bufcode[9] = messageBox;
    	memcpy(mem,bufcode,sizeof(bufcode));
    
    	system("pause");
    	
    	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE,3576);  //另一个进程的pid
    
    	HANDLE hThread = CreateRemoteThread(hProcess,NULL,NULL,0,NULL,NULL,NULL);
    	
    	CloseHandle(hThread);
    	system("pause");
    
    	printf("%x\r\n",*x);
    	
    	system("pause");
    	
    	return 0;
    }

    2.test.cpp

    // 07.0地址执行代码.cpp : 定义控制台应用程序的入口点。
    //
    
    
    #include "stdafx.h"
    #include <Windows.h>
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	int*x =  NULL;
    	PVOID mem = VirtualAlloc(0,0x100,MEM_COMMIT,PAGE_EXECUTE_READWRITE);  //申请内存
    
    	printf("%x\r\n	",mem);  
    	char bufcode[]=
    	{
    		//硬编码
    		0x6A,0,
    		0x6A,0,
    		0x6A,0,
    		0x6A,0,
    		0xb8,0,0,0,0,
    		0xff,0xd0,
    		0xc2,4,0
    		
    	};
    
    	char user32[]={'u','s','e','r','3','2','.','d','l','l',0};
    	char MessageBoxAA[]={"MessageBoxA"};
    
    	HMODULE hmodule = LoadLibraryA(user32);
    	ULONG messageBox = (ULONG)GetProcAddress(hmodule,MessageBoxAA);
    	*(PULONG)&bufcode[9] = messageBox;
    	memcpy(mem,bufcode,sizeof(bufcode));
    
    	system("pause");
    	
    	HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE,3576);  //另一个进程的pid
    
    	HANDLE hThread = CreateRemoteThread(hProcess,NULL,NULL,0,NULL,NULL,NULL);
    	
    	CloseHandle(hThread);
    	system("pause");
    
    	printf("%x\r\n",*x);
    	
    	system("pause");
    	
    
    	return 0;
    }

    3.挂物理页

    把A进程的PTE挂到test进程的0地址

    1.11.页属性

    P

    0:表示不在内存中
    1:表示在物理内存中

    R/W

    0:只读
    1:可读可写

    U/S

    0:该页为超级用户权限
    1:该页为普通用户权限

    A

    是否曾经被访问过。

    D

    是否曾经被写入过

    PS

    0:页尺寸为4KB,页目录项指向一个页表
    1:大页,页尺寸为32位寻址的4MB,页目录项指向一个页

    G

    全局页。当一个页被表明为全局,并且CR4中的启用全局页(PGE)标志被置位时,一旦CR3寄存器被
    载入或者发生任务切换,TLB中的页表或者指向页的目录项并不失效。这个标志可以防止使TLB中频繁
    使用的页失效

    1.12.页基址

    1.分析MiIsAddressValid函数

    2.通过上面分析得出结论

    • MiIsAddressValid函数只有一个参数,就是线性地址。

    • 判断一个线性地址是否有效,分大页和不是大页两种情况

    线性地址是否有效
    #大页
    PDE.p=1, PS=1 ,则有效
    
    #不是大页
    PDE.p=1,PS=0, PTE.p=1, PTE.PAT=0 则有效
    • PDE的页基址位C0300000

    #PDE计算
    线性地址右移20位,然后and FFC
    PDE:C0300000+上面的结果
    • PTE的页基址位C0000000

    #PTE计算
    线性地址右移10位,然后and 3FFFFC
    PDE:C0000000+上面的结果

    3.实验证明页基址,拿gdtr当线性地址80b93000

    线性地址:80b93000
    cr3= 7760e000
    ==================================
    !dd 7760e000+202*4    第一个10
    ===================================
    0018a063      把后面三位去掉补000, 结果:0018a000
    !dd 0018a000 +393*4
    ===================================
    00b93163     把后面三位去掉补000, 结果:00b93000
    !dd 00b93000

    用页基址的方式查找

    线性地址:80b93000
    #PDE
    80b93000 >> 20   #右移20得到80b
    80b & FFC    	 #得到808, PDE:C0300000+808
    
    #PTE
    80b93*4 & 3FFFFC   #得到202E4C,PTE:C0000000+202E4C

    1.13.29912分页

    1.13.1.拆分线性地址

    1.用ce搜索记事本内本,得到线性地址002244E8

    2.拆分线性地址

    线性地址:00224 4E8
    0000 0000 0010 0010 1000 
    00	      ->0		
    00 0000 001   ->1
    0 0010 1000   ->24
    4e8                ->4e8
    
    CR3:7edf85c0
    PDPTE
    !dq 7edf85c0+0*8
    
    PDE
    !dq 00000000`653df000+1*8
    
    PTE
    !dq 00000000`23b12000+24*8
    
    物理页
    !dq 80000000`22c70000+4e8

    1.13.2.页基址

    分析MiIsAddressValid函数

    PDE页基址:0xC0600000
    PTE页基址:0XC0000000

    1.13.3.页属性

    #XD位
    XD=1:不可执行
    XD=0:可执行

    1.14.缓存

    1.WC,WB,WT

    WC写组合,从L1拿地址,采用hash加密,一次64个字节
    
    WB(write-back)回写,L1缓存,一次4个字节
    
    WT直写

    2.PAT,PCD,PWT

    PAT(Page Attribute Table)

    1.15.TLB

    验证TLB的存在

    1.申请2个地址,分别赋值
    2.把第一个地址挂在0地址上,然后访问,取出结果保存变量
    3.把第二个地址挂在0地址上,然后访问,取出结果保存变量
    4.观察变量1,变量2的结果有什么不同

    实验

    // 08.TLB.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include <Windows.h>
    
    PUCHAR addr1 = NULL;
    PUCHAR addr2 = NULL;
    ULONG temp1=0,temp2 = 0;
    
    void __declspec(naked) test1()
    {
    	__asm
    	{
    		pushad;
    		pushfd;
    		push 0x30;
    		pop fs;
    	
    		mov eax,[addr1];//线性地址1
    		shr eax,0x9;    //下面三行汇编代码是取PTE,29912分页
    		and eax,0x7ffff8;
    		add eax,0xc0000000;
    		mov ecx,[eax];   //取PTE低4字节
    		mov edx,[eax+4]; //取PTE高4字节
    		or ecx,0x100;    //把PTE的G位改成1
    		mov dword ptr ds:[0xc0000000],ecx;
    		mov dword ptr ds:[0xc0000004],edx;
    		mov eax,dword ptr ds:[0];
    		mov [temp1],eax;
    	
    		//mov eax,cr3;
    		//mov cr3,eax;   //刷新cr3
    
    		mov eax,[addr2];//线性地址2
    		shr eax,0x9;
    		and eax,0x7ffff8;
    		add eax,0xc0000000;
    		mov ecx,[eax];   //取低4字节
    		mov edx,[eax+4]; //取高4字节
    
    		mov dword ptr ds:[0xc0000000],ecx;
    		mov dword ptr ds:[0xc0000004],edx;
    
    		invlpg dword ptr ds:[0]  //清除0地址页的TLB项目
    
    		mov eax,dword ptr ds:[0];
    		mov [temp2],eax;
    
    
    		push 0x3b;
    		pop fs;
    		popfd;
    		popad;
    
    		retf;
    	}
    }
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    
    	addr1 = (PUCHAR)VirtualAlloc(NULL,0x1000,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
    	addr2 = (PUCHAR)VirtualAlloc(NULL,0x1000,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
    	*(PULONG)addr1 = 0x1000;
    	*(PULONG)addr2 = 0x2000;
    
    	temp1 = 0;
    	temp2 = 0;
    
    	printf("addr1 = %x,addr2 = %x,test1=%x\r\n",addr1,addr2,test1);
    	system("pause");
    
    	char bufcode[]={0,0,0,0,0x48,0};   //调佣门
    
    	__asm
    	{
    		call fword ptr bufcode;
    	}
    	system("pause");
    	printf("temp1 = %x,temp2 = %x\r\n",temp1,temp2);
    	system("pause");
    
    	return 0;
    }

    1.16.控制寄存器

    CR2

    保存出现异常的线性地址

    CR0

    PE=1:开启保护模式
    PG=1:开启分页模式
    CD=1:关闭所有缓存
    AM:对齐位
    WP:写保护。wp=0:关闭写保护

    CR4

    PSE:是否允许大页,如果PSE=0,即使PDE.ps=1大页也不生效
    PAE:PAE=0是101012分页,PAE=1是29912分页
    PGE:页表的G位是否有效,如果PGE=0,即使G=1也无效
    SMAP:super mode execute protected #等于1(必须CR0的AM=1),内核(U/S=0)不能执行3环(U/S=1)的代码
    SMEO:super mode access protected  #等于1,内核(U/S=0)不能访问3环(U/S=1)的代码

     

  • 相关阅读:
    JVM命令
    悲观锁与乐观锁
    bean生命周期
    MyBatis面试题
    微服务面试题
    MyCat简介
    十大排序算法
    h5跳转微信公众号关注页面
    Maven项目 配置文件放在resources标记的目录下 却没有打包进target文件
    本机号码一键登录原理与应用
  • 原文地址:https://www.cnblogs.com/derek1184405959/p/16570785.html
Copyright © 2020-2023  润新知