一段nt下不用驱动进入ring0层的C代码,寻高手转成Delphi

ypyRock 2004-02-10 10:29:56
extern "C" {
#include "ntddk.h"
}

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

#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("%s\n", 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 %u\n", 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 %u\n", dwRes );
goto CleanUp;
}

if(dwRes=SetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,NULL,NULL,pNewDacl,NULL)!=ERROR_SUCCESS)
{
printf("SetSecurityInfo %u\n",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:%08X\n",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 = %x\n", r0Data.mcr0);
printf("CR2 = %x\n", r0Data.mcr2);
printf("CR3 = %x\n", r0Data.mcr3);
printf("Base memory = %dK\n", r0Data.BaseMemory);
printf("Extended memory = %dK\n", r0Data.ExtendedMemory);
}
...全文
85 57 打赏 收藏 举报
写回复
57 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
发帖
Windows SDK/API
加入

1169

社区成员

Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
申请成为版主
帖子事件
创建了帖子
2004-02-10 10:29
社区公告
暂无公告