
Ofuscar APIs específicas do Windows com APIs diferentes
Ofusca (oculta) as importações de PE de ferramentas de análise estática/dinâmica.
É bem direto: digamos que eu usei VirtualProtect e quero ofuscá-lo com Sleep. A ferramenta manipulará a IAT para que o thunk que aponta para VirtualProtect aponte em vez disso para Sleep. Ao executar o arquivo, o carregador do Windows carregará Sleep em vez de VirtualProtect e moverá a execução para o ponto de entrada. A partir daí, a execução será redirecionada para o shellcode colocado anteriormente pela ferramenta, para encontrar o endereço de VirtualProtect e usá-lo para substituir o endereço de Sleep que foi atribuído anteriormente pelo carregador.
#include <cobf.hpp>
int main() {
cobf obf_file = cobf("sample.exe");
obf_file.load_pe();
obf_file.obf_sym("kernel32.dll", "SetLastError", "Beep");
obf_file.obf_sym("kernel32.dll", "GetLastError", "GetACP");
obf_file.generate("sample_obfuscated.exe");
obf_file.unload_pe();
return 0;
};
config.ini).cobf.exe <input file> <out file> [config file]; Template for the config file:
; * Sections can be written as:
; [dll_name]
; old_sym=new_sym
; * The dll name is case insensitive, but
; the old and the new symbols are not.
; * You can use the wildcard on both the
; dll name and the old symbol.
; * You can use '#' at the start of
; the old or the new symbol to flag
; an ordinal.
; * The new symbol should be exported
; by the dll so the windows loader can resolve it.
; For example:
; * Obfuscating all of the symbols
; imported from user32.dll with ordinal 1600.
[user32.dll]
*=#1600
; * Obfuscating symbols imported from both
; kernel32.dll and kernelbase.dll with Sleep.
[kernel*.dll]
*=Sleep
; * Obfuscating fprintf with exit.
[*]
fprintf=exit
Compile este exemplo de código
#include <windows.h>
#include <stdio.h>
int main() {
SetLastError(5);
printf("Last error is %d\n", GetLastError());
return 0;
};
Após compilá-lo, é assim que as importações do kernel32 se parecem

Agora vamos ofuscar tanto SetLastError quanto GetLastError com Beep e GetACP (na verdade, qualquer api do kernel32 funcionará, mesmo que não esteja importada).
As configurações usadas são
[kernel32.dll]
SetLastError=Beep
GetLastError=GetACP
Aqui está a saída (você também pode usar a biblioteca diretamente como mostrado acima).

Novamente, vamos dar uma olhada nas importações do kernel32

Não há existência de SetLastError ou GetLastError
Uma confirmação de que os dois arquivos funcionarão corretamente

Decompilador IDA HexRays

Depurador IDA

Ghidra

ApiMonitor

Isso porque todas as ferramentas de análise estática dependem do nome da api escrito na IAT, que pode ser manipulado como mostrado.
Para o ApiMonitor, por usar hooking na IAT, o mesmo problema existe.
Por outro lado, para ferramentas como x64dbg, os nomes de api exibidos dependerão apenas do que é realmente chamado (não do que está escrito na IAT).

.cobf para armazenar o shellcode e outros dados necessários.git clone https://github.com/d35ha/CallObfuscator.