欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解C++的反調(diào)試技術(shù)與繞過(guò)手法

 更新時(shí)間:2021年06月23日 16:28:07   作者:lyshark  
反調(diào)試技術(shù),惡意代碼會(huì)用它識(shí)別自身是否被調(diào)試,或者讓調(diào)試器失效,給反病毒工程師們制造麻煩,拉長(zhǎng)提取特征碼的時(shí)間線,本章將具體總結(jié)常見(jiàn)的反調(diào)試基礎(chǔ)的實(shí)現(xiàn)原理以及如何過(guò)掉這些反調(diào)試手段,從而讓我們能夠繼續(xù)分析惡意代碼

反調(diào)試技術(shù)的實(shí)現(xiàn)方式有很多,最簡(jiǎn)單的一種實(shí)現(xiàn)方式莫過(guò)于直接調(diào)用Windows系統(tǒng)提供給我們的API函數(shù),這些API函數(shù)中有些專門用來(lái)檢測(cè)調(diào)試器的,有些則是可被改造為用于探測(cè)調(diào)試器是否存在的工具,多數(shù)情況下,調(diào)用系統(tǒng)API函數(shù)實(shí)現(xiàn)反調(diào)試是不明智的,原因很簡(jiǎn)單,目標(biāo)主機(jī)通常會(huì)安裝主動(dòng)防御系統(tǒng),而作為主動(dòng)防御產(chǎn)品默認(rèn)會(huì)加載RootKit驅(qū)動(dòng)掛鉤這些敏感函數(shù)的使用,如果被非法調(diào)用則會(huì)提示錯(cuò)誤信息,病毒作者通常會(huì)使用匯編自行實(shí)現(xiàn)這些類似于系統(tǒng)提供給我們的反調(diào)試函數(shù),并不會(huì)使用系統(tǒng)的API,這樣依附于API的主動(dòng)防御的系統(tǒng)將會(huì)失效。

1.加載調(diào)試符號(hào)鏈接文件并放入d:/symbols目錄下.

0:000> .sympath srv*d:\symbols*http://msdl.microsoft.com/download/symbols
0:000> .reload
Reloading current modules

2.位于fs:[0x30]的位置就是PEB結(jié)構(gòu)的指針,接著我們分析如何得到的該指針,并通過(guò)通配符找到TEB結(jié)構(gòu)的名稱.

0:000> dt ntdll!*teb*
          ntdll!_TEB
          ntdll!_GDI_TEB_BATCH
          ntdll!_TEB_ACTIVE_FRAME
          ntdll!_TEB_ACTIVE_FRAME_CONTEXT
          ntdll!_TEB_ACTIVE_FRAME_CONTEXT

3.接著可通過(guò)dt命令,查詢下ntdll!_TEB結(jié)構(gòu),如下可看到0x30處ProcessEnvironmentBlock存放的正是PEB結(jié)構(gòu).

0:000> dt -rv ntdll!_TEB
struct _TEB, 66 elements, 0xfb8 bytes
   +0x000 NtTib            : struct _NT_TIB, 8 elements, 0x1c bytes                  # NT_TIB結(jié)構(gòu)
   +0x018 Self             : Ptr32 to struct _NT_TIB, 8 elements, 0x1c bytes         # NT_TIB結(jié)構(gòu)
   +0x020 ClientId         : struct _CLIENT_ID, 2 elements, 0x8 bytes                # 保存進(jìn)程與線程ID
   +0x02c ThreadLocalStoragePointer : Ptr32 to Void
   +0x030 ProcessEnvironmentBlock : Ptr32 to struct _PEB, 65 elements, 0x210 bytes   # PEB結(jié)構(gòu)

偏移地址0x18是_NT_TIB結(jié)構(gòu),也就是指向自身偏移0x0的位置.

0:000> r $teb
$teb=7ffdf000

0:000> dd $teb+0x18
7ffdf018  7ffdf000 00000000 00001320 00000c10
7ffdf028  00000000 00000000 7ffd9000 00000000

而!teb地址加0x30正是PEB的位置,可以使用如下命令驗(yàn)證.

0:000> dd $teb+0x30
7ffdf030  7ffd9000 00000000 00000000 00000000
7ffdf040  00000000 00000000 00000000 00000000

0:000> !teb
TEB at 7ffdf000
    ExceptionList:        0012fd0c
    StackBase:            00130000
    StackLimit:           0012e000
    SubSystemTib:         00000000
    FiberData:            00001e00
    ArbitraryUserPointer: 00000000
    Self:                 7ffdf000
    EnvironmentPointer:   00000000
    ClientId:             00001320 . 00000c10
    RpcHandle:            00000000
    Tls Storage:          00000000
    PEB Address:          7ffd9000               # 此處teb地址

上方的查詢結(jié)果可得知偏移位置fs:[0x18]正是TEB的基址TEB:7ffdf000

0:000> dd fs:[0x18]
003b:00000018  7ffdf000 00000000 000010f4 00000f6c
003b:00000028  00000000 00000000 7ffda000 00000000

0:000> dt _teb 0x7ffdf000
ntdll!_TEB
   +0x000 NtTib            : _NT_TIB
   +0x01c EnvironmentPointer : (null) 
   +0x020 ClientId         : _CLIENT_ID         # 這里保存進(jìn)程與線程信息

0:000> dt _CLIENT_ID 0x7ffdf000                 # 查看進(jìn)程詳細(xì)結(jié)構(gòu)
ntdll!_CLIENT_ID
   +0x000 UniqueProcess    : 0x0012fd0c Void    # 獲取進(jìn)程PID
   +0x004 UniqueThread     : 0x00130000 Void    # 獲取線程PID

上方TEB首地址我們知道是fs:[0x18],接著我們通過(guò)以下公式計(jì)算得出本進(jìn)程的進(jìn)程ID.

在Windows系統(tǒng)中如果想要獲取到PID進(jìn)程號(hào),可以使用NtCurrentTeb()這個(gè)系統(tǒng)API來(lái)實(shí)現(xiàn),但這里我們手動(dòng)實(shí)現(xiàn)該API的獲取過(guò)程.

獲取進(jìn)程PID:

#include "stdafx.h"
#include <Windows.h>

DWORD GetPid(){
	DWORD dwPid=0;
	__asm
	{
		mov eax,fs:[0x18]    // 獲取PEB地址
		add eax,0x20         // 加0x20得到進(jìn)程PID
		mov eax,[eax]
		mov dwPid,eax
	}
	return dwPid;
}

int main()
{
	printf("%d\n",GetPid());
    return 0;
}

獲取線程PID:

#include "stdafx.h"
#include <Windows.h>

DWORD GetPid(){
	DWORD dwPid=0;
	__asm
	{
		mov eax,fs:[0x18]    // 獲取PEB地址
		add eax,0x20         // 加0x20得到進(jìn)程PID
		add eax,0x04         // 加0x04得到線程PID
		mov eax,[eax]
		mov dwPid,eax
	}
	return dwPid;
}

int main()
{
    printf("%d\n",GetPid());
    return 0;
}

通過(guò)標(biāo)志反調(diào)試:

下方的調(diào)試標(biāo)志BeingDebugged是Char類型,為1表示調(diào)試狀態(tài).為0表示沒(méi)有調(diào)試.可以用于反調(diào)試.

0:000> dt _peb
ntdll!_PEB
   +0x000 InheritedAddressSpace : UChar
   +0x001 ReadImageFileExecOptions : UChar
   +0x002 BeingDebugged    : UChar
   +0x003 SpareBool        : UChar
   +0x004 Mutant           : Ptr32 Void
#include "stdafx.h"
#include <Windows.h>

int main()
{
    DWORD dwIsDebug = 0;
    __asm
    {
        mov eax, fs:[0x18];      // 獲取TEB  
        mov eax, [eax + 0x30];   // 獲取PEB
        movzx eax, [eax + 2];    // 獲取調(diào)試標(biāo)志
        mov dwIsDebug,eax
    }

    if (1 == dwIsDebug)
    {
        printf("正在被調(diào)試");
    }
    else
    {
        printf("沒(méi)有被調(diào)試");
    }
    return 0;
}

通過(guò)API反調(diào)試:

#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>

int main()
{
    STARTUPINFO temp;
    temp.cb = sizeof(temp);
    GetStartupInfo(&temp);

    if (temp.dwFlags != 1)
    {
        ExitProcess(0);
    }
    printf("程序沒(méi)有被反調(diào)試");
    return 0;
}

反調(diào)試與繞過(guò)思路

BeingDebugged 屬性反調(diào)試:

進(jìn)程運(yùn)行時(shí),位置FS:[30h]指向PEB的基地址,為了實(shí)現(xiàn)反調(diào)試技術(shù),惡意代碼通過(guò)這個(gè)位置來(lái)檢查BeingDebugged標(biāo)志位是否為1,如果為1則說(shuō)明進(jìn)程被調(diào)試。

1.首先我們可以使用 dt _teb 命令解析一下TEB的結(jié)構(gòu),如下TEB結(jié)構(gòu)的起始偏移為0x0,而0x30的位置指向的是 ProcessEnvironmentBlock 也就是指向了進(jìn)程環(huán)境塊。

0:000> dt _teb
ntdll!_TEB
   +0x000 NtTib            : _NT_TIB
   +0x01c EnvironmentPointer : Ptr32 Void
   +0x020 ClientId         : _CLIENT_ID
   +0x028 ActiveRpcHandle  : Ptr32 Void
   +0x02c ThreadLocalStoragePointer : Ptr32 Void
   +0x030 ProcessEnvironmentBlock : Ptr32 _PEB       // 此處是進(jìn)程環(huán)境塊
   +0x034 LastErrorValue   : Uint4B
   +0x038 CountOfOwnedCriticalSections : Uint4B
   +0x03c CsrClientThread  : Ptr32 Void
   +0x040 Win32ThreadInfo  : Ptr32 Void
   +0x044 User32Reserved   : [26] Uint4B
   +0x0ac UserReserved     : [5] Uint4B
   +0x0c0 WOW32Reserved    : Ptr32 Void

只需要在進(jìn)程環(huán)境塊的基礎(chǔ)上 +0x2 就能定位到線程環(huán)境塊TEB中 BeingDebugged 的標(biāo)志,此處的標(biāo)志位如果為1則說(shuō)明程序正在被調(diào)試,為0則說(shuō)明沒(méi)有被調(diào)試。

0:000> dt _peb
ntdll!_PEB
   +0x000 InheritedAddressSpace : UChar
   +0x001 ReadImageFileExecOptions : UChar
   +0x002 BeingDebugged    : UChar
   +0x003 BitField         : UChar
   +0x003 ImageUsesLargePages : Pos 0, 1 Bit
   +0x003 IsProtectedProcess : Pos 1, 1 Bit

我們手動(dòng)來(lái)驗(yàn)證一下,首先線程環(huán)境塊地址是007f1000在此基礎(chǔ)上加0x30即可得到進(jìn)程環(huán)境快的基地址007ee000繼續(xù)加0x2即可得到BeingDebugged的狀態(tài) ffff0401 需要 byte=1

0:000> r $teb
$teb=007f1000

0:000> dd 007f1000 + 0x30
007f1030  007ee000 00000000 00000000 00000000
007f1040  00000000 00000000 00000000 00000000

0:000> r $peb
$peb=007ee000

0:000> dd 007ee000 + 0x2
007ee002  ffff0401 0000ffff 0c400112 19f0775f
007ee012  0000001b 00000000 09e0001b 0000775f

梳理一下知識(shí)點(diǎn)我們可以寫出一下反調(diào)試代碼,本代碼單獨(dú)運(yùn)行程序不會(huì)出問(wèn)題,一旦被調(diào)試器附加則會(huì)提示正在被調(diào)試。

#include <stdio.h>
#include <windows.h>

int main()
{
	BYTE IsDebug = 0;
	__asm{
		mov eax, dword ptr fs:[0x30]
		mov bl, byte ptr [eax+ 0x2]
		mov IsDebug, bl
	}
	/* 另一種反調(diào)試實(shí)現(xiàn)方式
	__asm{
		push dword ptr fs:[0x30]
		pop edx
		mov al, [edx + 2]
		mov IsDebug,al
	}
	*/

	if (IsDebug != 0)
		printf("本程序正在被調(diào)試. %d", IsDebug);
	else
		printf("程序沒(méi)有被調(diào)試.");
	getchar();
	return 0;
}

如果惡意代碼中使用該種技術(shù)阻礙我們正常調(diào)試,該如何繞過(guò)呢?如下我們只需要在命令行中執(zhí)行dump fs:[30]+2來(lái)定位到BeingDebugged的位置,并將其數(shù)值改為0然后運(yùn)行程序,會(huì)發(fā)現(xiàn)反調(diào)試已經(jīng)被繞過(guò)了。

ProcessHeap 屬性反調(diào)試:

該屬性是一個(gè)未公開(kāi)的屬性,它被設(shè)置為加載器為進(jìn)程分配的第一個(gè)堆的位置,ProcessHeap位于PEB結(jié)構(gòu)的0x18處,第一個(gè)堆頭部有一個(gè)屬性字段,這個(gè)屬性叫做ForceFlags和Flags屬性偏移為10,該屬性為0說(shuō)明程序沒(méi)有被調(diào)試,非0則說(shuō)明被調(diào)試。

0:000> dt !_peb
ntdll!_PEB
   +0x000 InheritedAddressSpace : UChar
   +0x001 ReadImageFileExecOptions : UChar
   +0x002 BeingDebugged    : UChar
   +0x018 ProcessHeap      : Ptr32 Void
   +0x01c FastPebLock      : Ptr32 _RTL_CRITICAL_SECTION

0:000> r $peb
$peb=006e1000

0:000> dd 006e1000+18
006e1018  00ca0000 775f09e0 00000000 00000000

0:000> dd 00ca0000 + 10
00ca0010  00ca00a4 00ca00a4 00ca0000 00ca0000

要實(shí)現(xiàn)反反調(diào)試,只需要將 00ca0000 + 10 位置的值修改為0即可,執(zhí)行dump ds:[fs:[30] + 0x18] + 0x10 定位到修改即可。

文章出處:https://www.cnblogs.com/lyshark

以上就是詳解C++的反調(diào)試技術(shù)與繞過(guò)手法的詳細(xì)內(nèi)容,更多關(guān)于C++ 反調(diào)試技術(shù)與繞過(guò)手法的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C++?opencv利用grabCut算法實(shí)現(xiàn)摳圖示例

    C++?opencv利用grabCut算法實(shí)現(xiàn)摳圖示例

    這篇文章主要為大家介紹了C++?opencv利用grabCut算法實(shí)現(xiàn)摳圖的代碼示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • C++中的模板類繼承和成員訪問(wèn)問(wèn)題

    C++中的模板類繼承和成員訪問(wèn)問(wèn)題

    這篇文章主要介紹了C++中的模板類繼承和成員訪問(wèn)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • C++代碼規(guī)范之命名規(guī)則

    C++代碼規(guī)范之命名規(guī)則

    以下是對(duì)C++中的命名規(guī)則進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以參考下
    2013-07-07
  • C++控制臺(tái)實(shí)現(xiàn)密碼管理系統(tǒng)

    C++控制臺(tái)實(shí)現(xiàn)密碼管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++控制臺(tái)實(shí)現(xiàn)密碼管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • C++內(nèi)存管理詳細(xì)解析

    C++內(nèi)存管理詳細(xì)解析

    這篇文章主要給大家分享的是C++內(nèi)存管理的詳細(xì)內(nèi)容學(xué)習(xí),下面文章圍繞C++內(nèi)存管理的相關(guān)資料展開(kāi)具體學(xué)習(xí)內(nèi)容,需要的朋友可以參考一下,希望對(duì)你有所幫助
    2021-11-11
  • DSP中浮點(diǎn)轉(zhuǎn)定點(diǎn)運(yùn)算--浮點(diǎn)與定點(diǎn)概述

    DSP中浮點(diǎn)轉(zhuǎn)定點(diǎn)運(yùn)算--浮點(diǎn)與定點(diǎn)概述

    本文主要介紹DSP中浮點(diǎn)與定點(diǎn)概述,很值得學(xué)習(xí)一下,需要的朋友可以參考一下。
    2016-06-06
  • C++ 詳細(xì)講解對(duì)象的構(gòu)造順序

    C++ 詳細(xì)講解對(duì)象的構(gòu)造順序

    對(duì)象的構(gòu)造往往和構(gòu)造函數(shù)會(huì)牽扯在一起,構(gòu)造函數(shù)的函數(shù)可能會(huì)由非常復(fù)雜的邏輯所組成,不同類的構(gòu)造函數(shù)的程序邏輯很可能是相互依賴的,當(dāng)這種相互依賴一旦成立,那么對(duì)象的構(gòu)造順序很可能導(dǎo)致難以調(diào)試的Bug出現(xiàn)
    2022-04-04
  • C++獲取指定目錄下的所有文件

    C++獲取指定目錄下的所有文件

    這篇文章主要為大家詳細(xì)介紹了C++獲取指定目錄下所有文件的相關(guān)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • VS2022連接sqlserver數(shù)據(jù)庫(kù)教程

    VS2022連接sqlserver數(shù)據(jù)庫(kù)教程

    本文主要介紹了VS2022連接sqlserver數(shù)據(jù)庫(kù)教程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • C語(yǔ)言實(shí)現(xiàn)階乘的示例詳解

    C語(yǔ)言實(shí)現(xiàn)階乘的示例詳解

    在現(xiàn)實(shí)中,我們做數(shù)學(xué)題總會(huì)遇到階乘問(wèn)題,這在計(jì)算機(jī)中也不例外。 那我們應(yīng)該怎么實(shí)現(xiàn)呢?下面小編就為大家講解一下C語(yǔ)言中階乘的實(shí)現(xiàn)
    2022-07-07

最新評(píng)論