/*
HOOK ZwReadVirtualMemory,ZwWriteVirtualMemory,ZwOpenProcess
逆向第一个驱动,只能说是F5的太过邪恶了...
By ZzAge[LCG]
*/
#include <ntddk.h>
#include <ntimage.h>
#define DWORD unsigned long
#define WORD unsigned short
#define BOOL unsigned long
#define BYTE unsigned char
#define SEC_IMAGE 0x01000000
typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase;
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry, *PServiceDescriptorTableEntry;
extern PServiceDescriptorTableEntry KeServiceDescriptorTable;
typedef struct _SECTION_IMAGE_INFORMATION {
PVOID EntryPoint;
ULONG StackZeroBits;
ULONG StackReserved;
ULONG StackCommit;
ULONG ImageSubsystem;
WORD SubsystemVersionLow;
WORD SubsystemVersionHigh;
ULONG Unknown1;
ULONG ImageCharacteristics;
ULONG ImageMachineType;
ULONG Unknown2[3];
} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;
NTSYSAPI NTSTATUS NTAPI ZwReadVirtualMemory(
IN HANDLE hProcess,
IN PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG BytesToRead,
OUT PULONG BytesRead);
NTSYSAPI NTSTATUS NTAPI ZwWriteVirtualMemory(
IN HANDLE hProcess,
IN PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG BytesToWrite,
OUT PULONG BytesRead);
NTSYSAPI NTSTATUS NTAPI ZwOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK AccessMask,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId);
NTSYSAPI NTSTATUS NTAPI ZwDuplicateObject(
IN HANDLE SourceProcessHandle,
IN HANDLE SourcrHandle,
IN HANDLE TaegetProcessHandle,
OUT PHANDLE TargetHandle,
IN ACCESS_MASK DesiredAccess OPTIONAL,
IN BOOLEAN InheritHandle,
IN ULONG Options);
NTSYSAPI NTSTATUS NTAPI ZwQueryInformationProcess(
IN HANDLE ProcessHandle,
PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL);
NTSTATUS MyZwReadVirtualMemory(
IN HANDLE hProcess,
N PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG BytesToRead,
IN PULONG BytesRead);
NTSTATUS MyZwWriteVirtualMemory(
N HANDLE hProcess,
IN PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG BytesToWrite,
IN PULONG BytesRead);
NTSTATUS MyZwOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK AccessMase,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId;
typedef NTSTATUS (*NTREADVIRTUALMEMORY)(
IN HANDLE hProcess,
IN PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG BytesToRead,
IN PULONG BytesRead);
typedef NTSTATUS (*NTWRITEVIRTUALMEMORY)(
IN HANDLE hProcess,
IN PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG BytesToWrite,
IN PULONG BytesRead);
typedef NTSTATUS (*NTOPENPROCESS)(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK AccessMask,
IN POBJECT_ATTRIBUTES ObjectAttbutes,
IN PCLIENT_ID ClientId);
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath);
VOID Unload(IN PDRIVER_OBJECT DriverObject);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, Unload)
#endif
NTREADVIRTUALMEMORY Real_ZwReadVirtualMemory;
NTWRITEVIRTUALMEMORY Real_ZwWriteVirtualMemory;
NTOPENPROCESS Real_ZwOpenProcess;
int Pread,Pwrite,Popen;
ULONG ProcessId=0;
ULONG g_Cr0;
DWORD GetDllFunctionAddress(char* lpFunctionName, PUNICODE_STRING pDllName)
{
HANDLE hThread, hSection, hFile, hMod;
SECTION_IMAGE_INFORMATION sii;
IMAGE_DOS_HEADER* dosheader;
IMAGE_OPTIONAL_HEADER* opthdr;
IMAGE_EXPORT_DIRECTORY* pExportTable;
DWORD* arrayOfFunctionAddresses;
DWORD* arrayOfFunctionNames;
WORD* arrayOfFunctionOrdinals;
DWORD functionOrdinal;
DWORD Base, x, functionAddress;
char* functionName;
STRING ntFunctionName, ntFunctionNameSearch;
PVOID BaseAddress = NULL;
SIZE_T size=0;
OBJECT_ATTRIBUTES oa = {sizeof oa, 0, pDllName, OBJ_CASE_INSENSITIVE};
IO_STATUS_BLOCK iosb;
ZwOpenFile(&hFile, FILE_EXECUTE | SYNCHRONIZE, &oa, &iosb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT);
oa.ObjectName = 0;
ZwCreateSection(&hSection, SECTION_ALL_ACCESS, &oa, 0,PAGE_EXECUTE, SEC_IMAGE, hFile);
ZwMapViewOfSection(hSection, NtCurrentProcess(), &BaseAddress, 0, 1000, 0, &size, (SECTION_INHERIT)1,
MEM_TOP_DOWN, PAGE_READWRITE);
ZwClose(hFile);
hMod = BaseAddress;
dosheader = (IMAGE_DOS_HEADER *)hMod;
opthdr =(IMAGE_OPTIONAL_HEADER *) ((BYTE*)hMod+dosheader->e_lfanew+24);
pExportTable =(IMAGE_EXPORT_DIRECTORY*)((BYTE*) hMod + opthdr->DataDirectory[ IMAGE_DIRECTORY_ENTRY_EXPORT].
VirtualAddress);
arrayOfFunctionAddresses = (DWORD*)( (BYTE*)hMod + pExportTable->AddressOfFunctions);
arrayOfFunctionNames = (DWORD*)( (BYTE*)hMod + pExportTable->AddressOfNames);
arrayOfFunctionOrdinals = (WORD*)( (BYTE*)hMod + pExportTable->AddressOfNameOrdinals);
Base = pExportTable->Base;
RtlInitString(&ntFunctionNameSearch, lpFunctionName);
for(x = 0; x < pExportTable->NumberOfFunctions; x++)
{
functionName = (char*)( (BYTE*)hMod + arrayOfFunctionNames[x]);
RtlInitString(&ntFunctionName, functionName);
functionOrdinal = arrayOfFunctionOrdinals[x] + Base - 1;
functionAddress = (DWORD)( (BYTE*)hMod + arrayOfFunctionAddresses[functionOrdinal]);
if (RtlCompareString(&ntFunctionName, &ntFunctionNameSearch, TRUE) == 0)
{
ZwClose(hSection);
return functionAddress;
}
}
ZwClose(hSection);
return 0;
}
NTSTATUS MyZwReadVirtualMemory( IN HANDLE hProcess, IN PVOID BaseAddress, OUT PVOID Buffer, IN ULONG BytesToRead, IN
PULONG BytesRead)
{
PROCESSINFOCLASS ProcessInformation;
HANDLE Handle;
if (hProcess==(HANDLE)-1
||!ProcessId
||ProcessId==(DWORD)PsGetCurrentProcessId()
||(memset(&ProcessInformation,0,0x18),ZwDuplicateObject((HANDLE)0xFFFFFFFF,hProcess,(HANDLE)
0xFFFFFFFF,&Handle,0x400u,0,0))
||(ZwQueryInformationProcess(Handle,0,&ProcessInformation,0x18,0),ZwClose(Handle))
)
{
return Real_ZwReadVirtualMemory(hProcess,BaseAddress,Buffer,BytesToRead,BytesRead);
} else
return -1073741823;
}
NTSTATUS MyZwWriteVirtualMemory( IN HANDLE hProcess, IN PVOID BaseAddress, OUT PVOID Buffer, IN ULONG BytesToWrite,
IN PULONG BytesRead )
{
PROCESSINFOCLASS ProcessInformation;
HANDLE Handle;
if (hProcess==(HANDLE)-1
||!ProcessId
||ProcessId==(DWORD)PsGetCurrentProcessId()
||(memset(&ProcessInformation,0,0x18),ZwDuplicateObject((HANDLE)0xFFFFFFFF,hProcess,(HANDLE)
0xFFFFFFFF,&Handle,0x400u,0,0))
||(ZwQueryInformationProcess(Handle,0,&ProcessInformation,0x18,0),ZwClose(Handle))
)
{
return Real_ZwWriteVirtualMemory(hProcess,BaseAddress,Buffer,BytesToWrite,BytesRead);
} else
return -1073741823;
}
NTSTATUS MyZwOpenProcess( OUT PHANDLE ProcessHandle, IN ACCESS_MASK AccessMase, IN POBJECT_ATTRIBUTES
ObjectAttributes, IN PCLIENT_ID ClientId )
{
if (!ProcessId)
{
if (ClientId->UniqueProcess==(HANDLE)-3)
ProcessId=(int)PsGetCurrentProcessId();
return Real_ZwOpenProcess(ProcessHandle,AccessMase,ObjectAttributes,ClientId);
}
if (ClientId->UniqueProcess!=(HANDLE)ProcessId)
return Real_ZwOpenProcess(ProcessHandle,AccessMase,ObjectAttributes,ClientId);
return -1073741823;
}
NTSTATUS
DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
UNICODE_STRING DllName;
DWORD FunctionAddress;
DriverObject->DriverUnload=Unload;
RtlInitUnicodeString(&DllName,L"\\Device\\HarddiskVolume1\\Windows\\System32\\ntdll.dll");
FunctionAddress=GetDllFunctionAddress("ZwReadVirtualMemory",&DllName);
Pread=*((WORD *)(FunctionAddress+1));
Real_ZwReadVirtualMemory=(NTREADVIRTUALMEMORY)(KeServiceDescriptorTable->ServiceTableBase[Pread]);
FunctionAddress=GetDllFunctionAddress("ZwWriteVirtualMemory",&DllName);
Pwrite=*((WORD *)(FunctionAddress+1));
Real_ZwWriteVirtualMemory=(NTWRITEVIRTUALMEMORY)(KeServiceDescriptorTable->ServiceTableBase[Pwrite]);
FunctionAddress=GetDllFunctionAddress("ZwOpenProcess",&DllName);
Popen=*((WORD *)(FunctionAddress+1));
Real_ZwOpenProcess=(NTOPENPROCESS)(KeServiceDescriptorTable->ServiceTableBase[Popen]);
__asm
{
cli
push eax
mov eax,cr0
mov g_Cr0,eax
and eax,not 10000h
mov cr0,eax
pop eax
}
(NTREADVIRTUALMEMORY)(KeServiceDescriptorTable->ServiceTableBase[Pread])=MyZwReadVirtualMemory;
(NTWRITEVIRTUALMEMORY)(KeServiceDescriptorTable->ServiceTableBase[Pwrite])=MyZwWriteVirtualMemory;
(NTOPENPROCESS)(KeServiceDescriptorTable->ServiceTableBase[Popen])=MyZwOpenProcess;
__asm
{
push eax
mov eax,g_Cr0
mov cr0,eax
pop eax
sti
}
DbgPrint("HOOK Success!\n");
return STATUS_SUCCESS ;
}
VOID
Unload(IN PDRIVER_OBJECT DriverObject)
{
__asm
{
cli
push eax
mov eax,cr0
mov g_Cr0,eax
and eax,not 10000h
mov cr0,eax
pop eax
}
(NTREADVIRTUALMEMORY)(KeServiceDescriptorTable->ServiceTableBase[Pread])=Real_ZwReadVirtualMemory;
(NTWRITEVIRTUALMEMORY)(KeServiceDescriptorTable->ServiceTableBase[Pwrite])=Real_ZwWriteVirtualMemory;
(NTOPENPROCESS)(KeServiceDescriptorTable->ServiceTableBase[Popen])=Real_ZwOpenProcess;
__asm
{
push eax
mov eax,g_Cr0
mov cr0,eax
pop eax
sti
}
DbgPrint("HOOK Unloaded\n");
}