/* * Warlock's Stave — Quick FFI Demo Harness * * Compile: gcc -o demo demo.c -ldl -Wl,-rpath,./target/release * Run: LD_LIBRARY_PATH=./target/release ./demo */ #include #include #include #include /* Mirrors the 4 C-FFI functions from libstave_core.so */ typedef void* (*init_fn)(void); typedef const char* (*ingest_fn)(void*, const unsigned char*, size_t, unsigned long, unsigned int); typedef void (*free_str_fn)(const char*); typedef void (*destroy_fn)(void*); int main(void) { printf("=== Warlock's Stave FFI Demo ===\n\n"); /* --- Load the shared library --- */ void *lib = dlopen("./target/release/libstave_core.so", RTLD_NOW); if (!lib) { fprintf(stderr, "dlopen failed: %s\n", dlerror()); fprintf(stderr, "Run ./build.sh first, then use:\n"); fprintf(stderr, " LD_LIBRARY_PATH=./target/release ./demo\n"); return 1; } init_fn init = (init_fn) dlsym(lib, "initialize_warlock_stave"); ingest_fn ingest = (ingest_fn) dlsym(lib, "stave_ingest_frame"); free_str_fn freestr = (free_str_fn)dlsym(lib, "free_stave_string"); destroy_fn destroy = (destroy_fn) dlsym(lib, "destroy_warlock_stave"); if (!init || !ingest || !freestr || !destroy) { fprintf(stderr, "dlsym failed: %s\n", dlerror()); dlclose(lib); return 1; } /* --- Initialize the engine --- */ void *ctx = init(); printf("[Engine] Context created: %p\n\n", ctx); /* * Feed a realistic x86-64 sequence. * Each frame: (bytes, length, RIP, EFLAGS) * * Instructions: * 0x7FF0: 48 31 C0 xor rax, rax * 0x7FF3: 48 89 C3 mov rbx, rax * 0x7FF6: 0F 84 10 00 00 00 je +0x10 (conditional — ZF=1 in EFLAGS) * 0x7FFC: E9 05 00 00 00 jmp +0x5 (unconditional) * 0x8001: 48 83 C4 28 add rsp, 0x28 */ struct { unsigned char *bytes; size_t len; unsigned long rip; unsigned int eflags; } frames[] = { { (unsigned char[]){ 0x48, 0x31, 0xC0 }, 3, 0x7FF0, 0x202 }, /* ZF=1 */ { (unsigned char[]){ 0x48, 0x89, 0xC3 }, 3, 0x7FF3, 0x202 }, { (unsigned char[]){ 0x0F, 0x84, 0x10, 0x00, 0x00, 0x00 }, 6, 0x7FF6, 0x246 }, /* ZF=1, SF=1 */ { (unsigned char[]){ 0xE9, 0x05, 0x00, 0x00, 0x00 }, 5, 0x7FFC, 0x246 }, { (unsigned char[]){ 0x48, 0x83, 0xC4, 0x28 }, 4, 0x8001, 0x246 }, }; int n = sizeof(frames) / sizeof(frames[0]); for (int i = 0; i < n; i++) { const char *json = ingest(ctx, frames[i].bytes, frames[i].len, frames[i].rip, frames[i].eflags); printf("[Frame %d] RIP=0x%04lX bytes=%zu EFLAGS=0x%X\n", i+1, frames[i].rip, frames[i].len, frames[i].eflags); printf(" %s\n\n", json); freestr(json); } /* --- Telemetry round-trip: hit the same cell twice --- */ printf("[Frame 6] Re-visiting RIP=0x7FF0 (heatmap intensity should increase)...\n"); const char *json = ingest(ctx, (unsigned char[]){ 0x48, 0x31, 0xC0 }, 3, 0x7FF0, 0x202); printf(" %s\n\n", json); freestr(json); /* --- Conditional branch with ZF=0 (not-taken path) --- */ printf("[Frame 7] je with ZF=0 (should report ConditionNotMet)...\n"); json = ingest(ctx, (unsigned char[]){ 0x0F, 0x84, 0x10, 0x00, 0x00, 0x00 }, 6, 0x7FF6, 0x242); printf(" %s\n\n", json); freestr(json); /* --- Dictionary scan: URL pattern in bytes --- */ printf("[Frame 8] Bytes containing 'http://' (dictionary hit expected)...\n"); json = ingest(ctx, (unsigned char[]){ 0x68, 0x74, 0x74, 0x70, 0x3A, 0x2F, 0x2F }, 7, 0x9000, 0x246); printf(" %s\n\n", json); freestr(json); /* --- Cleanup --- */ destroy(ctx); dlclose(lib); printf("=== Done. ===\n"); return 0; }