先上代码:

// 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;
}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86

C++ 反调试(NtSetInformationThread)_C++
注意:这个函数一定要加上 WINAPI ,如果不加的话运行程序时就会出现以下错误:
C++ 反调试(NtSetInformationThread)_C++_02解释起来就是,编译器不认识你定义的函数指针,因为你调用的dll函数是一个远函数,而且是一个C函数,你得告诉编译器它是个c函数才行。

效果图

1.正常打开,程序正常运行:
C++ 反调试(NtSetInformationThread)_C++_03

2.使用 vs 调试程序,在以下两处下断点,
C++ 反调试(NtSetInformationThread)_C++_04
启动调试,在 HideFromDebugger(); 正常断下,
C++ 反调试(NtSetInformationThread)_C++_05
再次点击 继续 按钮,本应该在第二个断点处断下,但是程序调试结束了:
C++ 反调试(NtSetInformationThread)_C++_06
3.使用 x32dbg 附加进程,这里为了方便出发断点,我把代码做了一点修改:
(这样就可以在 x32dbg 里下 api 断点了)

void myThread(){
	HideFromDebugger();
	while(1){
		//cout << "hello" << endl;
		MessageBox(NULL,"","",NULL);	// 改成 MessageBox

		Sleep(10000);					// 改成 10s
	}
}
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

当调试器出发 MessageBoxA 断点时,程序退出:
C++ 反调试(NtSetInformationThread)_C++_07

每天进步一点点 = =
C++ 反调试(NtSetInformationThread)_C++_08