Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/hbc/hbc.h
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,9 @@ typedef struct {

/* HBC context (optional, for object/array buffer resolution) */
HBC *hbc;

/* Cached ISA (optional, for performance - avoids repeated lookups) */
const void *isa; // HBCISA* if available, NULL to lookup from bytecode_version
} HBCDecodeCtx;

/**
Expand Down
51 changes: 38 additions & 13 deletions src/lib/hbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,17 @@ Result hbc_decode_fn(

/* Single-instruction decode functions */

static Result hbc_dec_insn_internal(
const u8 *bytes,
size_t len,
const HBCISA *isa,
u64 pc,
bool asm_syntax,
bool resolve_string_ids,
const HBCStrs *string_ctx,
HBC *hbc,
HBCInsnInfo *out);

Result hbc_dec(const HBCDecodeCtx *ctx, HBCInsnInfo *out) {
if (!ctx || !out) {
return ERROR_RESULT (RESULT_ERROR_INVALID_ARGUMENT, "Invalid context");
Expand All @@ -445,10 +456,17 @@ Result hbc_dec(const HBCDecodeCtx *ctx, HBCInsnInfo *out) {
hbc_debug_printf ("Warning: bytecode version not specified, defaulting to %u\n", bytecode_version);
}

return hbc_dec_insn (
const HBCISA *isa_ptr = (const HBCISA *)ctx->isa;
HBCISA isa_local;
if (!isa_ptr) {
isa_local = hbc_isa_getv (bytecode_version);
isa_ptr = &isa_local;
}

return hbc_dec_insn_internal (
ctx->bytes,
ctx->len,
bytecode_version,
isa_ptr,
ctx->pc,
ctx->asm_syntax,
ctx->resolve_string_ids,
Expand All @@ -472,23 +490,30 @@ Result hbc_dec_insn(
return ERROR_RESULT (RESULT_ERROR_INVALID_ARGUMENT, "Invalid arguments");
}

/* Get the ISA for this bytecode version */
HBCISA isa = hbc_isa_getv (bytecode_version);
if (!isa.instructions || isa.count == 0) {
return ERROR_RESULT (RESULT_ERROR_INVALID_ARGUMENT, "Invalid bytecode version");
return hbc_dec_insn_internal (bytes, len, &isa, pc, asm_syntax, resolve_string_ids, string_ctx, hbc, out);
}

static Result hbc_dec_insn_internal(
const u8 *bytes,
size_t len,
const HBCISA *isa,
u64 pc,
bool asm_syntax,
bool resolve_string_ids,
const HBCStrs *string_ctx,
HBC *hbc,
HBCInsnInfo *out) {

if (!isa || !isa->instructions || isa->count == 0) {
return ERROR_RESULT (RESULT_ERROR_INVALID_ARGUMENT, "Invalid ISA");
}

/* Read opcode */
u8 opcode = bytes[0];

/* Find instruction definition */
const Instruction *inst = NULL;
for (u32 i = 0; i < isa.count; i++) {
if (i == opcode) {
inst = &isa.instructions[i];
break;
}
}
/* Direct O(1) instruction lookup */
const Instruction *inst = (opcode < isa->count) ? &isa->instructions[opcode] : NULL;

if (!inst || !inst->name) {
out->text = strdup ("unk");
Expand Down
13 changes: 9 additions & 4 deletions src/r2/arch_hbc.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ typedef struct {
const void *small_string_table;
const void *overflow_string_table;
u64 string_storage_offset;
HBCISA isa; /* cached ISA for fast instruction lookup */
} HermesArchSession;

static ut32 detect_version_from_bin(RArchSession *s) {
Expand Down Expand Up @@ -86,6 +87,9 @@ static bool load_string_tables(HermesArchSession *hs, RArchSession *s) {
hs->overflow_string_table = tables.overflow_string_table;
hs->string_storage_offset = tables.string_storage_offset;

/* Cache ISA for fast instruction lookup */
hs->isa = hbc_isa_getv (hs->bytecode_version);

return true;
}

Expand All @@ -109,9 +113,8 @@ static bool opcode_is_conditional(u8 opcode) {
}

static void parse_operands_and_set_ptr(RAnalOp *op, const ut8 *bytes, ut32 size, ut8 opcode, HermesArchSession *hs) {
HBCISA isa = hbc_isa_getv (hs->bytecode_version);
const Instruction *inst_set = isa.instructions;
if (!inst_set || opcode >= isa.count) {
const Instruction *inst_set = hs->isa.instructions;
if (!inst_set || opcode >= hs->isa.count) {
return;
}

Expand Down Expand Up @@ -211,6 +214,7 @@ static bool decode(RArchSession *s, RAnalOp *op, RArchDecodeMask mask) {

if (!hs->bytecode_version) {
hs->bytecode_version = detect_version_from_bin (s);
hs->isa = hbc_isa_getv (hs->bytecode_version);
}

/* Load string tables if not already loaded */
Expand All @@ -233,7 +237,8 @@ static bool decode(RArchSession *s, RAnalOp *op, RArchDecodeMask mask) {
.asm_syntax = true,
.resolve_string_ids = true,
.string_tables = &string_tables,
.hbc = hs->hbc
.hbc = hs->hbc,
.isa = &hs->isa
};

HBCInsnInfo sinfo;
Expand Down
Loading