CSDN博客

img XmagicX

win2000下不用驱动进入ring0

发表于2004/9/30 7:39:00  1354人阅读


#define _X86_

#include <windows.h>
#include <stdio.h>
#include <aclapi.h>
#include <conio.h>
#include <windef.h>

typedef long NTSTATUS;
typedef unsigned short USHORT;
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define OBJ_INHERIT 0x00000002L
#define OBJ_PERMANENT 0x00000010L
#define OBJ_EXCLUSIVE 0x00000020L
#define OBJ_CASE_INSENSITIVE 0x00000040L
#define OBJ_OPENIF 0x00000080L
#define OBJ_OPENLINK 0x00000100L
#define OBJ_KERNEL_HANDLE 0x00000200L
#define OBJ_VALID_ATTRIBUTES 0x000003F2L

typedef struct _UNICODE_STRING {
  USHORT Length;
  USHORT MaximumLength;

#ifdef MIDL_PASS
  [size_is(MaximumLength / 2), length_is((Length) / 2) ] USHORT * Buffer;
#else // MIDL_PASS
  PWSTR Buffer;
#endif // MIDL_PASS
} UNICODE_STRING;

typedef UNICODE_STRING *PUNICODE_STRING;
typedef const UNICODE_STRING *PCUNICODE_STRING;
#define UNICODE_NULL ((WCHAR)0) // winnt

typedef struct _OBJECT_ATTRIBUTES {
  ULONG Length;
  HANDLE RootDirectory;
  PUNICODE_STRING ObjectName;
  ULONG Attributes;
  PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR
  PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES;

typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;

#define InitializeObjectAttributes( p, n, a, r, s ) {
  (p)->Length = sizeof( OBJECT_ATTRIBUTES );    
  (p)->RootDirectory = r;             
  (p)->Attributes = a;               
  (p)->ObjectName = n;               
  (p)->SecurityDescriptor = s;           
  (p)->SecurityQualityOfService = NULL;      
  }

extern "C"
NTSYSAPI
VOID
NTAPI
RtlInitUnicodeString(
           PUNICODE_STRING DestinationString,
           PCWSTR SourceString
           );
extern "C"
NTSYSAPI
NTSTATUS
NTAPI
ZwOpenSection(
       OUT PHANDLE SectionHandle,
       IN ACCESS_MASK DesiredAccess,
       IN POBJECT_ATTRIBUTES ObjectAttributes
       );
extern "C"
NTSYSAPI
NTSTATUS
NTAPI
ZwClose(
    IN HANDLE Handle
    );

#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) // ntsubauth
#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
#pragma comment(lib,"C:/NTDDK/libfre/i386/ntdll.lib")


#define ENTERRING0 _asm pushad
  _asm pushf
  _asm cli

#define LEAVERING0 _asm popf
  _asm popad
  _asm retf

typedef struct gdtr {
  unsigned short Limit;
  unsigned short BaseLow;
  unsigned short BaseHigh;
} Gdtr_t, *PGdtr_t;

typedef struct {
  unsigned short offset_0_15;
  unsigned short selector;
  
  unsigned char param_count : 4;
  unsigned char some_bits : 4;
  
  unsigned char type : 4;
  unsigned char app_system : 1;
  unsigned char dpl : 2;
  unsigned char present : 1;
  
  unsigned short offset_16_31;
} CALLGATE_DESCRIPTOR;


void PrintWin32Error( DWORD ErrorCode )
{
  LPVOID lpMsgBuf;
  
  FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, ErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL);
  printf("%sn", lpMsgBuf );
  LocalFree( lpMsgBuf );
}

ULONG MiniMmGetPhysicalAddress(ULONG virtualaddress)
{
  if(virtualaddress<0x80000000||virtualaddress>=0xA0000000)
    return 0;
  return virtualaddress&0x1FFFF000;
}

VOID SetPhyscialMemorySectionCanBeWrited(HANDLE hSection)
{
  PACL pDacl=NULL;
  PACL pNewDacl=NULL;
  PSECURITY_DESCRIPTOR pSD=NULL;
  DWORD dwRes;
  EXPLICIT_ACCESS ea;
  
  if(dwRes=GetSecurityInfo(hSection,SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL,NULL,&pDacl,NULL,&pSD) != ERROR_SUCCESS)
  {
    printf( "GetSecurityInfo Error %un", dwRes );
    goto CleanUp;
  }
  
  ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
  ea.grfAccessPermissions = SECTION_MAP_WRITE;
  ea.grfAccessMode = GRANT_ACCESS;
  ea.grfInheritance= NO_INHERITANCE;
  ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
  ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
  ea.Trustee.ptstrName = "CURRENT_USER";
  
  if(dwRes=SetEntriesInAcl(1,&ea,pDacl,&pNewDacl)!=ERROR_SUCCESS)
  {
    printf( "SetEntriesInAcl %un", dwRes );
    goto CleanUp;
  }
  
  if(dwRes=SetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,NULL,NULL,pNewDacl,NULL)!=ERROR_SUCCESS)
  {
    printf("SetSecurityInfo %un",dwRes);
    goto CleanUp;
  }

CleanUp:
  
  if(pSD)
    LocalFree(pSD);
  if(pNewDacl)
    LocalFree(pSD);
}

BOOL ExecRing0Proc(ULONG Entry,ULONG seglen)
{
  Gdtr_t gdt;
  __asm sgdt gdt;
  
  ULONG mapAddr=MiniMmGetPhysicalAddress(gdt.BaseHigh<<16U|gdt.BaseLow);
  if(!mapAddr) return 0;
  
  HANDLE hSection=NULL;
  NTSTATUS status;
  OBJECT_ATTRIBUTES objectAttributes;
  UNICODE_STRING objName;
  CALLGATE_DESCRIPTOR *cg;
  
  status = STATUS_SUCCESS;
  RtlInitUnicodeString(&objName,L"/Device/PhysicalMemory");
  
  InitializeObjectAttributes(&objectAttributes, &objName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, (PSECURITY_DESCRIPTOR) NULL);
  
  status = ZwOpenSection(&hSection,SECTION_MAP_READ|SECTION_MAP_WRITE,&objectAttributes);
  
  if(status == STATUS_ACCESS_DENIED){
    status = ZwOpenSection(&hSection,READ_CONTROL|WRITE_DAC,&objectAttributes);
    SetPhyscialMemorySectionCanBeWrited(hSection);
    ZwClose(hSection);
    status = ZwOpenSection(&hSection,SECTION_MAP_WRITE|SECTION_MAP_WRITE,&objectAttributes);
  }
  
  if(status != STATUS_SUCCESS)
  {
    printf("Error Open PhysicalMemory Section Object,Status:%08Xn",status);
    return 0;
  }
  
  PVOID BaseAddress;
  BaseAddress=MapViewOfFile(hSection,
    FILE_MAP_READ|FILE_MAP_WRITE,
    0,
    mapAddr, //low part
    (gdt.Limit+1));
  if(!BaseAddress)
  {
    printf("Error MapViewOfFile:");
    PrintWin32Error(GetLastError());
    return 0;
  }
  
  BOOL setcg=FALSE;
  
  for(cg=(CALLGATE_DESCRIPTOR *)((ULONG)BaseAddress+(gdt.Limit&0xFFF8));(ULONG)cg>(ULONG)BaseAddress;cg--)
    if(cg->type == 0){
      cg->offset_0_15 = LOWORD(Entry);
      cg->selector = 8;
      cg->param_count = 0;
      cg->some_bits = 0;
      cg->type = 0xC; // 386 call gate
      cg->app_system = 0; // A system descriptor
      cg->dpl = 3; // Ring 3 code can call
      cg->present = 1;
      cg->offset_16_31 = HIWORD(Entry);
      
      setcg=TRUE;
      break;
    }
    
    if(!setcg){
      ZwClose(hSection);
      return 0;
    }
    
    short farcall[3];
    
    farcall[2]=((short)((ULONG)cg-(ULONG)BaseAddress))|3; //Ring 3 callgate;
    if(!VirtualLock((PVOID)Entry,seglen))
    {
      printf("Error VirtualLock:");
      PrintWin32Error(GetLastError());
      return 0;
    }
    
    SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL);
    Sleep(0);
    
    _asm call fword ptr [farcall]
      
    SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL);
    
    VirtualUnlock((PVOID)Entry,seglen);
    
    //Clear callgate
    *(ULONG *)cg=0;
    *((ULONG *)cg+1)=0;
    ZwClose(hSection);
    return TRUE;
}

struct _RING0DATA
{
  DWORD mcr0,mcr2,mcr3;
  unsigned short BaseMemory;
  unsigned short ExtendedMemory;
}r0Data;

void __declspec (naked) Ring0Proc1()
{
  ENTERRING0;
  _asm {
    mov eax, cr0
    mov r0Data.mcr0, eax;
    mov eax, cr2
    mov r0Data.mcr2, eax;
    mov eax, cr3
      mov r0Data.mcr3, eax;
  }
  LEAVERING0;
}

void __declspec (naked) Ring0Proc2()
{
  ENTERRING0;
  _outp( 0x70, 0x15 );
  
  _asm
  {
    mov ax,0
    in al,71h
    mov r0Data.BaseMemory,ax
  }
  
  _outp( 0x70, 0x16 );
  r0Data.BaseMemory += _inp(0x71) << 8;
  _outp( 0x70, 0x17 );
  r0Data.ExtendedMemory = _inp( 0x71 );
  _outp( 0x70, 0x18 );
  r0Data.ExtendedMemory += _inp(0x71) << 8;
  LEAVERING0;
}

void main(void)
{
  ZeroMemory(&r0Data,sizeof(struct _RING0DATA));
  VirtualLock((PVOID)&r0Data,sizeof(struct _RING0DATA));
  ExecRing0Proc((ULONG)Ring0Proc1,0x100);
  ExecRing0Proc((ULONG)Ring0Proc2,0x100);
  VirtualUnlock((PVOID)&r0Data,sizeof(struct _RING0DATA));
  
  printf("CR0 = %xn", r0Data.mcr0);
  printf("CR2 = %xn", r0Data.mcr2);
  printf("CR3 = %xn", r0Data.mcr3);
  printf("Base memory = %dKn", r0Data.BaseMemory);
  printf("Extended memory = %dKn", r0Data.ExtendedMemory);
}
阅读全文
0 0

相关文章推荐

img
取 消
img