阅读:1146回复:0
请教,在win2k的ring0下I/O操作失败
请教,在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\"); } |
|