11_零地址读写

原理: 修改 进程空间 虚拟 零地址 的 pte 为 一个当前程序的全局变量;这样 零地址 指向的就是 同一个物理页且属性相同;修改 一个虚拟地址数据;另外的虚拟地址数据同样会改变。

1570372942798[4]

注意: 中间加阴影的部分 是为了刷新 TLB 快表,后面章节有详解。

 

测试结果:

这里不知道为什么printf时候 我的 exception handler 4 检测异常;导致输出不了;但是的确0页 映射到了 和全局变量同一个物理页。

1570414079132[4]

代码:

// 5_进程空间虚拟零地址读写.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//#include "pch.h"
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>#define PTE(x) ((DWORD *)(0xc0000000 + ((x>> 12)<< 3)))
#define PDE(x) ((DWORD *)(0xc0600000 + ((x >> 21) << 3)))
//0x4197b0
DWORD g_var = 0x12345678;
DWORD g_out;
//0x401040
void _declspec(naked) IdtEntry()
{
​
    PTE(0)[0] = PTE(0x4197b0)[0] ;
    PTE(0)[1] = PTE(0x4197b0)[1];
    __asm {
        mov eax, cr3
        mov cr3, eax
    }
    g_out = *(DWORD*)0x7b0;
    *(DWORD*)0x7b0 = 0x11111111;
    
    __asm {
        // 问题 所在 ,, fs 出错了 ,既然这里可以复制过去能成功;那么应该是前面的 修改 导致了fs 错误。
        push 0x3b;
        pop fs;
        iretd
    }
}
void  _declspec(naked) go()
{
    g_var = 0x2222222;
    __asm {
        int 0x20
        ret
    }
}
//eq 8003f500 0040ee00 081000
void main()
{
    if ((DWORD)IdtEntry != 0x401040)
    {
        printf("wrong addr: sp", IdtEntry);
        exit(-1);
    }
    go();
    //printf("out: %p\n", * (DWORD*)0x403000);printf("var: %d\n", 0x1);
    printf("var: %p\n", g_var);
    printf("out: %p\n", g_out);
    printf("var: %p\n", *(DWORD *)(0x4197b0));
    system(" pause");
}
​
​
//#include "pch.h"
#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>#define PTE(x) ((DWORD *)(0xc0000000 + ((x>> 12)<< 3)))
#define PDE(x) ((DWORD *)(0xc0600000 + ((x >> 21) << 3)))
//0x4197b0
DWORD g_var = 0x12345678;
DWORD g_out;
//0x401040
void _declspec(naked) IdtEntry()
{
​
    PTE(0)[0] = PTE(0x4197b0)[0] ;
    PTE(0)[1] = PTE(0x4197b0)[1];
    __asm {
        mov eax, cr3
        mov cr3, eax
    }
    g_out = *(DWORD*)0x7b0;
    *(DWORD*)0x7b0 = 0x11111111;
    
    __asm {
        // 问题 所在 ,, fs 出错了 ,既然这里可以复制过去能成功;那么应该是前面的 修改 导致了fs 错误。
        push 0x3b;
        pop fs;
        iretd
    }
}
void  _declspec(naked) go()
{
    g_var = 0x2222222;
    __asm {
        int 0x20
        ret
    }
}
//eq 8003f500 0040ee00 081000
void main()
{
    if ((DWORD)IdtEntry != 0x401040)
    {
        printf("wrong addr: sp", IdtEntry);
        exit(-1);
    }
    go();
    //printf("out: %p\n", * (DWORD*)0x403000);printf("var: %d\n", 0x1);
    printf("var: %p\n", g_var);
    printf("out: %p\n", g_out);
    printf("var: %p\n", *(DWORD *)(0x4197b0));
    system(" pause");
}
​
​

 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值