英文:
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 "Header.h"
#include <iostream>
#include <winternl.h>
#include<Windows.h>
// 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("ntdll.dll");
//HINSTANCE hNtDll = GetModuleHandleW(L"ntdll.dll");
std::cout << "hNtdll: " << std::hex << hNtdll << std::endl;
auto pfnNtQueryInformationProcess = (TNtQueryInformationProcess)GetProcAddress(
hNtdll, "NtQueryInformationProcess");
DWORD dwProcessDebugPort, dwReturned;
NTSTATUS status = pfnNtQueryInformationProcess(
//GetCurrentProcess(),
ProcessHandler,
ProcessDebugPort,
&dwProcessDebugPort,
sizeof(DWORD),
&dwReturned);
a = int(status);
std::cout << "Is debugged: " << a << std::endl;
std::cout << "OK ?";
std::cin >> 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 – 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";
}
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论