Jump to content

Search the Community

Showing results for tags 'antidebug'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Supporter area
    • Tools of the Trade
    • Finance transparency
  • MBConf
    • MBConf v1
    • MBConf v2
    • MBConf v3
  • Mente Binária
    • General
    • Computer Architecture
    • Certifications
    • Quantum computing
    • Cryptography
    • Challenges and CTF
    • Hardware Hacking
    • Electronics
    • Conferences
    • Forensics
    • Games
    • Data privacy and laws
    • Code breaking
    • Networking
    • Pentest
    • Speak to us!
    • Software releases
  • Career
    • Study and profession
    • Jobs
  • Reverse Engineering
    • General
    • Malware Analysis
    • Firmware
    • Linux and UNIX-like
    • Windows
  • Programming
    • Assembly
    • C/C++
    • Python
    • Other languages
  • Operating Systems
    • GNU/Linux and UNIX-like
    • Windows
  • Segurança na Internet's Discussão

Categories

  • Portal Mente Binária
  • Specials

Categories

  • Tech basics
    • Text comprehension
    • English
    • Mathematics
  • Computing Basics
    • Lógica de Programação
    • Computers Architecture
    • Cryptography
    • Data Structures
    • Network
    • Operating Systems
  • Specifics
    • SO Internals
    • Web
    • Python
    • Javascript
    • Infrastructure
    • Go
    • Reverse Engineering
    • DevOps
    • C/C++
    • Log Analysis

Categories

  • Crackmes
  • Documentation
  • Debuggers
  • PE tools
  • Books
  • Util
  • Packers
  • Unpackers
  • Virtual Machines

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


GitHub


Twitter


LinkedIn


Website

Found 2 results

  1. Introdução Reunir informações sobre técnica de "Anti- Engenharia Reversa" é a proposta dessa série de artigos que serão publicados aqui no Mente Binária. É um tema em que tenho pesquisado e criado pequenos tutoriais práticos para mim mesmo durante o último ano, e resolvi compartilhá-los. Em cada um deles darei uma passada nas principais técnicas encontradas em todas as classes de defesa dos criadores de malware, além de mostrar como desabilitá-las. Tudo com exemplos de código para se entender na prática mesmo. *Para a implementação estarei utilizando o Visual Studio Community, pois este tem o suporte ao ambiente C Runtime (CRT) necessário. A grande maioria das técnicas que serão apresentadas é para o ambiente Windows. Alguns poucos casos, que serão informados, são para Linux. Como pré-requisito, é necessário algum conhecimento de linguagem C\C++, um pouco de Assembly e principalmente Engenharia Reversa. Todos estes tópicos são abordados nos cursos gratuitos no canal do Mente Binária no Youtube. *No caso, não apresentarei a técnica mais simples/comum que utiliza a função IsDebuggerPresent(), pois esta técnica é explicada na última aula do curso do CERO aqui do Mente Binária. Classes de Anti-Engenharia Reversa Essas classes são uma forma de categorizar os métodos de "Anti-Engenharia Reversa", agrupando métodos de evasão semelhantes num mesmo grupo ou “classe”. Como não existe uma classificação oficial, estas classes estão baseadas na divisão apresentada nesta referência, com algumas adaptações. TLS Callback Windows: A Thread Local Storage (TLS) é um recurso do Windows para definir objetos (variáveis) na memória que possam ter valores diferentes para cada thread criada por um processo. Por exemplo, ao imprimir um documento, uma thread se encarrega de mostrar o documento na tela, enquanto outra acessa esta mesma informação simultaneamente para lidar com a impressão. A thread de impressão pode ter uma variável que armazena a quantidade de páginas impressas, porém, esta variável não se faz necessária na thread que apresenta o documento na tela. Esta informação é armazenada (daí o nome "Thread Local Storage") numa região definida no cabeçalho dos binários PE (Portable Executable), e o acesso só é permitido para sua respectiva thread. As funções TLS Callback executam antes do binário alcançar seu "ponto de início", chamando e inicializando estes objetos TLS através de métodos construtores e os removendo da memória por métodos destrutores após seu uso. Com isso em mente, as TLS Callbacks também podem ser utilizadas pelos desenvolvedores de malware para permitir que se execute código antes que o binário chegue à região tradicional de início do programa, conhecido como Entrypoint, que irá levar em seguida à função main(). Isto cria diversas oportunidades como por exemplo executar código malicioso antes que o depurador possa detectá-lo (levar o malware a encerrar o processo antes mesmo de executar as rotinas maliciosas ao perceber que está sendo depurado, por exemplo). Alguns exemplos de malwares que empregam TLS Callbacks no Windows são: Nadnadzzz botnet de 2009; Grum botnet de 2008, através do Grum rootkit; Ursnif (mais recente); Implementação A biblioteca C Runtime (CRT) do Visual Studio provê suporte para fácil criação de TLS Callbacks (como comentado aqui) graças ao código em “C:\Program Files (x86)\Microsoft Visual Studio xx.0\VC\crt\src\tlssup.c”, que cria um diretório de dados TLS baseado na seguinte estrutura: typedef struct _IMAGE_TLS_DIRECTORY32 { DWORD StartAddressOfRawData; /* Início da seção TLS AddressOfRawData*/ DWORD EndAddressOfRawData; /* Endereço final na seção TLS */ DWORD AddressOfIndex; /* Índice da seção TLS */ DWORD AddressOfCallBacks; /* Ponteiro para o array de funções callback */ DWORD SizeOfZeroFill; DWORD Characteristics; } __tls_used; Para criarmos a nossa própria callback precisamos primeiro defini-la no seguinte formato: VOID WINAPI tls_callback1( PVOID DllHandle, DWORD Reason, PVOID Reserved) { codigo_funcao; } As constantes para DWORD Reason podem ser: DLL_PROCESS_DETACH = 0 DLL_PROCESS_ATTACH = 1 DLL_THREAD_ATTACH = 2 DLL_THREAD_DETACH = 3 Depois a callback precisa ser alocada da seguinte forma: PIMAGE_TLS_CALLBACK ponteiro_tls_callback = tls_callback1; Após esta contextualização do mecanismo de funcionamento, segue um exemplo de código onde a função de callback detecta o ambiente de depuração através da função IsDebuggerPresent() e sai informando que o mesmo foi descoberto. Caso contrário, informa que o programa está executando normalmente: #include <iostream> #include <windows.h> using namespace std; // Declara uma variável global requerida para a chamada TLS Callback static int v1 = 0; // Declara a callback VOID WINAPI tls_callback1( PVOID DllHandle, DWORD Reason, PVOID Reserved) { if (Reason == DLL_PROCESS_ATTACH) { v1 = 1; // dentro da Callback altera o valor da variável if (IsDebuggerPresent()) { cout << "Stop debugging program!" << endl; TerminateProcess(GetCurrentProcess(), 0x1); exit(1); } } } // Cria objeto conforme a arquitetura através de #pragmas, que são instruções específicas do compilador #ifdef _M_AMD64 // para arquitetura x86_64 #pragma comment (linker, "/INCLUDE:__tls_used") // instrui linker usar o diretório TLS #pragma comment (linker, "/INCLUDE:p_tls_callback1") // instrui linker usar ponteiro do mesmo tipo da callback tls_callback1 declarada antes #pragma const_seg(push) // carrega o ponteiro na stack do compilador para uso da callback no segmento de dados const (.rdata) #pragma const_seg(".CRT$XLA") // cria nova seção TLS EXTERN_C const PIMAGE_TLS_CALLBACK p_tls_callback1 = tls_callback1; // atribui tls_callback1 ao ponteiro p_tls_callback1 #pragma const_seg(pop) // remove o ponteiro da stack após o uso #endif // fim deste bloco #ifdef _M_IX86 // para a arquitetura x86. as instruções tem as mesmas finalidades do bloco anterior #pragma comment (linker, "/INCLUDE:__tls_used") #pragma comment (linker, "/INCLUDE:_p_tls_callback1") #pragma data_seg(push) #pragma data_seg(".CRT$XLA") EXTERN_C PIMAGE_TLS_CALLBACK p_tls_callback1 = tls_callback1; #pragma data_seg(pop) #endif // main() só será executada depois, quando um depurador não for detectado int main(int argc, char* argv[]) { cout << "Normal execution!" << endl; printf("test value from tls callback is: tls = %d\n", v1); return 0; } Abaixo estão algumas dicas de como lidar com TLS Callbacks em diversas ferramentas: x64dbg: Options → Preferencias → Eventos → TLS Callbacks OllyDbg: Options -> Debug Options -> Events -> Make first pause at -> System breakpoint (para em TLS Callbacks) OllyDbg: Plugin Olly Advanced → Break on TLS Callback IDA Pro: Ctrl+E → Choose an entry point IDA Pro (Debugger): Debugger -> Debugger options -> Events -> Stop on (marcar todas as opções) Linux: O Linux também suporta o Thread Local Storage (TLS), conforme descrito nestes 2 excelentes artigos: https://maskray.me/blog/2021-02-14-all-about-thread-local-storage https://chao-tic.github.io/blog/2018/12/25/tls No entanto, o recurso de TLS no Linux aparentemente só permite a inicialização de variáveis ou objetos, e não chamada de função (como é o caso no Windows). Isto somente seria possível de dentro da main(), como nesse pequeno exemplo que usa o recurso de suporte a threads da Glibc: #include <stdio.h> // TLS que define e inicializa a variável __thread int main_tls_var = 2; int main() { printf("%d\n", main_tls_var); return 0; } $ ./tls 2 No entanto, ainda é possível executar funções antes ou depois da main() no Linux através das funções construtoras e destrutoras devido ao suporte do GCC. Observem que uma função construtora em C++ instancia uma variável, definindo seu valor, enquanto que a destrutora a remove da memória após a conclusão da execução (normalmente em retorno de funções): #include<stdio.h> /* atributo construtor em myStartupFun() para executar antes de main() */ void myStartupFun (void) __attribute__ ((constructor)); /* atributo destrutor em myCleanupFun() para executar depois de main() */ void myCleanupFun (void) __attribute__ ((destructor)); /* implementacao de myStartupFun */ void myStartupFun (void) { printf ("startup code before main()\n"); } /* implementacao de myCleanupFun */ void myCleanupFun (void) { printf ("cleanup code after main()\n"); } int main (void) { printf ("hello\n"); return 0; } *Por padrão a __libc_start_main(*main(), argc, **argv, __libc_csu_init(), __libc_csu_fini()) é a função da glibc que chama a main(), onde __libc_csu_init é o construtor e __libc_csu_fini é o destrutor. No Linux também é possível evadir o depurador através da função ptrace, mas isso é um assunto que abordarei mais para frente, inclusive com exemplo prático. Por hora convido vocês a continuarem sintonizados, pois no próximo artigo começarei a tratar de técnicas da classe que utiliza flags de depuração para detectar o debugger. Forte abraço & até lá! Referências: https://www.codeproject.com/Articles/1090943/Anti-Debug-Protection-Techniques-Implementation-an https://anti-debug.checkpoint.com/ https://rayanfam.com/topics/defeating-malware-anti-vm-techniques-cpuid-based-instructions/ https://evasions.checkpoint.com/ https://anti-reversing.com/Downloads/Anti-Reversing/The_Ultimate_Anti-Reversing_Reference.pdf
  2. Pessoal, recebi recentemente esta referência de técnicas anti-debug atualizadas por uma fonte confiável, que é a empresa Check Point. Não cheguei a olhar ainda, mas achei interessante de compartilhar logo com os colegas, por ser um tema de grande relevância na área de engenharia reversa. Abraços! https://research.checkpoint.com/2020/cpr-anti-debug-encyclopedia-the-check-point-anti-debug-techniques-repository/
×
×
  • Create New...