VC6下编译进Ring0代码的疑惑

华华78113230

华华78113230

2016-02-19 16:19

关注图老师设计创意栏目可以让大家能更好的了解电脑,知道有关于电脑的更多有趣教程,今天给大家分享VC6下编译进Ring0代码的疑惑教程,希望对大家能有一点小小的帮助。

VC6下编译进Ring0代码的疑惑,操作系统XPSP2,CPU:AMD3000+。现象,VC6总会优化代码,编译出来的代码不是想要的。

代码如下:

// tt.cpp : Defines the entry point for the application.
//

#include "stdafx.h"

#define _X86_

#include windows.h
#include stdio.h
#include aclapi.h
#include conio.h
#include windef.h
#include shellapi.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"
typedef VOID (*pRtlInitUnicodeString)( PUNICODE_STRING DestinationString,PCWSTR SourceString);

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

extern "C"
typedef NTSTATUS (*pZwOpenSection)(OUT PHANDLE SectionHandle,IN ACCESS_MASK DesiredAccess,IN POBJECT_ATTRIBUTES ObjectAttributes);

extern "C"
typedef NTSTATUS (*pZwClose)(IN HANDLE Handle);

static const HINSTANCE NTDLLHANDLE=(HINSTANCE)0x7c920000; //ntdll.dll加载的位置可以用GetModuleHandle获取

#define STATUS_SUCCESS ((NTSTATUS)0x00000000L) // ntsubauth
#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
//#pragma comment(lib,"C:NTDDKlibfrei386tdll.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("%s", lpMsgBuf );
 LocalFree( lpMsgBuf );
}

(本文来源于图老师网站,更多请访问http://m.tulaoshi.com/bianchengyuyan/)

ULONG MiniMmGetPhysicalAddress(ULONG virtualaddress)
{
 if(virtualaddress0x80000000||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", 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", dwRes );
  goto CleanUp;
 }
 
 if(dwRes=SetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,NULL,NULL,pNewDacl,NULL)!=ERROR_SUCCESS)
 {
  printf("SetSecurityInfo %u",dwRes);
  goto CleanUp;
 }
 
CleanUp:
 
 if(pSD)
  LocalFree(pSD);
 if(pNewDacl)
  LocalFree(pSD);
}
#define RING0PROC void __declspec (naked)

BOOL ExecRing0Proc(ULONG Entry,ULONG seglen)
{
 Gdtr_t gdt;
 __asm sgdt gdt;
 
 ULONG mapAddr=MiniMmGetPhysicalAddress(gdt.BaseHigh16U|gdt.BaseLow);
 if(!mapAddr) return 0;
 
 HANDLE hSection=NULL;
 NTSTATUS status;
 OBJECT_ATTRIBUTES objectAttributes;
 UNICODE_STRING objName;
 CALLGATE_DESCRIPTOR *cg;
 
 status = STATUS_SUCCESS;
 
 pRtlInitUnicodeString RtlInitUnicodeString;
 pZwOpenSection ZwOpenSection;
 pZwClose ZwClose;
 
 RtlInitUnicodeString=(pRtlInitUnicodeString)GetProcAddress(NTDLLHANDLE,"RtlInitUnicodeString");
 ZwOpenSection=(pZwOpenSection)GetProcAddress(NTDLLHANDLE,"ZwOpenSection");
 ZwClose=(pZwClose)GetProcAddress(NTDLLHANDLE,"ZwClose");

 RtlInitUnicodeString(&objName,L"DevicePhysicalMemory");
 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_READ|SECTION_MAP_WRITE,&objectAttributes);
 }
 
 if(status != STATUS_SUCCESS)
 {
  printf("Error Open PhysicalMemory Section Object,Status:%08X",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;
  }
  char *msg=new char[1000];
  sprintf(msg,"BaseAddress=%xhSection=%xmapAddr=%x",BaseAddress,hSection,mapAddr);
  MessageBox(NULL,msg,NULL,NULL);
  delete [] msg;
  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];
 
  MessageBox(NULL,"com",NULL,NULL);
  SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL);
 
  VirtualUnlock((PVOID)Entry,seglen);
 
  //Clear callgate
  *(ULONG *)cg=0;
  *((ULONG *)cg+1)=0;
  ZwClose(hSection);
  MessageBox(NULL,"com2",NULL,NULL);
  return TRUE;
}

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

RING0PROC 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;
}

RING0PROC 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;
}

展开更多 50%)
分享

猜你喜欢

VC6下编译进Ring0代码的疑惑

编程语言 网络编程
VC6下编译进Ring0代码的疑惑

NT/2000下不用驱动的Ring0代码实现

编程语言 网络编程
NT/2000下不用驱动的Ring0代码实现

s8lol主宰符文怎么配

英雄联盟 网络游戏
s8lol主宰符文怎么配

一例奇怪的编译错误(VC6)

编程语言 网络编程
一例奇怪的编译错误(VC6)

VC6几个技巧

编程语言 网络编程
VC6几个技巧

lol偷钱流符文搭配推荐

英雄联盟 网络游戏
lol偷钱流符文搭配推荐

VC6中设定命令行参数

编程语言 网络编程
VC6中设定命令行参数

QQ登陆错误0x00000001代码怎么办?

电脑入门
QQ登陆错误0x00000001代码怎么办?

lolAD刺客新符文搭配推荐

英雄联盟
lolAD刺客新符文搭配推荐

使用ZendEncode编译PHP程序

使用ZendEncode编译PHP程序

用VC读取和分析格式化文本配置文件

用VC读取和分析格式化文本配置文件
下拉加载更多内容 ↓