O objetivo desta biblioteca é dificultar a análise estática e dinâmica (depuração).
A biblioteca tem como alvo ambientes Linux.
Atualmente, é baseado no truque de anti-análise ptrace e fornece os seguintes recursos principais:
A invocação direta do syscall sem depender do LIBC (isso torna ineficaz o mecanismo de desvio LD_Preload);
Sistema chama a ofuscação que dificulta a engenharia estática reversa (esse recurso é suportado apenas apenas em x86_64 );
Múltiplas invocações de syscall ptrace . Cada chamada para ptrace deve retornar o valor esperado (isto é, 0 na primeira invocação e -1 a partir de então) e contribui para o cálculo de um valor de " offset " que, no final da cadeia de chamadas ptrace , deve corresponder a um valor esperado (veja aqui). Se o PTRACE retornar um valor não -acionado ou o valor " offset " não corresponder, o processo será encerrado;
'Ptrace' é chamado em loops aninhados. Os loops são desenrolados e o número de iterações é randomizado em cada compilação. Além disso, também o valor " offset " é radomizado em cada iteração;
O código gerado pode ser ofuscado ainda mais, permitindo o recurso obfuscate que se baseia em Goldberg Crate;
Para usar a caixa, adicione -a às suas dependências:
[dependencies]
debugoff = { version = "0.2.1, features = ["obfuscate"] }
Para ativar também o sistema de chamadas de sistema, use o recurso syscallobf (este é um recurso experimental e afeta apenas os binários direcionados à arquitetura x86_64 ):
[dependencies]
debugoff = { version = "0.2.1, features = ["obfuscate", "syscallobf"] }
Dado que a biblioteca gera código aleatório em cada compilação, reconstrua tudo de cada vez. Algo assim:
cargo clean
cargo build --release
A remoção de símbolos da construção de liberação também é uma boa ideia:
[profile.release]
debug = false
strip = "symbols"
panic = "abort"
No exemplo abaixo, debugoff é usado apenas quando o sistema operacional de destino é Linux e apenas para compilações de liberação (dessa maneira quando o código é compilado no modo de depuração, ele pode ser depurado sem a necessidade de ignorar debugoff ).
// Include only for Linux and when building in release mode
# [ cfg ( target_os = "linux" ) ]
# [ cfg ( not ( debug_assertions ) ) ]
use debugoff ;
use std :: time :: SystemTime ;
fn main ( ) {
// Call only for Linux and when building in release mode
# [ cfg ( target_os = "linux" ) ]
# [ cfg ( not ( debug_assertions ) ) ]
debugoff :: multi_ptraceme_or_die ( ) ;
println ! (
"Time: {}" ,
SystemTime :: now ( )
. duration_since ( SystemTime :: UNIX_EPOCH )
. unwrap ( )
. as_millis ( )
) ;
// Call only for Linux and when building in release mode
# [ cfg ( target_os = "linux" ) ]
# [ cfg ( not ( debug_assertions ) ) ]
debugoff :: multi_ptraceme_or_die ( ) ;
println ! ( "Example complete!" ) ;
}Veja outros exemplos no diretório de exemplos que podem ser construídos com:
cargo build --release --features obfuscate,syscallobf --examples Se construirmos o seguinte código (que não usa DebugOff ) no modo de liberação:
use std :: time :: SystemTime ;
fn main ( ) {
println ! (
"Time: {}" ,
SystemTime :: now ( )
. duration_since ( SystemTime :: UNIX_EPOCH )
. unwrap ( )
. as_millis ( )
) ;
println ! ( "Example complete!" ) ;
} Este é o gráfico de função correspondente da função main :
.
Se construirmos o mesmo código usando DebugOff com o recurso obfuscate :
# [ cfg ( target_os = "linux" ) ]
# [ cfg ( not ( debug_assertions ) ) ]
use debugoff ;
use std :: time :: SystemTime ;
fn main ( ) {
# [ cfg ( target_os = "linux" ) ]
# [ cfg ( not ( debug_assertions ) ) ]
debugoff :: multi_ptraceme_or_die ( ) ;
println ! (
"Time: {}" ,
SystemTime :: now ( )
. duration_since ( SystemTime :: UNIX_EPOCH )
. unwrap ( )
. as_millis ( )
) ;
# [ cfg ( target_os = "linux" ) ]
# [ cfg ( not ( debug_assertions ) ) ]
debugoff :: multi_ptraceme_or_die ( ) ;
println ! ( "Example complete!" ) ;
} Este é o gráfico de função ofuscado da função main :
.
Neste exemplo em particular, todo o código gerado pelo DebugOff foi inlinado na função main . Não é sempre que isso é sempre o caso, porque as funções que envolvem podem ser influenciadas por muitos fatores, como os locais onde DebugOff é chamado e a versão da cadeia de ferramentas usada para a criação do projeto. Em outros casos, o gráfico de função resultante pode ser mais simples do que o relatado no exemplo, mas, em qualquer caso, mais complexo do que o gerado quando DebugOff não é usado.
Licenciado em:
obfuscate está ativado;obfuscate não estiver ativado; x86_64 );