Skip to content

Commit 616d739

Browse files
committed
Enable to remove Mach-O symbols
1 parent 38c7ef8 commit 616d739

File tree

8 files changed

+204
-68
lines changed

8 files changed

+204
-68
lines changed

api/python/MachO/objects/pyBinary.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,11 @@ void create<Binary>(py::module& m) {
394394
"" RST_CLASS_REF(lief.MachO.LOAD_COMMAND_TYPES) "",
395395
"type"_a)
396396

397+
.def("remove",
398+
static_cast<bool (Binary::*)(const Symbol&)>(&Binary::remove),
399+
"Remove the given " RST_CLASS_REF(lief.MachO.Symbol)"",
400+
"symbol"_a)
401+
397402
.def("remove_command",
398403
static_cast<bool (Binary::*)(size_t)>(&Binary::remove_command),
399404
"Remove the " RST_CLASS_REF(lief.MachO.LoadCommand) " at ``index``",
@@ -403,6 +408,21 @@ void create<Binary>(py::module& m) {
403408
static_cast<bool (Binary::*)(void)>(&Binary::remove_signature),
404409
"Remove the " RST_CLASS_REF(lief.MachO.CodeSignature) " (if any)")
405410

411+
.def("remove_symbol",
412+
static_cast<bool (Binary::*)(const std::string&)>(&Binary::remove_symbol),
413+
"Remove all symbol(s) with the given name",
414+
"name"_a)
415+
416+
.def("unexport",
417+
static_cast<bool (Binary::*)(const std::string&)>(&Binary::unexport),
418+
"Remove the symbol from the export table",
419+
"name"_a)
420+
421+
.def("unexport",
422+
static_cast<bool (Binary::*)(const Symbol&)>(&Binary::unexport),
423+
"Remove the symbol from the export table",
424+
"symbol"_a)
425+
406426
.def("extend",
407427
static_cast<bool (Binary::*)(const LoadCommand&, uint64_t)>(&Binary::extend),
408428
"Extend a " RST_CLASS_REF(lief.MachO.LoadCommand) " by ``size``",

include/LIEF/MachO/Binary.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,18 @@ class LIEF_API Binary : public LIEF::Binary {
200200
const SegmentCommand* get_segment(const std::string& name) const;
201201
SegmentCommand* get_segment(const std::string& name);
202202

203+
//! Remove symbol with the given name
204+
bool remove_symbol(const std::string& name);
205+
206+
//! Remove the given symbol
207+
bool remove(const Symbol& sym);
208+
209+
//! Remove the given symbol from the export table
210+
bool unexport(const std::string& name);
211+
212+
//! Remove the given symbol from the export table
213+
bool unexport(const Symbol& sym);
214+
203215
// ======
204216
// Helper
205217
// ======

include/LIEF/MachO/DyldInfo.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class BinaryParser;
4040
class LIEF_API DyldInfo : public LoadCommand {
4141

4242
friend class BinaryParser;
43+
friend class Binary;
4344
friend class Builder;
4445

4546
public:

src/ELF/Binary.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,6 @@ void Binary::remove_static_symbol(Symbol* symbol) {
704704
this->static_symbols_.erase(it_symbol);
705705

706706
symbol = nullptr;
707-
708707
}
709708

710709

src/MachO/Binary.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1209,6 +1209,82 @@ LoadCommand& Binary::add(const SegmentCommand& segment) {
12091209
return segment_added;
12101210
}
12111211

1212+
bool Binary::unexport(const std::string& name) {
1213+
if (not this->has_symbol(name)) {
1214+
return false;
1215+
}
1216+
const Symbol& s = this->get_symbol(name);
1217+
return this->unexport(s);
1218+
}
1219+
1220+
bool Binary::unexport(const Symbol& sym) {
1221+
if (not this->has_dyld_info()) {
1222+
return false;
1223+
}
1224+
1225+
DyldInfo& dyld = this->dyld_info();
1226+
auto&& it_export = std::find_if(
1227+
std::begin(dyld.export_info_),
1228+
std::end(dyld.export_info_),
1229+
[&sym] (const ExportInfo* info) {
1230+
return info->has_symbol() and info->symbol() == sym;
1231+
});
1232+
1233+
if (it_export != std::end(dyld.export_info_)) {
1234+
delete *it_export;
1235+
dyld.export_info_.erase(it_export);
1236+
return true;
1237+
}
1238+
1239+
return false;
1240+
}
1241+
1242+
bool Binary::remove(const Symbol& sym) {
1243+
/* bool export_removed = */ this->unexport(sym);
1244+
1245+
auto&& it_symbol = std::find_if(
1246+
std::begin(this->symbols_),
1247+
std::end(this->symbols_),
1248+
[&sym] (const Symbol* s) {
1249+
return s->name() == sym.name();
1250+
});
1251+
1252+
// No Symbol
1253+
if (it_symbol == std::end(this->symbols_)) {
1254+
return false;
1255+
}
1256+
1257+
Symbol* symbol_to_remove = *it_symbol;
1258+
1259+
// Remove from the symbol command
1260+
// ------------------------------
1261+
if (this->has_symbol_command()) {
1262+
SymbolCommand& sym_cmd = this->symbol_command();
1263+
sym_cmd.numberof_symbols(sym_cmd.numberof_symbols() - 1);
1264+
}
1265+
1266+
1267+
// Remove from symbol table
1268+
// ------------------------
1269+
delete symbol_to_remove;
1270+
this->symbols_.erase(it_symbol);
1271+
symbol_to_remove = nullptr;
1272+
return true;
1273+
}
1274+
1275+
bool Binary::remove_symbol(const std::string& name) {
1276+
bool removed = false;
1277+
while (this->has_symbol(name)) {
1278+
const Symbol& s = this->get_symbol(name);
1279+
if (not this->remove(s)) {
1280+
break;
1281+
}
1282+
1283+
removed = true;
1284+
}
1285+
return removed;
1286+
}
1287+
12121288

12131289
bool Binary::remove_signature(void) {
12141290

src/MachO/Builder.tcc

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -626,9 +626,19 @@ void Builder::build(SymbolCommand* symbol_command) {
626626
raw_symbol_names.push_back(0);
627627
}
628628

629+
// If the table is smaller than th original one, fill with 0
630+
if (raw_symbol_names.size() < symbol_command->strings_size()) {
631+
raw_symbol_names.insert(
632+
std::end(raw_symbol_names),
633+
symbol_command->strings_size() - raw_symbol_names.size() ,
634+
0
635+
);
636+
}
637+
629638
size_t padding = align(raw_symbol_names.size(), sizeof(uint)) - raw_symbol_names.size();
630639
raw_symbol_names.insert(std::end(raw_symbol_names), padding, 0);
631640

641+
632642
// To be removed later
633643
CHECK(raw_symbol_names.size() <= symbol_command->strings_size()) << std::hex << std::showbase << raw_symbol_names.size() << " vs " << symbol_command->strings_size();
634644

@@ -696,9 +706,9 @@ void Builder::build(SymbolCommand* symbol_command) {
696706
//const uint32_t size_needed = sizeof(symtab_command) + nlist_table.size() + raw_symbol_names.size();
697707
symtab.cmd = static_cast<uint32_t>(symbol_command->command());
698708
symtab.cmdsize = static_cast<uint32_t>(symbol_command->size());
699-
symtab.symoff = static_cast<uint32_t>(symbol_command->symbol_offset()); // After the header
709+
symtab.symoff = static_cast<uint32_t>(symbol_command->symbol_offset()); // **Usually** After the header
700710
symtab.nsyms = static_cast<uint32_t>(symbol_command->numberof_symbols());
701-
symtab.stroff = static_cast<uint32_t>(symbol_command->strings_offset()); // After nlist table
711+
symtab.stroff = static_cast<uint32_t>(symbol_command->strings_offset()); // **Usually** After nlist table
702712
symtab.strsize = static_cast<uint32_t>(symbol_command->strings_size());
703713

704714
symbol_command->originalData_.clear();
@@ -710,18 +720,6 @@ void Builder::build(SymbolCommand* symbol_command) {
710720
std::back_inserter(symbol_command->originalData_)
711721
);
712722

713-
//std::move(
714-
// std::begin(nlist_table),
715-
// std::end(nlist_table),
716-
// std::back_inserter(symbol_command->originalData_)
717-
//);
718-
719-
//std::move(
720-
// std::begin(raw_symbol_names),
721-
// std::end(raw_symbol_names),
722-
// std::back_inserter(symbol_command->originalData_)
723-
//);
724-
725723
}
726724

727725

0 commit comments

Comments
 (0)