过HS硬件断点驱动源码
#include <ntddk.h>
typedef struct _tagSSDT {
PVOID pvSSDTBase;
} SSDT, *PSSDT;
extern PSSDT KeServiceDescriptorTable;
KPROCESSOR_MODE KeGetPreviousMode(VOID);
typedef NTSTATUS (NTAPI *pfnNtGetContextThread)(
HANDLE ThreadHandle,
PCONTEXT pContext );
pfnNtGetContextThread real_NtGetContextThread = 0;
ULONG offset_address = 0;
ULONG name_offset = 0;
int filter_enabled = 0;
int safe_memcpy(void *dest, void *src, int len)
{
PMDL pMdl_dest = 0, pMdl_src = 0;
void *map_addr_dest = 0, *map_addr_src = 0;
KIRQL old_IRQ = {0};
if (!MmIsAddressValid(dest) || !MmIsAddressValid(src)) {
return 1;
}
pMdl_dest = IoAllocateMdl(dest, len, FALSE, FALSE, 0);
pMdl_src = IoAllocateMdl(src, len, FALSE, FALSE, 0);
if (pMdl_dest && pMdl_src) {
__try {
MmProbeAndLockPages(pMdl_dest, KernelMode, IoWriteAccess | IoReadAccess);
MmProbeAndLockPages(pMdl_src, KernelMode, IoWriteAccess | IoReadAccess);
} __except (EXCEPTION_EXECUTE_HANDLER) {
goto bed;
}
map_addr_dest = MmGetSystemAddressForMdlSafe(pMdl_dest, NormalPagePriority);
map_addr_src = MmGetSystemAddressForMdlSafe(pMdl_src, NormalPagePriority);
if (map_addr_dest && map_addr_src) {
old_IRQ = KeRaiseIrqlToDpcLevel();
memcpy(map_addr_dest, map_addr_src, len);
KeLowerIrql(old_IRQ);
MmUnlockPages(pMdl_dest);
MmUnlockPages(pMdl_src);
IoFreeMdl(pMdl_dest);
IoFreeMdl(pMdl_src);
return 0;
} else {
goto bed;
}
}
bed:
if (pMdl_dest) {
MmUnlockPages(pMdl_dest);
IoFreeMdl(pMdl_dest);
}
if (pMdl_src) {
MmUnlockPages(pMdl_src);
IoFreeMdl(pMdl_src);
}
return 2;
}
NTSTATUS FilterNtGetContextThread(
HANDLE ThreadHandle,
PCONTEXT pContext)
{
int c;
char *pName = (char *)((ULONG)PsGetCurrentProcess() + name_offset);
if (KeGetPreviousMode() == UserMode) {
__try {
ProbeForRead(pContext, sizeof(CONTEXT), 4);
} __except (EXCEPTION_EXECUTE_HANDLER) {
return STATUS_UNSUCCESSFUL;
}
}
//DbgPrint("%s\n", pName);
if (!_stricmp(pName, "MapleStory.exe")) {
safe_memcpy(&c, (void *)pContext, 4);
//DbgPrint("%d\n", c);
if (c == 7) { //enable
filter_enabled = 1;
return 0;
}
if (c == 123) { //its me :)
pContext->ContextFlags = CONTEXT_CONTROL | CONTEXT_DEBUG_REGISTERS;
return real_NtGetContextThread(ThreadHandle, pContext);
}
if (filter_enabled) {
real_NtGetContextThread(ThreadHandle, pContext);
pContext->Dr0 = pContext->Dr1 = pContext->Dr2 = pContext->Dr3 = 0;
return 0;
}
}
return real_NtGetContextThread(ThreadHandle, pContext);
}
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject;
safe_memcpy((void *)offset_address, (void *)&real_NtGetContextThread, 4);
if (deviceObject != NULL) {
IoDeleteDevice(deviceObject);
}
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
ULONG build_number, ssdt_offset, tmp;
ULONG ulFilterNtGetContextThread = (ULONG)FilterNtGetContextThread;
PsGetVersion(0, 0, &build_number, 0);
switch (build_number) {
case 2195:
ssdt_offset = 0x49;
name_offset = 0x1fc;
break;
case 2600:
ssdt_offset = 0x55;
name_offset = 0x174;
break;
case 3790:
ssdt_offset = 0x59;
name_offset = 0x164;
break;
case 6000:
ssdt_offset = 0x95;
name_offset = 0x14c;
break;
case 7600:
ssdt_offset = 0x87;
name_offset = 0x16c;
break;
default:
return STATUS_UNSUCCESSFUL;
}
safe_memcpy(&tmp, (void *)KeServiceDescriptorTable, 4);
offset_address = tmp + ssdt_offset * 4;
safe_memcpy((void *)&real_NtGetContextThread, (void *)offset_address, 4);
safe_memcpy((void *)offset_address, &ulFilterNtGetContextThread, 4);
DriverObject->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
页:
[1]