軟件反調試(4)- 基于IsDebuggerPresent的檢測

反調原理

該檢測方式使用 IsDebuggerPresent 或者 CheckRemoteDebuggerPresent 函數,這兩個函數都是 kernel32.dll 中實現的

對于 IsDebuggerPresent 函數,如果返回值為 TRUE,那么表示當前進程在調試器上下文中運行

CheckRemoteDebuggerPresent 的底層是通過 NtQueryInformationProcess 函數來實現的,函數接受一個 BOOL 的指針參作為返回值

函數調用成功的時候返回非零值,這時候檢查出參 pbDebuggerPresent 指針的值,如果值為 TRUE,那么表示當前進程正在被調試中

使用這兩個函數需要引用 windows.h 頭文件,函數的原型分別如下

BOOL IsDebuggerPresent();BOOL CheckRemoteDebuggerPresent(HANDLE hProcess, PBOOL pbDebuggerPresent);

IsDebuggerPresent 實際上是查詢當前進程的 PEB(Process Environment Block)中的 BeingDebugged 字段

PEB 結構是進程環境塊,是 Windows 內核中一個核心的內部數據結構,包含了進程的大量信息,在 Windows SDK 的 winternl.h 提供了部分定義

PEB 的結構如下,IsDebuggerPresent 使用了第二個字段 BeingDebugged,當被調試的時候該字段值被置為 1

typedef struct _PEB {BYTE Reserved1[2];BYTE BeingDebugged;BYTE Reserved2[1];PVOID Reserved3[2];PPEB_LDR_DATA Ldr;PRTL_USER_PROCESS_PARAMETERS ProcessParameters;PVOID Reserved4[3];PVOID AtlThunkSListPtr;PVOID Reserved5;ULONG Reserved6;PVOID Reserved7;ULONG Reserved8;ULONG AtlThunkSListPtr32;PVOID Reserved9[45];BYTE Reserved10[96];PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;BYTE Reserved11[128];PVOID Reserved12[1];ULONG SessionId;
} PEB, *PPEB;

實現代碼

完整的反調試的實現代碼如下

#include <iostream>
#include <thread>
#include <string>
#include <vector>
#include <windows.h>
#include <TlHelp32.h>
#include <winternl.h>bool CheckProcessIsDebuging()
{//return IsDebuggerPresent();BOOL isDebugging = FALSE;HANDLE hHandle = GetCurrentProcess();CheckRemoteDebuggerPresent(hHandle, &isDebugging);return isDebugging;
}void ThreadProc()
{while (true){if (CheckProcessIsDebuging()){std::cout << "Debugging..." << std::endl;}else{std::cout << "Running..." << std::endl;}std::this_thread::sleep_for(std::chrono::milliseconds(1000));}
}int main()
{std::thread thrd(ThreadProc);thrd.join();return 0;
}

逆向處理

對于 IsDebuggerPresent 的繞過

x64dbg 附加載入 anti04.exe 后,在符號窗口中選中主模塊,然后右側查看到模塊,顯示它的一個導入函數 IsDebuggerPresent

20250704150632

選定 kernel32.IsDebuggerPresent 然后右鍵 “在內存窗口中轉到”,內存窗口中顯示了 IAT 表的該函數的導入項

內存的值即是 kernel32.IsDebuggerPresent 函數的實際地址,選擇該內存地址,右鍵 “搜索引用”

然后在引用頁面中雙擊引用記錄跳轉到 IsDebuggerPresent 函數的調用處,然后在該 call 處進行下斷點

20250704163412

這里的繞過方式有兩種,一個是在 call 之后 test 前修改 eax 的值為 0,但是這個只對當前的一次 call 調用生效

另一個是直接修改 peb 中的 BeingDebugged 字段值,需要先定位到 peb 的內存地址,然后再進行修改

關于 peb 地址是固定的 gs:[60],其中 gs 是 TEB 的段寄存器,gs:[0x60] 是 TEB + 0x60 偏移處的值,是當前線程所屬進程的 PEB 的地址

在左下角的命令框中輸入 gs:[60] 后回車,然后下方顯示出 peb 的內存地址,點擊該地址在內存窗口中進行跳轉

然后在該地址中,修改第三個字節為 0(未修改前為 1 表示在調試中),之后的運行就會顯示程序未處于調試中了

20250704163813

在 x64dbg 中,可以通過 ScyllaHide 插件進行繞過,安裝插件后,默認就已經勾選了對 BeingDebugged 的繞過

這里主要是學習反調試的基本原理,在此不會對插件的使用進行過多的說明

20250704165219

對于 CheckRemoteDebuggerPresent 的繞過

在 cpu 主窗口中 ctrl + G 輸入 CheckRemoteDebuggerPresent 進行搜索,得到下面的地址

20250704172952

選中該行記錄 entry 跳轉到 CheckRemoteDebuggerPresent 函數的匯編代碼位置

20250704173702

下面這兩行的 ds:[rdi] 就是函數的第二個參數 pbDebuggerPresent,ebx = 0 或 1(是否檢測到調試器)

setne bl 會根據前面 cmp 判斷是否寫入 bl = 1,因此將這句匯編進行覆蓋即可,覆蓋為清空 ebx

00007FF89ECC7B60     | 0F95C3                   | setne bl                                        |
00007FF89ECC7B63     | 891F                     | mov dword ptr ds:[rdi],ebx                      |

覆蓋后的代碼顯示如下,這時候就可以實現了對 CheckRemoteDebuggerPresent 的繞過

20250704174058

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/88052.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/88052.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/88052.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

翻譯《The Old New Thing》- Windows 媒體目錄中 onestop.mid 文件的故事

Whats the story of the onestop.mid file in the Media directory? - The Old New Thinghttps://devblogs.microsoft.com/oldnewthing/20130212-00/?p5263 如果你查看你的C:\Windows\Media文件夾&#xff0c;會發現一個名為onestop的MIDI文件。這個奇怪的小MIDI文件背后有什…

【方案】前端UI布局的絕技,響應式布局,多端適配

大家好&#xff0c;歡迎來到停止重構的頻道。本期討論網頁UI布局。網頁UI布局是前端開發中占比較多的部分&#xff0c;做完網頁布局也就差不多完成了一半的工作。本期視頻&#xff0c;我們不再討論基礎的UI布局。我們希望滿足響應式布局&#xff0c;一份代碼適配PC/平板/手機等…

【鄭大二年級信安小學期】Day4上午:Bool盲注時間盲注堆疊查詢post注入HTTP頭部注入ua字段

目錄 0 錄制文件 1 SQL注入-布爾盲注 1.1 布爾盲注優缺點 1.2 先看一下第八關嗯頁面特征 1.3 步驟 1.4 常用函數 1.5 判斷是否字符型 1.6 判斷閉合 1.7 查詢庫名 1.8 查詢數據表 1.9 獲取字段名 1.10 獲取數據 1.11 布爾盲注缺陷 2 時間盲注 2.1 基礎知識 2.2 判…

如何設計一個“真正可復用”的前端組件?

&#x1f9f1; 如何設計一個“真正可復用”的前端組件&#xff1f;&#x1f527; 一個按鈕可以寫10次&#xff0c;也可以封裝一次復用全場&#xff1b;組件是前端的積木&#xff0c;而設計模式才是組裝它們的說明書。你真的在寫“可復用”組件嗎&#xff1f;&#x1f9e0; 什么…

AlpineLinux安裝RabbitMQ及其管理界面

AlpineLinux安裝RabbitMQ及其管理界面 本文以 alpine linux 的 3.21版本為例,演示對于 RabbitMQ 在Linux 下的安裝,其他發行版本大同小異。主要是包管理軟件的命令區別,以及在線倉庫提供的 RabbitMQ 版本差異而已。 (一)安裝 Erlang 因為 RabbitMQ 是用 Erlang 語言編寫…

3S技術+ArcGIS/ENVI全流程實戰:水文、氣象、災害、生態、環境及衛生等領域應用

系統梳理3S技術的核心理論與實戰應用&#xff0c;涵蓋ArcGIS與ENVI軟件操作、空間數據管理、地圖投影轉換、遙感影像解譯、DEM地形分析、空間插值建模等關鍵技能&#xff0c;并結合農業、氣象、生態、災害等跨學科案例&#xff0c;提供從數據獲取到高級可視化的完整解決方案。無…

彈窗中el+table,二次打開彈窗,選擇列會攜帶第一次選擇的數據

1第一次打開彈窗選擇的數據&#xff0c;正確&#xff0c;然后關閉彈窗再次打開彈窗&#xff0c;重新選擇&#xff0c;第二次的數據&#xff0c;錯誤在打開彈窗/關閉彈窗等位置全部做了置空處理&#xff0c;以下是代碼&#xff1a;最后的原因是&#xff1a;el-dailog 自帶緩存&a…

RocketMQ在Spring Boot中的詳細使用指南

?? 目錄 ?? RocketMQ簡介 什么是RocketMQ? 核心概念 ??? 基礎架構組件 ?? 重要概念解釋 ?? 環境搭建 1. RocketMQ服務端安裝 Docker方式(推薦初學者) 手動安裝方式 2. 驗證安裝 ??? Spring Boot集成配置 1. 添加依賴 2. 配置文件 application.y…

基于Java+Springboot的醫院檔案管理系統

源碼編號&#xff1a;S597源碼名稱&#xff1a;基于Springboot的醫院檔案管理系統用戶類型&#xff1a;多角色&#xff0c;用戶、醫護人員、管理員數據庫表數量&#xff1a;11 張表主要技術&#xff1a;Java、Vue、ElementUl 、SpringBoot、Maven運行環境&#xff1a;Windows/M…

Pandas 學習教程

目錄 定義 基本操作 一維數組操作 二維數組操作 數據選擇過濾 數據處理 數據清洗 數據轉換 數據分析 排序 分組聚合 數據透視表 高級操作 合并數據 時間序列處理 自定義函數調用 數據可視化集成 數據導出和導入 大數據分塊處理 定義 全稱&#xff1a; panel da…

QueryWrapper 類的作用與示例詳解

通俗易懂的解釋想象一下你去圖書館找書&#xff1a;QueryWrapper 就像是一個智能的圖書管理員你告訴管理員你的需求&#xff1a;"我要找計算機類、2020年后出版的、作者是張三的書"管理員會根據你的要求組合查詢條件&#xff0c;然后去書庫幫你找書在編程中&#xff…

【PyTorch】PyTorch中torch.nn模塊的循環層

PyTorch深度學習總結 第九章 PyTorch中torch.nn模塊的循環層 文章目錄PyTorch深度學習總結前言一、循環層1. 簡單循環層&#xff08;RNN&#xff09;2. 長短期記憶網絡&#xff08;LSTM&#xff09;3. 門控循環單元&#xff08;GRU&#xff09;4. 雙向循環層二、循環層參數1. …

Ubuntu 24.04 LTS 服務器配置:安裝 JDK、Nginx、Redis。

Ubuntu 24.04 LTS 服務器配置&#xff1a;安裝 JDK、Nginx、Redis。新建用來放置軟件安裝包的目錄 mkdir /home/software 配置目錄所有者為 ubuntu 用戶&#xff1a; chown ubuntu /home/software將軟件安裝包上傳到 /home/software配置 JDK-8 新建 jdk 安裝目錄 mkdir /usr/ja…

工作中用到過哪些設計模式?是怎么實現的?

1. 單例模式&#xff08;結合 Spring Component&#xff09;場景&#xff1a;配置中心、全局狀態管理 Spring 實現&#xff1a;java// 自動注冊為Spring Bean&#xff08;默認單例&#xff09; Component public class AppConfig {Value("${server.port}")private in…

Leetcode 3609. Minimum Moves to Reach Target in Grid

Leetcode 3609. Minimum Moves to Reach Target in Grid 1. 解題思路2. 代碼實現 題目鏈接&#xff1a;3609. Minimum Moves to Reach Target in Grid 1. 解題思路 這一題我一開始走岔了&#xff0c;走了一個正向遍歷走法的思路&#xff0c;無論怎么剪枝都一直超時。后來看了…

工作流引擎:IDEA沒有actiBPMN插件怎么辦?

文章目錄一、問題描述二、替代方案一、問題描述 我們在學習activiti7工作流引擎的時候&#xff0c;需要設計流程圖。 一般推薦的就是使用IDEA插件actiBPMN進行開發。 但是&#xff0c;這個插件在IDEA2019后的版本都不在支持。 也就是搜不到 那么&#xff0c;怎么辦了&#x…

Android音視頻探索之旅 | CMake基礎語法 創建支持Ffmpeg的Android項目

一.CMake語法 CMake語法非常多&#xff0c;我們知道如何導入靜態庫和動態庫以及最基礎的使用&#xff0c;目前是夠用的。其它方面則根據實際項目同步學習。 1.1.基礎語法-常用 cmake_minimum_required&#xff1a;指定cmake最小版本include_directories&#xff1a;引入&#x…

React Native 初始化項目和模擬器運行

中文官方文檔&#xff1a;https://reactnative.cn/docs/environment-setup 英文官方文檔&#xff1a;https://reactnative.dev/docs/getting-started-without-a-framework#step-1-creating-a-new-application 創建新項目 1、初始化 # 如果你之前全局安裝過舊的react-native-cli…

20250706-5-Docker 快速入門(上)-創建容器常用選項_筆記

一、創建容器常用選項&#xfeff;&#xfeff;1. 創建容器常用選項&#xfeff;1&#xff09;常用選項創建容器常用選項&#xfeff;交互式選項&#xff1a;-i&#xff1a;保持標準輸入打開&#xff0c;允許交互式操作-t&#xff1a;分配偽終端&#xff0c;使容器像傳統終端一…

插值與擬合(3):B樣條曲線

在路徑規劃問題中&#xff0c;通常會用到B樣條來平滑路徑&#xff0c;本文實現并封裝了三次準均勻開放B樣條曲線&#xff0c;供大學學習使用。作者提供了三套代碼方案。可以用于不同平臺&#xff1a;方案1&#xff1a;MATLAB&#xff1b;方案2&#xff1a;標準C&#xff1b;方案…