首頁 資料庫 mysql教程 浅谈NT下Ring3无驱进入Ring0的汇编实现

浅谈NT下Ring3无驱进入Ring0的汇编实现

Jun 07, 2016 pm 03:05 PM
實現 文章 彙編 進入

文章作者:hopy(Kf2b@msn.com) 信息来源:邪恶八进制信息安全团队(www.eviloctal.com) 注意:本文章首发hopy.blogchina.com和blog.csdn.net/mydo,后由与原创作者友情提交到邪恶八进制信息安全团队技术论坛。 关键字:NT,Ring0,无驱。 测试环境:Windo

文章作者:hopy(Kf2b@msn.com)
信息来源:邪恶八进制信息安全团队(www.eviloctal.com)

注意:本文章首发hopy.blogchina.com和blog.csdn.net/mydo,后由与原创作者友情提交到邪恶八进制信息安全团队技术论坛。

关键字:NT,Ring0,无驱。
测试环境:Windows 2000 SP4,Windows XP SP2,Windows 2003 未测试

在NT下无驱进入Ring0是一个老生常谈的方法了,网上也有一些C代码的例子,我之所以用汇编重写是因为上次在
[原创/探讨]Windows 核心编程研究系列之一(改变进程 PTE)
的帖子中自己没有实验成功(其实已经成功了,只是自己太马虎,竟然还不知道 -_-b),顺面聊聊PM(保护模式)中的调用门的使用情况。鉴于这些都是可以作为基本功来了解的知识点,所以对此已经熟悉的朋友就可以略过不看了,当然由于本人水平有限,各位前来“挑挑刺”也是非常欢迎的,呵呵。

下面言归正传,我们知道在NT中进入Ring0的一般方法是通过驱动,我的Windows 核心编程研究系列 文章前两篇都使用了

这个方法进入Ring0 完成特定功能。现在我们还可以通过在Ring3下直接写物理内存的方法来进入Ring0,其主要步骤是:

0 以写权限打开物理内存对象;
1 取得 系统 GDT 地址,并转换成物理地址;
2 构造一个调用门;
3 寻找 GDT 中空闲的位置,将 CallGate 植入;
4 Call植入的调用门。

前面已打通主要关节,现在进一步看看细节问题:
[零] 默认只有 System 用户有写物理内存的权限 administrators 组的用户只有读的权限,但是通过修改用户安全对象中的DACL 可以增加写的权限:

Copy code
_SetPhyMemDACLs proc uses ebx edi esi
_hPhymem:HANDLE,
_ptusrname:dword
local @dwret:dword
local @htoken:HANDLE
local @hprocess:HANDLE
local @个
local @OldDACLs:PACL
local @SecurityDescriptor:PSECURITY_DESCRIPTOR
local @Access:EXPLICIT_ACCESS
mov @dwret,FALSE
invoke RtlZeroMemory,addr @NewDACLs,sizeof @NewDACLs
invoke RtlZeroMemory,addr @SecurityDescriptor,
sizeof @SecurityDescriptor
invoke GetSecurityInfo,_hPhymem,SE_KERNEL_OBJECT,
DACL_SECURITY_INFORMATION,NULL,NULL,
addr @OldDACLs,NULL,
addr @SecurityDescriptor
.if eax != ERROR_SUCCESS
jmp SAFE_RET
.endif
invoke RtlZeroMemory,addr @Access,sizeof @Access
mov @Access.grfAccessPermissions,SECTION_ALL_ACCESS
mov @Access.grfAccessMode,GRANT_ACCESS
mov @Access.grfInheritance,NO_INHERITANCE
mov @Access.stTRUSTEE.MultipleTrusteeOperation,
NO_MULTIPLE_TRUSTEE
mov @Access.stTRUSTEE.TrusteeForm,TRUSTEE_IS_NAME
mov @Access.stTRUSTEE.TrusteeType,TRUSTEE_IS_USER
push _ptusrname
pop @Access.stTRUSTEE.ptstrName
invoke GetCurrentProcess
mov @hprocess,eax
invoke OpenProcessToken,@hprocess,TOKEN_ALL_ACCESS,
addr @htoken
invoke SetEntriesInAcl,1,addr @Access,
@OldDACLs,addr @NewDACLs
.if eax != ERROR_SUCCESS
jmp SAFE_RET
.endif
invoke SetSecurityInfo,_hPhymem,SE_KERNEL_OBJECT,
DACL_SECURITY_INFORMATION,NULL,NULL,
@NewDACLs,NULL
.if eax != ERROR_SUCCESS
jmp SAFE_RET
.endif
mov @dwret,TRUE
SAFE_RET:
.if @NewDACLs != NULL
invoke LocalFree,@NewDACLs
mov @NewDACLs,NULL
.endif
.if @SecurityDescriptor != NULL
invoke LocalFree,@SecurityDescriptor
mov @SecurityDescriptor,NULL
.endif
mov eax,@dwret
ret
_SetPhyMemDACLs endp


[一] 可以在Ring3下使用SGDT指令取得系统GDT表的虚拟地址,这条指令没有被Intel设计成特权0级的指令。据我的观察,在 Windows 2000 SP4 中 GDT 表的基址都是相同的,而且在虚拟机VMware5.5 虚拟的 Windows 2000 SP4中执行 SGDT 指令后返回的是错误的结果,在虚拟的 Windows XP 中也有同样情况,可能是虚拟机的问题,大家如果有条件可以试一下:
local @stGE:GDT_ENTRY
mov @dwret,FALSE
lea esi,@stGE
sgdt fword ptr [esi]
assume esi:ptr GDT_ENTRY
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
;在 VMware 虚拟环境下用以下两条指令替代
;只用于 Windows 2000 SP4
;mov [esi].Base,80036000h
;mov [esi].Limit,03ffh
;xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
mov eax,[esi].Base
invoke @GetPhymemLite,eax
.if eax == FALSE
jmp quit
.endif
下面就是虚拟地址转换物理地址了,这在Ring0中很简单,直接调用MmGetPhysicalAddress 即可,但在Ring3中要另想办法,还好系统直接将 0x80000000 ? 0xa0000000 影射到物理0地址开始的位置,所以可以写一个轻量级的GetPhysicalAddress来替代。:)

Copy code
@GetPhymemLite proc uses esi edi ebx _vaddr
local @dwret:dword
mov @dwret,FALSE
.if _vaddr jmp quit
.endif
.if _vaddr >= 0a0000000h
jmp quit
.endif
mov eax,_vaddr
and eax,01ffff000h ;or sub eax,80000000h
mov @dwret,eax
quit:
mov eax,@dwret
ret
@GetPhymemLite endp

[二]调用门在保护模式中可以看成是低特权级代码向高特权级代码转换的一种实现机制,如图1所示(由于本人较懒,所以借用李彦昌先生所著的80x86保护模式系列教程 中的部分截图,希望李先生看到后不要见怪 ^-^):
图1 
 \




要说明的是调用门也可以完成相同特权级的转换。一般门的结构如图2所示:
图2
 \
简单的介绍一下各个主要位置的含义:

Offset 和 Selector 共同组成目的地址的48位全指针,这意味着,如果远CALL指令指向一个调用门,则CALL指令中的偏移被丢弃;
P位置位代表门有效,DPL是门描述符的特权级,后面要设置成3,以便在Ring3中可以访问。TYPE 是门的类型,386调用门是 0xC ,Dword Count 是系统要拷贝的双字参数的个数,后面也将用到。下面是设置CallGate的代码:

Copy code
mov eax,_FucAddr
mov @CallGate.OffsetL,ax ;Low Part Addr Of FucAddr
mov @CallGate.Selector,8h ;Ring0 Code Segment
mov @CallGate.DCount,1 ;1 Dword
mov @CallGate.GType,AT386CGate ;Must A CallGate
shr eax,16
mov @CallGate.OffsetH,ax ;Low Part Addr Of FucAddr


[三] 既然可以读些物理内存了,也知道了GDT的物理基地址和长度,所以可以通过将GDT整个读出,然后寻找一块空闲的区域来植入前面设置好的CallGate:

Copy code
;申请一片空间,以便存放读出的GDT
Invoke VirtualAlloc,NULL,@tmpGDTLimit,MEM_COMMIT,
PAGE_READWRITE
.if eax == NULL
jmp quit
.endif
mov @pmem,eax
invoke @ReadPhymem,@tmpGDTPhyBase,@pmem,@tmpGDTLimit,
_hmem
.if eax == FALSE
jmp quit
.endif
mov esi,@pmem
mov ebx,@tmpGDTLimit
shr ebx,3
;找到第一个GDT描述符中P位没有置位的地址
mov ecx,1
.while ecx mov al,byte ptr [esi+ecx*8+5]
bt ax,7
.if CARRY?
.else
jmp lop0
.endif
Inc ecx
.endw
invoke VirtualFree,@pmem,0,MEM_RELEASE
jmp quit
lop0:
lea eax,[ecx*8]
mov @OffsetGatePos,eax
add @PhyGatePos,eax
mov esi,@pmem
add esi,eax
invoke RtlMoveMemory,addr oldgatebuf,esi,8
;释放内存空间
invoke VirtualFree,@pmem,0,MEM_RELEASE


[四] 现在主要工作基本完成了,剩下的就是设计一个运行在Ring0中的子函数,在这个子函数中我将调用Ring0里面真正的MmGetPhysicalAddress来取得实际的物理地址,所以这个函数要有一个输入参数用来传递要转换的虚拟地址,并且还要考虑到如何获取返回的物理地址(EDX:EAX)。在网络上的C版本代码中,这是通过定义几个全局变量来传递的,因为没有发生进程切换,所以可以使用原进程中的一些变量。然而我在传递虚拟地址上采用了另一种做法,就是通过实际形参来传递的:

Copy code
Ring0Fuc proc ;_vaddr
;手动保存
push ebp
mov ebp,esp
sub esp,4
mov eax,[ebp+0ch]
mov [ebp-4],eax ;first local val
pushad
pushfd
cli
mov eax,[ebp-4]
;调用真正的 MmGetPhysicalAddress.
invoke MmGetPhysicalAddress,eax
mov phymem_L,eax
mov phymem_H,edx
popfd
popad
;手动还原
mov esp,ebp
pop ebp
retf 4
Ring0Fuc endp


最后,通过一个远CALL来调用这个调用门:

Quote:
lea edi,FarAddr
push _vaddr
call fword ptr [edi]

通过亲手编码,可以对调用门、远调用等一些80386+保护模式中的概念

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

華為手機如何實現雙微信登入? 華為手機如何實現雙微信登入? Mar 24, 2024 am 11:27 AM

華為手機如何實現雙微信登入?隨著社群媒體的興起,微信已成為人們日常生活中不可或缺的溝通工具之一。然而,許多人可能會遇到一個問題:在同一部手機上同時登入多個微信帳號。對於華為手機用戶來說,實現雙微信登入並不困難,本文將介紹華為手機如何實現雙微信登入的方法。首先,華為手機自帶的EMUI系統提供了一個很方便的功能-應用程式雙開。透過應用程式雙開功能,用戶可以在手機上同

今日頭條發布文章怎麼有收益?今日頭條發布文章獲得更多收益方法! 今日頭條發布文章怎麼有收益?今日頭條發布文章獲得更多收益方法! Mar 15, 2024 pm 04:13 PM

一、今日頭條發布文章怎麼有收益?今日頭條發布文章獲得更多收益方法! 1.開通基礎權益:原創文章選擇投放廣告可獲得收益,影片必須原創橫屏才會有收益。 2.開通百粉權益:粉絲量達百粉以上,微頭條、原創問答創作及問答均可獲得收益。 3.堅持原創作品:原創作品包含文章、微標題及問題等,要求300字以上。注意違規抄襲作品作為原創發布,會被扣信用分,即使有收益也會被扣除。 4.垂直度:做專業領域一類的文章,不能隨意跨領域寫文章,會得不到合適的推薦,達不到作品的專和精,難以吸引粉絲讀者。 5.活躍度:活躍度高,

PHP程式設計指南:實作斐波那契數列的方法 PHP程式設計指南:實作斐波那契數列的方法 Mar 20, 2024 pm 04:54 PM

程式語言PHP是一種用於Web開發的強大工具,能夠支援多種不同的程式設計邏輯和演算法。其中,實作斐波那契數列是一個常見且經典的程式設計問題。在這篇文章中,將介紹如何使用PHP程式語言來實作斐波那契數列的方法,並附上具體的程式碼範例。斐波那契數列是一個數學上的序列,其定義如下:數列的第一個和第二個元素為1,從第三個元素開始,每個元素的值等於前兩個元素的和。數列的前幾元

如何在華為手機上實現微信分身功能 如何在華為手機上實現微信分身功能 Mar 24, 2024 pm 06:03 PM

如何在華為手機上實現微信分身功能隨著社群軟體的普及和人們對隱私安全的日益重視,微信分身功能逐漸成為人們關注的焦點。微信分身功能可以幫助使用者在同一台手機上同時登入多個微信帳號,方便管理和使用。在華為手機上實現微信分身功能並不困難,只需要按照以下步驟操作即可。第一步:確保手機系統版本和微信版本符合要求首先,確保你的華為手機系統版本已更新至最新版本,以及微信App

掌握Golang如何實現遊戲開發的可能性 掌握Golang如何實現遊戲開發的可能性 Mar 16, 2024 pm 12:57 PM

在現今的軟體開發領域中,Golang(Go語言)作為一種高效、簡潔、並發性強的程式語言,越來越受到開發者的青睞。其豐富的標準庫和高效的並發特性使它成為遊戲開發領域的一個備受關注的選擇。本文將探討如何利用Golang來實現遊戲開發,並透過具體的程式碼範例來展示其強大的可能性。 1.Golang在遊戲開發中的優勢作為靜態類型語言,Golang正在建構大型遊戲系統

如何在Golang中實現精確除法運算 如何在Golang中實現精確除法運算 Feb 20, 2024 pm 10:51 PM

在Golang中實現精確除法運算是一個常見的需求,特別是在涉及金融計算或其它需要高精度計算的場景中。 Golang的內建的除法運算子「/」是針對浮點數計算的,並且有時會出現精度遺失的問題。為了解決這個問題,我們可以藉助第三方函式庫或自訂函數來實現精確除法運算。一種常見的方法是使用math/big套件中的Rat類型,它提供了分數的表示形式,可以用來實現精確的除法運算

PHP遊戲需求實作指南 PHP遊戲需求實作指南 Mar 11, 2024 am 08:45 AM

PHP遊戲需求實現指南隨著網路的普及和發展,網頁遊戲的市場也越來越火爆。許多開發者希望利用PHP語言來開發自己的網頁遊戲,而實現遊戲需求是其中一個關鍵步驟。本文將介紹如何利用PHP語言來實現常見的遊戲需求,並提供具體的程式碼範例。 1.創造遊戲角色在網頁遊戲中,遊戲角色是非常重要的元素。我們需要定義遊戲角色的屬性,例如姓名、等級、經驗值等,並提供方法來操作這些

使用PHP實作SaaS:全面解析 使用PHP實作SaaS:全面解析 Mar 07, 2024 pm 10:18 PM

實在抱歉,我無法提供即時的程式設計指導,但我可以為你提供一篇程式碼範例,讓你更能理解如何使用PHP實作SaaS。以下是一篇1500字以內的文章,標題為《使用PHP實作SaaS:全面解析》。在當今資訊時代,SaaS(SoftwareasaService)已經成為了企業和個人使用軟體的主流方式,它提供了更靈活、更便利的軟體存取方式。透過SaaS,用戶無需在本地

See all articles