Ochrana programu pred spustením v debuggeroch.
 

 

V tomto článku si popíšeme princíp dosť silnej ochrany programu nášho malwaru pred otvorením v debuggeroch. Ide o to, predísť debuggovaniu našého malwaru, a tým sťaženiu zistenia funkcionality.

Pred uverejnením kódov si povieme čo-to o tejto praktike.

Spustenie aplikácie, ako takej, spočíva v spustení vstupného bodu process entry point. Tento bod je obsiahnutý v linkery na metódu void/int main(void)/(argc, argv). Pri klasickom spustení sa tento prístupový bod vyvolá.
Pri otvorení v debuggeroch, debugger začína načítaním a nastavením breakpointu práve na tento vstupný bod.

Naskytuje sa nám otázka, ako debugger obísť respektíve, ako zistiť, že súbor bol spustený pod debuggerom. Odpoveď spočíva v takzvanom TLS spätnom volaní.

TLS (Thread Local Storage) je druh spätného volania, ktoré sa spúšťa pri inicializácií skoku na spomínaný entry point, čiže je vyvolané pred spustením entry pointu. Debuggery breakpoint zavádzajú až po tomto volaní. Na základe tochto volania je možné detekovať enviromentálne prostredie debuggeru.
Pri kontrolovaní tohto volania môžeme vytvoriť skok na metódu, ktorou môžeme kontrolovať priebeh spustenia, od vypnutia debuggeru až po zničenie počítča. Môžeme systém zaheslovať, prakticky vykonať hociakú funkcionalitu.


Aby sme neako začali s kódom, v prvom rade je nutné linkovo vytvoriť TLS a načítať sekciu CRT$XLB:

  
#pragma comment(linker,"/include:__tls_used")
#pragma section(".CRT$XLB",read)



Ďalej si deklarujeme metódu z ntdll.lib:

  
extern "C" 
{
   NTSTATUS _stdcall NtQueryInformationProcess(::HANDLE,::ULONG,::PVOID,::ULONG,::PULONG);
}



Nacitanie pamäte offsetu z GS segmentu:

  
__readfsdword(0x30)+2



Vytvorenie metódy pre overenie TLS:

  
void _stdcall TLSCallBackHook(::PVOID Module,::DWORD Reason,::PVOID Context)
{
   ::PBOOLEAN StartDebugged = (::PBOOLEAN) ThreadInformationBlock; //Nacitanie GS
   ::HANDLE DebugPort = nullptr;
   bool isdebugged = false;
if(*StartDebugged) //Zistenie hodnoty StartDebugged { isdebugged = true; } else { isdebugged = false; }
if(!::NtQueryInformationProcess(_Diall_CurrentProcess(),7,&DebugPort,sizeof(::HANDLE),NULL)) { if(DebugPort) { isdebugged = true; } else { isdebugged = false; } } }



Načítanie skoku pred spustením process entry pointu, zavedenie TLS callback pre sekciu CRT$XLB:

  
__declspec(allocate(".CRT$XLB")) PIMAGE_TLS_CALLBACK PIMAGETLSCALLBACK[]={TLSCallBackHook, nullptr};

 

 

 

-----------------------------------------------------------------

Celá funkcia je zakonpovaná do headeru WinAPI.h WinAPI.h



Spustenie ochrany procesu pred debuggerom:

  
#define _ProtectDebugger_ //define macro for "winapi.h"//

#include <stdio.h> #include "convert.h" #include "winapi.h" //https://www.netbot.sk/sk/14-blog-headers/31-winapi
void DProtectDebuggerNoDetected(void) { MessageBoxA(NULL,"No debugger enviroment","TLS",MB_ICONINFORMATION); }
void DProtectDebuggerDetected(void) { MessageBoxA(NULL,"Debugger enviroment","TLS",MB_ICONINFORMATION); //SetPassword(); }
int _cdecl main(void) { ::Diall_WinApi::WinApi::GetInstance()->SystemIntegrity(::Diall_WinApi::Privilege::ENABLE);
cout << " https://www.diallix.net "; system("pause");

return 0; }