背景
看雪上有人泄露了3.6.0.1406,第一时间先下载下来,然后加壳之后扔进x32dbg,A debugger has been found.......
还能怎么办?右键回收站。
分析
正准备放弃的时候,想了想要不在看看,好吧那就在看看,结果一段瞎分析之后定位到了scylla没有处理完善的函数NtQueryInformationThread和QueryInformationProcess
- HookNtQueryInformationThread ThreadHideFromDebugger
- HookNtQueryInformationProcess ProcessDebugPort
- HookNtQueryInformationProcess ProcessDebugObjectHandle
- HookNtQueryInformationProcess ProcessDebugPort
你问我怎么定位的,全是某牛姓男子给我说的,还有需要注意的是这些api下执行是不会断下的,因为它自己shadow了一份systemcall。
R3的反调试,在scylla配置如下的情况下,添加下面的代码(不管你是inline,vt,ifhook都可以,反正蓝的也不是我的电脑)
在内核的处理逻辑如下(都是最简单的返回,有的情况下返回是错误的)
- NTSTATUS HookNtQueryInformationProcess(
- HANDLE ProcessHandle,
- PROCESSINFOCLASS ProcessInformationClass,
- PVOID ProcessInformation,
- ULONG ProcessInformationLength,
- PULONG ReturnLength
- ) {
-
- UCHAR* fileName = PsGetProcessImageFileName(PsGetCurrentProcess());
-
- if (memcmp((const char*)fileName, "SuperKiller",strlen("SuperKiller")) == 0 && ExGetPreviousMode() == UserMode)//最新的3.6
- {
-
- if (ProcessInformationLength != 0)
- {
- __try
- {
- ProbeForRead(ProcessInformation, ProcessInformationLength, 4);
- if (ReturnLength != 0)
- ProbeForWrite(ReturnLength, 4, 1);
- }
-
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- return GetExceptionCode();
- }
- }
-
-
- if (ProcessInformationClass == ProcessDebugObjectHandle)
- {
- DbgPrint("HookNtQueryInformationProcess ProcessDebugObjectHandle \n");
- PEPROCESS TargetProcess;
- NTSTATUS Status = ObReferenceObjectByHandle(ProcessHandle, 0x0400, *PsProcessType, UserMode, (PVOID*)& TargetProcess, NULL);
- if (NT_SUCCESS(Status) == TRUE)
- {
- __try
- {
- *(ULONG64*)ProcessInformation = NULL;
- if (ReturnLength != NULL)* ReturnLength = sizeof(ULONG64);
-
- Status = STATUS_PORT_NOT_SET;
- }
-
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- Status = GetExceptionCode();
- }
-
- ObDereferenceObject(TargetProcess);
- return Status;
- }
- return Status;
- }
-
-
- else if (ProcessInformationClass == ProcessDebugPort)
- {
- DbgPrint("HookNtQueryInformationProcess ProcessDebugPort \n");
- if (ProcessInformationLength != sizeof(ULONG64))
- return STATUS_INFO_LENGTH_MISMATCH;
-
- PEPROCESS TargetProcess;
- NTSTATUS Status = ObReferenceObjectByHandle(ProcessHandle, 0x0400, *PsProcessType, UserMode, (PVOID*)& TargetProcess, NULL);
- if (NT_SUCCESS(Status) == TRUE)
- {
- __try
- {
- *(ULONG64*)ProcessInformation = 0;
- if (ReturnLength != 0)
- * ReturnLength = sizeof(ULONG64);
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- Status = GetExceptionCode();
- }
-
- ObDereferenceObject(TargetProcess);
- return Status;
- }
- return Status;
- }
-
- else if (ProcessInformationClass == ProcessDebugFlags)
- {
- DbgPrint("HookNtQueryInformationProcess ProcessDebugFlags \n");
- if (ProcessInformationLength != 4)
- return STATUS_INFO_LENGTH_MISMATCH;
-
- PEPROCESS TargetProcess;
- NTSTATUS Status = ObReferenceObjectByHandle(ProcessHandle, 0x0400, *PsProcessType, UserMode, (PVOID*)& TargetProcess, NULL);
- if (NT_SUCCESS(Status) == TRUE)
- {
- __try
- {
- *(ULONG*)ProcessInformation = 0;
- if (ReturnLength != 0)
- * ReturnLength = sizeof(ULONG);
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- Status = GetExceptionCode();
- }
-
- ObDereferenceObject(TargetProcess);
- return Status;
- }
-
- return Status;
- }
-
- else if (ProcessInformationClass == ProcessBreakOnTermination)
- {
- DbgPrint("HookNtQueryInformationProcess ProcessBreakOnTermination \n");
- if (ProcessInformationLength != 4)
- return STATUS_INFO_LENGTH_MISMATCH;
-
- PEPROCESS TargetProcess;
- NTSTATUS Status = ObReferenceObjectByHandle(ProcessHandle, 0x1000, *PsProcessType, UserMode, (PVOID*)& TargetProcess, NULL);
- if (NT_SUCCESS(Status) == TRUE)
- {
- __try
- {
- *(ULONG*)ProcessInformation = 0;
- if (ReturnLength != 0)
- * ReturnLength = sizeof(ULONG);
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- Status = GetExceptionCode();
- }
-
- ObDereferenceObject(TargetProcess);
- return Status;
- }
-
- return Status;
- }
- }
-
- return ((PNtQueryInformationProcess)g_jmpNtQueryInformationProcess)(ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength, ReturnLength);
- }
-
-
- NTSTATUS HookNtQueryInformationThread(
- HANDLE ThreadHandle,
- THREADINFOCLASS ThreadInformationClass,
- PVOID ThreadInformation,
- ULONG ThreadInformationLength,
- PULONG ReturnLength
- ) {
- UCHAR* fileName = PsGetProcessImageFileName(PsGetCurrentProcess());
-
- if (memcmp((const char*)fileName, "SuperKiller", strlen("SuperKiller")) == 0 && ExGetPreviousMode() == UserMode)//最新的3.6
- {
- if (ThreadInformationLength != 0)
- {
- __try
- {
- ProbeForRead(ThreadInformation, ThreadInformationLength, 4);
- if (ReturnLength != 0)
- ProbeForWrite(ReturnLength, 4, 1);
-
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- return GetExceptionCode();
- }
- }
-
- if (ThreadInformationClass == ThreadHideFromDebugger)
- {
- DbgPrint("HookNtQueryInformationThread ThreadHideFromDebugger \n");
- if (ThreadInformationLength != 1)
- return STATUS_INFO_LENGTH_MISMATCH;
-
- PETHREAD TargetThread;
- NTSTATUS Status = ObReferenceObjectByHandle(ThreadHandle, 0x40, *PsThreadType, UserMode, (PVOID*)& TargetThread, NULL);
- if (NT_SUCCESS(Status) == TRUE)
- {
- __try
- {
- *(BOOLEAN*)ThreadInformation =0;
-
- if (ReturnLength != 0)* ReturnLength = 1;
- }
- __except (EXCEPTION_EXECUTE_HANDLER)
- {
- Status = GetExceptionCode();
- }
-
- ObDereferenceObject(TargetThread);
- return Status;
- }
-
- return Status;
- }
-
- }
- return ((PNtQueryInformationThread)g_jmpNtQueryInformationThread)(ThreadHandle, ThreadInformationClass, ThreadInformation, ThreadInformationLength, ReturnLength);
- }
R0的反调试,都是直接返回失败
- NTSTATUS HookNtQuerySystemInformation(
- SYSTEM_INFORMATION_CLASS SystemInformationClass,
- PVOID SystemInformation,
- ULONG SystemInformationLength,
- PULONG ReturnLength
- ) {
- if(SystemInformationClass == SystemKernelDebuggerInformation || SystemInformationClass == SystemKernelDebuggerInformationEx || SystemCodeIntegrityInformation == SystemInformationClass || ProcessDebugObjectHandle == SystemInformationClass)
- return STATUS_UNSUCCESSFUL;
-
- return ((PNtQuerySystemInformation)g_jmpNtQuerySystemInformation)(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
- }
反虚拟机
1、需要处理的是cpuid,代码是抄的别人写的vt,随便改改
Registers->Rcx = (ULONG_PTR)dwCpuidRegisters.ecx & 0xFFFFFFFF7FFFFFFF;//绕过vmp的虚拟机检测
2、需要注意中断,如果用的vthook,需要判断当前的tf标志位
- if (GuestRflag.fields.tf)
- {
- ULONG64 info = 0;
- // 注入一个硬件调试中断
- InjectInterruption(kHardwareException, EXCEPTION_VECTOR_DEBUG, false, 0);
- info = VmxCsRead(GUEST_INTERRUPTIBILITY_INFO);
- info &= ~2;
- VmxCsWrite(GUEST_INTERRUPTIBILITY_INFO, info);
- }
3、NtQuerySystemInformation的处理,比3.5多了一个BMSR
- NTSTATUS HookNtQuerySystemInformation(
- SYSTEM_INFORMATION_CLASS SystemInformationClass,
- PVOID SystemInformation,
- ULONG SystemInformationLength,
- PULONG ReturnLength
- ) {
- if (SystemInformationClass == SystemFirmwareTableInformation && SystemInformation)
- {
- __try
- {
- if (*(PULONG)SystemInformation == 0x4649524d || *(PULONG)SystemInformation == 0x52534d42)//MRIF BMSR
- {
- return STATUS_UNSUCCESSFUL;
- }
- }
- __except (EXCEPTION_EXECUTE_HANDLER) {}
- }
-
- return ((PNtQuerySystemInformation)g_jmpNtQuerySystemInformation)(SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength);
- }
结束
做完上面的准备工作,vmp3.6就能在虚拟机正常被调试了,这些都是某牛姓男子教的,我啥也不会!我是真菜啊!