精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

簡單了解反調試技術

蛇矛實驗室 ? 來源:蛇矛實驗室 ? 2023-11-13 11:10 ? 次閱讀

本期作者/牛杰

前言

反調試技術,是一種防止逆向的方案。逆向人員如果遇到復雜的代碼混淆,有時會使用調試器動態分析代碼邏輯簡化分析流程。例如惡意軟件通常會被安全研究人員、反病毒廠商和其他安全專業人員分析和調試,以了解其行為和功能,并開發相應的安全措施來保護系統,這時,惡意軟件開發人員就會使用反調試技術阻礙逆向人員的分析,以達到增加自己惡意代碼的存活時間。此外,安全人員也需要了解反調試技術,當遇到反調試代碼時,可以使用相對應的反反調試。

反調試

1. IsDebuggerPresent

IsDebuggerPresent 用于檢測當前進程是否正在被調試。該函數屬于 Windows 調試輔助功能,可以幫助開發人員在程序運行過程中進行調試。

IsDebuggerPresent 函數的原型如下:

BOOL IsDebuggerPresent(void);

該函數返回一個布爾值,如果當前進程正在被調試,則返回 TRUE;否則返回 FALSE。

檢查進程環境塊(PEB)中是否設置了正在調試的標志。

這實際上與IsDebuggerPresent()內部執行的代碼相同。

x86的PEB指針從DWORD FS:[0x30]中獲取,x64在QWORD GS:[0x60]中獲取。

IsDebuggerPresent 函數只能檢測當前進程是否正在被調試,而不能檢測其他進程的調試狀態。此外,安全研究人員和反病毒廠商可以使用各種技術和工具來繞過 IsDebuggerPresent 函數的檢測,因此它并不是一個絕對可靠的方法來判斷系統是否正在進行調試。

2. CheckRemoteDebuggerPresent

CheckRemoteDebuggerPresent 用于檢測當前進程是否被遠程調試器附加。該函數可以檢測當前進程是否正在被遠程調試器(如遠程調試器工具或調試代理程序)監視和調試,惡意軟件可以使用該函數來判斷自身是否處于被遠程調試的環境中,并根據檢測結果采取相應的措施,如崩潰、隱藏關鍵代碼等,以防止被分析和調試。

CheckRemoteDebuggerPresent 函數的原型如下:

BOOL CheckRemoteDebuggerPresent(
HANDLE hProcess,
PBOOL pbDebuggerPresent
);

該函數接受兩個參數

hProcess:要檢查的進程的句柄。通常使用 GetCurrentProcess() 函數獲取當前進程的句柄。

pbDebuggerPresent:一個指向 BOOL 類型的變量的指針,用于接收檢測結果。如果檢測到遠程調試器附加,則該變量被設置為 TRUE;否則設置為 FALSE。

3. 斷點檢測

斷點是一種調試技術,用于在特定的內存地址上設置斷點,以便在程序執行到該地址時觸發中斷,因此可以通過判斷斷點的存在與否來確認程序是否被調試,斷點分為硬件斷點與軟件斷點,檢測的方式不同。

硬件斷點檢測

x86架構,DR0到DR3寄存器用于設置硬件斷點的地址,DR4和DR5寄存器在x86架構中沒有特定的用途,DR6寄存器是一個狀態寄存器,用于指示硬件斷點的觸發情況。因此我們需要判斷DR0-DR3的值,如果有值不為0,則處于調試狀態,x64架構引入了新的調試寄存器,稱為DR7寄存器,用于控制硬件斷點和其他調試功能,但是判斷是否被調試的方式與x86架構相同。獲取值的代碼如下:

BOOL HardwareBreakpoints()
{
BOOL bResult = FALSE;
PCONTEXT ctx = PCONTEXT(VirtualAlloc(NULL, sizeof(CONTEXT), MEM_COMMIT, PAGE_READWRITE));

if(ctx) {

SecureZeroMemory(ctx, sizeof(CONTEXT));
ctx->ContextFlags = CONTEXT_DEBUG_REGISTERS;
if(GetThreadContext(GetCurrentThread(), ctx)) {
if(ctx->Dr0 != 0|| ctx->Dr1 != 0|| ctx->Dr2 != 0|| ctx->Dr3 != 0)
bResult = TRUE;
}

VirtualFree(ctx, 0, MEM_RELEASE);
}

returnbResult;
}

軟件斷點檢測

軟件斷點又稱int3,在IA-32指令集中用操作碼CC (0xCC)表示,因此有時軟件點的檢測也稱為"0xCC"檢測,調試器在對應設置斷點的位置上修改該地址的字節為0xCC。若是關鍵位置檢測到該指令,可以判斷進程處于調試狀態。

4. PEB

在Windows操作系統中,PEB(Process Environment Block)是一個數據結構,它存儲了進程的環境信息和狀態。每個運行的進程都有一個獨立的PEB。

1. BeingDebugged

與IsDebuggerPresent()內部執行的代碼相同,獲取方式如下:

//x86
PPEB pPeb = (PPEB)__readfsdword(0x30);
//x64
PPEB pPeb = (PPEB)__readgsqword(0x60);

2. NtGlobalFlag

NtGlobalFlag 是PEB的一個字段,通常,當進程未被調試時,NtGlobalFlag字段包含值0x0。調試進程時,該字段通常包含值0x70。

該字段在x86越x64架構中的位置不同。

x86在PEB偏移0x68的位置,x64在PEB便0xBC的位置。

Windows內核全局標記,在Windows調試方案中經常用到。這個標記定義了一組系統的調試參數,包括啟用或禁用調試技術的開關、造成崩潰的錯誤代碼和處理方式等等。通過改變這個標記,可以在運行時設置和禁用不同的調試技術和錯誤處理方式,比如調試器只能訪問當前進程、只允許用戶模式調試、啟用特定的錯誤處理方式等等。但由于NtGlobalFlag標記是內核全局標記,其改變會影響整個系統的行為,需要謹慎處理。

5.ProcessHeap

通過PEB偏移0x18可以找到ProcessHeap,結構體如下:

struct _PEB32
{
UCHAR InheritedAddressSpace; //0x0
UCHAR ReadImageFileExecOptions; //0x1
UCHAR BeingDebugged; //0x2
union
{
UCHAR BitField; //0x3
struct
{
UCHAR ImageUsesLargePages:1; //0x3
UCHAR IsProtectedProcess:1; //0x3
UCHAR IsImageDynamicallyRelocated:1; //0x3
UCHAR SkipPatchingUser32Forwarders:1; //0x3
UCHAR IsPackagedProcess:1; //0x3
UCHAR IsAppContainer:1; //0x3
UCHAR IsProtectedProcessLight:1; //0x3
UCHAR IsLongPathAwareProcess:1; //0x3
};
};
ULONG Mutant; //0x4
ULONG ImageBaseAddress; //0x8
ULONG Ldr; //0xc
ULONG ProcessParameters; //0x10
ULONG SubSystemData; //0x14
ULONG ProcessHeap; //0x18
....
}

在ProcessHeap加上偏移可以找到HeapFlags與ForceFlags,偏移的值根據系統版本和位數會有變化,如下表:

HeapFlags

2baedfc0-7fb1-11ee-939d-92fbcf53809c.png

ForceFlags

2bd16c20-7fb1-11ee-939d-92fbcf53809c.png

如果HeapFlags的值大于2,或ForceFlags的值大于0時,說明被調試。

6. INT 2D

int 2d反調試原理很簡單,正常運行時int 2d觸發異常,進入程序的異常處理函數。而當調試運行時,OD會處理該異常,將eip+1繼續運行,因此可以在異常處理函數中添加一些操作,如果沒有執行這些代碼,說明被調試。這種只能檢測原版Ollydbg,x64dbg和一些帶有反檢測插件的調試器無效。

7. 進程列表

一般情況下,主進程在主線程中啟動核心代碼

QueryInformationJobObject這個api可以獲取當前程序所有的進程列表

不論是主進程還是主線程,他們的ImageFileName應該是都是源程序的文件名filename.exe

8. NtQueryInformationProcess

NtQueryInformationProcess原型如下:

NTSTATUS NTAPI NtQueryInformationProcess(
HANDLE ProcessHandle,// 進程句柄
PROCESSINFOCLASS ProcessInformationClass,// 檢索的進程信息類型
PVOID ProcessInformation,// 接收進程信息的緩沖區指針
ULONG ProcessInformationLength,// 緩沖區指針大小
PULONG ReturnLength // 實際接收的進程信息大小
);

PROCESSINFOCLASS原型如下:

typedefenum_PROCESSINFOCLASS
{
ProcessBasicInformation, 
ProcessQuotaLimits, 
ProcessIoCounters, 
ProcessVmCounters, 
ProcessTimes, 
ProcessBasePriority, 
ProcessRaisePriority,
ProcessDebugPort, //0x7 
ProcessExceptionPort, 
ProcessAccessToken, 
ProcessLdtInformation, 
ProcessLdtSize, 
ProcessDefaultHardErrorMode, 
ProcessIoPortHandlers, 
ProcessPooledUsageAndLimits, 
ProcessWorkingSetWatch,
ProcessUserModeIOPL,
ProcessEnableAlignmentFaultFixup, 
ProcessPriorityClass, 
ProcessWx86Information,
ProcessHandleCount, 
ProcessAffinityMask, 
ProcessPriorityBoost, 
ProcessDeviceMap, 
ProcessSessionInformation, 
ProcessForegroundInformation,
ProcessWow64Information, 
ProcessImageFileName, 
ProcessLUIDDeviceMapsEnabled, 
ProcessBreakOnTermination, 
ProcessDebugObjectHandle, // 0x1E
ProcessDebugFlags, // 0x1F
ProcessHandleTracing, 
ProcessIoPriority, 
ProcessExecuteFlags, 
ProcessResourceManagement, 
ProcessCookie, 
ProcessImageInformation, 
ProcessCycleTime, 
ProcessPagePriority, 
ProcessInstrumentationCallback, 
ProcessThreadStackAllocation, 
ProcessWorkingSetWatchEx,
ProcessImageFileNameWin32, 
ProcessImageFileMapping, 
ProcessAffinityUpdateMode, 
ProcessMemoryAllocationMode, 
ProcessGroupInformation,
ProcessTokenVirtualizationEnabled, 
ProcessConsoleHostProcess, 
ProcessWindowInformation, 
ProcessHandleInformation,
ProcessMitigationPolicy,
ProcessDynamicFunctionTableInformation,
ProcessHandleCheckingMode,
ProcessKeepAliveCount,
ProcessRevokeFileHandles,
ProcessWorkingSetControl,
ProcessHandleTable, 
ProcessCheckStackExtentsMode,
ProcessCommandLineInformation,
ProcessProtectionInformation,
ProcessMemoryExhaustion,
ProcessFaultInformation, 
ProcessTelemetryIdInformation, 
ProcessCommitReleaseInformation, 
ProcessDefaultCpuSetsInformation,
ProcessAllowedCpuSetsInformation,
ProcessSubsystemProcess,
ProcessJobMemoryInformation, 
ProcessInPrivate, 
ProcessRaiseUMExceptionOnInvalidHandleClose, 
ProcessIumChallengeResponse,
ProcessChildProcessInformation, 
ProcessHighGraphicsPriorityInformation,
ProcessSubsystemInformation, 
ProcessEnergyValues, 
ProcessActivityThrottleState, 
ProcessActivityThrottlePolicy,
ProcessWin32kSyscallFilterInformation,
ProcessDisableSystemAllowedCpuSets, 
ProcessWakeInformation,
ProcessEnergyTrackingState,
ProcessManageWritesToExecutableMemory,REDSTONE3
ProcessCaptureTrustletLiveDump,
ProcessTelemetryCoverage,
ProcessEnclaveInformation,
ProcessEnableReadWriteVmLogging, 
ProcessUptimeInformation,
ProcessImageSection,
ProcessDebugAuthInformation, 
ProcessSystemResourceManagement,
ProcessSequenceNumber,
ProcessLoaderDetour,
ProcessSecurityDomainInformation, 
ProcessCombineSecurityDomainsInformation, 
ProcessEnableLogging, 
ProcessLeapSecondInformation,
ProcessFiberShadowStackAllocation,
ProcessFreeFiberShadowStackAllocation,
MaxProcessInfoClass
} PROCESSINFOCLASS;

1. ProcessDbgPort

該方式是CheckRemoteDebuggerPresent的另一種調用方式。

通過NTDLL導出NtQueryInformationProcess函數,PROCESSINFOCLASS設置為7,該值是進程調試端口(ProcessDebugPort),該值不為0說明被調試。

2. ProcessDebugObjectHandle

通過NTDLL導出NtQueryInformationProcess函數,PROCESSINFOCLASS設置為0x1E,該值是進程的調試對象句柄(ProcessDebugObjectHandle),當該值存在且函數返回值不為NULL,說明進程處于調試狀態,當返回值為NULL,或該值不存在,說明處于非調試狀態。

3. ProcessDebugFlags

通過NTDLL導出NtQueryInformationProcess函數,PROCESSINFOCLASS設置為0x1f,該值獲取了EPROCESS中的成員NoDebugInherit,該值為0說明被調試。

9. WUDFPlatform.dll模塊

WUDFPlatform.dll模塊中,有三個導出函數 WudfIsAnyDebuggerPresent,WudfIsKernelDebuggerPresent,WudfIsUserDebuggerPresent,分別為任何調試器、0環調試器和3環調試器,該模塊只有x64。

通過調用這三個函數,如果返回值不為0,則正在被調試。

代碼如下:

HMODULE h_wudf = LoadLibrary(L"WUDFPlatform.dll");
if(h_wudf == NULL) {
cout << "fail"?<< endl;

????}

????// WudfIsAnyDebuggerPresent
????pWudfIsAnyDebuggerPresent WudfIsAnyDebuggerPresent = (pWudfIsAnyDebuggerPresent)GetProcAddress(h_wudf, "WudfIsAnyDebuggerPresent");
????if?(WudfIsAnyDebuggerPresent == NULL) {
????????cout << "未發現調試器"?<< endl;

????}
????if?(WudfIsAnyDebuggerPresent() != 0) {
????????cout << "發現調試器"?<< endl;
????}

????// WudfIsKernelDebuggerPresent
????pWudfIsKernelDebuggerPresent WudfIsKernelDebuggerPresent = (pWudfIsKernelDebuggerPresent)GetProcAddress(h_wudf, "WudfIsKernelDebuggerPresent");
????if?(WudfIsKernelDebuggerPresent == NULL) {
????????cout << "未發現3環調試器"" << endl;
????}
????if (WudfIsKernelDebuggerPresent() != 0) {
????????cout << "發現0環調試器" << endl;
????}

????// pWudfIsUserDebuggerPresent
????pWudfIsUserDebuggerPresent WudfIsUserDebuggerPresent = (pWudfIsUserDebuggerPresent)GetProcAddress(h_wudf, "WudfIsUserDebuggerPresent");
????if (WudfIsUserDebuggerPresent == NULL) {
????????cout << "未發現3環調試器" << endl;
????}
????if (WudfIsUserDebuggerPresent() != 0) {
????????cout << "發現3環調試器" << endl;

測試結果如下

2bee6bd6-7fb1-11ee-939d-92fbcf53809c.png

總結

本篇介紹了部分反調試的方法,在自己的代碼中使用反調試技術,可以增加逆向人員的分析難度,或是通過了解這些技術的原理,在分析惡意代碼時進行反反調試,在后續的文章中,將會介紹更多的反調試方法。

審核編輯:湯梓紅
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • WINDOWS
    +關注

    關注

    3

    文章

    3524

    瀏覽量

    88422
  • 調試
    +關注

    關注

    7

    文章

    572

    瀏覽量

    33898
  • 調試技術
    +關注

    關注

    0

    文章

    7

    瀏覽量

    6619
  • 代碼
    +關注

    關注

    30

    文章

    4748

    瀏覽量

    68349
  • 調試器
    +關注

    關注

    1

    文章

    300

    瀏覽量

    23689

原文標題:反調試技術-上

文章出處:【微信號:蛇矛實驗室,微信公眾號:蛇矛實驗室】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    介紹6種常見的反調試方法

    開發相應的安全措施來保護系統,這時,惡意軟件開發人員就會使用反調試技術阻礙逆向人員的分析,以達到增加自己惡意代碼的存活時間。此外,安全人員也需要了解反調試
    的頭像 發表于 01-15 09:53 ?3544次閱讀
    介紹6種常見的<b class='flag-5'>反調試</b>方法

    動態反調試技術總結

    ;windows.h"#include "tchar.h"void DynAD_RDTSC(){//Timing Check 技術通過計算運行時間的差異來反調試,反模擬
    發表于 07-10 06:21

    shell編程的簡單命令語句了解

    shell(腳本:批處理)適合職業:Linux系統運維工程師1.命令解析器(將用戶輸入的命令解析,調用相應的命令的可執行文件)2.腳本語言我們需要了解的是shell編程的簡單命令語句一個簡單的shell編程實現的程序:記錄100
    發表于 11-04 08:00

    學PLC技術簡單

    學PLC技術簡單 作者:蔡杏山 主編 出版時間:2013 《學技能超簡單:學PLC技術簡單》是一本介紹PLC
    發表于 11-05 10:52 ?0次下載

    labview怎么調試?基于labview的USB調試教程案例分析

    labview怎么調試是我們在使用NI LabVIEW軟件時候經常會碰到的問題,當軟件不能按照預期的情況運行時,我們可能會需要有一個自己的調試技巧和技術工具箱。這里給大家分享一個為了查看收發數據而編寫的基于labview的USB
    發表于 01-16 09:40 ?1.4w次閱讀

    何為調試調試為何?

    一、何為調試調試為何 這并不是廢話,作為一個菜鳥而言,面對一塊熟悉又陌生的板子如何下手調試也許并不是一件So easy的事。什么是調試呢?簡單
    發表于 01-18 14:48 ?3151次閱讀

    STM32調試DEBUG時需要了解那些知識相關資料概述

    學習STM32開發,肯定少不了DEBUG調試這一步驟。那么,本文帶你了解一下這個調試相關的知識。本文以STM
    的頭像 發表于 11-11 11:39 ?7039次閱讀
    STM32<b class='flag-5'>調試</b>DEBUG時需要<b class='flag-5'>了解</b>那些知識相關資料概述

    如何使用Xilinx SDK創建Linux應用程序,并進行開發和調試

    了解如何使用Xilinx SDK創建Linux應用程序。 我們還將重點介紹和演示支持Linux應用程序開發和調試的不同方面的SDK功能。 整個過程快速而簡單
    的頭像 發表于 11-20 07:03 ?1.1w次閱讀

    下載調試接口SWD和JTAG的區別

    作為嵌入式工程師,下載調試器都應該知道,但你真正了解其 SWD 和 JTAG 接口的含義和區別嗎? 1、什么是下載調試簡單來說,下載調試
    的頭像 發表于 11-28 11:44 ?4514次閱讀

    RISC-V的調試標準及跟蹤技術

    本文主要詳細介紹了RISC-V的調試標準以及RISC-V的跟蹤技術,感興趣的小伙伴跟小編一起了解一下吧。
    的頭像 發表于 06-23 17:19 ?2896次閱讀
    RISC-V的<b class='flag-5'>調試</b>標準及跟蹤<b class='flag-5'>技術</b>

    220kv電力變壓器正反調和粗細調沖擊電壓分析

    220kv電力變壓器正反調和粗細調沖擊電壓分析(通信電源技術期刊是什么級別)-220kv電力變壓器正反調和粗細調沖擊電壓分析? ? ? ? ? ? ?
    發表于 09-24 09:20 ?1次下載
    220kv電力變壓器正<b class='flag-5'>反調</b>和粗細調沖擊電壓分析

    基于OpenOCD和GDB的簡單且廉價的步進調試

    電子發燒友網站提供《基于OpenOCD和GDB的簡單且廉價的步進調試器.zip》資料免費下載
    發表于 08-02 09:47 ?0次下載
    基于OpenOCD和GDB的<b class='flag-5'>簡單</b>且廉價的步進<b class='flag-5'>調試</b>器

    了解 1-Wire 的簡單

    做得更好:了解 1-Wire 的簡單
    的頭像 發表于 12-29 10:02 ?1073次閱讀
    <b class='flag-5'>了解</b> 1-Wire 的<b class='flag-5'>簡單</b>性

    FPGA在線調試的方法簡單總結

    Xilinx被AMD收購的事情把我震出來了,看了看上上一篇文章講了下仿真的文件操作,這篇隔了很久遠,不知道該從何講起,就說說FPGA的在線調試的一些簡單的操作方法總結。
    發表于 06-19 15:52 ?1982次閱讀
    FPGA在線<b class='flag-5'>調試</b>的方法<b class='flag-5'>簡單</b>總結

    簡單了解SDK與APK的區別

    不少小伙伴在開發軟件中會提到兩個詞:API和SDK。雖然它們看起來很專業,但其實背后的概念并不復雜。這篇文章能簡單的幫你了解SDK與APK的區別。
    的頭像 發表于 10-11 10:08 ?753次閱讀