通過程式碼掛上物理頁
給0地址掛上物理頁,吧VirtualAlloc函式開闢的線性地址物理頁給0地址掛上,這樣這兩個線性地址訪問的就是同一個物理頁,
記憶體對映的本質就是相同或者不同程式的兩個線性地址,使用同一個物理頁
這個是2-9-9-12分頁的,如果10-10-12分頁會更簡單,程式碼可以在此基礎上改
這裡我將只提幾個需要注意到的問題
1.memset填充是為了 VirutalAlloc開闢記憶體後,線性地址並不會馬上掛上物理頁,PTE沒有指向物理頁需要注意
2.那個裸函式註釋掉的程式碼需要注意,雖然說要把那個線性地址PDE和PTE給0掛上,但是0本身有PDE而且一張PTT表(
寫可以找到2MB的實體記憶體)異常 而ring3堆疊 在0x0013XXXX 所以ring3堆疊訪問的時候需要依賴0線性地址本身的PDE
一個PDE項可以訪問2MB,0-0x00200000 這段線性地址公有一個PDE,所以如果給0地址掛上PDE直接就掛了,訪問堆疊的指令就全都完了,我除錯了大半天在才發現這第2個錯誤需要大家注意
#include "stdafx.h"
#include <Windows.h>
typedef struct AddresSegment{
DWORD PDPI;
DWORD PDEI;
DWORD PTEI;
}ADDRESSSEGMENT;
//將目標線性地址開始的一個頁,掛到源地址上上
typedef struct PageAttrib{
DWORD PTELOW;
DWORD PTEHIGH;
DWORD PDELOW;
DWORD PDEHIGH;
DWORD SrcAddress; //源地址線性地址
DWORD DestAddress; //目標線性地址
DWORD PDESrcAddress;
DWORD PTESrctAddress;
DWORD PDEDestAddress;
DWORD PTEDestAddress;
ADDRESSSEGMENT DestSeg;
ADDRESSSEGMENT SrcSeg;
}PAGEATTRIB;
PAGEATTRIB Page;
void InitAddress(){
Page.DestAddress=0x10000000;
Page.SrcAddress=0x0;
Page.DestSeg.PDPI =((Page.DestAddress&0xC0000000)>>30);
Page.DestSeg.PDEI =((Page.DestAddress&0x3FE00000)>>21); //0011 1111 1110
Page.DestSeg.PTEI =((Page.DestAddress&0x001FF000)>>12);
Page.SrcSeg.PDPI =((Page.SrcAddress&0xC0000000)>>30);
Page.SrcSeg.PDEI =((Page.SrcAddress&0x3FE00000)>>21);
Page.SrcSeg.PTEI =((Page.SrcAddress&0x001FF000)>>12);
Page.PDESrcAddress =0xC0600000+((Page.SrcAddress>>18)&0x3FF8);
Page.PTESrctAddress=0xC0000000+((Page.SrcAddress>>9)&0x7ffff8);
Page.PDEDestAddress=0xC0600000+((Page.DestAddress>>18)&0x3FF8);
Page.PTEDestAddress=0xC0000000+((Page.DestAddress>>9)&0x7ffff8);
}
void _declspec(naked) print(){
__asm{
pushad
pushfd
mov eax,dword ptr ds:[Page.PDEDestAddress]
mov ecx,dword ptr ds:[Page.PTEDestAddress]
mov ebx,[eax]
mov edx,[eax+4]
mov dword ptr ds:[Page.PDELOW],ebx
mov dword ptr ds:[Page.PDEHIGH],edx //獲得目標 物理頁 PDE
mov ebx,[ecx]
mov edx,[ecx+4]
mov dword ptr ds:[Page.PTELOW],ebx
mov dword ptr ds:[Page.PTEHIGH],edx
#if 0
mov eax,Page.PDELOW
mov ecx,Page.PDEHIGH
mov edx,Page.PDESrcAddress
mov dword ptr ds:[edx],eax
mov dword ptr ds:[edx+4],ecx
#endif
mov eax,Page.PTELOW
mov ecx,Page.PTEHIGH
mov edx,Page.PTESrctAddress
mov dword ptr ds:[edx],eax
mov dword ptr ds:[edx+4],ecx
popfd
popad
retf
}
}
int main(int argc, char* argv[])
{
char buf[6];
char* Addr=(char*)VirtualAlloc((void*)0x10000000,0x1000,MEM_RESERVE | MEM_COMMIT,PAGE_READWRITE);
if(NULL==Addr){
MessageBox(0,0,"開闢記憶體失敗",0);
}
memset(Addr,0x66,0x1000);
*(WORD*)&buf[4]=0x48;
InitAddress();
printf("Address=%p\n",print);
__asm{
call fword ptr buf;
mov ax,0x3b
mov fs,ax
}
int* p=NULL;
*p=0x1231435;
printf("Hello World!\n");
return 0;
}
相關文章
- 防止別人通過框架引用本站頁面程式碼框架
- jQuery語法高亮外掛,程式碼著色,頁面程式碼著色jQuery
- 通過RMAN Duplicate建立Oracle物理standby備庫Oracle
- Chrome瀏覽器恢復通過backspace返回上一頁面Chrome瀏覽器
- 通過Mac遠端除錯iPhone/iPad上的網頁Mac除錯iPhoneiPad網頁
- js返回上一頁程式碼例項JS
- JavaScript返回上一頁程式碼區別JavaScript
- 通過crontab更改DataGuard物理庫managed recover狀態
- 使用Megacli64對伺服器物理磁碟做Raid並通過uuid方式掛載伺服器AIUI
- Delphi通過IE視窗控制程式碼獲取網頁介面(IWebBrowser2)網頁Web
- oracle儲存過程分頁程式碼Oracle儲存過程
- 通過js引用外部指令碼(嘿嘿,方便直接在瀏覽器上除錯抓取程式碼)JS指令碼瀏覽器除錯
- 將jive掛載主頁上,透過session傳遞使用者資訊Session
- 通過釘釘網頁上的js學習xss打cookie網頁JSCookie
- [禁止chrome頁面翻譯程式碼塊]chrome外掛Chrome
- 點選返回上一頁程式碼例項
- jquery實現的通過左右方向鍵控制翻頁效果程式碼例項jQuery
- 通過ajax上傳excelExcel
- ORACLE高效分頁儲存過程程式碼Oracle儲存過程
- Java通過URLClassLoader讓程式支援外掛擴充套件(轉載)Java套件
- python+selenium 通過新增cookies或token解決網頁上驗證碼登入問題PythonCookie網頁
- windows上通過IDA遠端除錯linux程式Windows除錯Linux
- 通過行為引數化傳遞程式碼
- [轉載] python通過反射執行程式碼Python反射行程
- Android通過程式碼修改圖片顏色Android
- 通過一行程式碼學習javascript行程JavaScript
- 通過論壇實現登陸的程式碼
- 角色推動物理模型的程式碼模型
- Qt通過Http上傳檔案(路過)QTHTTP
- 通過程式找sqlSQL
- 在linux上通過ssh直接登入到windows系統上,不用密碼LinuxWindows密碼
- 如何透過Python程式碼旋轉PDF頁面Python
- asp.net利用儲存過程分頁程式碼ASP.NET儲存過程
- 天氣預報外掛程式碼--通過傳遞城市拼音名,最簡單的天氣外掛--更多看2345網站網站
- 詳解Dart中如何通過註解生成程式碼Dart
- XSS挑戰之旅(通過看程式碼解題)
- javascript通過class屬性獲取元素的程式碼JavaScript
- Linux下通過原始碼編譯安裝程式Linux原始碼編譯