Skip to content

Commit 4098ee1

Browse files
committed
feat: allow customizable string terminators
1 parent 1119e6e commit 4098ee1

6 files changed

Lines changed: 67 additions & 2 deletions

File tree

include/redasm/context.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,6 @@ RD_API bool rd_export(RDContext* self, const char* filepath, RDExportFormat f);
120120
RD_API bool rd_project_save(RDContext* self, const char* filepath);
121121
RD_API bool rd_reanalyze(RDContext* self);
122122
RD_API void rd_disassemble(RDContext* self);
123-
RD_API void rd_set_scan_char16(RDContext* self, bool b);
124123
RD_API const char* rd_get_working_dir(const RDContext* self);
125124
RD_API const char* rd_get_file_name(const RDContext* self);
126125
RD_API const char* rd_str_intern(RDContext* self, const char* s);
@@ -142,7 +141,9 @@ RD_API RDSegmentSlice rd_get_all_segments(const RDContext* self);
142141
RD_API RDAddressSpace rd_get_address_space(const RDContext* ctx);
143142
RD_API RDInputMappingSlice rd_get_all_mappings(const RDContext* self);
144143
RD_API RDLoadAddressing rd_get_load_addressing(const RDContext* self);
144+
RD_API void rd_set_scan_char16(RDContext* self, bool b);
145145
RD_API void rd_set_min_string(RDContext* self, int l);
146+
RD_API void rd_set_string_terminators(RDContext* ctx, const u8* terms, usize n);
146147
RD_API const RDSegment* rd_find_segment(const RDContext* self, RDAddress addr);
147148
RD_API const RDFunction* rd_find_function(const RDContext* self, RDAddress address);
148149
RD_API const RDLoaderPlugin* rd_get_loader_plugin(const RDContext* self);

src/core/context.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ RDContext* rd_i_context_create(const RDLoaderPlugin* lplugin,
142142
self->db = rd_i_db_create(dbpath);
143143
self->kb = rd_i_kb_create();
144144

145+
vect_push(&self->string_terminators, 0); // default string terminator
146+
145147
assert(self->working_dir);
146148
assert(self->file_name);
147149

@@ -692,6 +694,7 @@ void rd_destroy(RDContext* self) {
692694
vect_destroy(&self->lift_buf);
693695
vect_destroy(&self->chunk_buf);
694696
vect_destroy(&self->externals);
697+
vect_destroy(&self->string_terminators);
695698
vect_destroy(&self->hooks);
696699
hmap_destroy(&self->engine.current.registers);
697700
rd_i_analyzeritemvect_destroy(&self->analyzerplugins);
@@ -1403,6 +1406,16 @@ RDLoadAddressing rd_get_load_addressing(const RDContext* self) {
14031406

14041407
void rd_set_min_string(RDContext* self, int l) { self->min_string = l; }
14051408

1409+
void rd_set_string_terminators(RDContext* ctx, const u8* terms, usize n) {
1410+
if(!terms || !n) return;
1411+
1412+
vect_reserve(&ctx->string_terminators, n);
1413+
vect_clear(&ctx->string_terminators);
1414+
1415+
for(usize i = 0; i < n; i++)
1416+
vect_push(&ctx->string_terminators, terms[i]);
1417+
}
1418+
14061419
bool rd_operand_as_address(RDContext* self, RDAddress address, int index) {
14071420
if(index >= RD_MAX_OPERANDS) return false;
14081421

src/core/context.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ typedef struct RDPendingRenameVect {
3333
usize capacity;
3434
} RDPendingRenameVect;
3535

36+
typedef struct RDStringTerminatorVect {
37+
u8* data;
38+
usize length;
39+
usize capacity;
40+
} RDStringTerminatorVect;
41+
3642
typedef struct RDContext {
3743
const RDLoaderPlugin* loaderplugin;
3844
const RDProcessorPlugin* processorplugin;
@@ -82,6 +88,7 @@ typedef struct RDContext {
8288

8389
RDTypeDefVect typedefs;
8490
RDPendingRenameVect pending_renames;
91+
RDStringTerminatorVect string_terminators;
8592

8693
struct {
8794
RDAddress value;

src/core/stringfinder.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,15 @@ static void _rd_i_strings_init(void) {
4343
}
4444
}
4545

46+
static bool _rd_is_string_terminator(const RDContext* ctx, u8 v) {
47+
u8* it;
48+
vect_each(it, &ctx->string_terminators) {
49+
if(*it == v) return true;
50+
}
51+
52+
return false;
53+
}
54+
4655
static bool _rd_strings_check_format(const char* s, int len) {
4756
assert(len > 0);
4857

@@ -81,6 +90,12 @@ static void _rd_strings_try_classify(RDContext* ctx, const RDSegmentFull* seg,
8190

8291
static void _rd_find_char_strings(RDContext* ctx, RDCharVect* str,
8392
RDCharVect* fmt_buf) {
93+
if(vect_is_empty(&ctx->string_terminators)) {
94+
RD_LOG_WARN(
95+
"no string terminator(s) provided, skipping string detection...");
96+
return;
97+
}
98+
8499
const RDSegmentFullVect* segments = rd_i_db_get_segments(ctx);
85100

86101
RDSegmentFull** it;
@@ -104,7 +119,7 @@ static void _rd_find_char_strings(RDContext* ctx, RDCharVect* str,
104119
continue;
105120
}
106121

107-
if(v == 0) {
122+
if(_rd_is_string_terminator(ctx, v)) {
108123
vect_push(str, 0); // add null terminator
109124
_rd_strings_try_classify(ctx, seg, startidx, "char", str,
110125
fmt_buf);

src/project/load.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ typedef struct RDProjectManifest {
2424
bool has_value;
2525
} entry_point;
2626

27+
RDStringTerminatorVect string_terminators;
2728
RDAnalyzerItemVect analyzers;
2829

2930
toml_result_t toml;
@@ -54,6 +55,7 @@ static const RDTomlSchema MANIFEST_SCHEMA[] = {
5455
{.key = "format.file_name", .type = TOML_STRING},
5556

5657
{.key = "analysis.min_string", .type = TOML_INT64},
58+
{.key = "analysis.string_terminators", .type = TOML_ARRAY, .array_type = &(RDTomlSchema){.type = TOML_INT64}},
5759
{.key = "analysis.loader", .type = TOML_STRING},
5860
{.key = "analysis.processor", .type = TOML_STRING},
5961
{.key = "analysis.analyzers", .type = TOML_ARRAY, .array_type = ANALYZER_SCHEMA},
@@ -65,6 +67,7 @@ static const RDTomlSchema MANIFEST_SCHEMA[] = {
6567

6668
static void _rd_project_manifest_destroy(RDProjectManifest* m) {
6769
rd_i_analyzeritemvect_destroy(&m->analyzers);
70+
vect_destroy(&m->string_terminators);
6871
toml_free(m->toml);
6972
rd_free(m->raw);
7073
}
@@ -158,6 +161,17 @@ static bool _rd_project_read_manifest(mz_zip_archive* zip,
158161
out->min_string =
159162
(int)toml_seek(out->toml.toptab, "analysis.min_string").u.int64;
160163

164+
toml_datum_t string_terminators =
165+
toml_seek(out->toml.toptab, "analysis.string_terminators");
166+
167+
vect_reserve(&out->string_terminators,
168+
(usize)string_terminators.u.arr.size);
169+
170+
for(int i = 0; i < string_terminators.u.arr.size; i++) {
171+
toml_datum_t elem = string_terminators.u.arr.elem[i];
172+
vect_push(&out->string_terminators, (u8)elem.u.int64);
173+
}
174+
161175
const char* loader_id = toml_seek(out->toml.toptab, "analysis.loader").u.s;
162176
assert(loader_id);
163177

@@ -274,6 +288,9 @@ static RDContext* _rd_project_create_context(mz_zip_archive* zip,
274288

275289
ctx->entry_point.has_value = manifest->entry_point.has_value;
276290
ctx->entry_point.value = manifest->entry_point.value;
291+
292+
mem_swap(RDStringTerminatorVect, &ctx->string_terminators,
293+
&manifest->string_terminators);
277294
mem_swap(RDAnalyzerItemVect, &ctx->analyzerplugins, &manifest->analyzers);
278295

279296
ctx->engine.step = RD_WS_DONE;

src/project/save.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,18 @@ static const char* _rd_project_write_manifest(const RDContext* ctx,
2222

2323
str_append(v, "\n[analysis]\n");
2424
str_append(v, rd_i_format(&buf, "min_string = %d\n", ctx->min_string));
25+
26+
str_append(v, "string_terminators = [");
27+
28+
for(usize i = 0; i < vect_length(&ctx->string_terminators); i++) {
29+
if(i) str_push(v, ',');
30+
31+
const u8* t = vect_at(&ctx->string_terminators, i);
32+
str_append(v, rd_i_format(&buf, "%" PRIu8, t));
33+
}
34+
35+
str_append(v, "]\n");
36+
2537
str_append(v, rd_i_format(&buf, "loader = \"%s\"\n", ctx->loaderplugin->id));
2638
str_append(v, rd_i_format(&buf, "processor = \"%s\"\n", ctx->processorplugin->id));
2739
str_append(v, "analyzers = [");

0 commit comments

Comments
 (0)