Sna1lGo

反调试——5——检测调试对象

反调试——5——检测调试对象

有一些内容采用的是WRK里面的定义。因为这个算是没有公开的文档,公开的不能这样使用。

查询父进程实现反调试

正常打开(双击运行)的程序的父进程是explorer.exe(资源管理器)(Windows的内置机制),通过查询父进程的ID是否是explorer.exe来判断程序是否被调试了。

这里我直接上代码了。

NTSTATUS
NtQueryInformationProcess(
   __in HANDLE ProcessHandle,
   __in PROCESSINFOCLASS ProcessInformationClass,
   __out_bcount(ProcessInformationLength) PVOID ProcessInformation,
   __in ULONG ProcessInformationLength,
   __out_opt PULONG ReturnLength
  )
#include<iostream>
#include<Windows.h>
#include<winternl.h>
#include<tlhelp32.h>
#include<string.h>
using namespace std;


typedef struct _PROCESS_BASIC_INFORMATION_1 {
   NTSTATUS ExitStatus;
   PPEB PebBaseAddress;
   ULONG_PTR AffinityMask;
   KPRIORITY BasePriority;
   ULONG_PTR UniqueProcessId;
   ULONG_PTR InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION_1;

//定义函数指针
typedef NTSTATUS (NTAPI *_NtQueryInformationProcess)(
   __in HANDLE ProcessHandle,
   __in PROCESSINFOCLASS ProcessInformationClass,
   __out_bcount(ProcessInformationLength) PVOID ProcessInformation,
   __in ULONG ProcessInformationLength,
   __out_opt PULONG ReturnLength
);

_NtQueryInformationProcess NtQueryInformationProcess_My;

int main()
{
//获得NtQueryInformation函数指针
   HMODULE hNtdll = GetModuleHandleA("ntdll.dll");//因为每个程序都会有ntdll,所以就不用动态loadlibrary加载了,直接获取dll的句柄
   if (hNtdll == NULL)
  {
       cout << "获取ntdll句柄错误" << endl;
       return 0;
  }
   NtQueryInformationProcess_My = (_NtQueryInformationProcess)GetProcAddress(hNtdll, "NtQueryInformationProcess");

   //获取当前进程的信息
   HANDLE hCurrentProcess = GetCurrentProcess();
   PROCESS_BASIC_INFORMATION_1 CurrentInfo = { 0 };
   NtQueryInformationProcess_My(hCurrentProcess, ProcessBasicInformation, &CurrentInfo,sizeof(CurrentInfo),NULL);
   auto CurrentParentProcessId = CurrentInfo.InheritedFromUniqueProcessId;

   //遍历所有进程信息,对比进程ID
   PROCESSENTRY32 SnapshotInfo = { 0 };
   SnapshotInfo.dwSize = sizeof(PROCESSENTRY32);
   HANDLE  hSnapshot =  CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
   if (hSnapshot == INVALID_HANDLE_VALUE)
  {
       cout << "创建进程快照失败" << endl;
       return 0;
  }
   auto Sucess = Process32First(hSnapshot, &SnapshotInfo);
   if (Sucess == TRUE)
  {
       do {
           if (wcscmp(SnapshotInfo.szExeFile, L"explorer.exe")==0)//这里使用宽字符
          {
               if (SnapshotInfo.th32ProcessID == CurrentParentProcessId)
              {
                   cout << "程序通过父进程检测,程序的父进程正常" << endl;
              }
               else
              {
                   cout << "检测到父进程不对,程序正在被调试" << endl;
              }
               break;
          }
      } while (Process32Next(hSnapshot, &SnapshotInfo));
  }
   else

分类:

技术点:

相关文章: