
Generate Proxy DLLs em Rust
cargo install rustdllproxy
Esta crate atualmente suporta apenas o formato padrão de DLL PE.
O Rustdllproxy acompanha dois subcomandos:
| Comando | Finalidade |
|---|---|
rustdllproxy new | Gera uma nova crate cdylib proxy a partir de uma ou mais DLLs existentes. |
rustdllproxy build | Sincroniza o arquivo .def com src/lib.rs e compila a crate. |
rustdllproxy --help # ajuda de nível superior
rustdllproxy new --help # flags de geração
rustdllproxy build --help # flags de build
Antes de gerar sua crate, decida como você gostaria que seu proxy funcionasse. Um padrão típico é o sequestro de ordem de busca, onde você primeiro renomeia sua DLL alvo para algo como target_.dll e então usa o proxy compilado como target.dll. Isso cria um fluxo semelhante a binary -> target.dll -> target_.dll
Existem vários caminhos a seguir dependendo do seu caso de uso. No entanto, se você precisar renomear a DLL subjacente que está sendo usada como proxy, atualize o arquivo .def gerado de acordo.
rustdllproxy new -p path/to/target_.dll -n my_proxy
Dica: O rustdllproxy é construído como uma CLI com clap. Execute rustdllproxy --help para ver todas as opções e flags.
A biblioteca de macros suporta 3 tipos principais de hooks: prehook, posthook e fullhook.
Substitua a diretiva #[no_mangle] pela macro de hook (deixe o comentário final //<dllname>.dll no lugar)
#[prehook("dllbeingproxied.dll", "function_name")] //dllbeingproxied.dll
Preencha a assinatura da função (declare entradas como mut para modificá-las)
Compile com rustdllproxy build.
prehookExecuta código antes da função original. Permite adicionar funcionalidade ou modificar variáveis de entrada.
#[prehook("target.dll", "my_function")] //target.dll
fn my_function(mut param1: i32, mut param2: &str) {
// Seu código aqui - executa antes da função original
param1 *= 2; // Modifique os parâmetros se necessário
}
posthookExecuta código depois da função original. Visualize e edite o valor de retorno usando a variável mágica ret.
#[posthook("target.dll", "calculate")] //target.dll
fn calculate(input: i32) -> i32 {
// A função original executa primeiro
// Depois seu código executa com acesso a 'ret'
ret = ret * 2; // Modifique o valor de retorno
}
Nota: A variável
reté automaticamente definida como mutável. Você não precisa referenciá-la se não for necessário.
fullhookFornece controle total sobre a execução da função. Gerencie manualmente o valor de retorno e a chamada da função.
#[fullhook("target.dll", "do_multi_add")] //target.dll
fn do_multi_add(mut a: i32, mut b: i32, mut c: i32) -> i32 {
// Pré-processamento
a += 10;
b += 20;
// Chame a função original com a mágica func()
let mut return_value: i32 = func(a, b, c);
// Pós-processamento
return_value *= 2;
// Deve retornar o valor explicitamente
return_value
}
Execute a partir do diretório da crate proxy (ou passe-o como primeiro argumento):
rustdllproxy build [PATH] [--profile <name>] [--no-build] [-- <extra cargo args>]
| Flag | Padrão | Efeito |
|---|---|---|
PATH | . | Caminho para a raiz da crate proxy. |
--profile <name> | release | Perfil de build do Cargo (release, dev, custom). |
--no-build | off | Regenera o arquivo .def mas pula cargo build. |
-- <args> | — | Encaminhado literalmente para cargo build. |
.def é totalmente regenerado a cada build; alterações manuais serão sobrescritas. Se você precisar fazer alterações manuais no modo como o rustdllproxy compila, o cargo pode ser usado para isso.Digamos que você queira modificar office.dll usada em software de escritório via sequestro de ordem de busca de DLL:
# Renomeie a DLL original
mv office.dll office_.dll
rustdllproxy new -p office_.dll -n office_proxy
#[prehook("office_.dll", "open_window")] //office_.dll
fn open_window() {
// Seu código personalizado aqui...
println!("A janela está prestes a abrir!");
}
cd office_proxy
rustdllproxy build
Os arquivos de build estão localizados em
/target
É possível criar proxies para várias DLLs alvo com uma única crate. Esse recurso raramente é usado e vem com algumas ressalvas importantes.
Ao empacotar múltiplas DLLs:
As notas de versão estão em CHANGELOG.md.
Contribuições são bem-vindas! Sinta-se à vontade para enviar issues e pull requests.