Domanda [GUIDA]Anti Debug con C++

Stato
Discussione chiusa ad ulteriori risposte.

diolegend

Utente Silver
22 Luglio 2013
132
18
11
86
Ultima modifica:
Oggi vorrei trattare di un argomento molto interessante che e' l' Anti Debug.
Andiamo a vedere innanzitutto cos'e il Debug.
Il debugging (o semplicemente debug), in informatica, indica l'attività che consiste nell'individuazione da parte del programmatore della porzione di software affetta da errore (bug) rilevata nei software a seguito dell'utilizzo del programma.

Nel visual studio e' il tipico pallino rosso.
Appena viene eseguito il programma , il programma si ferma nel punto in cui hai messo il pallino , e da li puoi controllare ogni cosa che si verifica nel tuo programma.

Ci sono dei tools per fare il debugging direttamente con il programma (.exe) e vedere l'assembly code.
Quindi hanno inventato dei metodi per contrastare a questa cosa.
Perche' di certo non vuoi che qualcun'altro vedi come funziona il tuo programma.

Il tipico modo per visualizzare se c'e o meno un debugger che sta visualizzando il vostro assembly code e' di chiamare una funzione WINAPI di Windows.
Aspettate.
IsDebuggerPresent

e' facile da chiamare.
Vi metto qui il codice:
Codice:
#include <Windows.h>
#include <iostream>
 
int main()
{
if(IsDebuggerPresent())
   cout << "Debugger ON"....
return 0;
}

Questo e' il codice per visualizzare se c'e o meno il debugger, ma vorrei anche spiegare come funziona questa API di Windows.
Entriamo piu' in dettaglio ,appriamo WinDbg e visualizziamo il codice assembly di IsDebuggerPresent
7756dbe0 64a130000000 mov eax,dword ptr fs:[00000030h]
7756dbe6 0fb64002 movzx eax,byte ptr [eax+2]
7756dbea c3 ret

Che cosa fa qui dentro ?
Innanzitutto ricava l'indirizzo PEB che si trova nella struttura di TEB
C++:
struct TEB
typedef struct _TEB
{
     NT_TIB NtTib;
     PVOID EnvironmentPointer;
     CLIENT_ID ClientId;
     PVOID ActiveRpcHandle;
     PVOID ThreadLocalStoragePointer;
     PPEB ProcessEnvironmentBlock;
     ULONG LastErrorValue;

Allora cos'e il TEB ?
Volevo mettere anche la spiegazione di wikipedia , ma per sfortuna non c'e mm..
TEB sta per Thread Environment Block , contiene le informazione del thread che sta eseguendo ora, un header diciamo.
Cos'e il PEB?
Il PEB invece sta per Process Environment Block, questo invece contiene le informazione che riguarda il processo che sta eseguendo ora , se andate a vedere la struttura su msdn , vi fara' vedere che ci sono delle parti non documentate , inrealta' possiamo anche ricavare l'entry address.
Qui vi riporto la struttura per bene di PEB
Codice:
  +0x000 InheritedAddressSpace : UChar
   +0x001 ReadImageFileExecOptions : UChar
   +0x002 BeingDebugged    : UChar
   +0x003 BitField         : UChar
   +0x003 ImageUsesLargePages : Pos 0, 1 Bit
   +0x003 IsProtectedProcess : Pos 1, 1 Bit
   +0x003 IsImageDynamicallyRelocated : Pos 2, 1 Bit
   +0x003 SkipPatchingUser32Forwarders : Pos 3, 1 Bit
   +0x003 IsPackagedProcess : Pos 4, 1 Bit
   +0x003 IsAppContainer   : Pos 5, 1 Bit
   +0x003 IsProtectedProcessLight : Pos 6, 1 Bit
   +0x003 IsLongPathAwareProcess : Pos 7, 1 Bit
   +0x004 Mutant           : Ptr32 Void
   +0x008 ImageBaseAddress : Ptr32 Void
   +0x00c Ldr              : Ptr32 _PEB_LDR_DATA
   +0x010 ProcessParameters : Ptr32 _RTL_USER_PROCESS_PARAMETERS
   +0x014 SubSystemData    : Ptr32 Void
   +0x018 ProcessHeap      : Ptr32 Void
   +0x01c FastPebLock      : Ptr32 _RTL_CRITICAL_SECTION
   +0x020 AtlThunkSListPtr : Ptr32 _SLIST_HEADER
   +0x024 IFEOKey          : Ptr32 Void
   +0x028 CrossProcessFlags : Uint4B
   +0x028 ProcessInJob     : Pos 0, 1 Bit
   +0x028 ProcessInitializing : Pos 1, 1 Bit
   +0x028 ProcessUsingVEH  : Pos 2, 1 Bit
   +0x028 ProcessUsingVCH  : Pos 3, 1 Bit
   +0x028 ProcessUsingFTH  : Pos 4, 1 Bit
   +0x028 ReservedBits0    : Pos 5, 27 Bits
   +0x02c KernelCallbackTable : Ptr32 Void
   +0x02c UserSharedInfoPtr : Ptr32 Void
   +0x030 SystemReserved   : [1] Uint4B
   +0x034 AtlThunkSListPtr32 : Ptr32 _SLIST_HEADER
   +0x038 ApiSetMap        : Ptr32 Void
   +0x03c TlsExpansionCounter : Uint4B
   +0x040 TlsBitmap        : Ptr32 Void
   +0x044 TlsBitmapBits    : [2] Uint4B
   +0x04c ReadOnlySharedMemoryBase : Ptr32 Void
   +0x050 SparePvoid0      : Ptr32 Void
   +0x054 ReadOnlyStaticServerData : Ptr32 Ptr32 Void
   +0x058 AnsiCodePageData : Ptr32 Void
   +0x05c OemCodePageData  : Ptr32 Void
   +0x060 UnicodeCaseTableData : Ptr32 Void
   +0x064 NumberOfProcessors : Uint4B
   +0x068 NtGlobalFlag     : Uint4B
   +0x070 CriticalSectionTimeout : _LARGE_INTEGER
   +0x078 HeapSegmentReserve : Uint4B
   +0x07c HeapSegmentCommit : Uint4B
   +0x080 HeapDeCommitTotalFreeThreshold : Uint4B
   +0x084 HeapDeCommitFreeBlockThreshold : Uint4B
   +0x088 NumberOfHeaps    : Uint4B
   +0x08c MaximumNumberOfHeaps : Uint4B
   +0x090 ProcessHeaps     : Ptr32 Ptr32 Void
   +0x094 GdiSharedHandleTable : Ptr32 Void
   +0x098 ProcessStarterHelper : Ptr32 Void
   +0x09c GdiDCAttributeList : Uint4B
   +0x0a0 LoaderLock       : Ptr32 _RTL_CRITICAL_SECTION
   +0x0a4 OSMajorVersion   : Uint4B
   +0x0a8 OSMinorVersion   : Uint4B
   +0x0ac OSBuildNumber    : Uint2B
   +0x0ae OSCSDVersion     : Uint2B
   +0x0b0 OSPlatformId     : Uint4B
   +0x0b4 ImageSubsystem   : Uint4B
   +0x0b8 ImageSubsystemMajorVersion : Uint4B
   +0x0bc ImageSubsystemMinorVersion : Uint4B
   +0x0c0 ActiveProcessAffinityMask : Uint4B
   +0x0c4 GdiHandleBuffer  : [34] Uint4B
   +0x14c PostProcessInitRoutine : Ptr32     void
   +0x150 TlsExpansionBitmap : Ptr32 Void
   +0x154 TlsExpansionBitmapBits : [32] Uint4B
   +0x1d4 SessionId        : Uint4B
   +0x1d8 AppCompatFlags   : _ULARGE_INTEGER
   +0x1e0 AppCompatFlagsUser : _ULARGE_INTEGER
   +0x1e8 pShimData        : Ptr32 Void
   +0x1ec AppCompatInfo    : Ptr32 Void
   +0x1f0 CSDVersion       : _UNICODE_STRING
   +0x1f8 ActivationContextData : Ptr32 _ACTIVATION_CONTEXT_DATA
   +0x1fc ProcessAssemblyStorageMap : Ptr32 _ASSEMBLY_STORAGE_MAP
   +0x200 SystemDefaultActivationContextData : Ptr32 _ACTIVATION_CONTEXT_DATA
   +0x204 SystemAssemblyStorageMap : Ptr32 _ASSEMBLY_STORAGE_MAP
   +0x208 MinimumStackCommit : Uint4B
   +0x20c FlsCallback      : Ptr32 _FLS_CALLBACK_INFO
   +0x210 FlsListHead      : _LIST_ENTRY
   +0x218 FlsBitmap        : Ptr32 Void
   +0x21c FlsBitmapBits    : [4] Uint4B
   +0x22c FlsHighIndex     : Uint4B
   +0x230 WerRegistrationData : Ptr32 Void
   +0x234 WerShipAssertPtr : Ptr32 Void
   +0x238 pUnused          : Ptr32 Void
   +0x23c pImageHeaderHash : Ptr32 Void
   +0x240 TracingFlags     : Uint4B
   +0x240 HeapTracingEnabled : Pos 0, 1 Bit
   +0x240 CritSecTracingEnabled : Pos 1, 1 Bit
   +0x240 LibLoaderTracingEnabled : Pos 2, 1 Bit
   +0x240 SpareTracingBits : Pos 3, 29 Bits
   +0x248 CsrServerReadOnlySharedMemoryBase : Uint8B
   +0x250 TppWorkerpListLock : Uint4B
   +0x254 TppWorkerpList   : _LIST_ENTRY
   +0x25c WaitOnAddressHashTable : [128] Ptr32 Void

Per caso avete visto BeingDebugged ?
Infatti la funzione IsDebugPresent non fa altro che leggere in questa memoria il dato.
Se e' 1 allora significa che c'e un debugger che sta facendo delle cose con il nostro programma.
Quindi per rafforzare maggiormente il nostro antidebugger funzione possiamo invece scrivere direttamente cosi:
C++:
#include <iostream>
#include <Windows.h>
 
int main()
{
    bool IsDebugged;
    __asm
    {
        mov eax,fs:[30h]
        mov al,byte ptr[eax + 2]
        mov IsDebugged,al
    }
    if(IsDebugged)
    {
 
 
    }
 
 
    return 0;
}

Cosi rendiamo il programma meno facilmente bypassato.
Dopo vorrei discutere anche del int 2D

- Diolegend
 
Nella mia vita da reverser però ho visto circa una ventina di metodi diversi per fare l'antidebug, quindi ci aspettiamo una guida almeno sulla maggior parte di questi :) .
Il debugger espone molti connotati per essere riconosciuto, quindi ol giorno d'oggi non basta questo.
Andrebbe anche ricordato che esistono tutta una serie di plugins per che permettono di dimenticarsi di questo problema, e che quando si ha a che fare con protezioni importanti non possono essere omessi (es. strongOD, phant0m, hidedebugger, hideall ecc.).
 
Stato
Discussione chiusa ad ulteriori risposte.