[c166] Fix CIDs (overflows) (#6599)

CID 911455

CID 911454

CID 909873
This commit is contained in:
SSharshunov 2026-08-12 17:04:56 +05:00 committed by GitHub
parent 38d0a78e36
commit 5e0afe5402
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 233 additions and 98 deletions

View file

@ -37,9 +37,9 @@ IDX1.comment=MAC Address Pointer 1
ADEIC=io
ADEIC.address=0xff9a
ADEIC.comment=A/D Converter Overrun Error Interrupt Control Register
SYSCON=io
SYSCON.address=0xff0c
SYSCON.comment=CPU System Configuration Register
BUSCON0=io
BUSCON0.address=0xff0c
BUSCON0.comment=Bus Configuration Register 0 (Stack Pointer Segment Register [SPSEG])
VECSEG=io
VECSEG.address=0xff12
VECSEG.comment=Bus Configuration Register 0
@ -313,9 +313,6 @@ CCM7.comment=CAPCOM Mode Control Register 7
CP=io
CP.address=0xfe10
CP.comment=CPU Context Pointer Register
R1=io
R1.address=0xfe12
R1.comment=General Purpose Word Register R1
CRIC=io
CRIC.address=0xff6a
CRIC.comment=GPT2 CAPREL Interrupt Ctrl. Register

View file

@ -352,8 +352,7 @@ const char *c166_extx_names[] = {
};
RZ_API void c166_activate_ext(RZ_NONNULL C166State *state, ut32 addr, C166ExtState ext) {
// rz_return_if_fail(state->ext.i == 0); // realy need?
rz_return_if_fail(ext.i <= 3);
rz_return_if_fail(ext.i <= 4);
state->ext = ext;
state->last_addr = addr;
}

View file

@ -23,18 +23,25 @@ static bool is_valid_omf_type(ut8 type) {
return true;
}
}
// RZ_LOG_ERROR("Invalid record type\n");
return false;
}
bool rz_bin_checksum_omf_ok(const ut8 *buf, ut64 buf_size) {
ut8 checksum = 0;
if (!buf) {
RZ_LOG_ERROR("Invalid record (buf is null)\n");
return false;
}
if (buf_size < 3) {
RZ_LOG_ERROR("Invalid record (too short)\n");
return false;
}
ut16 size = rz_read_le16(buf + 1);
if (size == 0 || size == UINT16_MAX) {
RZ_LOG_ERROR("Invalid record (untrusted value)\n");
return false;
}
if (buf_size < size + 3) {
RZ_LOG_ERROR("Invalid record (too short)\n");
return false;

View file

@ -11,6 +11,8 @@
#include <rz_bin.h>
#include "omf_specs.h"
#define MAX_NAME_LEN UT8_MAX
#define FINAL_TYPE 0x00
/**
* <b>COMPONENT-LIST Descriptor</b><br>
@ -224,13 +226,23 @@ typedef enum omf_ityp_t {
/**
* Used to specify an object file as input for L166.
*/
ITYP_COMMANDLINE = 0x05, ///< Commandline descriptor.
ITYP_INVOCATION_LINE = 0xFF, ///< Invocation Line descriptor.
/**
* Contains the invocation line to the translator
* including all invocation controls.
*/
} OMF_ITYP;
/**
* \brief OMF_SEC_TYPE in SECDEF record, specifies the type of the section
*/
typedef enum omf_sec_t {
OMF_SEC_TYPE_BIT = 0x00, ///< BIT.
OMF_SEC_TYPE_DATA = 0x01, ///< DATA.
OMF_SEC_TYPE_CODE = 0x02, ///< CODE.
OMF_SEC_TYPE_CONST = 0x03, ///< CONST.
} OMF_SEC_TYPE;
typedef enum {
C166_CLASS_ICODE,
C166_CLASS_FCODE,
@ -300,7 +312,7 @@ typedef struct {
ut32 base; ///< specifies the local address base for the following symbolic formation using the base address format.
ut8 n; ///< n max 255, so name array len is 255
char *name;
char name2[255]; ///< represents the symbol name
char name2[MAX_NAME_LEN]; ///< represents the symbol name
ut64 size;
ut16 seg_idx;
ut32 offset; ///< is a 16 Bit offset of the symbol with respect to the referent value pecified by LocBase.
@ -360,7 +372,7 @@ typedef struct {
ut8 SectionIndex;
ut16 FrameNumber; // (optional) if GroupIndex and SectionIndex equals 0
ut8 n; ///< Pathname length, n max 255, so name array len is 255
char name[255]; ///< is the block name. If the record describes an unnamed block, then a null name is used.
char name[MAX_NAME_LEN]; ///< is the block name. If the record describes an unnamed block, then a null name is used.
ut16 BlockOffset16; ///< is a 16 Bit value which is the offset of the first byte of the block with respect to the referent value specified by BlockBase.
ut16 BlockLength16; ///< this field gives the length of the block in bytes.
@ -451,7 +463,7 @@ typedef struct {
typedef struct {
ut16 index;
char name[255];
char name[MAX_NAME_LEN];
} OMF_lnames;
/**
@ -483,7 +495,7 @@ typedef struct {
ut8 mark; ///< Byte, required to be zero.
ut32 timestamp; ///< File creation date in Microsofts fstat() format.
ut8 n; ///< Pathname length, n max 255, so name array len is 255
char pathname[255]; ///< specifies the Pathname of one file. In case of iTyp 4, more than one pathname may be specified.
char pathname[MAX_NAME_LEN]; ///< specifies the Pathname of one file. In case of iTyp 4, more than one pathname may be specified.
} OMF_deplsts;
/**
@ -509,7 +521,7 @@ typedef struct {
ut16 LineNumber; ///< gives the line number in range 0 to 32767. The most significant bit is reserved for future use and is always zero.
ut64 address; ///< Specifies the address of the following line numbers using the base address + offset format.
ut8 n;
char filename[255];
char filename[MAX_NAME_LEN];
} OMF_linnums;
typedef struct {
@ -559,7 +571,7 @@ typedef struct {
bool nopurge; ///< NOPURGE bit; 1 = comment may not be purged from the file
bool is_filename;
ut8 n;
char text[255]; ///< this field provides the commentary text.
char text[MAX_NAME_LEN]; ///< this field provides the commentary text.
} OMF_coments;
typedef struct {
@ -577,7 +589,7 @@ typedef struct {
typedef struct {
ut16 index;
ut8 n; ///< n max 255, so name array len is 255
char name[255];
char name[MAX_NAME_LEN];
} OMF_debug_includes;
typedef struct {
@ -593,7 +605,7 @@ typedef struct {
ut8 REP8;
ut8 POS8;
ut8 n; ///< n max 255, so name array len is 255
char name[255];
char name[MAX_NAME_LEN];
} OMF_component;
typedef struct {
@ -678,7 +690,7 @@ typedef struct {
struct {
bool is_struct; ///< 1 = struct, 2 = union
ut8 n; ///< struct/union-tag name length
char tagname[255]; ///< struct/union-tag name in OMF166 name format
char tagname[MAX_NAME_LEN]; ///< struct/union-tag name in OMF166 name format
ut32 size; ///< sizeof struct or union
ut16 member_ti; ///< reference to component list or <void>
} struct_union;
@ -709,16 +721,17 @@ typedef struct {
ut8 REP8;
ut8 POS8; ///< contains a bit position if REP8 contains method 1 (RegBit)
ut8 n; ///< member name length
char name[255]; ///< member name in OMF166 name format
char name[MAX_NAME_LEN]; ///< member name in OMF166 name format
} OMF_type_components;
typedef struct {
ut16 NrOfComp16; ///< Specifies the number of components
OMF_type_components components[255];
OMF_type_components components[MAX_NAME_LEN];
} OMF_type_component_list;
typedef struct {
ut8 bits;
ut64 base_addr;
ut8 modinfo;
int TI_INDEX;
int SEC_INDEX;

View file

@ -119,7 +119,7 @@ RZ_API const char *name_of_ti(const rz_bin_omf166_obj *obj, const ut16 ti_index)
}
case POINTER_DESCRIPTOR: {
const char *x = name_of_ti(obj, type->descriptor.pointer.ti);
static char x2[255] = { 0 };
static char x2[MAX_NAME_LEN] = { 0 };
if (type->descriptor.pointer.attrib == 1)
rz_snprintf(x2, sizeof(buffer), "%s *", x); ///< "POINTER: 1 = Data pointer (PAGE:OFFSET)"
if (type->descriptor.pointer.attrib == 2)
@ -147,8 +147,6 @@ RZ_API const char *name_of_ti(const rz_bin_omf166_obj *obj, const ut16 ti_index)
return NULL;
}
}
rz_warn_if_reached();
return NULL;
}
const char *name_of_iTyp(ut8 iTyp) {
@ -168,11 +166,11 @@ const char *name_of_iTyp(ut8 iTyp) {
case ITYP_OBJECT_INPUTFILE: {
return "Object-Inputfile";
}
case ITYP_COMMANDLINE: {
return "Commandline";
case ITYP_INVOCATION_LINE: {
return "InvocationLine";
}
default: {
rz_warn_if_reached();
RZ_LOG_WARN("UNKNOWN iTyp (%" PFMT32x ").\n", iTyp);
return "UNKNOWN";
}
}
@ -323,9 +321,9 @@ static ut16 omf166_get_idx(const ut8 *buf, const size_t buf_size) {
return ret;
}
static bool load_omf166_lnames(const rz_bin_omf166_obj *obj, const OMF_record *record, const ut8 *buf, const size_t buf_size, ut64 global_ct) {
static bool load_omf166_lnames(const rz_bin_omf166_obj *obj, const OMF_record *record, const ut8 *buf, const size_t buf_size) {
ut32 tmp_size = 0;
ut32 ct_name = 0;
ut16 ct_name = 0;
OMF_lnames *lname = NULL;
if (!(record && buf) || record->size <= 3) {
@ -351,7 +349,8 @@ static bool load_omf166_lnames(const rz_bin_omf166_obj *obj, const OMF_record *r
return false;
}
if ((tmp_size + 4 + cb) < buf_size) {
memcpy(lname->name, buf + 3 + tmp_size + 1, cb);
rz_mem_copy(lname->name, MAX_NAME_LEN,
buf + 3 + tmp_size + 1, cb);
lname->index = ct_name;
}
@ -380,8 +379,9 @@ static int load_omf166_global_sym_record(const rz_bin_omf166_obj *obj, const OMF
ct++;
base = rz_read_le32_offset(buf, &ct);
}
} else
} else {
base = rz_read_le32_offset(buf, &ct);
}
if (record->size <= ct) {
RZ_LOG_ERROR("Invalid sym record (bad size)\n");
@ -396,7 +396,13 @@ static int load_omf166_global_sym_record(const rz_bin_omf166_obj *obj, const OMF
sym->rec_type = record->type;
sym->base = base;
sym->n = rz_read_le8_offset(buf, &ct);
rz_str_ncpy(sym->name2, (const char *)&buf[ct], sym->n + 1);
if (ct + sym->n + 1 > buf_size) {
RZ_LOG_ERROR("Invalid sym record (overflow)\n");
RZ_FREE(sym);
continue;
}
rz_mem_copy(sym->name2, MAX_NAME_LEN, buf + ct, sym->n);
sym->name2[sym->n] = '\0';
ct += sym->n;
sym->offset = rz_read_le16_offset(buf, &ct);
@ -454,7 +460,7 @@ static int load_omf_data(const rz_bin_omf166_obj *obj, const ut8 *buf, const siz
return true;
}
static int load_omf_blkdef(const rz_bin_omf166_obj *obj, const ut8 *buf, const size_t buf_size, ut64 global_ct) {
static int load_omf_blkdef(const rz_bin_omf166_obj *obj, const ut8 *buf, const size_t buf_size) {
size_t ct = 3;
OMF_blocks *block = RZ_NEW0(OMF_blocks);
if (!block) {
@ -470,7 +476,13 @@ static int load_omf_blkdef(const rz_bin_omf166_obj *obj, const ut8 *buf, const s
}
block->n = rz_read_le8_offset(buf, &ct);
rz_str_ncpy(block->name, (const char *)&buf[ct], block->n + 1);
if (ct + block->n + 1 > buf_size) {
RZ_LOG_ERROR("Invalid record (overflow)\n");
RZ_FREE(block);
return true;
}
rz_mem_copy(block->name, MAX_NAME_LEN, buf + ct, block->n);
block->name[block->n] = '\0';
ct += block->n;
block->BlockOffset16 = rz_read_le16_offset(buf, &ct);
@ -488,7 +500,7 @@ static int load_omf_blkdef(const rz_bin_omf166_obj *obj, const ut8 *buf, const s
return true;
}
static int load_comment_data(const rz_bin_omf166_obj *obj, const ut8 *buf, const OMF_record *record, ut64 global_ct) {
static int load_comment_data(const rz_bin_omf166_obj *obj, const ut8 *buf, const OMF_record *record) {
if (!(obj && obj->coments_vec)) {
return false;
}
@ -504,17 +516,13 @@ static int load_comment_data(const rz_bin_omf166_obj *obj, const ut8 *buf, const
comment->nopurge = (ComTyp_b1 & 0x80) >> 7;
comment->is_filename = (ComTyp_b2 == 0x4b);
comment->n = record->size + 3 - ct;
rz_str_ncpy(comment->text,
(const char *)&buf[ct], comment->n);
rz_mem_copy(comment->text, MAX_NAME_LEN, buf + ct, comment->n);
comment->text[comment->n] = '\0';
rz_pvector_push(obj->coments_vec, comment);
return true;
}
static int load_grpdef_data(const rz_bin_omf166_obj *obj, const ut8 *buf, const OMF_record *record, ut64 global_ct) {
if (!obj) {
return false;
}
/*
* Group Definition Record - Used to combine sections
*
@ -531,12 +539,6 @@ static int load_grpdef_data(const rz_bin_omf166_obj *obj, const ut8 *buf, const
static int load_deplst_data(const ut8 *buf, const OMF_record *record) {
#if RZ_BUILD_DEBUG
size_t ct = 3;
const ut8 some_byte = rz_read_le8_offset(buf, &ct);
(void)some_byte;
const ut8 info_n = rz_read_le8_offset(buf, &ct);
char info[255] = RZ_EMPTY;
rz_str_ncpy(info, (const char *)&buf[ct], info_n + 1);
ct += info_n;
while (ct < record->size) {
/**
* iTyp | Mark8 | Time32 | Name(s)
@ -550,10 +552,14 @@ static int load_deplst_data(const ut8 *buf, const OMF_record *record) {
In case of iTyp 4, more than one pathname may be specified.
*/
const ut8 iTyp = rz_read_le8_offset(buf, &ct);
const ut8 Mark8 = rz_read_le8_offset(buf, &ct);
const ut32 Time32 = rz_read_le32_offset(buf, &ct);
ut8 Mark8 = 0;
ut32 Time32 = 0;
if (iTyp != ITYP_INVOCATION_LINE) {
Mark8 = rz_read_le8_offset(buf, &ct);
Time32 = rz_read_le32_offset(buf, &ct);
}
const ut8 n = rz_read_le8_offset(buf, &ct);
char pathname[255] = RZ_EMPTY;
char pathname[MAX_NAME_LEN] = RZ_EMPTY;
rz_str_ncpy(pathname,
(const char *)&buf[ct], n + 1);
RZ_LOG_DEBUG("iTyp: [0x%02x] `%16s`, Mark8: 0x%02x, Time32: %d, n: %3d `%s`\n",
@ -597,7 +603,7 @@ static int load_linnum_data(const rz_bin_omf166_obj *obj, const ut8 *buf, const
return true;
}
static int load_omf_pedata(const rz_bin_omf166_obj *obj, const ut8 *buf, const OMF_record *record, const ut64 global_ct) {
static int load_omf_pedata(rz_bin_omf166_obj *obj, const ut8 *buf, const OMF_record *record, const ut64 global_ct) {
if (!(obj && obj->pe_vec)) {
return false;
}
@ -622,6 +628,10 @@ static int load_omf_pedata(const rz_bin_omf166_obj *obj, const ut8 *buf, const O
*/
pe->size = pe->psize = record->size - 1 - (ct - 3);
pe->paddr = global_ct + ct;
if (pe->isVector) {
obj->base_addr = (ut32)pe->SegmentNumber8 << 16;
}
rz_pvector_push(obj->pe_vec, pe);
return true;
}
@ -651,7 +661,7 @@ static int load_omf_unk1(const rz_bin_omf166_obj *obj, const ut8 *buf, const siz
static int load_omf_unk2(const ut8 *buf, const size_t buf_size, const OMF_record *record, const ut64 global_ct) {
#if RZ_BUILD_DEBUG
char name[255] = RZ_EMPTY;
char name[MAX_NAME_LEN] = RZ_EMPTY;
size_t offset = 7;
const ut8 n = rz_read_le8_offset(buf, &offset);
rz_str_ncpy(name, (const char *)&buf[offset], n + 1);
@ -666,7 +676,7 @@ static int load_omf_unk2(const ut8 *buf, const size_t buf_size, const OMF_record
static int load_omf_unk3(const ut8 *buf, const size_t buf_size, const OMF_record *record, const ut64 global_ct) {
#if RZ_BUILD_DEBUG
char name[255] = RZ_EMPTY;
char name[MAX_NAME_LEN] = RZ_EMPTY;
size_t offset = 7;
const ut8 n = rz_read_le8_offset(buf, &offset);
rz_str_ncpy(name, (const char *)&buf[offset], n + 1); // cct = 12
@ -838,6 +848,8 @@ static int load_omf_typnew(rz_bin_omf166_obj *obj, const ut8 *buf) {
*/
const ut16 raw_count = rz_read_le16_offset(buf, &cct);
if (raw_count == 0 || raw_count > UINT16_MAX) {
RZ_LOG_ERROR("Invalid component count (untrusted value)\n");
RZ_FREE(newtype);
return false;
}
newtype->label = rz_str_dup("COMPONENT_LIST_DESCRIPTOR");
@ -860,7 +872,8 @@ static int load_omf_typnew(rz_bin_omf166_obj *obj, const ut8 *buf) {
component->REP8 = rz_read_le8_offset(buf, &cct);
component->POS8 = rz_read_le8_offset(buf, &cct);
component->n = rz_read_le8_offset(buf, &cct);
rz_str_ncpy(component->name, (const char *)&buf[cct], component->n + 1);
rz_mem_copy(component->name, MAX_NAME_LEN, buf + cct, component->n);
component->name[component->n] = '\0';
cct += component->n;
}
break;
@ -883,7 +896,7 @@ static int load_omf_typnew(rz_bin_omf166_obj *obj, const ut8 *buf) {
newtype->descriptor.array.attrib = rz_read_le8_offset(buf, &cct);
newtype->descriptor.array.ti = rz_read_le16_offset(buf, &cct);
newtype->descriptor.array.dimsz = rz_read_le32_offset(buf, &cct);
char array_length[255] = RZ_EMPTY;
char array_length[MAX_NAME_LEN] = RZ_EMPTY;
if (newtype->descriptor.array.dimsz != 0xFFFFFFFF) {
rz_strf(array_length, "%d", newtype->descriptor.array.dimsz);
}
@ -912,10 +925,10 @@ static int load_omf_typnew(rz_bin_omf166_obj *obj, const ut8 *buf) {
newtype->descriptor.struct_union.member_ti = rz_read_le16_offset(buf, &cct);
newtype->descriptor.struct_union.n = rz_read_le8_offset(buf, &cct);
rz_str_ncpy(
newtype->descriptor.struct_union.tagname,
(const char *)&buf[cct],
newtype->descriptor.struct_union.n + 1);
rz_mem_copy(newtype->descriptor.struct_union.tagname,
MAX_NAME_LEN, buf + cct,
newtype->descriptor.struct_union.n);
newtype->descriptor.struct_union.tagname[newtype->descriptor.struct_union.n] = '\0';
newtype->label = rz_str_dup(newtype->descriptor.struct_union.tagname);
break;
}
@ -944,7 +957,7 @@ static int rz_bin_format_omf166_load_content(rz_bin_omf166_obj *obj, OMF_record
switch (record->type) {
case OMF166_LNAMES: {
return load_omf166_lnames(obj, record, buf, buf_size, global_ct);
return load_omf166_lnames(obj, record, buf, buf_size);
}
case OMF166_GLBDEF:
case OMF166_LOCSYM:
@ -953,7 +966,7 @@ static int rz_bin_format_omf166_load_content(rz_bin_omf166_obj *obj, OMF_record
return load_omf166_global_sym_record(obj, record, buf, buf_size);
}
case OMF166_BLKDEF: {
return load_omf_blkdef(obj, buf, buf_size, global_ct);
return load_omf_blkdef(obj, buf, buf_size);
}
case OMF166_VECTAB:
case OMF166_PEDATA: {
@ -961,10 +974,15 @@ static int rz_bin_format_omf166_load_content(rz_bin_omf166_obj *obj, OMF_record
}
case OMF166_LHEADR:
case OMF166_THEADR: {
char name[255] = RZ_EMPTY;
char name[MAX_NAME_LEN] = RZ_EMPTY;
size_t offset = 3;
ut8 n = rz_read_le8_offset(buf, &offset);
rz_str_ncpy(name, (const char *)&buf[offset], n + 1);
const ut8 n = rz_read_le8_offset(buf, &offset);
if (n + 1 + offset > buf_size) {
RZ_LOG_WARN("File may be corrupted (Overflow detected).\n");
} else {
rz_mem_copy(name, MAX_NAME_LEN, buf + offset, n);
name[n] = '\0';
}
RZ_LOG_DEBUG("load_omf = %s = [0x%08" PFMT64x "] (%05d) `%s`\n",
record->type == OMF166_THEADR ? "THEADR" : "LHEADR",
global_ct,
@ -999,7 +1017,7 @@ static int rz_bin_format_omf166_load_content(rz_bin_omf166_obj *obj, OMF_record
return true;
}
case OMF166_COMMENT: {
return load_comment_data(obj, buf, record, global_ct);
return load_comment_data(obj, buf, record);
}
case OMF166_GRPDEF: {
return load_grpdef_data(obj, buf, record, global_ct);
@ -1037,9 +1055,14 @@ static int rz_bin_format_omf166_load_content(rz_bin_omf166_obj *obj, OMF_record
*/
size_t left = 14;
while (record->size - 1 > left) {
char name[255] = RZ_EMPTY;
char name[MAX_NAME_LEN] = RZ_EMPTY;
const ut8 n = rz_read_le8_offset(buf, &left);
rz_str_ncpy(name, (const char *)&buf[left], n + 1);
if (n + 1 + left > buf_size) {
RZ_LOG_WARN("File may be corrupted (Overflow detected).\n");
} else {
rz_mem_copy(name, MAX_NAME_LEN, buf + left, n);
name[n] = '\0';
}
left += n;
}
return true;
@ -1056,6 +1079,11 @@ static int rz_bin_format_omf166_load_content(rz_bin_omf166_obj *obj, OMF_record
case OMF166_UNKNOWN4: {
return load_omf_unk4(buf, buf_size, record, global_ct);
}
case OMF166_SSKDEF: {
RZ_LOG_DEBUG("load_omf: [%05d] [0x%08" PFMT64x "] 0x%02x (%" PFMTSZu ")\n",
record->size, global_ct, record->type, buf_size);
return true;
}
default: {
RZ_LOG_DEBUG("load_omf: [%05d] [0x%08" PFMT64x "] 0x%02x (%" PFMTSZu ")\t",
record->size, global_ct, record->type, buf_size);
@ -1083,6 +1111,8 @@ static OMF_record *rz_bin_format_omf166_load_record(rz_bin_omf166_obj *obj, cons
new->type = rz_read_le8_offset(buf, &offset);
const ut16 raw_count = rz_read_le16_offset(buf, &offset);
if (raw_count == 0 || raw_count > UINT16_MAX) {
RZ_LOG_ERROR("Invalid record (untrusted value)\n");
RZ_FREE(new);
return false;
}
new->size = raw_count;

View file

@ -35,7 +35,7 @@ rz_bin_c166_obj *rz_bin_format_c166_load(const ut8 *buf, ut64 size) {
return NULL;
}
const ut8 c = rz_read_le8(buf + 1);
ret->base_addr = c << 16 | 0x000000;
ret->base_addr = (ut32)c << 16;
return ret;
}
@ -111,7 +111,7 @@ static RzPVector /*<RzBinAddr *>*/ *entries(RzBinFile *bf) {
if (!bf || !bf->o || !bf->o->bin_obj) {
return NULL;
}
rz_bin_c166_obj *obj = bf->o->bin_obj;
const rz_bin_c166_obj *obj = bf->o->bin_obj;
RzPVector *ret;
RzBinAddr *addr;
@ -158,6 +158,11 @@ static RzBinAddr *binsym(RzBinFile *bf, RzBinSpecialSymbol type) {
}
}
static ut64 baddr(RzBinFile *bf) {
const rz_bin_c166_obj *obj = (rz_bin_c166_obj *)bf->o->bin_obj;
return obj->base_addr;
}
struct rz_bin_plugin_t rz_bin_plugin_c166 = {
.name = "c166",
.desc = "Siemens/Infineon C166 family microcontroller binary",
@ -171,6 +176,7 @@ struct rz_bin_plugin_t rz_bin_plugin_c166 = {
.info = &info,
.binsym = &binsym,
.strings = &strings,
.baddr = baddr
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -100,6 +100,8 @@ static bool check_buffer(RzBuffer *b) {
static RzPVector /*<RzBinAddr *>*/ *entries(RzBinFile *bf) {
RzPVector *ret;
RzBinAddr *addr;
rz_bin_omf166_obj *obj = (rz_bin_omf166_obj *)bf->o->bin_obj;
if (!((ret = rz_pvector_new(free)))) {
return NULL;
}
@ -108,7 +110,7 @@ static RzPVector /*<RzBinAddr *>*/ *entries(RzBinFile *bf) {
return NULL;
}
addr->type = RZ_BIN_SPECIAL_SYMBOL_ENTRY;
addr->vaddr = 0xC00000;
addr->vaddr = obj->base_addr;
rz_pvector_push(ret, addr);
return ret;
}
@ -180,8 +182,8 @@ static RzPVector /*<RzBinSection *>*/ *sections(RzBinFile *bf) {
new->name = rz_str_newf("%s_%s", name, class_name);
new->size = new->vsize = section->Seclen;
new->vaddr = (section->SegmentNumber8 << 16) + section->offset;
new->has_strings = (section->Type == 1) ? true : false;
new->is_data = (section->Type == 1) ? true : false;
new->has_strings = section->Type != OMF_SEC_TYPE_CODE;
new->is_data = section->Type != OMF_SEC_TYPE_CODE;
new->is_segment = 0;
new->perm = c166_get_perms_from_class(section->class_index);
rz_pvector_push(ret, new);
@ -217,6 +219,9 @@ static RzPVector /*<RzBinSymbol *>*/ *symbols(RzBinFile *bf) {
}
RzPVector *ret = rz_pvector_new((RzPVectorFree)rz_bin_symbol_free);
if (!ret) {
return NULL;
}
rz_pvector_sort(obj->symbols_vec, offset_cmp, NULL);
void **it;
rz_pvector_foreach (obj->symbols_vec, it) {
@ -371,6 +376,7 @@ static RzBinInfo *info(RzBinFile *bf) {
ret->rclass = rz_str_dup("OMF166");
ret->compiler = rz_str_dup("keil");
ret->os = rz_str_dup("c166");
ret->cpu = rz_str_dup("c166-generic");
ret->machine = rz_str_dup("Siemens/Infineon C166 family microcontroller");
ret->arch = rz_str_dup("c166");
ret->big_endian = false;
@ -395,6 +401,7 @@ static RzPVector /*<RzBinString *>*/ *strings(RzBinFile *bf) {
static RzBinAddr *binsym(RzBinFile *bf, RzBinSpecialSymbol type) {
RzBinAddr *ptr = NULL;
rz_bin_omf166_obj *obj = (rz_bin_omf166_obj *)bf->o->bin_obj;
switch (type) {
case RZ_BIN_SPECIAL_SYMBOL_ENTRY:
@ -404,7 +411,7 @@ static RzBinAddr *binsym(RzBinFile *bf, RzBinSpecialSymbol type) {
return NULL;
}
ptr->type = RZ_BIN_SPECIAL_SYMBOL_ENTRY;
ptr->vaddr = 0xC00000;
ptr->vaddr = obj->base_addr;
return ptr;
case RZ_BIN_SPECIAL_SYMBOL_MAIN:
if (!((ptr = RZ_NEW0(RzBinAddr)))) {
@ -421,6 +428,11 @@ static RzBinAddr *binsym(RzBinFile *bf, RzBinSpecialSymbol type) {
}
}
static ut64 baddr(RzBinFile *bf) {
const rz_bin_omf166_obj *obj = (rz_bin_omf166_obj *)bf->o->bin_obj;
return obj->base_addr;
}
RzBinPlugin rz_bin_plugin_omf166 = {
.name = "omf166",
.desc = "OMF166 (Object Module Format by Siemens)",
@ -438,6 +450,7 @@ RzBinPlugin rz_bin_plugin_omf166 = {
.info = &info,
.strings = &strings,
.get_vaddr = &get_vaddr,
.baddr = baddr
};
#ifndef RZ_PLUGIN_INCORE

View file

@ -819,7 +819,7 @@ RZ_API ut64 rz_num_math_ut64(RzNum *num, const char *str) {
}
return segoff;
}
ut64 lead;
ut64 lead = 0;
if (num_leading_value(str, &lead)) {
free(new_err);
rz_num_value_fini(&v);

View file

@ -311,20 +311,20 @@ EXPECT=<<EOF
@| ;-- section.PR_GETKEY_FCODE:
@| ;-- _getkey:
/ _getkey();
| @=-> 0x00c0001c 9ab7fe70 jnb 0xff6e, _getkey ; Getkey.c:22 ; 0xc0001c ; [09] -rw- section size 12 named PR_GETKEY_FCODE
| @=-> 0x00c0001c 9ab7fe70 jnb S0RIC.7, _getkey ; Getkey.c:22 ; 0xc0001c ; [09] -rw- section size 12 named PR_GETKEY_FCODE
| | 0x00c00020 f2f4b2fe mov r4, 0xfe06:0x3eb2 ; Getkey.c:26
| | 0x00c00024 7eb7 bclr 0xff6e ; Getkey.c:27
| | 0x00c00024 7eb7 bclr S0RIC.7 ; Getkey.c:27
\ | 0x00c00026 db00 rets ; Getkey.c:28
/ sym.isr_vec_0x28();
\ ,==< 0x00c00028 fac07a00 jmps Class_B_trap ; 0xc0007a ; "\r\xff\xff\xff\xff\xff\xfa\xc0\x80\U00000012\xa5Z\xa5\xa5р\xe6\xea"
|| ;-- section.C_CLRMEMSEC_UNKNOWN:
|| 0x00c0002c 1a800400 bfldh 0xff00, #0x00, #0x04 ; [26] -r-- section size 24 named C_CLRMEMSEC_UNKNOWN
|| 0x00c0002c 1a800400 bfldh P0L, #0x00, #0x04 ; [26] -r-- section size 24 named C_CLRMEMSEC_UNKNOWN
|| 0x00c00030 40c2 cmp r12, r2
|| 0x00c00032 0fa0 bset 0xff40.0
|| 0x00c00034 04005cc2 add 0xfe06:0x025c, 0xfe00
|| 0x00c00038 03000000 addb 0xfe00, 0xfe00:0x0000
|| 0x00c00032 0fa0 bset T2CON.0
|| 0x00c00034 04005cc2 add 0xfe06:0x025c, DPP0
|| 0x00c00038 03000000 addb DPP0, 0xfe00:0x0000
|| 0x00c0003c 0080 add r8, r0
|| 0x00c0003e 04005bc2 add 0xfe06:0x025b, 0xfe00
|| 0x00c0003e 04005bc2 add 0xfe06:0x025b, DPP0
|| 0x00c00042 0000 add r0, r0
|| ;-- section.C_LIB_NCONST_NCONST:
|| 0x00c00044 0000 add r0, r0 ; [19] -r-- section size 48 named C_LIB_NCONST_NCONST
@ -338,13 +338,13 @@ EXPECT=<<EOF
|| 0x00c00056 1c46 rol r6, #0x04
|| 0x00c00058 0050 add r5, r0
|| 0x00c0005a c3470024 CoSTORE r4, 0xffde
|| 0x00c0005e 74498096 or 0xfe04:0x1680, 0xfe92
|| 0x00c0005e 74498096 or 0xfe04:0x1680, CC9
|| 0x00c00062 184b addc r4, [r3]
|| 0x00c00064 20bc sub r11, r12
|| 0x00c00066 be4c bclr 0xfd98.11
|| 0x00c00068 ca1b0e5a calla- cc_NUSR1, 0xc05a0e ; 0x5a0e
|| 0x00c0006c 1cc2 rol r2, #0x0c
|| 0x00c0006e 5367aec5 xorb 0xfece, 0xfe06:0x05ae
|| 0x00c0006e 5367aec5 xorb PECC7, 0xfe06:0x05ae
|| 0x00c00072 9d74 jmpr cc_NC/UGE, 0xc0015c ; sym.a166_NEAR.RepeatInit+0x2
@|| ; CODE XREF from sym.isr_vec_0x8 @ 0xc00008
@|| ;-- section.PR_TRAPS_FCODE:
@ -381,21 +381,21 @@ EXPECT=<<EOF
| 0x00c000a8 f6f012ee mov 0xfe06:0x2e12, r0 ; START_V2.A66:1519
| 0x00c000ac d180 extr #1 ; START_V2.A66:1651
| 0x00c000ae e6e88978 mov 0xf1d0, #0x7889 ; START_V2.A66:1652
| 0x00c000b2 e6d50000 mov 0xffaa, #0x0000 ; START_V2.A66:1657
| 0x00c000b6 e60b00f8 mov 0xfe16, #0xf800 ; START_V2.A66:1660
| 0x00c000ba e60a0cf6 mov 0xfe14, #0xf60c ; START_V2.A66:1661
| 0x00c000be e60900f8 mov 0xfe12, #0xf800 ; START_V2.A66:1662
| 0x00c000c2 e6860000 mov 0xff0c, #0x0000 ; START_V2.A66:1663
| 0x00c000c6 e6000400 mov 0xfe00, #0x0004 ; START_V2.A66:1672
| 0x00c000ca e6010500 mov 0xfe02, #0x0005 ; START_V2.A66:1674
| 0x00c000ce e6020003 mov 0xfe04, #0x0300 ; START_V2.A66:1675
| 0x00c000d2 e60820fc mov 0xfe10, #0xfc20 ; START_V2.A66:1679
| 0x00c000b2 e6d50000 mov FOCON, #0x0000 ; START_V2.A66:1657
| 0x00c000b6 e60b00f8 mov STKUN, #0xf800 ; START_V2.A66:1660
| 0x00c000ba e60a0cf6 mov STKOV, #0xf60c ; START_V2.A66:1661
| 0x00c000be e60900f8 mov SP, #0xf800 ; START_V2.A66:1662
| 0x00c000c2 e6860000 mov BUSCON0, #0x0000 ; START_V2.A66:1663
| 0x00c000c6 e6000400 mov DPP0, #0x0004 ; START_V2.A66:1672
| 0x00c000ca e6010500 mov DPP1, #0x0005 ; START_V2.A66:1674
| 0x00c000ce e6020003 mov DPP2, #0x0300 ; START_V2.A66:1675
| 0x00c000d2 e60820fc mov CP, #0xfc20 ; START_V2.A66:1679
| 0x00c000d6 b54ab5b5 einit ; START_V2.A66:1686
| 0x00c000da 1a880203 bfldh 0xff10, #0x03, #0x02 ; START_V2.A66:1690
| 0x00c000da 1a880203 bfldh PSW, #0x03, #0x02 ; START_V2.A66:1690
| 0x00c000de e6f02002 mov r0, #0x0220 ; START_V2.A66:1691
| 0x00c000e2 1a880303 bfldh 0xff10, #0x03, #0x03 ; START_V2.A66:1695
| 0x00c000e2 1a880303 bfldh PSW, #0x03, #0x03 ; START_V2.A66:1695
| 0x00c000e6 e6f04002 mov r0, #0x0240 ; START_V2.A66:1696
| 0x00c000ea 1a880003 bfldh 0xff10, #0x03, #0x00 ; START_V2.A66:1700
| 0x00c000ea 1a880003 bfldh PSW, #0x03, #0x00 ; START_V2.A66:1700
\ 0x00c000ee e6f00002 mov r0, #0x0200 ; START_V2.A66:1703
/ sym.a166_NEAR.Clr_Memory();
| 0x00c000f2 e6f9c000 mov r9, #0x00c0 ; START_V2.A66:1755
@ -453,7 +453,7 @@ EXPECT=<<EOF
\ 0x00c00156 e6f80400 mov r8, #0x0004 ; START_V2.A66:1874
; DATA XREF from sym.a166_NEAR.NoDPP3Adj @ 0xc001b6
/ sym.a166_NEAR.RepeatInit();
| 0x00c0015a e6030300 mov 0xfe06, #0x0003 ; START_V2.A66:1880
| 0x00c0015a e6030300 mov DPP3, #0x0003 ; START_V2.A66:1880
| 0x00c0015e dc09 exts r9, #1 ; START_V2.A66:1881
| 0x00c00160 a828 mov r2, [r8] ; START_V2.A66:1882
| 0x00c00162 2d3d jmpr cc_Z/EQ, sym.a166_NEAR.EndInit ; START_V2.A66:1883
@ -474,7 +474,7 @@ EXPECT=<<EOF
| 0x00c00182 0882 add r8, #2 ; START_V2.A66:1897
| 0x00c00184 1890 addc r9, #0 ; START_V2.A66:1898
| 0x00c00186 8af406e0 jb r4.14, sym.a166_NEAR.CopyInitVal ; START_V2.A66:1899 ; 0xc00196
| 0x00c0018a f6f306fe mov 0xfe06:0x3e06, r3 ; START_V2.A66:1900
| 0x00c0018a f6f306fe mov DPP3:0x3e06, r3 ; START_V2.A66:1900
| 0x00c0018e dc09 exts r9, #1 ; START_V2.A66:1901
| 0x00c00190 a838 mov r3, [r8] ; START_V2.A66:1902
| 0x00c00192 0882 add r8, #2 ; START_V2.A66:1903

View file

@ -0,0 +1,12 @@
NAME=c166 base address check
FILE=bins/c166/measure_raw.bin
CMDS=<<EOF
e bin.baddr
echo
iH
EOF
EXPECT=<<EOF
0x00c00000
EOF
RUN

View file

@ -195,10 +195,13 @@ RUN
NAME=omf166 modinfo check
FILE=bins/omf/omf166/measure
CMDS=<<EOF
e asm.arch=c166
e bin.baddr
echo
iH
EOF
EXPECT=<<EOF
0x00c00000
omf166-modinfo:
DoubleUsed: false
FloatUsed: true
@ -210,6 +213,61 @@ omf166-modinfo:
EOF
RUN
NAME=omf166 modinfo check
FILE=bins/omf/omf166/emulateme
CMDS=<<EOF
e bin.baddr
echo
iH
EOF
EXPECT=<<EOF
0
omf166-modinfo:
DoubleUsed: false
FloatUsed: false
MOD167: true
CaseSensitive: true
Segmented: true
MemoryModel: "Large: 'far' functions and data"
EOF
RUN
NAME=omf166 THEADR overflow check
FILE=bins/omf/omf166/sym_overflow_theadr
CMDS=<<EOF
e bin.baddr
EOF
EXPECT=<<EOF
0
EOF
REGEXP_FILTER_ERR=<<EOF
WARNING:.+
EOF
EXPECT_ERR=<<EOF
WARNING: File may be corrupted (Overflow detected).
WARNING: The binary loader searches strings only in the read only sections, but the binary has no sections.
EOF
RUN
NAME=omf166 sym overflow check
FILE=bins/omf/omf166/sym_overflow
CMDS=<<EOF
e bin.baddr
EOF
EXPECT=<<EOF
0
EOF
REGEXP_FILTER_ERR=<<EOF
[WARNING,ERROR]:.+
EOF
EXPECT_ERR=<<EOF
R: Invalid sym record (overflow)
G: The binary loader searches strings only in the read only sections, but the binary has no sections.
EOF
RUN
NAME=omf166 modinfo check if record not exists
FILE=bins/omf/omf166/no_modinfo.bin
CMDS=<<EOF