Obfuscate (hide) the PE imports from static/dynamic analysis tools.
Theory.
- It can be included directly as a library, see the following snippet (based on the example), also you can take a look at cli.cpp.
#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;};
- Also can be used as a command line tool by supplying it with the input PE path, the output PE path and optionally the path to the configuration file (default is
config.ini).
cobf.exe <input file> <out file> [config file]
The config file contains the obfuscations needed (dlls, symbols, ...).
Here is a template for the config file content
; 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
Example).
The used configurations are
[kernel32.dll]SetLastError=BeepGetLastError=GetACP
Here is the output (also you can use the library directly as shown above).
Again let's have a look on the kernel32 imports
There's no existence of
SetLastError or
GetLastError
A confirmation that two files will work properly
Impact
IDA HexRays Decompiler
IDA Debugger
Ghidra
ApiMonitor
That's because all of
- Dumping the obfuscated PE out from memory won't deobfuscate it, because the manipulated IAT will be the same.
- The main purpose for this tool is to mess up with the analysis process (make it slower).
- One can obfuscate any imported symbol (by name or by ordinal) with another symbol (name or ordinal).
- The shellcode is executed as the first tls callback to process the obfuscated symbols needed by the other tls callbacks before the entry point is executed.
- The shellcode is shipped as c code, generated when the tool is compiled to facilitate editing it.
- The obfuscated symbols names are being resolved by hash not by name directly.
- The tool disables the relocations and strips any of the debug symbols.
- The tool creates a new rwx section named
.cobffor holding the shellcode and the other needed datas.
- It can be used multiple times on the same obfuscated PE.
- Tested only on Windows 10 x64.
- Get source with
git clone.
- Download binaries from the Release Section.
TODO
- Shellcode obfuscation (probably with obfusion).
- Support the delay-loaded symbols.
- Minimize the created section size.
- Compile time hashing.
- Better testing.