Windows NT/2000/XP下不用驱动的Ring0代码实现(二)

无驱动执行 Ring0 代码  作者 free2000fly
关键字 无驱动执行 Ring0 代码
原作者姓名 free2000fly
文章原始出处 http://webcrazy.yeah.net

介绍
无驱动执行 Ring0 代码的源程序的改写, 使得能在 VC6 及 vc71 下编译

正文
前不久因为有一个加密及直接操纵硬件的问题, 使用直接访问硬件更直接一点, 但操作系统是NT的,
不能用 CIH 的技术, 在网上狂找, 终于在 http://webcrazy.yeah.net 网站上找到了,
但下载下来的源代码怎么折腾就是编译不过, 当然这其中包括了安装 vc6 加 NTDDK2000,
VC71 加 NTDDK2000 (BTW, 我找不到 XPDDK, M$ 开始要钱了).

后来, 一不做二不休, 直接把 DDK 内的函数声明摘录下来放到我的源代码内, 这下行了.
编译通过有了一线曙光, 但是下下来的源码里的有 inp(...) 和 outp(...) 语句, 编译报错;
干脆,直接改成 汇编指令. 现在编译通过了, 运行一切符合预期.

下面是源代码

//
// Ring0NT.cpp  
// 演示无驱动执行 Ring0 代码, 改编自  http://webcrazy.yeah.net/  网站相关内容 
// 能用 VC71 或 VC6 搭配最新 SDK 编译, 同时得有 NTDDK 内的 ntdll.lib 库文件 
// 编译方法:  cl Ring0NT.cpp 
//

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

#pragma comment (lib,"ntdll.lib")       // Copy From DDK
#pragma comment (lib,"Kernel32.lib")
#pragma comment (lib,"Advapi32.lib")


/// 从 NTDDK 摘来 /// 
#ifdef __cplusplus
extern "C" {
#endif
    
typedef long NTSTATUS;
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) 
    
#define STATUS_SUCCESS              0x00000000
#define OBJ_KERNEL_HANDLE           0x00000200
#define STATUS_ACCESS_DENIED        0xC0000022
#define OBJ_CASE_INSENSITIVE        0x00000040L
    
    typedef struct _OBJECT_ATTRIBUTES {
        ULONG Length;
        HANDLE RootDirectory;
        PUNICODE_STRING ObjectName;
        ULONG Attributes;
        PVOID SecurityDescriptor;
        PVOID SecurityQualityOfService;
    } 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;             /
    }
    
    NTSYSAPI
        VOID
        NTAPI
        RtlInitUnicodeString(
        PUNICODE_STRING DestinationString,
        PCWSTR SourceString
        );
    
    NTSYSAPI
        NTSTATUS
        NTAPI
        ZwOpenSection(
        OUT PHANDLE SectionHandle,
        IN ACCESS_MASK DesiredAccess,
        IN POBJECT_ATTRIBUTES ObjectAttributes
        );
    
    NTSYSAPI
        NTSTATUS
        NTAPI
        ZwClose(
        IN HANDLE Handle
        );
    
#ifdef __cplusplus
}
#endif




#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 al, 15h    ; 
    _asm out 70h, al    ; 
    
    _asm mov ax,0 ; 
    _asm in al,71h ; 
    _asm mov r0Data.BaseMemory,ax ; 
    
    // outp( 0x70, 0x16 ); 
    _asm mov al, 16h    ;  
    _asm out 70h, al    ; 
    // r0Data.BaseMemory += inp(0x71) << 8; 
    _asm xor eax, eax   ; 
    _asm in al, 71h     ; 
    _asm shl eax, 8h    ; 
    _asm add r0Data.BaseMemory, ax  ; 

    //------ 求扩展内存 --------------------------------------------- 
    // outp( 0x70, 0x17 );
    _asm mov al, 17h    ; 
    _asm out 70h, al    ; 
    // r0Data.ExtendedMemory = inp( 0x71 ); 
    _asm xor eax, eax   ; 
    _asm in al, 71h     ; 
    _asm mov r0Data.ExtendedMemory, ax  ; 

    // outp( 0x70, 0x18 ); 
    _asm mov al, 18h    ; 
    _asm out 70h, al    ; 
    // r0Data.ExtendedMemory += inp(0x71) << 8;
    _asm xor eax, eax   ; 
    _asm in al, 71h     ; 
    _asm shl eax, 8h    ; 
    _asm add r0Data.ExtendedMemory, ax  ; 

    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);

代码和可执行文件的压缩包在这里1 Ring0NT.zip

正文完

附件:

1 Ring0NT.zip

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值