emailxj
驱动牛犊
驱动牛犊
  • 注册日期2002-05-15
  • 最后登录2009-04-09
  • 粉丝0
  • 关注0
  • 积分5分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1146回复:0

请教,在win2k的ring0下I/O操作失败

楼主#
更多 发布于:2002-05-15 16:07
请教,在win2k的ring0下I/O操作失败

       我有个项目,是使用winnt4.0的工控机,想在程序运行后把键盘和鼠标功能锁定;
       我使用了SetWIndowHookEx(),但有些系统键不能被屏蔽,象CTRL+ALT+DEL等;
       我不使用驱动;
       我参考网上的一些资料,在GDT描述表中增加了一个调用门,调用门指向我的程序;
       程序中对I/O 20h端口进行操作(参考了dos下20h端口功能),想屏蔽键盘中断功能,但失败了(也无异常发生);
       后来,使用softice的i,o指令,也是这个结果;
       编译测试环境是win2k ddk;
       请各位指教;
///////////////////////////////////////////source///////////

////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
////////source


TARGETNAME=keyring0
TARGETPATH=obj
TARGETTYPE=PROGRAM

TARGETLIBS=$(SDK_LIB_PATH)\\kernel32.lib \\
           $(SDK_LIB_PATH)\\advapi32.lib \\
           $(SDK_LIB_PATH)\\user32.lib \\
           $(SDK_LIB_PATH)\\ntdll.lib \\
           $(SDK_LIB_PATH)\\msvcrt.lib \\
           $(SDK_LIB_PATH)\\hal.lib \\

INCLUDES=D:\\NTDDK\\inc\\ddk;D:\\NTDDK\\inc

UMTYPE=console
UMENTRY=main

SOURCES=main.c

////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
////////////////////////////////////////
////////main.h



// begin_ntndis begin_windbgkd
//
// NTSTATUS
//

typedef LONG NTSTATUS;
/*lint -save -e624 */  // Don\'t complain about different typedefs.
typedef NTSTATUS *PNTSTATUS;
/*lint -restore */  // Resume checking for different typedefs.


// begin_winnt begin_ntndis

#if (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
#define NTAPI __stdcall
#else
#define _cdecl
#define NTAPI
#endif






//
// Define API decoration for direct importing system DLL references.
//

#if !defined(_NTSYSTEM_)
#define NTSYSAPI     DECLSPEC_IMPORT
#define NTSYSCALLAPI DECLSPEC_IMPORT
#else
#define NTSYSAPI
#if defined(_NTDLLBUILD_)
#define NTSYSCALLAPI
#else
#define NTSYSCALLAPI DECLSPEC_ADDRSAFE
#endif

#endif


#if !defined(_NTSYSTEM_)

#define NTHALAPI DECLSPEC_IMPORT         // wdm

#else

#define NTHALAPI

#endif


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;


//
// UNICODE (Wide Character) types
//

#ifndef _MAC
typedef wchar_t WCHAR;    // wc,   16-bit UNICODE character
#else
// some Macintosh compilers don\'t define wchar_t in a convenient location, or define it as a char
typedef unsigned short WCHAR;    // wc,   16-bit UNICODE character
#endif

typedef WCHAR *PWCHAR;
typedef WCHAR *LPWCH, *PWCH;
typedef CONST WCHAR *LPCWCH, *PCWCH;
typedef WCHAR *NWPSTR;
typedef WCHAR *LPWSTR, *PWSTR;

typedef CONST WCHAR *LPCWSTR, *PCWSTR;




//
// Valid values for the Attributes field
//

#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

//
// Object Attributes structure
//

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;


typedef ULONG ACCESS_MASK;
typedef ACCESS_MASK *PACCESS_MASK;


NTSYSAPI
VOID
NTAPI
RtlInitUnicodeString(
    PUNICODE_STRING DestinationString,
    PCWSTR SourceString
    );

NTSYSAPI
NTSTATUS
NTAPI
ZwClose(
    IN HANDLE Handle
    );

NTSYSAPI
NTSTATUS
NTAPI
ZwOpenSection(
    OUT PHANDLE SectionHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes
    );

//++
//
// VOID
// InitializeObjectAttributes(
//     OUT POBJECT_ATTRIBUTES p,
//     IN PUNICODE_STRING n,
//     IN ULONG a,
//     IN HANDLE r,
//     IN PSECURITY_DESCRIPTOR s
//     )
//
//--

#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;               \\
    }


////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
////////////////////////main.cpp/////////////////////////////////
#include <stdio.h>
#include <windows.h>
#include <aclapi.h>
#include <conio.h>

extern \"C\" {
#include \"ntstatus.h\"
#include \"main.h\"
}

#define ENTERRING0   _asm pushad \\
                     _asm pushf

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

//屏蔽8259中断控制器上的键盘中断,
  _asm{
   in al,21h
or al,02h
out 21h,al
  }


LEAVERING0;
}

void __declspec (naked) Ring0Proc2()
{
        ENTERRING0;


//恢复8259中断控制器上的键盘中断,
_asm{
in al,21h
and al,0fdh
out 21h,al
}

LEAVERING0;
}

void main(void)
{
   ZeroMemory(&r0Data,sizeof(struct _RING0DATA));
   printf(\"start 4\\n\");
   VirtualLock((PVOID)&r0Data,sizeof(struct _RING0DATA));
   printf(\"exec 1\\n\");
   ExecRing0Proc((ULONG)Ring0Proc1,0x100);
   printf(\"exec 1 end\\n\");
   Sleep(1000*60);
   printf(\"exec 2\\n\");
   ExecRing0Proc((ULONG)Ring0Proc2,0x100);
   printf(\"exec 2 end\\n\");
   VirtualUnlock((PVOID)&r0Data,sizeof(struct _RING0DATA));
   printf(\"end\\n\");
 }


游客

返回顶部