Skip to content

Commit 96873f0

Browse files
committed
feat!: use new external APIs
1 parent d2c4a1b commit 96873f0

9 files changed

Lines changed: 100 additions & 82 deletions

File tree

elf/plugin.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,21 +90,21 @@ static void _elf_process_sym(RDContext* ctx, const ELFFormat* elf, RDReader* r,
9090
RDAddress symaddr = elf_norm(ctx, elf, (RDAddress)sym->st_value);
9191

9292
if(type == ELF_STT_FUNC) {
93-
if(is_imported)
94-
rd_set_external(ctx, symaddr, NULL, name, RD_EXT_IMPORTED);
93+
if(is_imported) {
94+
rd_set_external(ctx, symaddr, NULL, RD_EXT_IMPORTED);
95+
rd_library_name(ctx, symaddr, name);
96+
}
9597
else
9698
rd_library_function(ctx, symaddr, name);
9799
}
98100
else if(type == ELF_STT_OBJECT) {
99-
if(is_imported)
100-
rd_set_external(ctx, symaddr, NULL, name, RD_EXT_IMPORTED);
101-
else
102-
rd_library_name(ctx, symaddr, name);
101+
if(is_imported) rd_set_external(ctx, symaddr, NULL, RD_EXT_IMPORTED);
102+
rd_library_name(ctx, symaddr, name);
103103
}
104104

105105
// mark globals defined in this binary as exported
106106
if(!is_imported && bind == ELF_STB_GLOBAL)
107-
rd_set_external(ctx, symaddr, NULL, NULL, RD_EXT_EXPORTED);
107+
rd_set_external(ctx, symaddr, NULL, RD_EXT_EXPORTED);
108108
}
109109

110110
static void _elf_read_symtab(ELFFormat* elf, RDContext* ctx, RDReader* r,
@@ -168,7 +168,8 @@ static void _elf_read_relocs(ELFFormat* elf, RDContext* ctx, RDReader* r,
168168
const char* name = _elf_sym_name(r, &dynstr, sym.st_name);
169169
if(!name || !(*name)) continue;
170170

171-
rd_set_external(ctx, r_offset, NULL, name, RD_EXT_IMPORTED);
171+
rd_set_external(ctx, r_offset, NULL, RD_EXT_IMPORTED);
172+
rd_library_name(ctx, r_offset, name);
172173
}
173174
}
174175

mz/le/exports.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,10 @@ static void _le_read_name_table(const LEFormat* le, RDReader* r, u64 table_off,
124124
RDAddress addr = _le_entry_address(le, r, ordinal);
125125
rd_reader_restore(r);
126126

127-
if(addr) rd_set_external(ctx, addr, NULL, name, RD_EXT_EXPORTED);
127+
if(addr) {
128+
rd_set_external(ctx, addr, NULL, RD_EXT_EXPORTED);
129+
rd_library_name(ctx, addr, name);
130+
}
128131
}
129132
}
130133

mz/le/imports.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,17 @@ RDAddress le_importslice_resolve(const LEImportSlice* self, RDContext* ctx,
5959
if(!mod_idx || mod_idx > (u16)self->length) return 0;
6060

6161
const char* mod_name = self->names[mod_idx - 1];
62-
const char* hint = rd_get_external_hint(ctx, sym_name, RD_EXT_IMPORTED);
6362

6463
// deduplication: already registered from a previous fixup
6564
RDAddress addr;
66-
if(rd_get_address(ctx, hint, &addr)) return addr;
65+
if(rd_get_address(ctx, sym_name, &addr)) return addr;
6766

6867
LEImport* mod = &self->imports[mod_idx - 1]; // mod_idx is 1-based
6968
addr = mod->base + mod->next_off;
7069
mod->next_off += sizeof(u32);
7170

72-
rd_set_external(ctx, addr, mod_name, sym_name, RD_EXT_IMPORTED);
71+
rd_set_external(ctx, addr, mod_name, RD_EXT_IMPORTED);
72+
rd_library_name(ctx, addr, sym_name);
7373
return addr;
7474
}
7575

@@ -78,15 +78,14 @@ RDAddress le_importslice_resolve_ord(const LEImportSlice* self, RDContext* ctx,
7878
if(!mod_idx || mod_idx > (u16)self->length) return 0;
7979

8080
const char* mod_name = self->names[mod_idx - 1];
81-
const char* hint =
82-
rd_get_external_ord_hint(ctx, mod_name, ordinal, RD_EXT_IMPORTED);
8381

8482
// deduplication: already registered from a previous fixup
85-
RDAddress addr;
86-
if(rd_get_address(ctx, hint, &addr)) return addr;
83+
RDExternal ext;
84+
if(rd_get_external_ord(ctx, mod_name, ordinal, RD_EXT_IMPORTED, &ext))
85+
return ext.address;
8786

8887
LEImport* mod = &self->imports[mod_idx - 1]; // mod_idx is 1-based
89-
addr = mod->base + mod->next_off;
88+
RDAddress addr = mod->base + mod->next_off;
9089
mod->next_off += sizeof(u32);
9190

9291
rd_set_external_ord(ctx, addr, mod_name, ordinal, RD_EXT_IMPORTED);

mz/le/vxd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ void le_load_vxd(const LEFormat* le, RDContext* ctx) {
5959
if(vxd.DDB_Control_Proc) {
6060
rd_library_function(ctx, vxd.DDB_Control_Proc,
6161
rd_format("%s_Control", vxd_name));
62-
rd_set_external(ctx, vxd.DDB_Control_Proc, NULL, NULL, RD_EXT_EXPORTED);
62+
rd_set_external(ctx, vxd.DDB_Control_Proc, NULL, RD_EXT_EXPORTED);
6363
}
6464

6565
if(vxd.DDB_V86_API_Proc && vxd.DDB_V86_API_Proc == vxd.DDB_PM_API_Proc) {

mz/ne/exports.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ void ne_load_exports(NEFormat* ne, RDContext* ctx,
4949
else
5050
rd_library_name(ctx, addr, name);
5151

52-
rd_set_external(ctx, addr, NULL, name, RD_EXT_EXPORTED);
52+
rd_set_external(ctx, addr, NULL, RD_EXT_EXPORTED);
5353
}
5454

5555
rd_free(name);

mz/ne/modules.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ RDAddress ne_moduleslice_resolve_import(NEModuleSlice* self, RDContext* ctx,
9595
RDAddress addr = mod->base + off;
9696
mod->next_off += sizeof(u16);
9797

98-
rd_set_external(ctx, addr, NULL, sym_name, RD_EXT_IMPORTED);
98+
rd_set_external(ctx, addr, NULL, RD_EXT_IMPORTED);
99+
rd_library_name(ctx, addr, sym_name);
99100
return addr;
100101
}

mz/pe/dirs/exports.c

Lines changed: 68 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
* _etext lands inside the executable segment it is bounding.
1313
*/
1414
static bool _pe_is_linker_boundary(const char* name) {
15+
if(!name) return false;
16+
1517
static const char* const BOUNDARIES[] = {
1618
"_etext",
1719
"_edata",
@@ -68,66 +70,83 @@ bool pe_read_exports(RDContext* ctx, PEFormat* pe) {
6870
}
6971
}
7072

71-
for(u32 i = 0; i < exportdir.NumberOfNames; i++) {
72-
RDAddress names_va, ordinals_va;
73+
RDAddress functions_va, names_va, ordinals_va;
74+
if(!pe_from_rva(pe, exportdir.AddressOfFunctions, &functions_va) ||
75+
!pe_from_rva(pe, exportdir.AddressOfNames, &names_va) ||
76+
!pe_from_rva(pe, exportdir.AddressOfNameOrdinals, &ordinals_va))
77+
return false;
7378

74-
if(!pe_from_rva(pe, exportdir.AddressOfNames + (i * sizeof(u32)),
75-
&names_va))
76-
continue;
77-
if(!pe_from_rva(pe, exportdir.AddressOfNameOrdinals + (i * sizeof(u16)),
78-
&ordinals_va))
79-
continue;
79+
rd_reader_seek(r, functions_va);
8080

81-
u32 name_rva;
82-
u16 ordinal_idx;
81+
for(u32 i = 0; i < exportdir.NumberOfFunctions; i++) {
82+
u32 entry_rva;
83+
if(!rd_reader_read_le32(r, &entry_rva)) return false;
84+
if(!entry_rva) continue;
8385

84-
rd_reader_seek(r, names_va);
85-
rd_reader_read_le32(r, &name_rva);
86-
if(rd_reader_has_error(r)) continue;
86+
u32 ord = exportdir.Base + i;
87+
const char* export_name = NULL;
8788

89+
rd_reader_save(r);
8890
rd_reader_seek(r, ordinals_va);
89-
rd_reader_read_le16(r, &ordinal_idx);
90-
if(rd_reader_has_error(r)) continue;
91-
92-
RDAddress entry_va, funcptrs_va;
93-
if(!pe_from_rva(
94-
pe, exportdir.AddressOfFunctions + (ordinal_idx * sizeof(u32)),
95-
&funcptrs_va))
96-
continue;
97-
98-
u32 funcrva;
99-
rd_reader_seek(r, funcptrs_va);
100-
rd_reader_read_le32(r, &funcrva);
101-
if(rd_reader_has_error(r)) continue;
102-
103-
bool is_fwd =
104-
funcrva >= d.VirtualAddress && funcrva < d.VirtualAddress + d.Size;
105-
if(is_fwd) continue; // don't handle export forwarding (yet)
106-
107-
if(!pe_from_rva(pe, funcrva, &entry_va)) continue;
108-
109-
RDAddress exportname_va;
110-
if(!pe_from_rva(pe, name_rva, &exportname_va)) continue;
11191

112-
rd_reader_seek(r, exportname_va);
113-
114-
usize n;
115-
const char* name = rd_reader_peek_str(r, &n);
116-
if(!name) continue;
92+
for(u32 j = 0; j < exportdir.NumberOfNames; j++) {
93+
u16 name_ord;
94+
95+
if(!rd_reader_read_le16(r, &name_ord)) {
96+
rd_reader_restore(r);
97+
return false;
98+
}
99+
100+
if((u32)name_ord == i) {
101+
u32 exportname_rva;
102+
rd_reader_seek(r, names_va + (j * sizeof(u32)));
103+
rd_reader_read_le32(r, &exportname_rva);
104+
105+
RDAddress exportname_va;
106+
if(pe_from_rva(pe, exportname_rva, &exportname_va)) {
107+
rd_reader_seek(r, exportname_va);
108+
usize export_len = 0;
109+
export_name = rd_reader_peek_str(r, &export_len);
110+
111+
if(export_name && export_len) {
112+
rd_library_type(ctx, exportname_va, "char",
113+
export_len + 1, RD_TYPE_NONE);
114+
}
115+
}
116+
117+
break;
118+
}
119+
}
117120

118-
rd_library_type(ctx, exportname_va, "char", n + 1, RD_TYPE_NONE);
121+
RDAddress entry_va;
122+
if(pe_from_rva(pe, entry_rva, &entry_va)) {
123+
rd_set_external_ord(ctx, entry_va, NULL, ord, RD_EXT_EXPORTED);
124+
if(export_name) rd_library_name(ctx, entry_va, export_name);
125+
}
119126

120127
const RDSegment* seg = rd_find_segment(ctx, entry_va);
121-
if(!seg) continue;
122-
123-
if((seg->perm & RD_SP_X) && !_pe_is_linker_boundary(name)) {
124-
entry_va = pe_norm(ctx, pe, entry_va);
125-
rd_library_function(ctx, entry_va, name);
128+
bool is_func = seg && (seg->perm & RD_SP_X) &&
129+
!_pe_is_linker_boundary(export_name);
130+
131+
bool is_fwd = entry_rva >= d.VirtualAddress &&
132+
entry_rva < d.VirtualAddress + d.Size;
133+
134+
if(is_fwd) {
135+
// forwarded exports points to a null-terminated string
136+
// like DLLNAME.FunctionNName
137+
usize fwd_len;
138+
rd_reader_seek(r, entry_va);
139+
const char* fwd_name = rd_reader_peek_str(r, &fwd_len);
140+
141+
if(fwd_name) {
142+
rd_library_type(ctx, entry_va, "char", fwd_len + 1,
143+
RD_TYPE_NONE);
144+
}
126145
}
127-
else
128-
rd_library_name(ctx, entry_va, name);
146+
else if(is_func)
147+
rd_library_function(ctx, entry_va, NULL);
129148

130-
rd_set_external(ctx, entry_va, NULL, name, RD_EXT_EXPORTED);
149+
rd_reader_restore(r);
131150
}
132151

133152
return true;

mz/pe/dirs/imports.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,8 @@ static void _pe_read_thunks(RDContext* ctx, const PEFormat* pe, RDReader* r,
9898
rd_library_name(ctx, thunkva + sizeof(u16),
9999
rd_format("%s_%s_name", module, name));
100100

101-
rd_set_external(ctx, ft_va, module, name, RD_EXT_IMPORTED);
101+
rd_set_external(ctx, ft_va, module, RD_EXT_IMPORTED);
102+
rd_library_name(ctx, ft_va, name);
102103

103104
if(oft_va != ft_va) {
104105
rd_library_name(ctx, oft_va,

mz/pe/vb/decompiler.c

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -78,20 +78,14 @@ static void _pe_vb_decompiler_events(const PEVBPublicObjectDescriptor* descr,
7878
rd_library_type(ctx, ctrlinfo->lpEventInfo, "PE_VB_EVENT_INFO", 0,
7979
RD_TYPE_NONE);
8080

81-
if(evinfo.lpEVENT_SINK_QueryInterface) {
82-
rd_library_function(ctx, evinfo.lpEVENT_SINK_QueryInterface,
83-
"EVENT_SINK_QueryInterface");
84-
}
81+
if(evinfo.lpEVENT_SINK_QueryInterface)
82+
rd_library_function(ctx, evinfo.lpEVENT_SINK_QueryInterface, NULL);
8583

86-
if(evinfo.lpEVENT_SINK_AddRef) {
87-
rd_library_function(ctx, evinfo.lpEVENT_SINK_AddRef,
88-
"EVENT_SINK_AddRef");
89-
}
84+
if(evinfo.lpEVENT_SINK_AddRef)
85+
rd_library_function(ctx, evinfo.lpEVENT_SINK_AddRef, NULL);
9086

91-
if(evinfo.lpEVENT_SINK_Release) {
92-
rd_library_function(ctx, evinfo.lpEVENT_SINK_Release,
93-
"EVENT_SINK_Release");
94-
}
87+
if(evinfo.lpEVENT_SINK_Release)
88+
rd_library_function(ctx, evinfo.lpEVENT_SINK_Release, NULL);
9589

9690
const RDKBObject* events = rd_kbobject_get_array(c, "events");
9791

0 commit comments

Comments
 (0)