crossfire/agent-deployment/main_cs.c

164 lines
5.0 KiB
C

// 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 <https://www.gnu.org/licenses/>.
#include "crossfire-embedding.h"
#include "find-section.h"
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#include <unistd.h>
#include <chezscheme.h>
#include <racketcs.h>
#include <monocypher.h>
#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;
}