Skip to content
Permalink
Browse files
Enable to remove Mach-O symbols
  • Loading branch information
romainthomas committed Feb 18, 2019
1 parent 38c7ef8 commit 616d739
Show file tree
Hide file tree
Showing 8 changed files with 204 additions and 68 deletions.
@@ -394,6 +394,11 @@ void create<Binary>(py::module& m) {
"" RST_CLASS_REF(lief.MachO.LOAD_COMMAND_TYPES) "",
"type"_a)

.def("remove",
static_cast<bool (Binary::*)(const Symbol&)>(&Binary::remove),
"Remove the given " RST_CLASS_REF(lief.MachO.Symbol)"",
"symbol"_a)

.def("remove_command",
static_cast<bool (Binary::*)(size_t)>(&Binary::remove_command),
"Remove the " RST_CLASS_REF(lief.MachO.LoadCommand) " at ``index``",
@@ -403,6 +408,21 @@ void create<Binary>(py::module& m) {
static_cast<bool (Binary::*)(void)>(&Binary::remove_signature),
"Remove the " RST_CLASS_REF(lief.MachO.CodeSignature) " (if any)")

.def("remove_symbol",
static_cast<bool (Binary::*)(const std::string&)>(&Binary::remove_symbol),
"Remove all symbol(s) with the given name",
"name"_a)

.def("unexport",
static_cast<bool (Binary::*)(const std::string&)>(&Binary::unexport),
"Remove the symbol from the export table",
"name"_a)

.def("unexport",
static_cast<bool (Binary::*)(const Symbol&)>(&Binary::unexport),
"Remove the symbol from the export table",
"symbol"_a)

.def("extend",
static_cast<bool (Binary::*)(const LoadCommand&, uint64_t)>(&Binary::extend),
"Extend a " RST_CLASS_REF(lief.MachO.LoadCommand) " by ``size``",
@@ -200,6 +200,18 @@ class LIEF_API Binary : public LIEF::Binary {
const SegmentCommand* get_segment(const std::string& name) const;
SegmentCommand* get_segment(const std::string& name);

//! Remove symbol with the given name
bool remove_symbol(const std::string& name);

//! Remove the given symbol
bool remove(const Symbol& sym);

//! Remove the given symbol from the export table
bool unexport(const std::string& name);

//! Remove the given symbol from the export table
bool unexport(const Symbol& sym);

// ======
// Helper
// ======
@@ -40,6 +40,7 @@ class BinaryParser;
class LIEF_API DyldInfo : public LoadCommand {

friend class BinaryParser;
friend class Binary;
friend class Builder;

public:
@@ -704,7 +704,6 @@ void Binary::remove_static_symbol(Symbol* symbol) {
this->static_symbols_.erase(it_symbol);

symbol = nullptr;

}


@@ -1209,6 +1209,82 @@ LoadCommand& Binary::add(const SegmentCommand& segment) {
return segment_added;
}

bool Binary::unexport(const std::string& name) {
if (not this->has_symbol(name)) {
return false;
}
const Symbol& s = this->get_symbol(name);
return this->unexport(s);
}

bool Binary::unexport(const Symbol& sym) {
if (not this->has_dyld_info()) {
return false;
}

DyldInfo& dyld = this->dyld_info();
auto&& it_export = std::find_if(
std::begin(dyld.export_info_),
std::end(dyld.export_info_),
[&sym] (const ExportInfo* info) {
return info->has_symbol() and info->symbol() == sym;
});

if (it_export != std::end(dyld.export_info_)) {
delete *it_export;
dyld.export_info_.erase(it_export);
return true;
}

return false;
}

bool Binary::remove(const Symbol& sym) {
/* bool export_removed = */ this->unexport(sym);

auto&& it_symbol = std::find_if(
std::begin(this->symbols_),
std::end(this->symbols_),
[&sym] (const Symbol* s) {
return s->name() == sym.name();
});

// No Symbol
if (it_symbol == std::end(this->symbols_)) {
return false;
}

Symbol* symbol_to_remove = *it_symbol;

// Remove from the symbol command
// ------------------------------
if (this->has_symbol_command()) {
SymbolCommand& sym_cmd = this->symbol_command();
sym_cmd.numberof_symbols(sym_cmd.numberof_symbols() - 1);
}


// Remove from symbol table
// ------------------------
delete symbol_to_remove;
this->symbols_.erase(it_symbol);
symbol_to_remove = nullptr;
return true;
}

bool Binary::remove_symbol(const std::string& name) {
bool removed = false;
while (this->has_symbol(name)) {
const Symbol& s = this->get_symbol(name);
if (not this->remove(s)) {
break;
}

removed = true;
}
return removed;
}


bool Binary::remove_signature(void) {

@@ -626,9 +626,19 @@ void Builder::build(SymbolCommand* symbol_command) {
raw_symbol_names.push_back(0);
}

// If the table is smaller than th original one, fill with 0
if (raw_symbol_names.size() < symbol_command->strings_size()) {
raw_symbol_names.insert(
std::end(raw_symbol_names),
symbol_command->strings_size() - raw_symbol_names.size() ,
0
);
}

size_t padding = align(raw_symbol_names.size(), sizeof(uint)) - raw_symbol_names.size();
raw_symbol_names.insert(std::end(raw_symbol_names), padding, 0);


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

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

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

//std::move(
// std::begin(nlist_table),
// std::end(nlist_table),
// std::back_inserter(symbol_command->originalData_)
//);

//std::move(
// std::begin(raw_symbol_names),
// std::end(raw_symbol_names),
// std::back_inserter(symbol_command->originalData_)
//);

}


0 comments on commit 616d739

Please sign in to comment.