How do I develop a BOF-PE?
Open your preferred text editor and start writing a C program that exports go. A BOF-PE is a complete Windows PE file, so it can use normal Windows imports directly. By default, it does not need beacon.h or Beacon APIs.
Here's a simple MessageBoxA BOF-PE:
#include <windows.h>
__declspec(dllexport) void go(const char *args, int len) {
MessageBoxA(NULL, "Hello from BOF-PE", "BOF-PE", MB_OK);
}
int main(void) {
return 0; // Stub function so we can build a normal .exe
}
To compile this with Visual Studio as an EXE:
cl.exe /GS- messagebox.c user32.lib /link /EXPORT:go /OUT:messagebox.exe
To compile this with x86 MinGW as an EXE:
i686-w64-mingw32-gcc messagebox.c -o messagebox.x86.exe -Wl,--export-all-symbols -luser32
To compile this with x64 MinGW as an EXE:
x86_64-w64-mingw32-gcc messagebox.c -o messagebox.x64.exe -Wl,--export-all-symbols -luser32
These commands produce a Windows EXE that exports go. Use inline-execute-pe in the Beacon Console to run the BOF-PE:
beacon> inline-execute-pe /path/to/messagebox.x64.exe
From Aggressor Script, load the BOF-PE bytes and execute them with beacon_inline_execute_pe:
alias messagebox_pe {
local('$handle $data');
$handle = openf(script_resource("messagebox.x64.exe"));
$data = readb($handle, -1);
closef($handle);
btask($1, "Running MessageBoxA BOF-PE");
beacon_inline_execute_pe($1, $data, "go", $null);
}
The BOF-PE's go function is similar to main in a normal program. It is the function Beacon calls after loading the PE. Packed arguments are delivered through the args pointer and len length, but the MessageBoxA example does not use them.
For advanced BOF-PE use cases, including debugging guidance, Beacon API use, and implementations in other languages, see the original specification.