浅谈NT下Ring3无驱进入Ring0的汇编实现
文章作者: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+保护模式中的概念

Outils d'IA chauds

Undresser.AI Undress
Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover
Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool
Images de déshabillage gratuites

Clothoff.io
Dissolvant de vêtements AI

AI Hentai Generator
Générez AI Hentai gratuitement.

Article chaud

Outils chauds

Bloc-notes++7.3.1
Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise
Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1
Puissant environnement de développement intégré PHP

Dreamweaver CS6
Outils de développement Web visuel

SublimeText3 version Mac
Logiciel d'édition de code au niveau de Dieu (SublimeText3)

1. Comment pouvez-vous gagner de l'argent en publiant des articles sur Toutiao aujourd'hui ? Comment gagner plus de revenus en publiant des articles sur Toutiao dès aujourd'hui ! 1. Activer les droits et intérêts fondamentaux : les articles originaux peuvent générer des bénéfices grâce à la publicité, et les vidéos doivent être originales en mode écran horizontal pour générer des bénéfices. 2. Activez les droits de 100 fans : si le nombre de fans atteint 100 fans ou plus, vous pouvez tirer des bénéfices des micro-titres, de la création originale de questions-réponses et des questions-réponses. 3. Insistez sur les œuvres originales : les œuvres originales comprennent des articles, des micro-titres, des questions, etc., et doivent contenir plus de 300 mots. Veuillez noter que si des œuvres illégalement plagiées sont publiées en tant qu'œuvres originales, des points de crédit seront déduits, et même les éventuels bénéfices seront déduits. 4. Verticalité : lorsque vous rédigez des articles dans des domaines professionnels, vous ne pouvez pas écrire à volonté des articles dans tous les domaines, vous n'obtiendrez pas de recommandations appropriées, vous ne pourrez pas atteindre le professionnalisme et le raffinement de votre travail et il sera difficile d'attirer des fans. et les lecteurs. 5. Activité : forte activité,

Comment mettre en œuvre la double connexion WeChat sur les téléphones mobiles Huawei ? Avec l’essor des réseaux sociaux, WeChat est devenu l’un des outils de communication indispensables dans la vie quotidienne des gens. Cependant, de nombreuses personnes peuvent rencontrer un problème : se connecter à plusieurs comptes WeChat en même temps sur le même téléphone mobile. Pour les utilisateurs de téléphones mobiles Huawei, il n'est pas difficile d'obtenir une double connexion WeChat. Cet article explique comment obtenir une double connexion WeChat sur les téléphones mobiles Huawei. Tout d'abord, le système EMUI fourni avec les téléphones mobiles Huawei offre une fonction très pratique : l'ouverture d'une double application. Grâce à la fonction de double ouverture de l'application, les utilisateurs peuvent simultanément

Le langage de programmation PHP est un outil puissant pour le développement Web, capable de prendre en charge une variété de logiques et d'algorithmes de programmation différents. Parmi eux, l’implémentation de la séquence de Fibonacci est un problème de programmation courant et classique. Dans cet article, nous présenterons comment utiliser le langage de programmation PHP pour implémenter la séquence de Fibonacci et joindrons des exemples de code spécifiques. La suite de Fibonacci est une suite mathématique définie comme suit : le premier et le deuxième élément de la suite valent 1, et à partir du troisième élément, la valeur de chaque élément est égale à la somme des deux éléments précédents. Les premiers éléments de la séquence

Comment mettre en œuvre la fonction de clonage WeChat sur les téléphones mobiles Huawei Avec la popularité des logiciels sociaux et l'importance croissante accordée à la confidentialité et à la sécurité, la fonction de clonage WeChat est progressivement devenue le centre d'attention. La fonction de clonage WeChat peut aider les utilisateurs à se connecter simultanément à plusieurs comptes WeChat sur le même téléphone mobile, ce qui facilite la gestion et l'utilisation. Il n'est pas difficile de mettre en œuvre la fonction de clonage WeChat sur les téléphones mobiles Huawei. Il vous suffit de suivre les étapes suivantes. Étape 1 : Assurez-vous que la version du système de téléphonie mobile et la version de WeChat répondent aux exigences. Tout d'abord, assurez-vous que la version de votre système de téléphonie mobile Huawei a été mise à jour vers la dernière version, ainsi que l'application WeChat.

Dans le domaine actuel du développement logiciel, Golang (langage Go), en tant que langage de programmation efficace, concis et hautement simultané, est de plus en plus favorisé par les développeurs. Sa riche bibliothèque de normes et ses fonctionnalités de concurrence efficaces en font un choix de premier plan dans le domaine du développement de jeux. Cet article explorera comment utiliser Golang pour le développement de jeux et démontrera ses puissantes possibilités à travers des exemples de code spécifiques. 1. Avantages de Golang dans le développement de jeux. En tant que langage typé statiquement, Golang est utilisé dans la construction de systèmes de jeux à grande échelle.

Guide d'implémentation des exigences du jeu PHP Avec la popularité et le développement d'Internet, le marché des jeux Web devient de plus en plus populaire. De nombreux développeurs espèrent utiliser le langage PHP pour développer leurs propres jeux Web, et la mise en œuvre des exigences du jeu constitue une étape clé. Cet article explique comment utiliser le langage PHP pour implémenter les exigences courantes du jeu et fournit des exemples de code spécifiques. 1. Créer des personnages de jeu Dans les jeux Web, les personnages de jeu sont un élément très important. Nous devons définir les attributs du personnage du jeu, tels que le nom, le niveau, la valeur de l'expérience, etc., et fournir des méthodes pour les exploiter.

La mise en œuvre d'opérations de division exactes dans Golang est un besoin courant, en particulier dans les scénarios impliquant des calculs financiers ou d'autres scénarios nécessitant des calculs de haute précision. L'opérateur de division intégré "/" de Golang est calculé pour les nombres à virgule flottante, et il y a parfois un problème de perte de précision. Afin de résoudre ce problème, nous pouvons utiliser des bibliothèques tierces ou des fonctions personnalisées pour implémenter des opérations de division exactes. Une approche courante consiste à utiliser le type Rat du package math/big, qui fournit une représentation des fractions et peut être utilisé pour implémenter des opérations de division exactes.

Je suis vraiment désolé de ne pas pouvoir fournir de conseils de programmation en temps réel, mais je peux vous fournir un exemple de code pour vous permettre de mieux comprendre comment utiliser PHP pour implémenter SaaS. Ce qui suit est un article de 1 500 mots intitulé « Utiliser PHP pour implémenter SaaS : une analyse complète ». À l'ère de l'information d'aujourd'hui, le SaaS (Software as a Service) est devenu le moyen courant pour les entreprises et les particuliers d'utiliser les logiciels. Il offre un moyen plus flexible et plus pratique d'accéder aux logiciels. Avec le SaaS, les utilisateurs n'ont pas besoin d'être sur site
