Use NtQueryInformationProcess 来检查是否附加了调试器

huangapple go评论67阅读模式
英文:

Use NtQueryInformationProcess to check for debugger attached

问题

Here is the translated code portion:

我正在编写一个简单的C++项目,使用Microsoft的Visual Studio 2022,在其中使用`NtQueryInformationProcess`来检查进程是否正在被调试,但它不起作用。

以下是我的代码:

#include "Header.h"
#include <iostream>
#include <winternl.h>
#include <Windows.h>

// 使用PEB中的Debug标志的方法。这个方法有效并返回a = 1
int PEB_Flag() {
    int a;
    __asm {
        mov eax, dword ptr fs : [18h]
        mov eax, dword ptr ds : [eax + 30h]
        movzx eax, byte ptr ds : [eax + 2h]
        mov[a], eax
    }
    return a;
}

typedef enum _PROCESSINFOCLASS {
    ProcessBasicInformation = 0,
    ProcessDebugPort = 7,
    ProcessWow64Information = 26,
    ProcessImageFileName = 27,
    ProcessBreakOnTermination = 29
} PROCESSINFOCLASS;

typedef NTSTATUS(NTAPI* TNtQueryInformationProcess)(
    IN HANDLE           ProcessHandle,
    IN PROCESSINFOCLASS ProcessInformationClass,
    OUT PVOID           ProcessInformation,
    IN ULONG            ProcessInformationLength,
    OUT PULONG          ReturnLength
);

int main() {
    HANDLE ProcessHandler = OpenProcess(PROCESS_ALL_ACCESS, TRUE, GetCurrentProcessId());

    HMODULE hNtdll = LoadLibraryA("ntdll.dll");
    std::cout << "hNtdll: " << std::hex << hNtdll << std::endl;

    auto pfnNtQueryInformationProcess = (TNtQueryInformationProcess)GetProcAddress(
        hNtdll, "NtQueryInformationProcess");
    DWORD dwProcessDebugPort, dwReturned;
    NTSTATUS status = pfnNtQueryInformationProcess(
        ProcessHandler,
        ProcessDebugPort,
        &dwProcessDebugPort,
        sizeof(DWORD),
        &dwReturned);

    int a = int(status);
    std::cout << "Is debugged: " << a << std::endl;

    std::cout << "OK ?";
    std::cin >> a; // 我在这里设置了一个断点
}

This is the translated portion of your C++ code.

英文:

I am writing a simple C++ project on Microsoft's Visual Studio 2022, that uses NtQueryInformationProcess to check if a process is being debugged but it is not working.

Here is my code:

#include &quot;Header.h&quot;
#include &lt;iostream&gt;
#include &lt;winternl.h&gt;
#include&lt;Windows.h&gt;

// Method use Debug flags in the PEB. This worked and return a = 1
int PEB_Flag() {
    int a;
    __asm {
        mov eax, dword ptr fs : [18h]
        mov eax, dword ptr ds : [eax + 30h]
        movzx eax, byte ptr ds : [eax + 2h]
        mov[a], eax
    }
    return a;
}

typedef enum _PROCESSINFOCLASS {
    ProcessBasicInformation = 0,
    ProcessDebugPort = 7,
    ProcessWow64Information = 26,
    ProcessImageFileName = 27,
    ProcessBreakOnTermination = 29
} PROCESSINFOCLASS;


typedef NTSTATUS(NTAPI* TNtQueryInformationProcess)(
    IN HANDLE           ProcessHandle,
    IN PROCESSINFOCLASS ProcessInformationClass,
    OUT PVOID           ProcessInformation,
    IN ULONG            ProcessInformationLength,
    OUT PULONG          ReturnLength
    );
int main() {
    HANDLE ProcessHandler = OpenProcess(PROCESS_ALL_ACCESS, TRUE, GetCurrentProcessId());

    HMODULE hNtdll = LoadLibraryA(&quot;ntdll.dll&quot;);
    //HINSTANCE hNtDll = GetModuleHandleW(L&quot;ntdll.dll&quot;);
    std::cout &lt;&lt; &quot;hNtdll: &quot; &lt;&lt; std::hex &lt;&lt; hNtdll &lt;&lt; std::endl;

    auto pfnNtQueryInformationProcess = (TNtQueryInformationProcess)GetProcAddress(
        hNtdll, &quot;NtQueryInformationProcess&quot;);
    DWORD dwProcessDebugPort, dwReturned;
    NTSTATUS status = pfnNtQueryInformationProcess(
        //GetCurrentProcess(),
        ProcessHandler,
        ProcessDebugPort,
        &amp;dwProcessDebugPort,
        sizeof(DWORD),
        &amp;dwReturned);



    a = int(status);
    std::cout &lt;&lt; &quot;Is debugged: &quot; &lt;&lt; a &lt;&lt; std::endl;

    std::cout &lt;&lt; &quot;OK ?&quot;;
    std::cin &gt;&gt; a; // I set a breakpoint here
}

I build it, run it in both debug mode and realease mode, and it print "Is debugged: 0", which is wrong because this process is being debugged. I know that my code has something wrong, because I had tried with method check for debugger flag and it prints "1".

答案1

得分: 0

The return value of a call to the NtQueryInformationProcess function indicates only whether or not the call succeeded (and, if it failed, and indication of the nature of the error). Thus, your status variable – assuming the call succeeds – will have the value STATUS_SUCCESS, which is defined as zero (whether or not you cast it to an int).

The actual data that you want to inspect is the dwProcessDebugPort DWORD, whose address you (seemingly correctly) pass to the system call. That will have a non-zero value if the process is being run under a debugger.

So, after your call to NtQueryInformationProcess, your 'diagnostic' code should look something like this:

if (NT_SUCCESS(status)) {
    std::cout << (dwProcessDebugPort == 0 ? "Not debugging.\n" : "Debugging.\n");
}
else {
    std::cout << "Call failed!\n";
}
英文:

The return value of a call to the NtQueryInformationProcess function indicates only whether or not the call succeeded (and, if it failed, and indication of the nature of the error). Thus, your status variable &ndash; assuming the call succeeds &ndash; will have the value STATUS_SUCCESS, which is defined as zero (whether or not you cast it to an int).

The actual data that you want to inspect is the dwProcessDebugPort DWORD, whose address you (seemingly correctly) pass to the system call. That will have a non-zero value if the process is being run under a debugger.

So, after your call to NtQueryInformationProcess, your 'diagnostic' code should look something like this:

if (NT_SUCCESS(status)) {
    std::cout &lt;&lt; (dwProcessDebugPort == 0 ? &quot;Not debugging.\n&quot; : &quot;Debugging.\n&quot;);
}
else {
    std::cout &lt;&lt; &quot;Call failed!\n&quot;;
}

</details>



huangapple
  • 本文由 发表于 2023年5月14日 17:09:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76246680.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定