亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
12下一頁
最近訪問板塊 發(fā)新帖
查看: 19729 | 回復(fù): 19
打印 上一主題 下一主題

在內(nèi)核窺視用戶態(tài) [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2010-08-07 10:39 |只看該作者 |倒序?yàn)g覽
在內(nèi)核窺視用戶態(tài)

首先,環(huán)境:VMware Server上運(yùn)行的ubuntu10.4,arch為x86_64。


先看下面這個(gè)程序:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>


  4. int dataA;
  5. char bufA[1000];

  6. int main()
  7. {
  8.         int dataB;

  9.         int i_GetChar;

  10.         char * bufB = NULL;

  11.         bufB = malloc(1500);

  12.         if (NULL == bufB)
  13.         {
  14.                 printf("malloc failed\n");

  15.                 return 0;
  16.         }

  17.         dataA = 0X55aa;

  18.         dataB = 0Xaa55;

  19.         memcpy(bufA, "bufA org data", strlen("bufA org data"));

  20.         memcpy(bufB, "bufB org data", strlen("bufB org data"));

  21.         printf("bufA = %p, bufB = %p, &dataA = %p, &dataB = %p\n", bufA, bufB, &dataA, &dataB);
  22.        

  23.         for ( ; ; )
  24.         {
  25.                 printf("get char(p:print; e:exit):");
  26.                
  27.                 i_GetChar = getchar();

  28.                 if ('p' == i_GetChar)
  29.                 {
  30.                         printf("bufA: %s\n", bufA);
  31.                         printf("bufA: %s\n", bufB);
  32.                         printf("dataA: 0x%x\n", dataA);
  33.                         printf("dataA: 0x%x\n", dataB);
  34.                 }
  35.                 else if ('e' == i_GetChar)
  36.                 {
  37.                         break;
  38.                 }
  39.         }

  40.         free(bufB);
  41.        
  42.         return 0;
  43. }
復(fù)制代碼
這個(gè)程序中有:
一個(gè)int型的全局變量dataA;
一個(gè)int型的局部變量dataB;
一個(gè)char型的全局?jǐn)?shù)組bufA;
一段malloc的空間bufB。

程序先輸出以上變量的地址,然后按"p"輸出一次內(nèi)容,按"e"退出程序。



接下來,簡單的分析一下:
bufA = 0x601080, bufB = 0x6a0010, &dataA = 0x601468, &dataB = 0x7fff337284ac
僅從地址上看,他們就在不同的內(nèi)存區(qū)域。
bufA和dataA是全局變量,在數(shù)據(jù)區(qū);
bufB是malloc來的,在堆中;
dataB是局部變量,在進(jìn)程的運(yùn)行棧中。

抄一段linux自帶的關(guān)于x86_64下地址空間的說明:
0000000000000000 - 00007fffffffffff (=47 bits) user space, different per mm
hole caused by [48:63] sign extension
ffff800000000000 - ffff80ffffffffff (=40 bits) guard hole
ffff880000000000 - ffffc7ffffffffff (=64 TB) direct mapping of all phys. memory
ffffc80000000000 - ffffc8ffffffffff (=40 bits) hole
ffffc90000000000 - ffffe8ffffffffff (=45 bits) vmalloc/ioremap space
ffffe90000000000 - ffffe9ffffffffff (=40 bits) hole
ffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB)
... unused hole ...
ffffffff80000000 - ffffffffa0000000 (=512 MB)  kernel text mapping, from phys 0
ffffffffa0000000 - fffffffffff00000 (=1536 MB) module mapping space


可見,這些變量的地址都在user space中。

對各個(gè)用戶態(tài)進(jìn)程來說,地址空間都是0000000000000000 - 00007fffffffffff,而不會(huì)沖突;
因?yàn)檫@只是虛擬地址,每個(gè)用戶態(tài)進(jìn)程都擁有自身的頁表,相同的虛擬地址地址經(jīng)過不同的頁表轉(zhuǎn)換為不同的物理地址;
而內(nèi)核的頁表并不映射user space,這些后面會(huì)用到。

評分

參與人數(shù) 1可用積分 +30 收起 理由
T-Bagwell + 30 精品文章

查看全部評分

論壇徽章:
0
2 [報(bào)告]
發(fā)表于 2010-08-07 10:41 |只看該作者
本帖最后由 zyr-linux 于 2010-08-07 10:48 編輯

內(nèi)核中,每個(gè)進(jìn)程有個(gè)結(jié)構(gòu)體存放相關(guān)信息:struct task_struct;
struct task_struct內(nèi)容很多,現(xiàn)在只找和內(nèi)存資源相關(guān)的struct mm_struct *mm;

struct mm_struct中內(nèi)容很多也很多,目前關(guān)心的是下面幾個(gè):
1,保存了進(jìn)程使用的各個(gè)地址區(qū)域(vma)的struct vm_area_struct * mmap;;
2,保存了進(jìn)程頁表的位置的pgd_t * pgd;
3,保存進(jìn)程堆/棧/數(shù)據(jù)區(qū)/代碼區(qū)地址的一大堆東東
        unsigned long total_vm, locked_vm, shared_vm, exec_vm;
        unsigned long stack_vm, reserved_vm, def_flags, nr_ptes;
        unsigned long start_code, end_code, start_data, end_data;
        unsigned long start_brk, brk, start_stack;
        unsigned long arg_start, arg_end, env_start, env_end;

把他們?nèi)看虺鰜砜纯春昧耍?br />


bufA和dataA在數(shù)據(jù)區(qū);bufB是malloc來的,在堆之中;dataB是局部變量,在棧之中。
和理論分析一致!
更重要的是,用戶態(tài)下輸出的地址和內(nèi)核態(tài)下得到的地址范圍對的上,那么,這些地址就是虛擬地址。

把頁表的第四級打出來,看看。
說明一下,下面兩張圖是補(bǔ)截的,地址和其他圖不能完全對上。




再和內(nèi)核的頁表第四級對比,可以看出什么?

論壇徽章:
0
3 [報(bào)告]
發(fā)表于 2010-08-07 10:45 |只看該作者
本帖最后由 zyr-linux 于 2010-08-07 10:54 編輯

現(xiàn)在,我們知道了這些變量的虛擬地址,是不是就能直接在內(nèi)核態(tài)下操作了呢?
實(shí)踐的結(jié)果是————OOPS……
因?yàn)椋脩魬B(tài)進(jìn)程的虛擬地址,其轉(zhuǎn)換是通過該進(jìn)程的頁表進(jìn)行,內(nèi)核的頁表沒有這些地址的信息。

不過已經(jīng)知道了頁表的位置,自己轉(zhuǎn)一遍:




得到了物理地址,再加上PAGE_OFFSET獲得內(nèi)核態(tài)下能夠操作的虛擬地址,把內(nèi)容打出來驗(yàn)證:



最后,嘗試修改:



每改一次,在用戶態(tài)程序上驗(yàn)證一次,結(jié)果符合預(yù)期:



以上只是一個(gè)簡單的嘗試,因?yàn)樵谝婚_始就獲得了用戶態(tài)進(jìn)程中各個(gè)變量的地址;
獲得了一個(gè)用戶態(tài)進(jìn)程的堆、棧、數(shù)據(jù)段、代碼段的地址,并能轉(zhuǎn)換為可在內(nèi)核態(tài)下操作的地址;
那么,理論上,可以對該用戶態(tài)進(jìn)程做任何事。
但要想實(shí)用,還需要進(jìn)一步的研究,比如通過反編譯,objdump之類的手段獲得用戶態(tài)程序中的地址。

論壇徽章:
0
4 [報(bào)告]
發(fā)表于 2010-08-08 11:49 |只看該作者
呵呵,大贊!

論壇徽章:
1
2015年辭舊歲徽章
日期:2015-03-03 16:54:15
5 [報(bào)告]
發(fā)表于 2010-08-11 09:27 |只看該作者
好東東哦

論壇徽章:
0
6 [報(bào)告]
發(fā)表于 2011-09-09 17:12 |只看該作者
樓主關(guān)鍵地方代碼也貼出來給我們學(xué)習(xí)學(xué)習(xí)阿

論壇徽章:
0
7 [報(bào)告]
發(fā)表于 2011-09-09 17:48 |只看該作者
是的不錯(cuò)的。

論壇徽章:
0
8 [報(bào)告]
發(fā)表于 2012-01-13 23:35 |只看該作者
回復(fù) 1# zyr-linux


    能否把程序代碼發(fā)到我的郵箱?rickcheung@foxmail.com
    多謝啦!

論壇徽章:
0
9 [報(bào)告]
發(fā)表于 2012-01-14 02:12 |只看該作者
:wink: 看得不太懂

論壇徽章:
0
10 [報(bào)告]
發(fā)表于 2012-01-16 10:38 |只看該作者
查找頁表,轉(zhuǎn)換地址的代碼,linux源代碼中有現(xiàn)成的,不過我習(xí)慣了自己寫。
  1. //進(jìn)行轉(zhuǎn)換是傳遞信息的結(jié)構(gòu)體
  2. struct PGT_TansInfo
  3. {
  4.         //地址信息
  5.         unsigned long ul_Vaddr;    //虛擬地址
  6.         unsigned long ul_Paddr;    //物理地址

  7.         //頁表信息       
  8.         pgd_t * pst_Level4Table;         //頁表位置
  9.         unsigned long ul_PageSize;       //頁大小
  10.         struct PGT_Level_Info astLevel[PGT_LEVEL_BULL];

  11. };

  12. /******************************************************************************

  13. 函數(shù): int PgtOp_VaddrTrans(struct PGT_TansInfo * vpst_TansInfo)

  14. 功能: 地址轉(zhuǎn)換函數(shù)

  15. 輸入: 1) struct PGT_TansInfo * vpst_TansInfo: 轉(zhuǎn)換信息結(jié)構(gòu)體指針
  16.              
  17. 輸出: 成功返回0,失敗返回非0

  18. 備注: 轉(zhuǎn)換虛擬地址為物理地址,并紀(jì)錄轉(zhuǎn)換中信息
  19.              可用于檢查虛擬地址是否正確

  20. ******************************************************************************/
  21. int MemTool_VaddrTrans(struct PGT_TansInfo * vpst_TansInfo)
  22. {
  23.         unsigned long ul_Index;
  24.        
  25.         unsigned long * aul_Talbe = NULL;

  26.         //參數(shù)檢查并賦值
  27.         if ((NULL == vpst_TansInfo) || (NULL == vpst_TansInfo->pst_Level4Table))
  28.         {
  29.                 printk("vpst_TansInfo or pst_Level4Table is NULL!\n");
  30.                 return -1;
  31.         }

  32.         //X86_64中,虛擬地址前17bit一致
  33.         if ((0 != (vpst_TansInfo->ul_Vaddr & MEMTOOL_ADDR_HEAD_MASK))
  34.                  && (MEMTOOL_ADDR_HEAD_MASK != (vpst_TansInfo->ul_Vaddr & MEMTOOL_ADDR_HEAD_MASK)))
  35.         {
  36.                 printk("vaddr 0x%lx is error!\n", vpst_TansInfo->ul_Vaddr);
  37.                 return -1;
  38.         }

  39.         aul_Talbe = (unsigned long *)vpst_TansInfo->pst_Level4Table;


  40.         //查找第四級頁表

  41.         ul_Index = pgd_index(vpst_TansInfo->ul_Vaddr);

  42.         if (0 == vpst_TansInfo->pst_Level4Table[ul_Index].pgd)
  43.         {
  44.                 return -1;
  45.         }
  46.         else
  47.         {
  48.                 vpst_TansInfo->astLevel[PGT_LEVEL_LV4].ul_TableAddr = (unsigned long)aul_Talbe;       
  49.                 vpst_TansInfo->astLevel[PGT_LEVEL_LV4].ul_Index = ul_Index;
  50.                 vpst_TansInfo->astLevel[PGT_LEVEL_LV4].ul_Value = aul_Talbe[ul_Index];
  51.         }

  52.        
  53.         //查找第三級頁表
  54.         aul_Talbe = (unsigned long *)(PAGE_OFFSET + ((aul_Talbe[ul_Index] & PAGE_MASK) & MEMTOOL_ADDR_NX_MASK));

  55.         ul_Index = pud_index(vpst_TansInfo->ul_Vaddr);

  56.         if (0 == aul_Talbe[ul_Index])
  57.         {
  58.                 return -1;
  59.         }
  60.         else
  61.         {
  62.                 vpst_TansInfo->astLevel[PGT_LEVEL_PGD].ul_TableAddr = (unsigned long)aul_Talbe;       
  63.                 vpst_TansInfo->astLevel[PGT_LEVEL_PGD].ul_Index = ul_Index;
  64.                 vpst_TansInfo->astLevel[PGT_LEVEL_PGD].ul_Value = aul_Talbe[ul_Index];


  65.                 //判斷是不是1GB頁
  66.                 if (0 != (_PAGE_PAT & aul_Talbe[ul_Index]))
  67.                 {
  68.                         vpst_TansInfo->ul_PageSize = PGT_PAGESIZE_1G;

  69.                         //取物理地址
  70.                         vpst_TansInfo->ul_Paddr = ((aul_Talbe[ul_Index] & PUD_MASK) & MEMTOOL_ADDR_NX_MASK)
  71.                                                   + (vpst_TansInfo->ul_Vaddr & (PUD_SIZE - 1));

  72.                         return 0;
  73.                 }
  74.         }

  75.         //查找第二級頁表
  76.         aul_Talbe = (unsigned long *)(PAGE_OFFSET + ((aul_Talbe[ul_Index] & PAGE_MASK) & MEMTOOL_ADDR_NX_MASK));

  77.         ul_Index = pmd_index(vpst_TansInfo->ul_Vaddr);

  78.         if (0 == aul_Talbe[ul_Index])
  79.         {
  80.                 return -1;
  81.         }
  82.         else
  83.         {
  84.                 vpst_TansInfo->astLevel[PGT_LEVEL_PMD].ul_TableAddr = (unsigned long)aul_Talbe;       
  85.                 vpst_TansInfo->astLevel[PGT_LEVEL_PMD].ul_Index = ul_Index;
  86.                 vpst_TansInfo->astLevel[PGT_LEVEL_PMD].ul_Value = aul_Talbe[ul_Index];
  87.         }

  88.         //判斷4K頁還是2MB頁
  89.         if (0 == (_PAGE_PAT & aul_Talbe[ul_Index]))
  90.         {
  91.                 //4K頁,查找第一級頁表
  92.                
  93.                 aul_Talbe = (unsigned long *)(PAGE_OFFSET + ((aul_Talbe[ul_Index] & PAGE_MASK) & MEMTOOL_ADDR_NX_MASK));
  94.                
  95.                 ul_Index = pte_index(vpst_TansInfo->ul_Vaddr);

  96.                 if (0 == aul_Talbe[ul_Index])
  97.                 {
  98.                         return -1;
  99.                 }
  100.                 else
  101.                 {
  102.                         vpst_TansInfo->astLevel[PGT_LEVEL_PTE].ul_TableAddr = (unsigned long)aul_Talbe;       
  103.                         vpst_TansInfo->astLevel[PGT_LEVEL_PTE].ul_Index = ul_Index;
  104.                         vpst_TansInfo->astLevel[PGT_LEVEL_PTE].ul_Value = aul_Talbe[ul_Index];

  105.                         vpst_TansInfo->ul_PageSize = PGT_PAGESIZE_4K;

  106.                         //取物理地址
  107.                         vpst_TansInfo->ul_Paddr = ((aul_Talbe[ul_Index] & PAGE_MASK) & MEMTOOL_ADDR_NX_MASK)
  108.                                                   + (vpst_TansInfo->ul_Vaddr & (PAGE_SIZE - 1));

  109.                 }
  110.        
  111.         }
  112.         else
  113.         {
  114.                 vpst_TansInfo->ul_PageSize = PGT_PAGESIZE_2M;
  115.                 //取物理地址
  116.                 vpst_TansInfo->ul_Paddr = ((aul_Talbe[ul_Index] & PMD_MASK)& MEMTOOL_ADDR_NX_MASK)
  117.                                           + (vpst_TansInfo->ul_Vaddr & (PMD_SIZE - 1));
  118.         }

  119.         return 0;

  120. }
復(fù)制代碼
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP