// crossfire: distributed brute force infrastructure // // Copyright (C) 2020 haskal // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #include "crossfire-embedding.h" #include "find-section.h" #include #include #include #include #include #include #include #define error() \ fprintf(stderr, "[WRAPPER] fatal boot error... corrupted binary?\n"); \ return -1; static const ffi_ent ffi_table[] = { FFI_ENT(crypto_sign_public_key), FFI_ENT(crypto_sign), FFI_ENT(crypto_check), FFI_ENT(crypto_key_exchange_public_key), FFI_ENT(crypto_key_exchange), FFI_ENT(crypto_lock), FFI_ENT(crypto_unlock), FFI_ENT(crypto_wipe), FFI_ENT(crypto_blake2b_init), FFI_ENT(crypto_blake2b_update), FFI_ENT(crypto_blake2b_final), FFI_ENT(clock_gettime), FFI_ENT(gethostname), FFI_ENT(fsync) }; static const size_t ffi_table_size = sizeof(ffi_table)/sizeof(ffi_ent); // yeet // chez people don't yell at me pls static ptr scheme_list(int count, ...) { va_list ap; va_start(ap, count); ptr vals[count]; for (int i = 0; i < count; i++) { ptr arg = va_arg(ap, ptr); vals[i] = arg; } va_end(ap); ptr val = Snil; for (int i = 0; i < count; i++) { val = Scons(vals[count - i - 1], val); } return val; } static void cs_setup_ffi_table() { // this is pain // chez scheme is pain // why is it like this // gimme my scheme_primitive_module holy shit pls,,,, racket_namespace_require(Sstring_to_symbol("racket/base")); // also since this is '#%kernel level code, technically it's all UB // which is fun ptr module = Sstring_to_symbol("module"); ptr __module_begin = Sstring_to_symbol("#%module-begin"); ptr quote = Sstring_to_symbol("quote"); ptr __kernel = Sstring_to_symbol("#%kernel"); ptr __provide = Sstring_to_symbol("#%provide"); ptr define_values = Sstring_to_symbol("define-values"); ptr __static_ffi = Sstring_to_symbol("#%static-ffi"); ptr table_n = Sstring_to_symbol("table"); ptr table_size_n = Sstring_to_symbol("table-size"); ptr arch_n = Sstring_to_symbol("arch"); ptr table_e = scheme_list(2, quote, Sunsigned64((uint64_t) &ffi_table[0])); ptr table_size_e = scheme_list(2, quote, Sunsigned64(ffi_table_size)); ptr arch_e = scheme_list(2, quote, Sstring(APP_ARCH)); ptr table_d = scheme_list(3, define_values, scheme_list(1, table_n), table_e); ptr table_size_d = scheme_list(3, define_values, scheme_list(1, table_size_n), table_size_e); ptr arch_d = scheme_list(3, define_values, scheme_list(1, arch_n), arch_e); ptr e = scheme_list(4, module, __static_ffi, scheme_list(2, quote, __kernel), scheme_list(5, __module_begin, scheme_list(4, __provide, table_n, table_size_n, arch_n), table_d, table_size_d, arch_d)); // evaling this magically registers it in the default namespace // it's magic // don't ask questions racket_eval(e); } int main(int argc, char* argv[]) { printf("[WRAPPER] booting racket CS\n"); boot_ctx ctx; if (init_boot_ctx(&ctx) < 0) { error(); } racket_boot_arguments_t args; memset(&args, 0, sizeof(args)); args.boot1_path = ctx.self_name; args.boot2_path = ctx.self_name; args.boot3_path = ctx.self_name; boot_lookup boot1 = boot_ctx_lookup(&ctx, ".csboot1"); boot_lookup boot2 = boot_ctx_lookup(&ctx, ".csboot2"); boot_lookup boot3 = boot_ctx_lookup(&ctx, ".csboot3"); if (boot1.offset == (off_t) -1 || boot2.offset == (off_t) -1 || boot3.offset == (off_t) -1) { error(); } args.boot1_offset = boot1.offset; args.boot2_offset = boot2.offset; args.boot3_offset = boot3.offset; args.exec_file = argv[0]; racket_boot(&args); boot_lookup app_offset = boot_ctx_lookup(&ctx, ".boot"); if (app_offset.offset == (off_t) -1) { error(); } racket_embedded_load_bytes(((uint8_t*) ctx.self_mm) + app_offset.offset, app_offset.size, false); unload_boot_ctx(&ctx); cs_setup_ffi_table(); ptr mod = Scons(Sstring_to_symbol("quote"), Scons(Sstring_to_symbol(APP_NAME), Snil)); racket_dynamic_require(mod, Sfalse); return 0; }