游戏保护大放送之TP
程序员文章站
2022-06-27 16:48:55
本人寻求游戏安全方面的工作,请Email:wtxpwh@163.com联系
做挂者请绕道!
本人不保证此办法现在还生效!蓝屏死机于本人无关!
...
本人寻求游戏安全方面的工作,请Email:wtxpwh@163.com联系
做挂者请绕道!
本人不保证此办法现在还生效!蓝屏死机于本人无关!
tp主要hook NtOpenProcess NtReadVirturalMemory NtWriteVirtualMemory KiattachProcess 还有debugport清零。直接上代码懒的多说,代码面前了无秘密。
代码:
/***************************************************************************************
* AUTHOR : sudami [sudami@163.com]
* TIME : 2008/08/13
* MODULE : aNgE.C
*
* Command:
*
*
*
* Description:
* s
*
*
***
* Copyright (c) 2008 - 2010 sudami.
* Freely distributable in source or binary for noncommercial purposes.
* TAKE IT EASY,JUST FOR FUN.
*
****************************************************************************************/
#include "struct.h"
#include "aNgE.h"
#include <stdlib.h>
#include <stdio.h>
//////////////////////////////////////////////////////////////////////////
ULONG Pass_NtOpenThread();
ULONG Pass_NtOpenProcess();
ULONG Pass_NtProcess();
ULONG Pass_NtReadVirtualMemory();
ULONG Pass_NtWriteVirtualMemory();
ULONG Pass_KiAttachProcess();
ULONG Pass_DebugPort();
ULONG Pass_KernelDebug();
VOID UnDetour_NtOpenProcess();
VOID UnDetour_NtProcess();
VOID UnDetour_NtOpenThread();
VOID UnDetour_NtReadVirtualMemory();
VOID UnDetour_NtWriteVirtualMemory();
unsigned long Pass_PsCreateSystemThread();
VOID UnDetour_PsCreateSystemThread();
VOID
CitydOnTimer(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context
);
ULONG TenBase=0;
//////////////////////////////////////////////////////////////////////////
NTSTATUS
DriverEntry(
PDRIVER_OBJECT pDriverObj,
PUNICODE_STRING pRegistryString
)
{
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING ustrLinkName;
UNICODE_STRING ustrDevName;
PDEVICE_OBJECT pDevObj;
dprintf("[aNgE] DriverEntry\n");
pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
pDriverObj->DriverUnload = DriverUnload;
RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
status = IoCreateDevice(pDriverObj,
0,
&ustrDevName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&pDevObj);
if(!NT_SUCCESS(status)) {
dprintf("[aNgE] IoCreateDevice = 0x%x\n", status);
return status;
}
IoInitializeTimer(pDevObj,CitydOnTimer,NULL);
IoStartTimer(pDevObj);
RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);
if(!NT_SUCCESS(status)) {
dprintf("[aNgE] IoCreateSymbolicLink = 0x%x\n", status);
IoDeleteDevice(pDevObj);
return status;
}
/**/
Pass_NtProcess();
Pass_NtOpenThread();
Pass_NtReadVirtualMemory();
Pass_NtWriteVirtualMemory();
Pass_PsCreateSystemThread();
// Pass_NtOpenProcess();
// Pass_KiAttachProcess();
// Pass_DebugPort();
// Pass_KernelDebug();
return STATUS_SUCCESS;
}
VOID
DriverUnload(
PDRIVER_OBJECT pDriverObj
)
{
UNICODE_STRING strLink;
LARGE_INTEGER Delay;
RtlInitUnicodeString(&strLink, LINK_NAME);
/**/
IoStopTimer(pDriverObj->DeviceObject);
UnDetour_NtProcess();
UnDetour_NtOpenThread();
UnDetour_NtReadVirtualMemory();
UnDetour_NtWriteVirtualMemory();
UnDetour_PsCreateSystemThread();
// UnDetour_NtOpenProcess();
Delay.QuadPart = -50000;
KeDelayExecutionThread(KernelMode, TRUE, &Delay);
IoDeleteSymbolicLink(&strLink);
IoDeleteDevice(pDriverObj->DeviceObject);
dprintf("[aNgE] Unloaded\n");
}
NTSTATUS
DispatchCreate(
PDEVICE_OBJECT pDevObj,
PIRP pIrp
)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
dprintf("[aNgE] IRP_MJ_CREATE\n");
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS
DispatchClose(
PDEVICE_OBJECT pDevObj,
PIRP pIrp
)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
dprintf("[aNgE] IRP_MJ_CLOSE\n");
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS
DispatchIoctl(
PDEVICE_OBJECT pDevObj,
PIRP pIrp
)
{
NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
PIO_STACK_LOCATION pIrpStack;
ULONG uIoControlCode;
PVOID pIoBuffer;
ULONG uInSize;
ULONG uOutSize;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
switch(uIoControlCode) {
case IOCTL_HELLO: {
dprintf("[aNgE] Hello\n");
status = STATUS_SUCCESS;
}
break;
//
// 添加执行代码
//
}
if(status == STATUS_SUCCESS)
pIrp->IoStatus.Information = uOutSize;
else
pIrp->IoStatus.Information = 0;
/////////////////////////////////////
pIrp->IoStatus.Status = status;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
#pragma pack(1)
typedef struct ServiceDescriptorEntry
{
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase;
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} SSDT_Entry;
#pragma pack()
__declspec(dllimport) SSDT_Entry KeServiceDescriptorTable;
//////////////////////////////////////////////////////////////////////////
ULONG g_uCr0;
void WPOFF()
{
ULONG uAttr;
_asm
{
push eax;
mov eax, cr0;
mov uAttr, eax;
and eax, 0FFFEFFFFh; // CR0 16 BIT = 0
mov cr0, eax;
pop eax;
cli
};
g_uCr0 = uAttr; //保存原有的CRO 屬性
}
VOID WPON()
{
_asm
{
sti
push eax;
mov eax, g_uCr0; //恢復原有CR0 屬性
mov cr0, eax;
pop eax;
};
}
//////////////////////////////////////////////////////////////////////////NtReadVirtualMemory
ULONG OldNtReadVirtualMemoryAdd;//原来NtReadVirtualMemory的服务地址
ULONG reentryadd_NtReadVirtualMemory;
__declspec(naked) NTSTATUS __stdcall NewNtReadVirtualMemory(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG NumberOfBytesToRead,
OUT PULONG NumberOfBytesReaded OPTIONAL)
{
__asm
{
push 0x1C
push 0x804daef0
jmp [reentryadd_NtReadVirtualMemory]
}
}
ULONG Pass_NtReadVirtualMemory()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)KeServiceDescriptorTable.ServiceTableBase + 0xBA * 4;
OldNtReadVirtualMemoryAdd = *(ULONG*)Address;
reentryadd_NtReadVirtualMemory = *(ULONG*)Address;
reentryadd_NtReadVirtualMemory=reentryadd_NtReadVirtualMemory + 0x7;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)NewNtReadVirtualMemory; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_NtReadVirtualMemory()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)KeServiceDescriptorTable.ServiceTableBase + 0xBA * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = OldNtReadVirtualMemoryAdd; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////NtWriteVirtualMemory
ULONG OldNtWriteVirtualMemoryAdd;//原来NtWriteVirtualMemory的服务地址
ULONG reentryadd_NtWriteVirtualMemory;
__declspec(naked) NTSTATUS __stdcall NewNtWriteVirtualMemory(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN PVOID Buffer,
IN ULONG NumberOfBytesToWrite,
OUT PULONG NumberOfBytesWritten OPTIONAL )
{
__asm
{
push 0x1C
push 0x804daf08
jmp [reentryadd_NtWriteVirtualMemory]
}
}
ULONG Pass_NtWriteVirtualMemory()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)KeServiceDescriptorTable.ServiceTableBase + 0x115 * 4;
OldNtWriteVirtualMemoryAdd = *(ULONG*)Address;
reentryadd_NtWriteVirtualMemory = *(ULONG*)Address;
reentryadd_NtWriteVirtualMemory=reentryadd_NtWriteVirtualMemory + 0x7;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)NewNtWriteVirtualMemory; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_NtWriteVirtualMemory()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)KeServiceDescriptorTable.ServiceTableBase + 0x115 * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = OldNtWriteVirtualMemoryAdd; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
ULONG GetFunctionAddr( IN PCWSTR FunctionName);
//////////////////////////////////////////////////////////////////////////KiAttachProcess
//ULONG* UX;
ULONG Pass_KiAttachProcess()
{
// *UX++;
unsigned char* actual_function;
KIRQL oldIrql;
int i=0;
unsigned char newcode[] = { 0x8b, 0xff, 0x55, 0x8b, 0xec, 0x53, 0x56 };
actual_function = (unsigned char *) GetFunctionAddr(L"KeUnstackDetachProcess");
actual_function=actual_function+0x324;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
for(i=0;i < 7;i++)
{
actual_function[i] = newcode[i];
}
KeLowerIrql(oldIrql);
WPON();
return 1;
}
//////////////////////////////////////////////////////////////////////////NtOpenProcess
ULONG OldNtProcessAdd;
ULONG reentryadd_NtWriteVirtualMemory;
NTSTATUS
_NtOpenProcess (
__out PHANDLE ProcessHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__in_opt PCLIENT_ID ClientId
)
{
HANDLE Handle;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status;
PEPROCESS Process;
PETHREAD Thread;
CLIENT_ID CapturedCid={0};
BOOLEAN ObjectNamePresent;
BOOLEAN ClientIdPresent;
ACCESS_STATE AccessState;
AUX_ACCESS_DATA AuxData;
ULONG Attributes;
LUID SeDebugPrivilege = {0};
POBJECT_TYPE _PsProcessType;
PEPROCESS cpeprocess,temp_peprocess;
PAGED_CODE();
cpeprocess=PsGetCurrentProcess();
if (!_stricmp("DNF.exe",(char*)((ULONG)cpeprocess+0x174)))
{
// DbgPrint("DNF called!");
Status = PsLookupProcessByProcessId(
CapturedCid.UniqueProcess,
&temp_peprocess
);
if (NT_SUCCESS(Status))
{
if (!_stricmp("csrss.exe",(char*)((ULONG)temp_peprocess+0x174)))
{
return STATUS_ACCESS_DENIED;
}
if (!_stricmp("OllyDBG.EXE",(char*)((ULONG)temp_peprocess+0x174)))
{
return STATUS_ACCESS_DENIED;
}
if (!_stricmp("Ollyice.EXE",(char*)((ULONG)temp_peprocess+0x174)))
{
return STATUS_ACCESS_DENIED;
}
}
// DbgPrint("%08x called! want to open %s\n",(unsigned long)cpeprocess,((ULONG)temp_peprocess+0x174));
return NtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes, ClientId);
}
(ULONG)_PsProcessType=*(ULONG*)PsProcessType;
PreviousMode = KeGetPreviousMode();
SeDebugPrivilege =RtlConvertLongToLuid(SE_DEBUG_PRIVILEGE);
if (PreviousMode != KernelMode) {
__try {
ProbeForWriteHandle (ProcessHandle);
ProbeForReadSmallStructure (ObjectAttributes,
sizeof(OBJECT_ATTRIBUTES),
sizeof(ULONG));
ObjectNamePresent = (BOOLEAN)ARGUMENT_PRESENT (ObjectAttributes->ObjectName);
Attributes = 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);
Attributes = 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,
&_PsProcessType->TypeInfo.GenericMapping
);
if ( !NT_SUCCESS(Status) ) {
return Status;
}
if (SeSinglePrivilegeCheck( SeDebugPrivilege, PreviousMode )) {
if ( AccessState.RemainingDesiredAccess & MAXIMUM_ALLOWED ) {
AccessState.PreviouslyGrantedAccess |= PROCESS_ALL_ACCESS;
} else {
AccessState.PreviouslyGrantedAccess |= ( AccessState.RemainingDesiredAccess );
}
AccessState.RemainingDesiredAccess = 0;
}
if (ObjectNamePresent) {
Status = ObOpenObjectByName(
ObjectAttributes,
_PsProcessType,
PreviousMode,
&AccessState,
0,
NULL,
&Handle
);
SeDeleteAccessState( &AccessState );
if ( NT_SUCCESS(Status) ) {
__try {
*ProcessHandle = Handle;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode ();
}
}
return Status;
}
if ( ClientIdPresent ) {
Thread = NULL;
if (CapturedCid.UniqueThread) {
Status = PsLookupProcessThreadByCid(
&CapturedCid,
&Process,
&Thread
);
if (!NT_SUCCESS(Status)) {
SeDeleteAccessState( &AccessState );
return Status;
}
} else {
Status = PsLookupProcessByProcessId(
CapturedCid.UniqueProcess,
&Process
);
if ( !NT_SUCCESS(Status) ) {
SeDeleteAccessState( &AccessState );
return Status;
}
}
//
// OpenObjectByAddress
//
Status = ObOpenObjectByPointer(
Process,
Attributes,
&AccessState,
0,
_PsProcessType,
PreviousMode,
&Handle
);
SeDeleteAccessState( &AccessState );
if (Thread) {
ObDereferenceObject(Thread);
}
ObDereferenceObject(Process);
if (NT_SUCCESS (Status)) {
__try {
*ProcessHandle = Handle;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode ();
}
}
return Status;
}
return STATUS_INVALID_PARAMETER_MIX;
}
ULONG Pass_NtProcess()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)KeServiceDescriptorTable.ServiceTableBase + 0x7A * 4;
OldNtProcessAdd = *(ULONG*)Address;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)_NtOpenProcess; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_NtProcess()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)KeServiceDescriptorTable.ServiceTableBase + 0x7A * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = OldNtProcessAdd; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
//base ab78e000
//nop-2 ab78fe9e ab79359d
//jmp-1 ab79558f ab79171c
//////////////////////////////////////////////////////////////////////////
ULONG Pass_DebugPort()
{
// ULONG Detour_Add;
unsigned char* Detour_Add_559d;//nop 2 byte
unsigned char* Detour_Add_1e9e;//nop 2 byte
unsigned char* Detour_Add_371c;//jmp 1 byte check code seg
unsigned char* Detour_Add_758f;//jmp 1 byte check kiattachprocess
// unsigned char* Detour_Add_735e;//jmp
// unsigned char* Detour_Add_2471;//jmp
// unsigned char* Detour_Add_2490;//jmp
// unsigned char* Detour_Add_5f8c;//jmp
// unsigned char* Detour_Add_4f9a;//jmp
// unsigned char* Detour_Add_6352;//jmp
// unsigned char* Detour_Add_4232;//jmp
// unsigned char* Detour_Add_3787;//jmp
KIRQL oldIrql;
ULONG Address=0,tempadd=0;
ULONG i=0;
// unsigned char code_ret[] = { 0xc3, 0x90};//16ac 4250 ret
//73ce jmp
// Address = (ULONG)KeServiceDescriptorTable.ServiceTableBase + 0xBA * 4;
// tempadd = *(ULONG*)Address;
// TenBase=((*(ULONG*)(tempadd+1))-0x3308);
(ULONG)Detour_Add_559d=TenBase+0x559d;
(ULONG)Detour_Add_1e9e=TenBase+0x1e9e;
(ULONG)Detour_Add_371c=TenBase+0x371c;
(ULONG)Detour_Add_758f=TenBase+0x758f;
// (ULONG)Detour_Add_735e=TenBase+0x735e;
// (ULONG)Detour_Add_2471=TenBase+0x2471;
// (ULONG)Detour_Add_2490=TenBase+0x2490;
// (ULONG)Detour_Add_5f8c=TenBase+0x5f8c;
// (ULONG)Detour_Add_4f9a=TenBase+0x4f9a;
// (ULONG)Detour_Add_6352=TenBase+0x6352;
// (ULONG)Detour_Add_4232=TenBase+0x4232;
// (ULONG)Detour_Add_3787=TenBase+0x3787;
//Detour_Add=*(ULONG*)(TenBase+0xcedc)+4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
Detour_Add_371c[0]=0xeb;
Detour_Add_758f[0]=0xeb;
// Detour_Add_735e[0]=0xeb;
// Detour_Add_2471[0]=0xeb;
// Detour_Add_2490[0]=0xeb;
// Detour_Add_5f8c[0]=0xeb;
// Detour_Add_4f9a[0]=0xeb;
// Detour_Add_6352[0]=0xeb;
// Detour_Add_4232[0]=0xeb;
// Detour_Add_3787[0]=0xeb;
for(i=0;i < 2;i++)
{
Detour_Add_559d[i] = 0x90;
Detour_Add_1e9e[i] = 0x90;
}
// *(ULONG*)Detour_Add=0x70;
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_DebugPort()
{
KIRQL oldIrql;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
// *(ULONG*)Detour_Add=0xbc;
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
ULONG Pass_KernelDebug()
{
KIRQL oldIrql;
ULONG Address=0;
ULONG _Detour_Add;
Address = *(ULONG*)((ULONG)KeServiceDescriptorTable.ServiceTableBase + 0xBA * 4);
Address=*(ULONG*)(Address+1);
_Detour_Add=Address-0x2e1;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*(unsigned short*)_Detour_Add=0x9090;
KeLowerIrql(oldIrql);
WPON();
KdEnableDebugger();
return 1;
}
//////////////////////////////////////////////////////////////////////////
VOID
CitydOnTimer(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context
)
{
unsigned char* Detour_Add_559d;//nop 2 byte
unsigned char* Detour_Add_1e9e;//nop 2 byte
unsigned char* Detour_Add_371c;//jmp 1 byte check code seg
unsigned char* Detour_Add_758f;//jmp 1 byte check kiattachprocess
unsigned char* ntreadmem=(unsigned char*)OldNtReadVirtualMemoryAdd;
__try
{ www.2cto.com
if (ntreadmem[0]!=0x6a)
{
//TenBase=((*(ULONG*)(OldNtReadVirtualMemoryAdd+1))-0x3308);
TenBase=((*(ULONG*)(OldNtReadVirtualMemoryAdd+1))-0x273c);
DbgPrint("TenBase=%08x\n",TenBase);
(ULONG)Detour_Add_559d=TenBase+0x559d;
(ULONG)Detour_Add_1e9e=TenBase+0x1e9e;
(ULONG)Detour_Add_371c=TenBase+0x371c;
(ULONG)Detour_Add_758f=TenBase+0x758f;
if (Detour_Add_371c[0]==0x74 || Detour_Add_758f[0]==0x74 || Detour_Add_559d[0]==0x87 || Detour_Add_1e9e[0]==0x87)
{
DbgPrint("fix debugport!!!!!!\n");
Pass_DebugPort();
Pass_KiAttachProcess();
DbgPrint("Pass_DebugPort()!!!\n");
}
}
}
__except(1)
{
DbgPrint("CitydOnTimer error!\n");
}
}
//////////////////////////////////////////////////////////////////////////
ULONG ObOpenObjectByPointerAdd;
void __declspec(naked) my_function_detour_NtOpenProcess()
{
__asm
{
push eax
push dword ptr [ebp-38h]
push dword ptr [ebp-24h]
mov eax,ObOpenObjectByPointerAdd
call eax
_emit 0xEA
_emit 0xAA
_emit 0xAA
_emit 0xAA
_emit 0xAA
_emit 0x08
_emit 0x00
}
}
//////////////////////////////////////////////////////////////////////////
ULONG GetFunctionAddr( IN PCWSTR FunctionName)
{
UNICODE_STRING UniCodeFunctionName;
RtlInitUnicodeString( &UniCodeFunctionName, FunctionName );
return (ULONG)MmGetSystemRoutineAddress( &UniCodeFunctionName );
}
char OpenProcess_g_oricode[8];
char* OpenProcess_non_paged_memory;
ULONG OpenProcess_g_KiInsertQueueApc;
ULONG Pass_NtOpenProcess()
{
unsigned long detour_address;
unsigned long reentry_address;
KIRQL oldIrql;
int i = 0;
char* actual_function;
unsigned char newcode[] = { 0xEA, 0x44, 0x33, 0x22, 0x11, 0x08,0x00};
//////////////////////////////////////////////////////////////////////////获得ObOpenObjectByPointer的地址
ObOpenObjectByPointerAdd=GetFunctionAddr( L"ObOpenObjectByPointer");
//////////////////////////////////////////////////////////////////////////修改跳转地址
OpenProcess_g_KiInsertQueueApc=GetFunctionAddr(L"NtOpenProcess");
actual_function = (char *)(OpenProcess_g_KiInsertQueueApc+0x21d);
reentry_address = ((unsigned long)OpenProcess_g_KiInsertQueueApc) + 0x229;
OpenProcess_non_paged_memory =(char*) ExAllocatePool(NonPagedPool, 256);
for(i=0;i<256;i++)
{
((unsigned char *)OpenProcess_non_paged_memory)[i] = ((unsigned char *)my_function_detour_NtOpenProcess)[i];
}
detour_address = (unsigned long)OpenProcess_non_paged_memory;
*( (unsigned long *)(&newcode[1]) ) = detour_address;
for(i=0;i<200;i++)
{
if( (0xAA == ((unsigned char *)OpenProcess_non_paged_memory)[i]) &&
(0xAA == ((unsigned char *)OpenProcess_non_paged_memory)[i+1]) &&
(0xAA == ((unsigned char *)OpenProcess_non_paged_memory)[i+2]) &&
(0xAA == ((unsigned char *)OpenProcess_non_paged_memory)[i+3]))
{
*( (unsigned long *)(&OpenProcess_non_paged_memory[i]) ) = reentry_address;
break;
}
}
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
for(i=0;i < 7;i++)
{
OpenProcess_g_oricode[i] = actual_function[i];
actual_function[i] = newcode[i];
}
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_NtOpenProcess()
{
char *actual_function = (char *)(OpenProcess_g_KiInsertQueueApc+0x21d);
KIRQL oldIrql;
int i = 0;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
for(i=0;i < 7;i++)
{
actual_function[i] = OpenProcess_g_oricode[i];
}
KeLowerIrql(oldIrql);
WPON();
ExFreePool(OpenProcess_non_paged_memory);
}
//////////////////////////////////////////////////////////////////////////
void __declspec(naked) my_function_detour_NtOpenThread()
{
__asm
{
push eax
push dword ptr [ebp-34h]
push dword ptr [ebp-20h]
mov eax,ObOpenObjectByPointerAdd
call eax
_emit 0xEA
_emit 0xAA
_emit 0xAA
_emit 0xAA
_emit 0xAA
_emit 0x08
_emit 0x00
}
}
//////////////////////////////////////////////////////////////////////////
char OpenThread_g_oricode[8];
char* OpenThread_non_paged_memory;
ULONG OpenThread_g_KiInsertQueueApc;
ULONG Pass_NtOpenThread()
{
char *actual_function;
unsigned long detour_address;
unsigned long reentry_address;
KIRQL oldIrql;
int i = 0;
unsigned char newcode[] = { 0xEA, 0x44, 0x33, 0x22, 0x11, 0x08,0x00};
//////////////////////////////////////////////////////////////////////////获得ObOpenObjectByPointer的地址
ObOpenObjectByPointerAdd=GetFunctionAddr( L"ObOpenObjectByPointer");
//////////////////////////////////////////////////////////////////////////修改跳转地址
OpenThread_g_KiInsertQueueApc=GetFunctionAddr(L"NtOpenThread");
actual_function = (char *)(OpenThread_g_KiInsertQueueApc+0x213);
reentry_address = ((unsigned long)OpenThread_g_KiInsertQueueApc) + 0x21f;
OpenThread_non_paged_memory =(char*) ExAllocatePool(NonPagedPool, 256);
for(i=0;i<256;i++)
{
((unsigned char *)OpenThread_non_paged_memory)[i] = ((unsigned char *)my_function_detour_NtOpenThread)[i];
}
detour_address = (unsigned long)OpenThread_non_paged_memory;
*( (unsigned long *)(&newcode[1]) ) = detour_address;
for(i=0;i<200;i++)
{
if( (0xAA == ((unsigned char *)OpenThread_non_paged_memory)[i]) &&
(0xAA == ((unsigned char *)OpenThread_non_paged_memory)[i+1]) &&
(0xAA == ((unsigned char *)OpenThread_non_paged_memory)[i+2]) &&
(0xAA == ((unsigned char *)OpenThread_non_paged_memory)[i+3]))
{
*( (unsigned long *)(&OpenThread_non_paged_memory[i]) ) = reentry_address;
break;
}
}
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
for(i=0;i < 7;i++)
{
OpenThread_g_oricode[i] = actual_function[i];
actual_function[i] = newcode[i];
}
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_NtOpenThread()
{
char *actual_function = (char *)(OpenThread_g_KiInsertQueueApc+0x213);
KIRQL oldIrql;
int i = 0;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
for(i=0;i < 7;i++)
{
actual_function[i] = OpenThread_g_oricode[i];
}
KeLowerIrql(oldIrql);
WPON();
ExFreePool(OpenThread_non_paged_memory);
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
unsigned long FindKey(unsigned char* Base,unsigned long Offset,unsigned char* Code, unsigned long SizeCode)
{
unsigned long i;
for (i=0;i<SizeCode;i++)
{
if (Base[i+Offset]==Code[i])
{
continue;
}
else
{
return 0;
}
}
return 1;
}
VOID FakeThread(IN PVOID pContext)
{
LARGE_INTEGER liTime = RtlConvertLongToLargeInteger(-(LONG)200000* 10000);
while(1)
{
DbgPrint("[FakeThread] In Wanmei FakeThread\n");
KeDelayExecutionThread(KernelMode,TRUE,&liTime);
}
}
//NTSTATUS PsLookupThreadByThreadId( IN HANDLE ThreadId, OUT PETHREAD *Thread );
unsigned long pPsCreateSystemThread = 0;
ULONG __stdcall CheckWanmeiCreateSystemThread(OUT PHANDLE ThreadHandle,
IN ULONG DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ProcessHandle OPTIONAL,
OUT PCLIENT_ID ClientId OPTIONAL,
IN PKSTART_ROUTINE StartRoutine,
IN PVOID StartContext)
{
char str[256];
ULONG ulBase = (ULONG)StartRoutine;
UCHAR cThreadCode1[] = {0xe9,0xbd,0xb8,0x04,0x00,0xac,0xc0,0x28,0x73,0xde};
UCHAR cThreadCode2[] = {0xe9,0x75,0x62,0x04,0x00,0x10,0x39,0xd0,0xb5,0x48};
if(FindKey((unsigned char *)ulBase, 0x0, cThreadCode1, sizeof(cThreadCode1)))
{
sprintf(str,"CheckWanmeiCreateThread : find cThreadCode1 StartRoutine %08x\n",(unsigned long)StartRoutine);
DbgPrint(str);
return 1;
}
if(FindKey((unsigned char *)ulBase, 0x0, cThreadCode2, sizeof(cThreadCode2)))
{
sprintf(str,"CheckWanmeiCreateThread : find cThreadCode2 StartRoutine %08x\n",(unsigned long)StartRoutine);
DbgPrint(str);
return 2;
}
return 0;
}
__declspec(naked) MyPsCreateSystemThread( OUT PHANDLE ThreadHandle,
IN ULONG DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ProcessHandle OPTIONAL,
OUT PCLIENT_ID ClientId OPTIONAL,
IN PKSTART_ROUTINE StartRoutine,
IN PVOID StartContext)
{
__asm
{
mov edi,edi
push ebp
mov ebp, esp
mov eax, pPsCreateSystemThread
add eax,5
jmp eax
}
}
PETHREAD pethread1=0;
PETHREAD pethread2=0;
NTSTATUS
_PsCreateSystemThread( OUT PHANDLE ThreadHandle,
IN ULONG DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ProcessHandle OPTIONAL,
OUT PCLIENT_ID ClientId OPTIONAL,
IN PKSTART_ROUTINE StartRoutine,
IN PVOID StartContext)
{
NTSTATUS nstatus;
CLIENT_ID clientid;
switch (CheckWanmeiCreateSystemThread(ThreadHandle,DesiredAccess,ObjectAttributes,ProcessHandle,ClientId,StartRoutine,StartContext))
{
case 0:
return MyPsCreateSystemThread(ThreadHandle,DesiredAccess,ObjectAttributes,ProcessHandle,ClientId,StartRoutine,StartContext);
break;
case 1:
nstatus=MyPsCreateSystemThread(ThreadHandle,DesiredAccess,ObjectAttributes,ProcessHandle,&clientid,FakeThread/*StartRoutine*/,StartContext);
PsLookupThreadByThreadId(clientid.UniqueThread,&pethread1);
DbgPrint("pethread1 %08x \n",pethread1);
return nstatus;
break;
case 2:
nstatus=MyPsCreateSystemThread(ThreadHandle,DesiredAccess,ObjectAttributes,ProcessHandle,&clientid,FakeThread/*StartRoutine*/,StartContext);
PsLookupThreadByThreadId(clientid.UniqueThread,&pethread2);
DbgPrint("pethread2 %08x \n",pethread2);
return nstatus;
break;
}
return MyPsCreateSystemThread(ThreadHandle,DesiredAccess,ObjectAttributes,ProcessHandle,ClientId,StartRoutine,StartContext);
}
unsigned char g_oldcode[8]={0};
unsigned long Pass_PsCreateSystemThread()
{
KIRQL oldIrql;
unsigned char newcode[] = { 0xE9, 0x44, 0x33, 0x22, 0x11};
pPsCreateSystemThread=GetFunctionAddr(L"PsCreateSystemThread");
memcpy(g_oldcode,(PVOID)pPsCreateSystemThread,5);
*( (unsigned long *)(&newcode[1]) ) = (ULONG)_PsCreateSystemThread-pPsCreateSystemThread-5;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
memcpy((PVOID)pPsCreateSystemThread,newcode,5);
KeLowerIrql(oldIrql);
WPON();
return STATUS_SUCCESS;
}
VOID UnDetour_PsCreateSystemThread()
{
KIRQL oldIrql;
// unsigned char newcode[] = { 0xE9, 0x44, 0x33, 0x22, 0x11};
pPsCreateSystemThread=GetFunctionAddr(L"PsCreateSystemThread");
// memcpy(g_oldcode,(PVOID)pPsCreateSystemThread,5);
// *( (unsigned long *)(&newcode[1]) ) = (ULONG)MyPsCreateSystemThread-pPsCreateSystemThread-5;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
memcpy((PVOID)pPsCreateSystemThread,g_oldcode,5);
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
做挂者请绕道!
本人不保证此办法现在还生效!蓝屏死机于本人无关!
tp主要hook NtOpenProcess NtReadVirturalMemory NtWriteVirtualMemory KiattachProcess 还有debugport清零。直接上代码懒的多说,代码面前了无秘密。
代码:
/***************************************************************************************
* AUTHOR : sudami [sudami@163.com]
* TIME : 2008/08/13
* MODULE : aNgE.C
*
* Command:
*
*
*
* Description:
* s
*
*
***
* Copyright (c) 2008 - 2010 sudami.
* Freely distributable in source or binary for noncommercial purposes.
* TAKE IT EASY,JUST FOR FUN.
*
****************************************************************************************/
#include "struct.h"
#include "aNgE.h"
#include <stdlib.h>
#include <stdio.h>
//////////////////////////////////////////////////////////////////////////
ULONG Pass_NtOpenThread();
ULONG Pass_NtOpenProcess();
ULONG Pass_NtProcess();
ULONG Pass_NtReadVirtualMemory();
ULONG Pass_NtWriteVirtualMemory();
ULONG Pass_KiAttachProcess();
ULONG Pass_DebugPort();
ULONG Pass_KernelDebug();
VOID UnDetour_NtOpenProcess();
VOID UnDetour_NtProcess();
VOID UnDetour_NtOpenThread();
VOID UnDetour_NtReadVirtualMemory();
VOID UnDetour_NtWriteVirtualMemory();
unsigned long Pass_PsCreateSystemThread();
VOID UnDetour_PsCreateSystemThread();
VOID
CitydOnTimer(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context
);
ULONG TenBase=0;
//////////////////////////////////////////////////////////////////////////
NTSTATUS
DriverEntry(
PDRIVER_OBJECT pDriverObj,
PUNICODE_STRING pRegistryString
)
{
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING ustrLinkName;
UNICODE_STRING ustrDevName;
PDEVICE_OBJECT pDevObj;
dprintf("[aNgE] DriverEntry\n");
pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
pDriverObj->DriverUnload = DriverUnload;
RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
status = IoCreateDevice(pDriverObj,
0,
&ustrDevName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&pDevObj);
if(!NT_SUCCESS(status)) {
dprintf("[aNgE] IoCreateDevice = 0x%x\n", status);
return status;
}
IoInitializeTimer(pDevObj,CitydOnTimer,NULL);
IoStartTimer(pDevObj);
RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);
if(!NT_SUCCESS(status)) {
dprintf("[aNgE] IoCreateSymbolicLink = 0x%x\n", status);
IoDeleteDevice(pDevObj);
return status;
}
/**/
Pass_NtProcess();
Pass_NtOpenThread();
Pass_NtReadVirtualMemory();
Pass_NtWriteVirtualMemory();
Pass_PsCreateSystemThread();
// Pass_NtOpenProcess();
// Pass_KiAttachProcess();
// Pass_DebugPort();
// Pass_KernelDebug();
return STATUS_SUCCESS;
}
VOID
DriverUnload(
PDRIVER_OBJECT pDriverObj
)
{
UNICODE_STRING strLink;
LARGE_INTEGER Delay;
RtlInitUnicodeString(&strLink, LINK_NAME);
/**/
IoStopTimer(pDriverObj->DeviceObject);
UnDetour_NtProcess();
UnDetour_NtOpenThread();
UnDetour_NtReadVirtualMemory();
UnDetour_NtWriteVirtualMemory();
UnDetour_PsCreateSystemThread();
// UnDetour_NtOpenProcess();
Delay.QuadPart = -50000;
KeDelayExecutionThread(KernelMode, TRUE, &Delay);
IoDeleteSymbolicLink(&strLink);
IoDeleteDevice(pDriverObj->DeviceObject);
dprintf("[aNgE] Unloaded\n");
}
NTSTATUS
DispatchCreate(
PDEVICE_OBJECT pDevObj,
PIRP pIrp
)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
dprintf("[aNgE] IRP_MJ_CREATE\n");
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS
DispatchClose(
PDEVICE_OBJECT pDevObj,
PIRP pIrp
)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
dprintf("[aNgE] IRP_MJ_CLOSE\n");
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS
DispatchIoctl(
PDEVICE_OBJECT pDevObj,
PIRP pIrp
)
{
NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
PIO_STACK_LOCATION pIrpStack;
ULONG uIoControlCode;
PVOID pIoBuffer;
ULONG uInSize;
ULONG uOutSize;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
switch(uIoControlCode) {
case IOCTL_HELLO: {
dprintf("[aNgE] Hello\n");
status = STATUS_SUCCESS;
}
break;
//
// 添加执行代码
//
}
if(status == STATUS_SUCCESS)
pIrp->IoStatus.Information = uOutSize;
else
pIrp->IoStatus.Information = 0;
/////////////////////////////////////
pIrp->IoStatus.Status = status;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
#pragma pack(1)
typedef struct ServiceDescriptorEntry
{
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase;
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} SSDT_Entry;
#pragma pack()
__declspec(dllimport) SSDT_Entry KeServiceDescriptorTable;
//////////////////////////////////////////////////////////////////////////
ULONG g_uCr0;
void WPOFF()
{
ULONG uAttr;
_asm
{
push eax;
mov eax, cr0;
mov uAttr, eax;
and eax, 0FFFEFFFFh; // CR0 16 BIT = 0
mov cr0, eax;
pop eax;
cli
};
g_uCr0 = uAttr; //保存原有的CRO 屬性
}
VOID WPON()
{
_asm
{
sti
push eax;
mov eax, g_uCr0; //恢復原有CR0 屬性
mov cr0, eax;
pop eax;
};
}
//////////////////////////////////////////////////////////////////////////NtReadVirtualMemory
ULONG OldNtReadVirtualMemoryAdd;//原来NtReadVirtualMemory的服务地址
ULONG reentryadd_NtReadVirtualMemory;
__declspec(naked) NTSTATUS __stdcall NewNtReadVirtualMemory(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG NumberOfBytesToRead,
OUT PULONG NumberOfBytesReaded OPTIONAL)
{
__asm
{
push 0x1C
push 0x804daef0
jmp [reentryadd_NtReadVirtualMemory]
}
}
ULONG Pass_NtReadVirtualMemory()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)KeServiceDescriptorTable.ServiceTableBase + 0xBA * 4;
OldNtReadVirtualMemoryAdd = *(ULONG*)Address;
reentryadd_NtReadVirtualMemory = *(ULONG*)Address;
reentryadd_NtReadVirtualMemory=reentryadd_NtReadVirtualMemory + 0x7;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)NewNtReadVirtualMemory; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_NtReadVirtualMemory()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)KeServiceDescriptorTable.ServiceTableBase + 0xBA * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = OldNtReadVirtualMemoryAdd; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////NtWriteVirtualMemory
ULONG OldNtWriteVirtualMemoryAdd;//原来NtWriteVirtualMemory的服务地址
ULONG reentryadd_NtWriteVirtualMemory;
__declspec(naked) NTSTATUS __stdcall NewNtWriteVirtualMemory(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
IN PVOID Buffer,
IN ULONG NumberOfBytesToWrite,
OUT PULONG NumberOfBytesWritten OPTIONAL )
{
__asm
{
push 0x1C
push 0x804daf08
jmp [reentryadd_NtWriteVirtualMemory]
}
}
ULONG Pass_NtWriteVirtualMemory()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)KeServiceDescriptorTable.ServiceTableBase + 0x115 * 4;
OldNtWriteVirtualMemoryAdd = *(ULONG*)Address;
reentryadd_NtWriteVirtualMemory = *(ULONG*)Address;
reentryadd_NtWriteVirtualMemory=reentryadd_NtWriteVirtualMemory + 0x7;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)NewNtWriteVirtualMemory; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_NtWriteVirtualMemory()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)KeServiceDescriptorTable.ServiceTableBase + 0x115 * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = OldNtWriteVirtualMemoryAdd; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
ULONG GetFunctionAddr( IN PCWSTR FunctionName);
//////////////////////////////////////////////////////////////////////////KiAttachProcess
//ULONG* UX;
ULONG Pass_KiAttachProcess()
{
// *UX++;
unsigned char* actual_function;
KIRQL oldIrql;
int i=0;
unsigned char newcode[] = { 0x8b, 0xff, 0x55, 0x8b, 0xec, 0x53, 0x56 };
actual_function = (unsigned char *) GetFunctionAddr(L"KeUnstackDetachProcess");
actual_function=actual_function+0x324;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
for(i=0;i < 7;i++)
{
actual_function[i] = newcode[i];
}
KeLowerIrql(oldIrql);
WPON();
return 1;
}
//////////////////////////////////////////////////////////////////////////NtOpenProcess
ULONG OldNtProcessAdd;
ULONG reentryadd_NtWriteVirtualMemory;
NTSTATUS
_NtOpenProcess (
__out PHANDLE ProcessHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__in_opt PCLIENT_ID ClientId
)
{
HANDLE Handle;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status;
PEPROCESS Process;
PETHREAD Thread;
CLIENT_ID CapturedCid={0};
BOOLEAN ObjectNamePresent;
BOOLEAN ClientIdPresent;
ACCESS_STATE AccessState;
AUX_ACCESS_DATA AuxData;
ULONG Attributes;
LUID SeDebugPrivilege = {0};
POBJECT_TYPE _PsProcessType;
PEPROCESS cpeprocess,temp_peprocess;
PAGED_CODE();
cpeprocess=PsGetCurrentProcess();
if (!_stricmp("DNF.exe",(char*)((ULONG)cpeprocess+0x174)))
{
// DbgPrint("DNF called!");
Status = PsLookupProcessByProcessId(
CapturedCid.UniqueProcess,
&temp_peprocess
);
if (NT_SUCCESS(Status))
{
if (!_stricmp("csrss.exe",(char*)((ULONG)temp_peprocess+0x174)))
{
return STATUS_ACCESS_DENIED;
}
if (!_stricmp("OllyDBG.EXE",(char*)((ULONG)temp_peprocess+0x174)))
{
return STATUS_ACCESS_DENIED;
}
if (!_stricmp("Ollyice.EXE",(char*)((ULONG)temp_peprocess+0x174)))
{
return STATUS_ACCESS_DENIED;
}
}
// DbgPrint("%08x called! want to open %s\n",(unsigned long)cpeprocess,((ULONG)temp_peprocess+0x174));
return NtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes, ClientId);
}
(ULONG)_PsProcessType=*(ULONG*)PsProcessType;
PreviousMode = KeGetPreviousMode();
SeDebugPrivilege =RtlConvertLongToLuid(SE_DEBUG_PRIVILEGE);
if (PreviousMode != KernelMode) {
__try {
ProbeForWriteHandle (ProcessHandle);
ProbeForReadSmallStructure (ObjectAttributes,
sizeof(OBJECT_ATTRIBUTES),
sizeof(ULONG));
ObjectNamePresent = (BOOLEAN)ARGUMENT_PRESENT (ObjectAttributes->ObjectName);
Attributes = 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);
Attributes = 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,
&_PsProcessType->TypeInfo.GenericMapping
);
if ( !NT_SUCCESS(Status) ) {
return Status;
}
if (SeSinglePrivilegeCheck( SeDebugPrivilege, PreviousMode )) {
if ( AccessState.RemainingDesiredAccess & MAXIMUM_ALLOWED ) {
AccessState.PreviouslyGrantedAccess |= PROCESS_ALL_ACCESS;
} else {
AccessState.PreviouslyGrantedAccess |= ( AccessState.RemainingDesiredAccess );
}
AccessState.RemainingDesiredAccess = 0;
}
if (ObjectNamePresent) {
Status = ObOpenObjectByName(
ObjectAttributes,
_PsProcessType,
PreviousMode,
&AccessState,
0,
NULL,
&Handle
);
SeDeleteAccessState( &AccessState );
if ( NT_SUCCESS(Status) ) {
__try {
*ProcessHandle = Handle;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode ();
}
}
return Status;
}
if ( ClientIdPresent ) {
Thread = NULL;
if (CapturedCid.UniqueThread) {
Status = PsLookupProcessThreadByCid(
&CapturedCid,
&Process,
&Thread
);
if (!NT_SUCCESS(Status)) {
SeDeleteAccessState( &AccessState );
return Status;
}
} else {
Status = PsLookupProcessByProcessId(
CapturedCid.UniqueProcess,
&Process
);
if ( !NT_SUCCESS(Status) ) {
SeDeleteAccessState( &AccessState );
return Status;
}
}
//
// OpenObjectByAddress
//
Status = ObOpenObjectByPointer(
Process,
Attributes,
&AccessState,
0,
_PsProcessType,
PreviousMode,
&Handle
);
SeDeleteAccessState( &AccessState );
if (Thread) {
ObDereferenceObject(Thread);
}
ObDereferenceObject(Process);
if (NT_SUCCESS (Status)) {
__try {
*ProcessHandle = Handle;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode ();
}
}
return Status;
}
return STATUS_INVALID_PARAMETER_MIX;
}
ULONG Pass_NtProcess()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)KeServiceDescriptorTable.ServiceTableBase + 0x7A * 4;
OldNtProcessAdd = *(ULONG*)Address;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)_NtOpenProcess; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_NtProcess()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)KeServiceDescriptorTable.ServiceTableBase + 0x7A * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = OldNtProcessAdd; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
//base ab78e000
//nop-2 ab78fe9e ab79359d
//jmp-1 ab79558f ab79171c
//////////////////////////////////////////////////////////////////////////
ULONG Pass_DebugPort()
{
// ULONG Detour_Add;
unsigned char* Detour_Add_559d;//nop 2 byte
unsigned char* Detour_Add_1e9e;//nop 2 byte
unsigned char* Detour_Add_371c;//jmp 1 byte check code seg
unsigned char* Detour_Add_758f;//jmp 1 byte check kiattachprocess
// unsigned char* Detour_Add_735e;//jmp
// unsigned char* Detour_Add_2471;//jmp
// unsigned char* Detour_Add_2490;//jmp
// unsigned char* Detour_Add_5f8c;//jmp
// unsigned char* Detour_Add_4f9a;//jmp
// unsigned char* Detour_Add_6352;//jmp
// unsigned char* Detour_Add_4232;//jmp
// unsigned char* Detour_Add_3787;//jmp
KIRQL oldIrql;
ULONG Address=0,tempadd=0;
ULONG i=0;
// unsigned char code_ret[] = { 0xc3, 0x90};//16ac 4250 ret
//73ce jmp
// Address = (ULONG)KeServiceDescriptorTable.ServiceTableBase + 0xBA * 4;
// tempadd = *(ULONG*)Address;
// TenBase=((*(ULONG*)(tempadd+1))-0x3308);
(ULONG)Detour_Add_559d=TenBase+0x559d;
(ULONG)Detour_Add_1e9e=TenBase+0x1e9e;
(ULONG)Detour_Add_371c=TenBase+0x371c;
(ULONG)Detour_Add_758f=TenBase+0x758f;
// (ULONG)Detour_Add_735e=TenBase+0x735e;
// (ULONG)Detour_Add_2471=TenBase+0x2471;
// (ULONG)Detour_Add_2490=TenBase+0x2490;
// (ULONG)Detour_Add_5f8c=TenBase+0x5f8c;
// (ULONG)Detour_Add_4f9a=TenBase+0x4f9a;
// (ULONG)Detour_Add_6352=TenBase+0x6352;
// (ULONG)Detour_Add_4232=TenBase+0x4232;
// (ULONG)Detour_Add_3787=TenBase+0x3787;
//Detour_Add=*(ULONG*)(TenBase+0xcedc)+4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
Detour_Add_371c[0]=0xeb;
Detour_Add_758f[0]=0xeb;
// Detour_Add_735e[0]=0xeb;
// Detour_Add_2471[0]=0xeb;
// Detour_Add_2490[0]=0xeb;
// Detour_Add_5f8c[0]=0xeb;
// Detour_Add_4f9a[0]=0xeb;
// Detour_Add_6352[0]=0xeb;
// Detour_Add_4232[0]=0xeb;
// Detour_Add_3787[0]=0xeb;
for(i=0;i < 2;i++)
{
Detour_Add_559d[i] = 0x90;
Detour_Add_1e9e[i] = 0x90;
}
// *(ULONG*)Detour_Add=0x70;
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_DebugPort()
{
KIRQL oldIrql;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
// *(ULONG*)Detour_Add=0xbc;
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
ULONG Pass_KernelDebug()
{
KIRQL oldIrql;
ULONG Address=0;
ULONG _Detour_Add;
Address = *(ULONG*)((ULONG)KeServiceDescriptorTable.ServiceTableBase + 0xBA * 4);
Address=*(ULONG*)(Address+1);
_Detour_Add=Address-0x2e1;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*(unsigned short*)_Detour_Add=0x9090;
KeLowerIrql(oldIrql);
WPON();
KdEnableDebugger();
return 1;
}
//////////////////////////////////////////////////////////////////////////
VOID
CitydOnTimer(
IN PDEVICE_OBJECT DeviceObject,
IN PVOID Context
)
{
unsigned char* Detour_Add_559d;//nop 2 byte
unsigned char* Detour_Add_1e9e;//nop 2 byte
unsigned char* Detour_Add_371c;//jmp 1 byte check code seg
unsigned char* Detour_Add_758f;//jmp 1 byte check kiattachprocess
unsigned char* ntreadmem=(unsigned char*)OldNtReadVirtualMemoryAdd;
__try
{ www.2cto.com
if (ntreadmem[0]!=0x6a)
{
//TenBase=((*(ULONG*)(OldNtReadVirtualMemoryAdd+1))-0x3308);
TenBase=((*(ULONG*)(OldNtReadVirtualMemoryAdd+1))-0x273c);
DbgPrint("TenBase=%08x\n",TenBase);
(ULONG)Detour_Add_559d=TenBase+0x559d;
(ULONG)Detour_Add_1e9e=TenBase+0x1e9e;
(ULONG)Detour_Add_371c=TenBase+0x371c;
(ULONG)Detour_Add_758f=TenBase+0x758f;
if (Detour_Add_371c[0]==0x74 || Detour_Add_758f[0]==0x74 || Detour_Add_559d[0]==0x87 || Detour_Add_1e9e[0]==0x87)
{
DbgPrint("fix debugport!!!!!!\n");
Pass_DebugPort();
Pass_KiAttachProcess();
DbgPrint("Pass_DebugPort()!!!\n");
}
}
}
__except(1)
{
DbgPrint("CitydOnTimer error!\n");
}
}
//////////////////////////////////////////////////////////////////////////
ULONG ObOpenObjectByPointerAdd;
void __declspec(naked) my_function_detour_NtOpenProcess()
{
__asm
{
push eax
push dword ptr [ebp-38h]
push dword ptr [ebp-24h]
mov eax,ObOpenObjectByPointerAdd
call eax
_emit 0xEA
_emit 0xAA
_emit 0xAA
_emit 0xAA
_emit 0xAA
_emit 0x08
_emit 0x00
}
}
//////////////////////////////////////////////////////////////////////////
ULONG GetFunctionAddr( IN PCWSTR FunctionName)
{
UNICODE_STRING UniCodeFunctionName;
RtlInitUnicodeString( &UniCodeFunctionName, FunctionName );
return (ULONG)MmGetSystemRoutineAddress( &UniCodeFunctionName );
}
char OpenProcess_g_oricode[8];
char* OpenProcess_non_paged_memory;
ULONG OpenProcess_g_KiInsertQueueApc;
ULONG Pass_NtOpenProcess()
{
unsigned long detour_address;
unsigned long reentry_address;
KIRQL oldIrql;
int i = 0;
char* actual_function;
unsigned char newcode[] = { 0xEA, 0x44, 0x33, 0x22, 0x11, 0x08,0x00};
//////////////////////////////////////////////////////////////////////////获得ObOpenObjectByPointer的地址
ObOpenObjectByPointerAdd=GetFunctionAddr( L"ObOpenObjectByPointer");
//////////////////////////////////////////////////////////////////////////修改跳转地址
OpenProcess_g_KiInsertQueueApc=GetFunctionAddr(L"NtOpenProcess");
actual_function = (char *)(OpenProcess_g_KiInsertQueueApc+0x21d);
reentry_address = ((unsigned long)OpenProcess_g_KiInsertQueueApc) + 0x229;
OpenProcess_non_paged_memory =(char*) ExAllocatePool(NonPagedPool, 256);
for(i=0;i<256;i++)
{
((unsigned char *)OpenProcess_non_paged_memory)[i] = ((unsigned char *)my_function_detour_NtOpenProcess)[i];
}
detour_address = (unsigned long)OpenProcess_non_paged_memory;
*( (unsigned long *)(&newcode[1]) ) = detour_address;
for(i=0;i<200;i++)
{
if( (0xAA == ((unsigned char *)OpenProcess_non_paged_memory)[i]) &&
(0xAA == ((unsigned char *)OpenProcess_non_paged_memory)[i+1]) &&
(0xAA == ((unsigned char *)OpenProcess_non_paged_memory)[i+2]) &&
(0xAA == ((unsigned char *)OpenProcess_non_paged_memory)[i+3]))
{
*( (unsigned long *)(&OpenProcess_non_paged_memory[i]) ) = reentry_address;
break;
}
}
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
for(i=0;i < 7;i++)
{
OpenProcess_g_oricode[i] = actual_function[i];
actual_function[i] = newcode[i];
}
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_NtOpenProcess()
{
char *actual_function = (char *)(OpenProcess_g_KiInsertQueueApc+0x21d);
KIRQL oldIrql;
int i = 0;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
for(i=0;i < 7;i++)
{
actual_function[i] = OpenProcess_g_oricode[i];
}
KeLowerIrql(oldIrql);
WPON();
ExFreePool(OpenProcess_non_paged_memory);
}
//////////////////////////////////////////////////////////////////////////
void __declspec(naked) my_function_detour_NtOpenThread()
{
__asm
{
push eax
push dword ptr [ebp-34h]
push dword ptr [ebp-20h]
mov eax,ObOpenObjectByPointerAdd
call eax
_emit 0xEA
_emit 0xAA
_emit 0xAA
_emit 0xAA
_emit 0xAA
_emit 0x08
_emit 0x00
}
}
//////////////////////////////////////////////////////////////////////////
char OpenThread_g_oricode[8];
char* OpenThread_non_paged_memory;
ULONG OpenThread_g_KiInsertQueueApc;
ULONG Pass_NtOpenThread()
{
char *actual_function;
unsigned long detour_address;
unsigned long reentry_address;
KIRQL oldIrql;
int i = 0;
unsigned char newcode[] = { 0xEA, 0x44, 0x33, 0x22, 0x11, 0x08,0x00};
//////////////////////////////////////////////////////////////////////////获得ObOpenObjectByPointer的地址
ObOpenObjectByPointerAdd=GetFunctionAddr( L"ObOpenObjectByPointer");
//////////////////////////////////////////////////////////////////////////修改跳转地址
OpenThread_g_KiInsertQueueApc=GetFunctionAddr(L"NtOpenThread");
actual_function = (char *)(OpenThread_g_KiInsertQueueApc+0x213);
reentry_address = ((unsigned long)OpenThread_g_KiInsertQueueApc) + 0x21f;
OpenThread_non_paged_memory =(char*) ExAllocatePool(NonPagedPool, 256);
for(i=0;i<256;i++)
{
((unsigned char *)OpenThread_non_paged_memory)[i] = ((unsigned char *)my_function_detour_NtOpenThread)[i];
}
detour_address = (unsigned long)OpenThread_non_paged_memory;
*( (unsigned long *)(&newcode[1]) ) = detour_address;
for(i=0;i<200;i++)
{
if( (0xAA == ((unsigned char *)OpenThread_non_paged_memory)[i]) &&
(0xAA == ((unsigned char *)OpenThread_non_paged_memory)[i+1]) &&
(0xAA == ((unsigned char *)OpenThread_non_paged_memory)[i+2]) &&
(0xAA == ((unsigned char *)OpenThread_non_paged_memory)[i+3]))
{
*( (unsigned long *)(&OpenThread_non_paged_memory[i]) ) = reentry_address;
break;
}
}
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
for(i=0;i < 7;i++)
{
OpenThread_g_oricode[i] = actual_function[i];
actual_function[i] = newcode[i];
}
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_NtOpenThread()
{
char *actual_function = (char *)(OpenThread_g_KiInsertQueueApc+0x213);
KIRQL oldIrql;
int i = 0;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
for(i=0;i < 7;i++)
{
actual_function[i] = OpenThread_g_oricode[i];
}
KeLowerIrql(oldIrql);
WPON();
ExFreePool(OpenThread_non_paged_memory);
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
unsigned long FindKey(unsigned char* Base,unsigned long Offset,unsigned char* Code, unsigned long SizeCode)
{
unsigned long i;
for (i=0;i<SizeCode;i++)
{
if (Base[i+Offset]==Code[i])
{
continue;
}
else
{
return 0;
}
}
return 1;
}
VOID FakeThread(IN PVOID pContext)
{
LARGE_INTEGER liTime = RtlConvertLongToLargeInteger(-(LONG)200000* 10000);
while(1)
{
DbgPrint("[FakeThread] In Wanmei FakeThread\n");
KeDelayExecutionThread(KernelMode,TRUE,&liTime);
}
}
//NTSTATUS PsLookupThreadByThreadId( IN HANDLE ThreadId, OUT PETHREAD *Thread );
unsigned long pPsCreateSystemThread = 0;
ULONG __stdcall CheckWanmeiCreateSystemThread(OUT PHANDLE ThreadHandle,
IN ULONG DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ProcessHandle OPTIONAL,
OUT PCLIENT_ID ClientId OPTIONAL,
IN PKSTART_ROUTINE StartRoutine,
IN PVOID StartContext)
{
char str[256];
ULONG ulBase = (ULONG)StartRoutine;
UCHAR cThreadCode1[] = {0xe9,0xbd,0xb8,0x04,0x00,0xac,0xc0,0x28,0x73,0xde};
UCHAR cThreadCode2[] = {0xe9,0x75,0x62,0x04,0x00,0x10,0x39,0xd0,0xb5,0x48};
if(FindKey((unsigned char *)ulBase, 0x0, cThreadCode1, sizeof(cThreadCode1)))
{
sprintf(str,"CheckWanmeiCreateThread : find cThreadCode1 StartRoutine %08x\n",(unsigned long)StartRoutine);
DbgPrint(str);
return 1;
}
if(FindKey((unsigned char *)ulBase, 0x0, cThreadCode2, sizeof(cThreadCode2)))
{
sprintf(str,"CheckWanmeiCreateThread : find cThreadCode2 StartRoutine %08x\n",(unsigned long)StartRoutine);
DbgPrint(str);
return 2;
}
return 0;
}
__declspec(naked) MyPsCreateSystemThread( OUT PHANDLE ThreadHandle,
IN ULONG DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ProcessHandle OPTIONAL,
OUT PCLIENT_ID ClientId OPTIONAL,
IN PKSTART_ROUTINE StartRoutine,
IN PVOID StartContext)
{
__asm
{
mov edi,edi
push ebp
mov ebp, esp
mov eax, pPsCreateSystemThread
add eax,5
jmp eax
}
}
PETHREAD pethread1=0;
PETHREAD pethread2=0;
NTSTATUS
_PsCreateSystemThread( OUT PHANDLE ThreadHandle,
IN ULONG DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ProcessHandle OPTIONAL,
OUT PCLIENT_ID ClientId OPTIONAL,
IN PKSTART_ROUTINE StartRoutine,
IN PVOID StartContext)
{
NTSTATUS nstatus;
CLIENT_ID clientid;
switch (CheckWanmeiCreateSystemThread(ThreadHandle,DesiredAccess,ObjectAttributes,ProcessHandle,ClientId,StartRoutine,StartContext))
{
case 0:
return MyPsCreateSystemThread(ThreadHandle,DesiredAccess,ObjectAttributes,ProcessHandle,ClientId,StartRoutine,StartContext);
break;
case 1:
nstatus=MyPsCreateSystemThread(ThreadHandle,DesiredAccess,ObjectAttributes,ProcessHandle,&clientid,FakeThread/*StartRoutine*/,StartContext);
PsLookupThreadByThreadId(clientid.UniqueThread,&pethread1);
DbgPrint("pethread1 %08x \n",pethread1);
return nstatus;
break;
case 2:
nstatus=MyPsCreateSystemThread(ThreadHandle,DesiredAccess,ObjectAttributes,ProcessHandle,&clientid,FakeThread/*StartRoutine*/,StartContext);
PsLookupThreadByThreadId(clientid.UniqueThread,&pethread2);
DbgPrint("pethread2 %08x \n",pethread2);
return nstatus;
break;
}
return MyPsCreateSystemThread(ThreadHandle,DesiredAccess,ObjectAttributes,ProcessHandle,ClientId,StartRoutine,StartContext);
}
unsigned char g_oldcode[8]={0};
unsigned long Pass_PsCreateSystemThread()
{
KIRQL oldIrql;
unsigned char newcode[] = { 0xE9, 0x44, 0x33, 0x22, 0x11};
pPsCreateSystemThread=GetFunctionAddr(L"PsCreateSystemThread");
memcpy(g_oldcode,(PVOID)pPsCreateSystemThread,5);
*( (unsigned long *)(&newcode[1]) ) = (ULONG)_PsCreateSystemThread-pPsCreateSystemThread-5;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
memcpy((PVOID)pPsCreateSystemThread,newcode,5);
KeLowerIrql(oldIrql);
WPON();
return STATUS_SUCCESS;
}
VOID UnDetour_PsCreateSystemThread()
{
KIRQL oldIrql;
// unsigned char newcode[] = { 0xE9, 0x44, 0x33, 0x22, 0x11};
pPsCreateSystemThread=GetFunctionAddr(L"PsCreateSystemThread");
// memcpy(g_oldcode,(PVOID)pPsCreateSystemThread,5);
// *( (unsigned long *)(&newcode[1]) ) = (ULONG)MyPsCreateSystemThread-pPsCreateSystemThread-5;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
memcpy((PVOID)pPsCreateSystemThread,g_oldcode,5);
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////