12.进程挂靠
進程與線程的關系:
一個逃程可以包含多個線程
一個進程至少要有一個線程
進程為線程提供資源,也就是提供Cr3的值, Cr3中存儲的是頁目錄表基址, Cr3確定了,線程能訪問的內存也就確定了。
進程與線程的關系
線程代碼:
mov eax, dword ptr ds:(0x12345678]
CPU如何解析0x12345678這個地址呢?
線程與進程如何關聯
ETHREAD結構體:
...+0x034 ApcStateI ...+0x000 ApcListHead+0x010 Process+0x014 KernelApclnProgress +0x015 KernelApcPending +0x016 UserApcPending... +0x220 ThreadsProcess//指向此線程所屬的進程...KTHREAD:+0x34 ApcState
kd> dt _KAPC_STATE nt!_KAPC_STATE+0x000 ApcListHead : [2] _LIST_ENTRY+0x010 Process : Ptr32 _KPROCESS//指向此線程所屬的進程+0x014 KernelApcInProgress : UChar+0x015 KernelApcPending : UChar+0x016 UserApcPending : UChar養父母負責提供Cr3
線程切換的時候,會比較_KTHREAD結構體0x044處指定的EPROCESS是否為同一個,如果不是同一個,會將0x044處指定的EPROCESS的DirectoryTableBase的值取出,賦值給Cr3。
所以,線程需要的Cr3的值來源于0x044處偏移指定的EPROCESS。
總結:
0x220親生父母:這個線程誰創建的
0x044養父母:誰在為這個線程提供資源(也就是提供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的值改為其他進程,稱為進程掛靠
分析NtReadVirtualMemory函數
核心代碼就在這函數中
真正COPY的函數
可不可以只修改Cr3而不修改養父母?不可以,如果不修改養父母的值,一旦產生線程切換,就會變成自己讀自己!
如果我們自己來寫這個代碼,在切換Cr3后關閉中斷,并且不調用會導致線程切換的api,就可以不用修改養父母的值。
總結:
正常情況下,當前線程使用的Cr3是由其所屬進程提供的(ETHREAD 0x44偏移處指定的EPROCESS),正是因為如此, A進程中的線程只能訪問A的內存。
如果要讓A進程中的線程能夠訪問B進程的內存,就必須要修改Cr3的值為B進程的頁目錄表基址(B.DirectoryTableBase),這就是所謂的 進程掛靠.
總結
- 上一篇: 11.Windows线程切换_线程优先级
- 下一篇: 13.跨进程读写内存