|
|
14个函数
53 NtCreateThread
68 NtDuplicateObject
122 NtOpenProcess //
128 NtOpenThread //
137 NtProtectVirtualMemory
154 NtQueryInformationProcess
155 NtQueryInformationThread
//7C8105BC . FF15 3811807C CALL DWORD PTR DS:[<&ntdll.NtQueryInformationThread>] ; \ZwQueryInformationThread
173 NtQuerySystemInformation
178 NtQueryVirtualMemory
180 NtQueueApcThread
186 NtReadVirtualMemory
228 NtSetInformationProcess
255 NtSystemDebugControl
277 NtWriteVirtualMemory
RtlPrefetchMemoryNonTemporal
Ke386IoSetAccessProcess
KeInsertQueueApc
KeUserModeCallback
PsLookUpThreadByThreadID
PsLookupProcessByProcessId //805d4122
ObReferenceObjectByHandle
??KeAttachProcess
??PsSetCreateProcessNotifyRoutine
??PsSetCreateThreadNotifyRoutine
??PsSetLoadImageNotifyRoutine
//用RemoveNotifyRoutine清空回调函数
导出函数的hook
NtAllocateVirtualMemory+0x15A处
PsPCreateThread+0x4F处 //805D1116 //805D1124
ObReferenceObjectByHandle
0: kd> u ObReferenceObjectByHandle l 11
nt!ObReferenceObjectByHandle:
805bc49e 8bff mov edi,edi
805bc4a0 55 push ebp
805bc4a1 8bec mov ebp,esp
805bc4a3 51 push ecx
805bc4a4 53 push ebx
805bc4a5 56 push esi
805bc4a6 57 push edi
0: kd> u pspCreateThread+30 l 30
nt!PspCreateThread+0x30:
805d1106 e033 loopne nt!PspCreateThread+0x65 (805d113b)
805d1108 db895dc03975 fisttp dword ptr [ecx+7539C05Dh]
805d110e 1474 adc al,74h
805d1110 20568d and byte ptr [esi-73h],dl
805d1113 45 inc ebp
805d1114 8050ff75 adc byte ptr [eax-1],75h
805d1118 dcff fdiv st(7),st
805d111a 35b8495680 xor eax,offset nt!PsProcessType (805649b8)
//从805d1000开始找 nt!PsProcessType地址+A
805d111f 6a02 push 2
805d1121 ff7514 push dword ptr [ebp+14h]
805d1124 e875b3feff call nt!ObReferenceObjectByHandle (805bc49e)
805d1129 8b5d80 mov ebx,dword ptr [ebp-80h]
进入PsLookupProcessByProcessId内,它有2个参数
__in HANDLE ProcessId, // 传进来进程ID
__deref_out PEPROCESS *Process // 传出去进程的EPROCESS
#include <ntddk.h>
typedef struct _ServiceDescriptorTable {
PVOID ServiceTableBase; //System Service Dispatch Table 的基地址
PVOID ServiceCounterTable;
//包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。
unsigned int NumberOfServices;//由 ServiceTableBase 描述的服务的数目。
PVOID ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表
}*PServiceDescriptorTable;
extern "C" extern PServiceDescriptorTable KeServiceDescriptorTable;
typedef struct _KAPC_STATE{
LIST_ENTRY ApcListHead[2];
PEPROCESS Process;
UCHAR KernelApcInProgress;
UCHAR KernelApcPending;
UCHAR UserApcPending;
}KAPC_STATE,*PKAPC_STATE;
extern "C" NTKERNELAPI NTSTATUS PsLookupProcessByProcessId(IN ULONG ulProcId,OUT PEPROCESS * pEProcess);
extern "C" NTKERNELAPI NTSTATUS ObOpenObjectByPointer(
IN PVOID Object,
IN ULONG HandleAttributes,
IN PACCESS_STATE PassedAccessState OPTIONAL,
IN ACCESS_MASK DesiredAccess OPTIONAL,
IN POBJECT_TYPE ObjectType OPTIONAL,
IN KPROCESSOR_MODE AccessMode,
OUT PHANDLE Handle
);
extern "C"NTKERNELAPI NTSTATUS ObReferenceObjectByHandle(
__in HANDLE Handle,
__in ACCESS_MASK DesiredAccess,
__in_opt POBJECT_TYPE ObjectType,
__in KPROCESSOR_MODE AccessMode,
__out PVOID *Object,
__out_opt POBJECT_HANDLE_INFORMATION HandleInformation
);
extern "C" NTKERNELAPI VOID KeUnstackDetachProcess(IN PKAPC_STATE ApcState);
extern "C" NTKERNELAPI VOID KeStackAttachProcess (IN PEPROCESS Process, OUT PKAPC_STATE ApcState);
ULONG oldNtCreateThread,oldNtCreateThread_Offset,GameNtCreateThread;//53
ULONG oldNtDuplicateObject,oldNtDuplicateObject_Offset,GameNtDuplicateObject; // 68
ULONG oldNtOpenProcess,oldNtOpenProcess_Offset,GameNtOpenProcess;//122
ULONG oldNtOpenThread,oldNtOpenThread_Offset;//128
ULONG oldNtProtectVirtualMemory,oldNtProtectVirtualMemory_Offset;//137
ULONG oldNtQueryInformationProcess; //154
ULONG oldNtQueryInformationThread; //155
ULONG oldNtQuerySystemInformation; //173
ULONG oldNtQueryVirtualMemory,oldNtQueryVirtualMemory_Offset;//178
ULONG oldNtQueueApcThread; //180
ULONG oldNtReadVirtualMemory,oldNtReadVirtualMemory_Offset; //186
ULONG oldNtSetInformationProcess; //228
ULONG oldNtSystemDebugControl; //255
ULONG oldNtWriteVirtualMemory,oldNtWriteVirtualMemory_Offset;//277
//*ULONG*/ ObOpenObjectByPointer
//#pragma alloc_text(PAGE, NtOpenThread);
#pragma PAGECODE
ULONG GetNt_Addr_SSDT(ULONG ssdt_index) //获取当前SSDT Index的当前地址
{
LONG *SSDT_Adr,SSDT_NtOpenProcess_Cur_Addr,t_addr;
KdPrint(("驱动成功被加载中.............................\n"));
//读取SSDT表中索引值为0x7A的函数
//poi(poi(KeServiceDescriptorTable)+0x7a*4)
t_addr=(LONG)KeServiceDescriptorTable->ServiceTableBase;
KdPrint(("当前ServiceTableBase地址为%x \n",t_addr));
SSDT_Adr=(PLONG)(t_addr+ssdt_index*4);
KdPrint(("当前t_addr+%x*4=%x \n",ssdt_index,SSDT_Adr));
SSDT_NtOpenProcess_Cur_Addr=*SSDT_Adr; //取指针SSDT_Adr的值
KdPrint(("当前SSDT %x 地址为%x \n",ssdt_index,SSDT_NtOpenProcess_Cur_Addr));
return SSDT_NtOpenProcess_Cur_Addr;
}
LUID SeCreateTokenPrivilege;
LUID SeAssignPrimaryTokenPrivilege;
LUID SeLockMemoryPrivilege;
LUID SeIncreaseQuotaPrivilege;
LUID SeUnsolicitedInputPrivilege;
LUID SeTcbPrivilege;
LUID SeSecurityPrivilege;
LUID SeTakeOwnershipPrivilege;
LUID SeLoadDriverPrivilege;
LUID SeCreatePagefilePrivilege;
LUID SeIncreaseBasePriorityPrivilege;
LUID SeSystemProfilePrivilege;
LUID SeSystemtimePrivilege;
LUID SeProfileSingleProcessPrivilege;
LUID SeCreatePermanentPrivilege;
LUID SeBackupPrivilege;
LUID SeRestorePrivilege;
LUID SeShutdownPrivilege;
LUID SeDebugPrivilege;
LUID SeAuditPrivilege;
LUID SeSystemEnvironmentPrivilege;
LUID SeChangeNotifyPrivilege;
LUID SeRemoteShutdownPrivilege;
///////////////
#define TOKEN_SOURCE_LENGTH 8
typedef struct _TOKEN_SOURCE {
CHAR SourceName[TOKEN_SOURCE_LENGTH];
LUID SourceIdentifier;
} TOKEN_SOURCE, *PTOKEN_SOURCE;
typedef struct _TOKEN_CONTROL {
LUID TokenId;
LUID AuthenticationId;
LUID ModifiedId;
TOKEN_SOURCE TokenSource;
} TOKEN_CONTROL, *PTOKEN_CONTROL;
typedef struct _TOKEN_ORIGIN {
LUID OriginatingLogonSession ;
} TOKEN_ORIGIN, * PTOKEN_ORIGIN ;
typedef struct _SECURITY_CLIENT_CONTEXT {
SECURITY_QUALITY_OF_SERVICE SecurityQos;
PACCESS_TOKEN ClientToken;
BOOLEAN DirectlyAccessClientToken;
BOOLEAN DirectAccessEffectiveOnly;
BOOLEAN ServerIsRemote;
TOKEN_CONTROL ClientTokenControl;
} SECURITY_CLIENT_CONTEXT, *PSECURITY_CLIENT_CONTEXT;
typedef struct _AUX_ACCESS_DATA {
PPRIVILEGE_SET PrivilegesUsed;
GENERIC_MAPPING GenericMapping;
ACCESS_MASK AccessesToAudit;
ACCESS_MASK MaximumAuditMask;
} AUX_ACCESS_DATA, *PAUX_ACCESS_DATA;
extern "C" KPROCESSOR_MODE KeGetPreviousMode ( VOID );
#define ProbeForWriteHandle(Address) { \
if ((Address) >= (HANDLE * const)MM_USER_PROBE_ADDRESS) { \
*(volatile HANDLE * const)MM_USER_PROBE_ADDRESS = 0; \
} \
\
*(volatile HANDLE *)(Address) = *(volatile HANDLE *)(Address); \
}
#define ProbeForReadSmallStructure(Address, Size, Alignment) { \
ASSERT(((Alignment) == 1) || ((Alignment) == 2) || \
((Alignment) == 4) || ((Alignment) == 8) || \
((Alignment) == 16)); \
if ((Size == 0) || (Size > 0x10000)) { \
ASSERT(0); \
ProbeForRead(Address, Size, Alignment); \
} else { \
if (((ULONG_PTR)(Address) & ((Alignment) - 1)) != 0) { \
ExRaiseDatatypeMisalignment(); \
} \
if ((ULONG_PTR)(Address) >= (ULONG_PTR)MM_USER_PROBE_ADDRESS) { \
*(volatile UCHAR * const)MM_USER_PROBE_ADDRESS = 0; \
} \
} \
}
#define OBJ_KERNEL_EXCLUSIVE 0x00010000L
#define OBJ_VALID_PRIVATE_ATTRIBUTES 0x00010000L
#define OBJ_ALL_VALID_ATTRIBUTES (OBJ_VALID_PRIVATE_ATTRIBUTES | OBJ_VALID_ATTRIBUTES)
FORCEINLINE
ULONG
ObSanitizeHandleAttributes (
IN ULONG HandleAttributes,
IN KPROCESSOR_MODE Mode
)
{
if (Mode == KernelMode) {
return HandleAttributes & OBJ_ALL_VALID_ATTRIBUTES;
} else {
return HandleAttributes & (OBJ_ALL_VALID_ATTRIBUTES & ~(OBJ_KERNEL_HANDLE | OBJ_KERNEL_EXCLUSIVE));
}
}
extern "C"
NTKERNELAPI
NTSTATUS
PsLookupProcessThreadByCid(
__in PCLIENT_ID Cid,
__deref_opt_out PEPROCESS *Process,
__deref_out PETHREAD *Thread
);
// begin_ntosp
extern "C"
NTKERNELAPI
NTSTATUS
PsLookupThreadByThreadId(
__in HANDLE ThreadId,
__deref_out PETHREAD *Thread
);
extern "C"
NTKERNELAPI
NTSTATUS
SeCreateAccessState(
__out PACCESS_STATE AccessState,
__out PAUX_ACCESS_DATA AuxData,
__in ACCESS_MASK DesiredAccess,
__in PGENERIC_MAPPING GenericMapping
);
extern "C"
NTKERNELAPI
VOID
SeDeleteAccessState(
__in PACCESS_STATE AccessState
);
// end_ntosp
NTSTATUS
SeCreateAccessStateEx(
__in_opt PETHREAD Thread,
__in PEPROCESS Process,
__out PACCESS_STATE AccessState,
__out PAUX_ACCESS_DATA AuxData,
__in ACCESS_MASK DesiredAccess,
__in_opt PGENERIC_MAPPING GenericMapping
);
NTSTATUS
SeUpdateClientSecurity(
IN PETHREAD ClientThread,
IN OUT PSECURITY_CLIENT_CONTEXT ClientContext,
OUT PBOOLEAN ChangesMade,
OUT PBOOLEAN NewToken
);
BOOLEAN
SeRmInitPhase1(
VOID
);
NTSTATUS
SeInitializeProcessAuditName (
__in __typefix(PFILE_OBJECT) PVOID FileObject,
__in BOOLEAN bIgnoreAuditPolicy,
__deref_out POBJECT_NAME_INFORMATION *pAuditName
);
NTSTATUS
SeLocateProcessImageName(
__in PEPROCESS Process,
__deref_out PUNICODE_STRING *pImageFileName
);
VOID
SeAuditSystemTimeChange(
__in LARGE_INTEGER OldTime,
__in LARGE_INTEGER NewTime
);
// begin_ntifs begin_ntosp
NTKERNELAPI
NTSTATUS
SeQuerySecurityDescriptorInfo (
__in PSECURITY_INFORMATION SecurityInformation,
__out_bcount(*Length) PSECURITY_DESCRIPTOR SecurityDescriptor,
__inout PULONG Length,
__deref_inout PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor
);
NTKERNELAPI
NTSTATUS
SeSetSecurityDescriptorInfo (
__in_opt PVOID Object,
__in PSECURITY_INFORMATION SecurityInformation,
__in PSECURITY_DESCRIPTOR ModificationDescriptor,
__inout PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
__in POOL_TYPE PoolType,
__in PGENERIC_MAPPING GenericMapping
);
NTKERNELAPI
NTSTATUS
SeSetSecurityDescriptorInfoEx (
__in_opt PVOID Object,
__in PSECURITY_INFORMATION SecurityInformation,
__in PSECURITY_DESCRIPTOR ModificationDescriptor,
__inout PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
__in ULONG AutoInheritFlags,
__in POOL_TYPE PoolType,
__in PGENERIC_MAPPING GenericMapping
);
NTKERNELAPI
NTSTATUS
SeAppendPrivileges(
__inout PACCESS_STATE AccessState,
__in PPRIVILEGE_SET Privileges
);
// end_ntifs end_ntosp
NTSTATUS
SeComputeQuotaInformationSize(
__in PSECURITY_DESCRIPTOR SecurityDescriptor,
__out PULONG Size
);
VOID
SePrivilegedServiceAuditAlarm (
__in_opt PUNICODE_STRING ServiceName,
__in PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
__in PPRIVILEGE_SET Privileges,
__in BOOLEAN AccessGranted
);
NTKERNELAPI // ntddk ntifs ntosp
BOOLEAN // ntddk ntifs ntosp
SeSinglePrivilegeCheck( // ntddk ntifs ntosp
__in LUID PrivilegeValue, // ntddk ntifs ntosp
__in KPROCESSOR_MODE PreviousMode // ntddk ntifs ntosp
); // ntddk ntifs ntosp
extern "C"
BOOLEAN
SeFastTraverseCheck(
__in PSECURITY_DESCRIPTOR SecurityDescriptor,
__in_opt PACCESS_STATE AccessState,
__in ACCESS_MASK TraverseAccess,
__in KPROCESSOR_MODE AccessMode
);
extern "C"
NTKERNELAPI
NTSTATUS
ObOpenObjectByName(
__in POBJECT_ATTRIBUTES ObjectAttributes,
__in_opt POBJECT_TYPE ObjectType,
__in KPROCESSOR_MODE AccessMode,
__inout_opt PACCESS_STATE AccessState,
__in_opt ACCESS_MASK DesiredAccess,
__inout_opt PVOID ParseContext,
__out PHANDLE Handle
);
extern "C" POBJECT_TYPE *ExEventPairObjectType;
extern "C" PGENERIC_MAPPING *PsProcessType;
extern "C" POBJECT_TYPE *PsThreadType;
extern "C" POBJECT_TYPE *PsJobType;
extern "C" POBJECT_TYPE *LpcPortObjectType;
extern "C" POBJECT_TYPE *LpcWaitablePortObjectType;
////////////////////////////////////
// begin_ntddk begin_wdm
//extern "C" NTHALAPI KIRQL NTAPI KeGetCurrentIrql();
// end_ntddk end_wdm
extern "C"
NTSTATUS
My_NtOpenThread (
__out PHANDLE ThreadHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__in_opt PCLIENT_ID ClientId
)
{
HANDLE Handle;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status;
PETHREAD Thread;
CLIENT_ID CapturedCid={0};
BOOLEAN ObjectNamePresent;
BOOLEAN ClientIdPresent;
ACCESS_STATE AccessState;
AUX_ACCESS_DATA AuxData;
ULONG HandleAttributes;
PAGED_CODE();
//
// Make sure that only one of either ClientId or ObjectName is
// present.
//
PreviousMode = KeGetPreviousMode();
if (PreviousMode != KernelMode) {
//
// Since we need to look at the ObjectName field, probe
// ObjectAttributes and capture object name present indicator.
//
_try {
ProbeForWriteHandle(ThreadHandle);
ProbeForReadSmallStructure (ObjectAttributes,
sizeof(OBJECT_ATTRIBUTES),
sizeof(ULONG));
ObjectNamePresent = (BOOLEAN)ARGUMENT_PRESENT(ObjectAttributes->ObjectName);
HandleAttributes = ObSanitizeHandleAttributes (ObjectAttributes->Attributes, UserMode);
if (ARGUMENT_PRESENT(ClientId)) {
ProbeForReadSmallStructure (ClientId, sizeof(CLIENT_ID), sizeof(ULONG));
CapturedCid = *ClientId;
ClientIdPresent = TRUE;
} else {
ClientIdPresent = FALSE;
}
} _except (EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode();
}
} else {
ObjectNamePresent = (BOOLEAN) ARGUMENT_PRESENT(ObjectAttributes->ObjectName);
HandleAttributes = ObSanitizeHandleAttributes (ObjectAttributes->Attributes, KernelMode);
if (ARGUMENT_PRESENT(ClientId)) {
CapturedCid = *ClientId;
ClientIdPresent = TRUE;
} else {
ClientIdPresent = FALSE;
}
}
if (ObjectNamePresent && ClientIdPresent) {
return STATUS_INVALID_PARAMETER_MIX;
}
Status = SeCreateAccessState(
&AccessState,
&AuxData,
DesiredAccess,
(PGENERIC_MAPPING)(*(PULONG)PsProcessType+0x68)//PsProcessType->TypeInfo.GenericMapping
);
if (!NT_SUCCESS (Status)) {
return Status;
}
//
// Check here to see if the caller has SeDebugPrivilege. If
// he does, we will allow him any access he wants to the process.
// We do this by clearing the DesiredAccess in the AccessState
// and recording what we want him to have in the PreviouslyGrantedAccess
// field.
if (SeSinglePrivilegeCheck( SeDebugPrivilege, PreviousMode )) {
if ( AccessState.RemainingDesiredAccess & MAXIMUM_ALLOWED ) {
AccessState.PreviouslyGrantedAccess |= THREAD_ALL_ACCESS;
} else {
AccessState.PreviouslyGrantedAccess |= ( AccessState.RemainingDesiredAccess );
}
AccessState.RemainingDesiredAccess = 0;
}
if ( ObjectNamePresent ) {
//
// Open handle to the Thread object with the specified desired access,
// set Thread handle value, and return service completion status.
//
Status = ObOpenObjectByName(
ObjectAttributes,
(POBJECT_TYPE)PsThreadType,
PreviousMode,
&AccessState,
0,
NULL,
&Handle
);
SeDeleteAccessState( &AccessState );
if ( NT_SUCCESS(Status) ) {
_try {
*ThreadHandle = Handle;
} _except(EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode ();
}
}
return Status;
}
if ( ClientIdPresent ) {
if ( CapturedCid.UniqueProcess ) {
Status = PsLookupProcessThreadByCid(
&CapturedCid,
NULL,
&Thread
);
if ( !NT_SUCCESS(Status) ) {
SeDeleteAccessState( &AccessState );
return Status;
}
} else {
Status = PsLookupThreadByThreadId(
CapturedCid.UniqueThread,
&Thread
);
if ( !NT_SUCCESS(Status) ) {
SeDeleteAccessState( &AccessState );
return Status;
}
}
Status = ObOpenObjectByPointer(
Thread,
HandleAttributes,
&AccessState,
0,
(POBJECT_TYPE)PsThreadType,
PreviousMode,
&Handle
);
SeDeleteAccessState( &AccessState );
ObDereferenceObject(Thread);
if ( NT_SUCCESS(Status) ) {
_try {
*ThreadHandle = Handle;
} _except (EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode ();
}
}
return Status;
}
return STATUS_INVALID_PARAMETER_MIX;
}
extern "C" NTSTATUS __stdcall MyOpenProcess(ULONG PID,__out PHANDLE pHandle)
{
NTSTATUS status;
PEPROCESS EProcess = NULL;
HANDLE handle = NULL;
UNICODE_STRING y;
PULONG PsProcessType;
//__asm int 3
status = PsLookupProcessByProcessId(PID, &EProcess);
if (NT_SUCCESS(status))
{
handle = 0;
RtlInitUnicodeString(&y, L" sProcessType");
PsProcessType =(PULONG) MmGetSystemRoutineAddress(&y);
//__asm int 3
if (PsProcessType)
{ //__asm int 3
status = ObOpenObjectByPointer(EProcess, 0, 0, PROCESS_ALL_ACCESS, (POBJECT_TYPE)*PsProcessType, UserMode, &handle);
if (NT_SUCCESS(status))
{
//__asm int 3
*pHandle = handle;
}
}
ObfDereferenceObject(EProcess);
}
//return 0x666888;
return status;
}
extern "C" VOID __declspec(naked) __stdcall MyNtCreateThread()
{
__asm
{
push 28h
push 804DB8D8h
jmp oldNtCreateThread_Offset
mov eax,1
}
}
extern "C" VOID __declspec(naked) __stdcall MyNtOpenThread()
{
__asm
{
push 0xC0
push 0x804DB4E8
jmp oldNtOpenThread_Offset
mov eax,1
}
}
//初始化 所有参数
#pragma PAGECODE
NTSTATUS Old_NtProc_Init(void)
{
//#define XPSSDT_NtCreateThread 53
oldNtCreateThread=GetNt_Addr_SSDT(53);
__asm
{
mov ebx,oldNtCreateThread
mov ebx,[ebx+1]
add ebx,5
add ebx,oldNtCreateThread
mov GameNtCreateThread,ebx
}
//#define XPSSDT_NtDuplicateObject 68
oldNtDuplicateObject=GetNt_Addr_SSDT(53);
__asm
{
mov ebx,oldNtDuplicateObject
mov ebx,[ebx+1]
add ebx,5
add ebx,oldNtDuplicateObject
mov GameNtDuplicateObject,ebx
}
//#define XPSSDT_NtOpenProcess 122
oldNtOpenProcess=GetNt_Addr_SSDT(122);
__asm
{
mov ebx,oldNtOpenProcess
mov ebx,[ebx+1]
add ebx,5
add ebx,oldNtOpenProcess
mov GameNtOpenProcess,ebx
}
//#define XPSSDT_NtOpenThread 128
//#define XPSSDT_NtProtectVirtualMemory 137
//#define XPSSDT_NtQueryInformationProcess 154
//#define XPSSDT_NtQueryInformationThread 155
//#define XPSSDT_NtQuerySystemInformation 173
//
//#define XPSSDT_NtQueryVirtualMemory 178
//#define XPSSDT_NtQueueApcThread 180
//#define XPSSDT_NtReadVirtualMemory 186
//#define XPSSDT_NtSetInformationProcess 228
//#define XPSSDT_NtSystemDebugControl 255
//#define XPSSDT_NtWriteVirtualMemory 277
return 0;
}
#pragma PAGECODE
NTSTATUS __stdcall HookNt(void)
{
//写入HookNtReadFilebyWrite数据 到 My_NtReadFile前7字节
//关中断 关写保护
__asm //去掉页面保护
{
cli
mov eax,cr0
and eax,not 10000h //and eax,0FFFEFFFFh
mov cr0,eax
}
__asm
{
}
//恢复中断 恢复写保护
__asm //恢复页保护
{
mov eax,cr0
or eax,10000h //or eax,not 0FFFEFFFFh
mov cr0,eax
sti
}
return 1;
} |
|