Writing a Blob
A blob is a freestanding C program that runs at any address. Include the target OS header first, then the syscall wrappers you need.
Linux blob
#include "picblobs/os/linux.h"
#include "picblobs/section.h"
#include "picblobs/reloc.h"
#include "picblobs/sys/write.h"
#include "picblobs/sys/exit_group.h"
PIC_RODATA
static const char msg[] = "Hello, world!\n";
PIC_ENTRY
void _start(void)
{
PIC_SELF_RELOCATE();
pic_write(1, msg, sizeof(msg) - 1);
pic_exit_group(0);
}
Windows blob
#include "picblobs/os/windows.h"
#include "picblobs/section.h"
#include "picblobs/reloc.h"
#include "picblobs/win/resolve.h"
/* DJB2 hashes of API function names */
#define HASH_KERNEL32 0x7040EE75
#define HASH_GetStdHandle 0xF178843C
#define HASH_WriteFile 0x663CECB0
#define HASH_ExitProcess 0xB769339E
PIC_RODATA
static const char msg[] = "Hello, world!\n";
PIC_ENTRY
void _start(void)
{
PIC_SELF_RELOCATE();
void *k32 = pic_resolve_module(HASH_KERNEL32);
void *(*GetStdHandle)(unsigned long) = pic_resolve_export(k32, HASH_GetStdHandle);
// ... resolve and call APIs
}
Key conventions
- Each
sys/*.hheader is a self-contained module with syscall numbers for every OS/architecture combination, constants, and wrapper function. - Use
PIC_RODATAfor read-only data (ensures correct section placement in freestanding PIC). - Use
PIC_ENTRYfor the entry point andPIC_SELF_RELOCATE()at the top for MIPS GOT relocation. - Drop a
.cfile intosrc/payload/, runpython tools/generate.py, and it will be picked up automatically.