参考 https://blog.csdn.net/Simon798/article/details/103161482
先上代码:
// Test_Console.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include <afx.h> #include <tchar.h> #include <afxwin.h> #include <Windows.h> #include <vector> #include <iostream> #include <assert.h> #include <psapi.h> #include <tlhelp32.h> #include <WtsApi32.h> #include <locale.h> #include <ShObjIdl.h> #include <stdio.h> #include <fstream> #include <string> #include<thread> using namespace std; #pragma region 依赖 typedef enum _THREADINFOCLASS { ThreadBasicInformation, ThreadTimes, ThreadPriority, ThreadBasePriority, ThreadAffinityMask, ThreadImpersonationToken, ThreadDescriptorTableEntry, ThreadEnableAlignmentFaultFixup, ThreadEventPair_Reusable, ThreadQuerySetWin32StartAddress, ThreadZeroTlsCell, ThreadPerformanceCount, ThreadAmILastThread, ThreadIdealProcessor, ThreadPriorityBoost, ThreadSetTlsArrayAddress, ThreadIsIoPending, ThreadHideFromDebugger, ThreadBreakOnTermination, MaxThreadInfoClass } THREADINFOCLASS; typedef NTSTATUS(WINAPI *NtSetInformationThreadPtr)( HANDLE threadHandle, THREADINFOCLASS threadInformationClass, PVOID threadInformation, ULONG threadInformationLength ); // 反调试函数 void HideFromDebugger(){ HMODULE hNtDll = LoadLibrary(TEXT("ntdll.dll")); NtSetInformationThreadPtr NtSetInformationThread = (NtSetInformationThreadPtr)GetProcAddress(hNtDll,"NtSetInformationThread"); NTSTATUS status = NtSetInformationThread(GetCurrentThread(),ThreadHideFromDebugger,NULL,0); } // 线程函数 void myThread(){ HideFromDebugger(); while(1){ cout << "hello" << endl; Sleep(1000); } } #pragma endregion int _tmain(int argc, _TCHAR* argv[]) { // 创建线程 thread thr(myThread); thr.join(); getchar(); return 0; }
注意:这个函数一定要加上 WINAPI ,如果不加的话运行程序时就会出现以下错误:
解释起来就是,编译器不认识你定义的函数指针,因为你调用的dll函数是一个远函数,而且是一个C函数,你得告诉编译器它是个c函数才行。
1.正常打开,程序正常运行:
2.使用 vs 调试程序,在以下两处下断点,
启动调试,在 HideFromDebugger();
正常断下,
再次点击 继续 按钮,本应该在第二个断点处断下,但是程序调试结束了:
3.使用 x32dbg 附加进程,这里为了方便出发断点,我把代码做了一点修改:
(这样就可以在 x32dbg 里下 api 断点了)
void myThread(){ HideFromDebugger(); while(1){ //cout << "hello" << endl; MessageBox(NULL,"","",NULL); // 改成 MessageBox Sleep(10000); // 改成 10s } }
当调试器出发 MessageBoxA 断点时,程序退出:
每天进步一点点 = =