〔转贴〕原作者姓名 free2000fly
介绍
无驱动执行 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);
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)