11 進程掛靠

1、進程跟線程之間的關係
mov eax,dword ptr ds:[0x12345678]
CPU如何解析0x12345678這個線性地址呢?
<1>CPU解析線性地址時要通過頁目錄表來找對應的物理頁,頁目錄表基址存在Cr3中
<2>當前Cr3的值來源與當前進程(_KPROCESS+0x018 DirectoryTableBase : [2] Uint4B)

2、線程與進程如何關聯
ETHREAD結構體
+0x220 ThreadsProcess : Ptr32 _EPROCESS
以上屬性存儲了該線程屬於哪個進程
在KTHREAD有個子結構體_KAPC_STATE
kd> dt _KAPC_STATE
ntdll!_KAPC_STATE
+0x000 ApcListHead : [2] _LIST_ENTRY
+0x010 Process : Ptr32 _KPROCESS
+0x014 KernelApcInProgress : UChar
+0x015 KernelApcPending : UChar
+0x016 UserApcPending : UChar
以上也存儲了當前線程所屬進程

3、養父母負責提供Cr3
線程切換時,會比較_KTHREAD結構體0x44指定的EPROCESS是否爲同一個,如果不是同一個,會將0x44指定的EPROCESS結構體中DirectoryTableBase取出來賦值給Cr3
所以,線程需要的Cr3的值0x44處的EPROCESS
此處從SwapContext中得知的
cmp eax, [esi+44h]
總結:
0x220親生父母:這個線程誰創建的
0x44養父母:誰在爲這個線程提供資源(也就是提供Cr3)
一般情況下,0x220和0x44指向的是同一個進程

4、Cr3的值可以隨便改嗎
通常情況下,Cr3的值是由養父母提供的,但Cr3的值也可以改成和當前線程毫不相關的其他進程的DirectoryTableBase
mov Cr3,A.DirectoryTableBase
mov eax,dword ptr ds:[0x12345678] //A進程裏的0x12345678
mov Cr3,B.DirectoryTableBase
mov eax,dword ptr ds:[0x12345678] //B進程裏的0x12345678
mov Cr3,C.DirectoryTableBase
mov eax,dword ptr ds:[0x12345678] //C進程裏的0x12345678
當Cr3的值改成其他進程的值,稱爲進程掛靠
進程掛靠的目的是爲了當前的進程能夠訪問其他進程裏的內存空間

5、分析NtReadVirtualMemory()函數
NtReadVirtualMemory–>KiAttachProcess–>修改養父母–>修改Cr3
可不可以只修改Cr3不修改養父母?不可以,如果不修改養父母的值,如果發生線程切換,就會變成自己讀自己
如果我們自己寫代碼,在切換Cr3後關閉中斷,並且不調用會導致線程切換的API,就可以不用修改養父母。

6、總結:
正常情況下當前線程使用的Cr3是由所屬進程提供的(ETHREAD 0X44偏移處指定的EPROCESS),正因爲如此,A進程的線程只能訪問A的內存
如果要讓A進程中的線程能夠訪問B進程的內存,就必須修改Cr3的值爲B進程的頁目錄表基址(B.DirectoryTableBase),這就是所謂的進程掛靠

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章