librz/bin: add CaRT container format support (#5964)
* Add CaRT extractor plugin * Update cmd_list expected output for CaRT extractor plugin Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
parent
7bac9f75fa
commit
5fab5584e2
9 changed files with 442 additions and 1 deletions
197
librz/bin/format/cart/cart.c
Normal file
197
librz/bin/format/cart/cart.c
Normal file
|
|
@ -0,0 +1,197 @@
|
||||||
|
// SPDX-FileCopyrightText: 2025 Ayush Dwivedi <ayushd785@gmail.com>
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-only
|
||||||
|
|
||||||
|
#include "cart.h"
|
||||||
|
#include <rz_crypto/rz_rc4.h>
|
||||||
|
#include <rz_util.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default RC4 key used by CaRT: first 8 digits of PI repeated twice.
|
||||||
|
* Reference: https://github.com/CybercentreCanada/cart/blob/master/cart/cart.py#L34
|
||||||
|
*/
|
||||||
|
static const ut8 CART_DEFAULT_RC4_KEY[CART_ARC4_KEY_LENGTH] = {
|
||||||
|
0x03, 0x01, 0x04, 0x01, 0x05, 0x09, 0x02, 0x06,
|
||||||
|
0x03, 0x01, 0x04, 0x01, 0x05, 0x09, 0x02, 0x06
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool cart_key_is_null(const ut8 *key) {
|
||||||
|
for (int i = 0; i < CART_ARC4_KEY_LENGTH; i++) {
|
||||||
|
if (key[i] != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
RZ_API bool rz_bin_cart_check_buffer(RZ_NONNULL RzBuffer *buf) {
|
||||||
|
rz_return_val_if_fail(buf, false);
|
||||||
|
|
||||||
|
ut64 sz = rz_buf_size(buf);
|
||||||
|
if (sz < CART_MINIMUM_LENGTH) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ut8 header_magic[CART_HEADER_MAGIC_SIZE];
|
||||||
|
if (rz_buf_read_at(buf, 0, header_magic, CART_HEADER_MAGIC_SIZE) != CART_HEADER_MAGIC_SIZE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(header_magic, CART_HEADER_MAGIC, CART_HEADER_MAGIC_SIZE) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ut8 footer_magic[CART_FOOTER_MAGIC_SIZE];
|
||||||
|
ut64 footer_start = sz - CART_FOOTER_LENGTH;
|
||||||
|
if (rz_buf_read_at(buf, footer_start, footer_magic, CART_FOOTER_MAGIC_SIZE) != CART_FOOTER_MAGIC_SIZE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(footer_magic, CART_FOOTER_MAGIC, CART_FOOTER_MAGIC_SIZE) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
RZ_API RZ_OWN CartObj *rz_bin_cart_new_from_buffer(RZ_NONNULL RzBuffer *buf) {
|
||||||
|
rz_return_val_if_fail(buf, NULL);
|
||||||
|
|
||||||
|
if (!rz_bin_cart_check_buffer(buf)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ut64 sz = rz_buf_size(buf);
|
||||||
|
|
||||||
|
CartObj *obj = RZ_NEW0(CartObj);
|
||||||
|
if (!obj) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj->file_size = sz;
|
||||||
|
|
||||||
|
ut64 off = 0;
|
||||||
|
if (!rz_buf_read_offset(buf, &off, (ut8 *)obj->header.magic, CART_HEADER_MAGIC_SIZE) ||
|
||||||
|
!rz_buf_read_le16_offset(buf, &off, &obj->header.version) ||
|
||||||
|
!rz_buf_read_le64_offset(buf, &off, &obj->header.reserved) ||
|
||||||
|
!rz_buf_read_offset(buf, &off, obj->header.arc4_key, CART_ARC4_KEY_LENGTH) ||
|
||||||
|
!rz_buf_read_le64_offset(buf, &off, &obj->header.opt_header_len)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj->header.version != CART_VERSION) {
|
||||||
|
RZ_LOG_WARN("CaRT: Unsupported version %d (expected %d)\n", obj->header.version, CART_VERSION);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj->header.reserved != 0) {
|
||||||
|
RZ_LOG_WARN("CaRT: Invalid header reserved value (expected 0)\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
ut64 footer_start = sz - CART_FOOTER_LENGTH;
|
||||||
|
off = footer_start;
|
||||||
|
if (!rz_buf_read_offset(buf, &off, (ut8 *)obj->footer.magic, CART_FOOTER_MAGIC_SIZE) ||
|
||||||
|
!rz_buf_read_le64_offset(buf, &off, &obj->footer.reserved) ||
|
||||||
|
!rz_buf_read_le64_offset(buf, &off, &obj->footer.opt_footer_pos) ||
|
||||||
|
!rz_buf_read_le64_offset(buf, &off, &obj->footer.opt_footer_len)) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj->footer.reserved != 0) {
|
||||||
|
RZ_LOG_WARN("CaRT: Invalid footer reserved value (expected 0)\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj->footer.opt_footer_pos + obj->footer.opt_footer_len != footer_start) {
|
||||||
|
RZ_LOG_WARN("CaRT: Invalid footer position/length\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj->data_start = CART_HEADER_LENGTH + obj->header.opt_header_len;
|
||||||
|
obj->data_len = obj->footer.opt_footer_pos - obj->data_start;
|
||||||
|
|
||||||
|
if (obj->data_start > sz || obj->data_start + obj->data_len > sz) {
|
||||||
|
RZ_LOG_WARN("CaRT: Invalid data block boundaries\n");
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
free(obj);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
RZ_API void rz_bin_cart_free(RZ_NULLABLE CartObj *obj) {
|
||||||
|
free(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
RZ_API RZ_OWN ut8 *rz_bin_cart_extract(RZ_NONNULL RzBuffer *buf, RZ_NONNULL CartObj *obj, RZ_NONNULL int *out_size) {
|
||||||
|
rz_return_val_if_fail(buf && obj && out_size, NULL);
|
||||||
|
|
||||||
|
*out_size = 0;
|
||||||
|
|
||||||
|
if (obj->data_len == 0) {
|
||||||
|
RZ_LOG_WARN("CaRT: Empty data block\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj->data_len > 0x10000000) {
|
||||||
|
RZ_LOG_WARN("CaRT: Data block too large\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ut8 *encrypted = malloc(obj->data_len);
|
||||||
|
if (!encrypted) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rz_buf_read_at(buf, obj->data_start, encrypted, obj->data_len) != obj->data_len) {
|
||||||
|
free(encrypted);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ut8 *key = obj->header.arc4_key;
|
||||||
|
if (cart_key_is_null(key)) {
|
||||||
|
key = CART_DEFAULT_RC4_KEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
ut8 *decrypted = malloc(obj->data_len);
|
||||||
|
if (!decrypted) {
|
||||||
|
free(encrypted);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rz_rc4_crypt(key, CART_ARC4_KEY_LENGTH, encrypted, decrypted, obj->data_len);
|
||||||
|
free(encrypted);
|
||||||
|
|
||||||
|
int decompressed_len = 0;
|
||||||
|
ut8 *decompressed = rz_inflate(decrypted, obj->data_len, NULL, &decompressed_len);
|
||||||
|
free(decrypted);
|
||||||
|
|
||||||
|
if (!decompressed) {
|
||||||
|
RZ_LOG_WARN("CaRT: Failed to decompress payload\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*out_size = decompressed_len;
|
||||||
|
return decompressed;
|
||||||
|
}
|
||||||
|
|
||||||
|
RZ_API RZ_OWN RzBuffer *rz_bin_cart_extract_buf(RZ_NONNULL RzBuffer *buf, RZ_NONNULL CartObj *obj) {
|
||||||
|
rz_return_val_if_fail(buf && obj, NULL);
|
||||||
|
|
||||||
|
int payload_size = 0;
|
||||||
|
ut8 *payload = rz_bin_cart_extract(buf, obj, &payload_size);
|
||||||
|
if (!payload) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
RzBuffer *result = rz_buf_new_with_pointers(payload, payload_size, true);
|
||||||
|
if (!result) {
|
||||||
|
free(payload);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
66
librz/bin/format/cart/cart.h
Normal file
66
librz/bin/format/cart/cart.h
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
// SPDX-FileCopyrightText: 2025 Ayush Dwivedi <ayushd785@gmail.com>
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-only
|
||||||
|
|
||||||
|
#ifndef RZ_BIN_CART_H
|
||||||
|
#define RZ_BIN_CART_H
|
||||||
|
|
||||||
|
#include <rz_types.h>
|
||||||
|
#include <rz_util.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CART_HEADER_MAGIC "CART"
|
||||||
|
#define CART_FOOTER_MAGIC "TRAC"
|
||||||
|
#define CART_HEADER_MAGIC_SIZE 4
|
||||||
|
#define CART_FOOTER_MAGIC_SIZE 4
|
||||||
|
|
||||||
|
#define CART_VERSION 1
|
||||||
|
|
||||||
|
#define CART_HEADER_LENGTH 38
|
||||||
|
#define CART_FOOTER_LENGTH 28
|
||||||
|
#define CART_MINIMUM_LENGTH (CART_HEADER_LENGTH + CART_FOOTER_LENGTH)
|
||||||
|
|
||||||
|
#define CART_ARC4_KEY_LENGTH 16
|
||||||
|
#define CART_BLOCK_SIZE (64 * 1024)
|
||||||
|
|
||||||
|
typedef struct cart_header_t {
|
||||||
|
char magic[CART_HEADER_MAGIC_SIZE];
|
||||||
|
ut16 version;
|
||||||
|
ut64 reserved;
|
||||||
|
ut8 arc4_key[CART_ARC4_KEY_LENGTH];
|
||||||
|
ut64 opt_header_len;
|
||||||
|
} CartHeader;
|
||||||
|
|
||||||
|
typedef struct cart_footer_t {
|
||||||
|
char magic[CART_FOOTER_MAGIC_SIZE];
|
||||||
|
ut64 reserved;
|
||||||
|
ut64 opt_footer_pos;
|
||||||
|
ut64 opt_footer_len;
|
||||||
|
} CartFooter;
|
||||||
|
|
||||||
|
typedef struct cart_obj_t {
|
||||||
|
CartHeader header;
|
||||||
|
CartFooter footer;
|
||||||
|
ut64 data_start;
|
||||||
|
ut64 data_len;
|
||||||
|
ut64 file_size;
|
||||||
|
} CartObj;
|
||||||
|
|
||||||
|
/** Check if buffer contains valid CaRT magic (CART/TRAC) */
|
||||||
|
RZ_API bool rz_bin_cart_check_buffer(RZ_NONNULL RzBuffer *buf);
|
||||||
|
/** Parse CaRT header and footer from buffer */
|
||||||
|
RZ_API RZ_OWN CartObj *rz_bin_cart_new_from_buffer(RZ_NONNULL RzBuffer *buf);
|
||||||
|
/** Free CartObj */
|
||||||
|
RZ_API void rz_bin_cart_free(RZ_NULLABLE CartObj *obj);
|
||||||
|
/** Extract decrypted and decompressed payload */
|
||||||
|
RZ_API RZ_OWN ut8 *rz_bin_cart_extract(RZ_NONNULL RzBuffer *buf, RZ_NONNULL CartObj *obj, RZ_NONNULL int *out_size);
|
||||||
|
/** Extract payload as RzBuffer */
|
||||||
|
RZ_API RZ_OWN RzBuffer *rz_bin_cart_extract_buf(RZ_NONNULL RzBuffer *buf, RZ_NONNULL CartObj *obj);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -60,6 +60,7 @@ bin_plugins_list = [
|
||||||
]
|
]
|
||||||
|
|
||||||
bin_xtr_plugins_list = [
|
bin_xtr_plugins_list = [
|
||||||
|
'cart',
|
||||||
'fatmach0',
|
'fatmach0',
|
||||||
'sep64',
|
'sep64',
|
||||||
# this was never built.
|
# this was never built.
|
||||||
|
|
@ -157,6 +158,7 @@ rz_bin_sources = [
|
||||||
'p/bin_wasm.c',
|
'p/bin_wasm.c',
|
||||||
'p/bin_xbe.c',
|
'p/bin_xbe.c',
|
||||||
'p/bin_xnu_kernelcache.c',
|
'p/bin_xnu_kernelcache.c',
|
||||||
|
'p/bin_xtr_cart.c',
|
||||||
'p/bin_xtr_fatmach0.c',
|
'p/bin_xtr_fatmach0.c',
|
||||||
# this was never built.
|
# this was never built.
|
||||||
# 'p/bin_xtr_pemixed.c',
|
# 'p/bin_xtr_pemixed.c',
|
||||||
|
|
@ -276,6 +278,7 @@ rz_bin_sources = [
|
||||||
'format/pyc/marshal.c',
|
'format/pyc/marshal.c',
|
||||||
'format/pyc/pyc.c',
|
'format/pyc/pyc.c',
|
||||||
'format/pyc/pyc_magic.c',
|
'format/pyc/pyc_magic.c',
|
||||||
|
'format/cart/cart.c',
|
||||||
'format/te/te.c',
|
'format/te/te.c',
|
||||||
'format/wasm/wasm.c',
|
'format/wasm/wasm.c',
|
||||||
|
|
||||||
|
|
@ -328,6 +331,7 @@ rz_bin = library('rz_bin', rz_bin_sources,
|
||||||
rz_search_dep,
|
rz_search_dep,
|
||||||
rz_cons_dep,
|
rz_cons_dep,
|
||||||
rz_io_dep,
|
rz_io_dep,
|
||||||
|
rz_crypto_dep,
|
||||||
rz_type_dep,
|
rz_type_dep,
|
||||||
libmspack_dep,
|
libmspack_dep,
|
||||||
],
|
],
|
||||||
|
|
|
||||||
110
librz/bin/p/bin_xtr_cart.c
Normal file
110
librz/bin/p/bin_xtr_cart.c
Normal file
|
|
@ -0,0 +1,110 @@
|
||||||
|
// SPDX-FileCopyrightText: 2025 Ayush Dwivedi <ayushd785@gmail.com>
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-only
|
||||||
|
|
||||||
|
#include <rz_types.h>
|
||||||
|
#include <rz_util.h>
|
||||||
|
#include <rz_lib.h>
|
||||||
|
#include <rz_bin.h>
|
||||||
|
#include "../format/cart/cart.h"
|
||||||
|
|
||||||
|
static bool check_buffer(RzBuffer *buf) {
|
||||||
|
rz_return_val_if_fail(buf, false);
|
||||||
|
return rz_bin_cart_check_buffer(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_xtr(void *xtr_obj) {
|
||||||
|
rz_bin_cart_free((CartObj *)xtr_obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void destroy(RzBin *bin) {
|
||||||
|
if (bin && bin->cur) {
|
||||||
|
free_xtr(bin->cur->xtr_obj);
|
||||||
|
bin->cur->xtr_obj = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool load(RzBin *bin) {
|
||||||
|
rz_return_val_if_fail(bin && bin->cur, false);
|
||||||
|
bin->cur->xtr_obj = rz_bin_cart_new_from_buffer(bin->cur->buf);
|
||||||
|
return bin->cur->xtr_obj != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int size(RzBin *bin) {
|
||||||
|
rz_return_val_if_fail(bin && bin->cur && bin->cur->xtr_obj, 0);
|
||||||
|
CartObj *obj = (CartObj *)bin->cur->xtr_obj;
|
||||||
|
return (int)obj->file_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static RzBinXtrData *oneshot_buffer(RzBin *bin, RzBuffer *b, int idx) {
|
||||||
|
rz_return_val_if_fail(bin && bin->cur && b, NULL);
|
||||||
|
|
||||||
|
if (idx != 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bin->cur->xtr_obj) {
|
||||||
|
bin->cur->xtr_obj = rz_bin_cart_new_from_buffer(b);
|
||||||
|
}
|
||||||
|
if (!bin->cur->xtr_obj) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
CartObj *obj = (CartObj *)bin->cur->xtr_obj;
|
||||||
|
RzBuffer *payload_buf = rz_bin_cart_extract_buf(b, obj);
|
||||||
|
if (!payload_buf) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
RzBinXtrMetadata *metadata = RZ_NEW0(RzBinXtrMetadata);
|
||||||
|
if (!metadata) {
|
||||||
|
rz_buf_free(payload_buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
metadata->xtr_type = "cart";
|
||||||
|
metadata->libname = rz_str_dup("cart_payload");
|
||||||
|
|
||||||
|
ut64 payload_size = rz_buf_size(payload_buf);
|
||||||
|
RzBinXtrData *res = rz_bin_xtrdata_new(payload_buf, 0, payload_size, 1, metadata);
|
||||||
|
|
||||||
|
rz_buf_free(payload_buf);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static RzList /*<RzBinXtrData *>*/ *oneshotall_buffer(RzBin *bin, RzBuffer *b) {
|
||||||
|
RzBinXtrData *data = oneshot_buffer(bin, b, 0);
|
||||||
|
if (!data) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
RzList *res = rz_list_newf(rz_bin_xtrdata_free);
|
||||||
|
if (!res) {
|
||||||
|
rz_bin_xtrdata_free(data);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
rz_list_append(res, data);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
RzBinXtrPlugin rz_bin_xtr_plugin_cart = {
|
||||||
|
.name = "xtr.cart",
|
||||||
|
.desc = "CaRT (Compressed and RC4 Transport) extractor",
|
||||||
|
.license = "LGPL3",
|
||||||
|
.check_buffer = check_buffer,
|
||||||
|
.load = &load,
|
||||||
|
.destroy = &destroy,
|
||||||
|
.size = &size,
|
||||||
|
.extract_from_buffer = &oneshot_buffer,
|
||||||
|
.extractall_from_buffer = &oneshotall_buffer,
|
||||||
|
.free_xtr = &free_xtr,
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef RZ_PLUGIN_INCORE
|
||||||
|
RZ_API RzLibStruct rizin_plugin = {
|
||||||
|
.type = RZ_LIB_TYPE_BIN_XTR,
|
||||||
|
.data = &rz_bin_xtr_plugin_cart,
|
||||||
|
.version = RZ_VERSION
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
#include <rz_lib.h>
|
#include <rz_lib.h>
|
||||||
#include <rz_crypto.h>
|
#include <rz_crypto.h>
|
||||||
|
#include <rz_crypto/rz_rc4.h>
|
||||||
#include <rz_util.h>
|
#include <rz_util.h>
|
||||||
|
|
||||||
struct rc4_state {
|
struct rc4_state {
|
||||||
|
|
@ -71,6 +72,21 @@ static void rc4_crypt(struct rc4_state *const state, const ut8 *inbuf, ut8 *outb
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief One-shot RC4 encrypt/decrypt.
|
||||||
|
*
|
||||||
|
* Initializes the RC4 state with the given key and processes the input buffer.
|
||||||
|
* Since RC4 is symmetric, the same function is used for both encryption and decryption.
|
||||||
|
*/
|
||||||
|
RZ_API void rz_rc4_crypt(RZ_NONNULL const ut8 *key, int keylen, RZ_NONNULL const ut8 *in, RZ_NONNULL ut8 *out, int len) {
|
||||||
|
rz_return_if_fail(key && in && out);
|
||||||
|
struct rc4_state state = { 0 };
|
||||||
|
if (!rc4_init_state(&state, key, keylen)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rc4_crypt(&state, in, out, len);
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static bool rc4_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction) {
|
static bool rc4_set_key(RzCrypto *cry, const ut8 *key, int keylen, int mode, int direction) {
|
||||||
|
|
|
||||||
|
|
@ -167,6 +167,7 @@ install_headers(rz_il_files, install_dir: join_paths(rizin_incdir, 'rz_il'))
|
||||||
rz_crypto_files = [
|
rz_crypto_files = [
|
||||||
'rz_crypto/rz_des.h',
|
'rz_crypto/rz_des.h',
|
||||||
'rz_crypto/rz_aes.h',
|
'rz_crypto/rz_aes.h',
|
||||||
|
'rz_crypto/rz_rc4.h',
|
||||||
'rz_crypto/rz_sm4.h',
|
'rz_crypto/rz_sm4.h',
|
||||||
]
|
]
|
||||||
install_headers(rz_crypto_files, install_dir: join_paths(rizin_incdir, 'rz_crypto'))
|
install_headers(rz_crypto_files, install_dir: join_paths(rizin_incdir, 'rz_crypto'))
|
||||||
|
|
|
||||||
19
librz/include/rz_crypto/rz_rc4.h
Normal file
19
librz/include/rz_crypto/rz_rc4.h
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
// SPDX-FileCopyrightText: 2025 Ayush Dwivedi <ayushd785@gmail.com>
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-only
|
||||||
|
|
||||||
|
#ifndef RZ_RC4_H
|
||||||
|
#define RZ_RC4_H
|
||||||
|
|
||||||
|
#include <rz_types.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RZ_API void rz_rc4_crypt(RZ_NONNULL const ut8 *key, int keylen, RZ_NONNULL const ut8 *in, RZ_NONNULL ut8 *out, int len);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // RZ_RC4_H
|
||||||
File diff suppressed because one or more lines are too long
25
test/db/formats/cart
Normal file
25
test/db/formats/cart
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
NAME=CaRT: iI and extractor info
|
||||||
|
FILE=bins/cart/sample.cart
|
||||||
|
CMDS=<<EOF
|
||||||
|
iI~binsz
|
||||||
|
i~packet
|
||||||
|
EOF
|
||||||
|
EXPECT=<<EOF
|
||||||
|
binsz 0x00000039
|
||||||
|
packet xtr.cart
|
||||||
|
EOF
|
||||||
|
RUN
|
||||||
|
|
||||||
|
NAME=CaRT: Extract payload with rz-bin -x
|
||||||
|
FILE==
|
||||||
|
CMDS=<<EOF
|
||||||
|
!rm -rf sample.cart.fat
|
||||||
|
!rz-bin -x bins/cart/sample.cart
|
||||||
|
!cat sample.cart.fat/sample.cart.unknown.cart_payload_0.0
|
||||||
|
!rm -rf sample.cart.fat
|
||||||
|
EOF
|
||||||
|
EXPECT=<<EOF
|
||||||
|
sample.cart.fat/sample.cart.unknown.cart_payload_0.0 created (57)
|
||||||
|
This is a test payload for CaRT container format testing
|
||||||
|
EOF
|
||||||
|
RUN
|
||||||
Loading…
Reference in a new issue