mirror of
https://github.com/QuasarApp/LIEF.git
synced 2025-05-10 18:59:33 +00:00
Add function to apply a permutation on the dynamic symbols
This commit is contained in:
parent
95affa6490
commit
99042451d8
@ -198,6 +198,10 @@ void init_ELF_Binary_class(py::module& m) {
|
||||
&Binary::strip,
|
||||
"Strip the binary")
|
||||
|
||||
.def("permute_dynamic_symbols",
|
||||
&Binary::permute_dynamic_symbols,
|
||||
"Apply the given permutation on the dynamic symbols table")
|
||||
|
||||
.def("write",
|
||||
&Binary::write,
|
||||
"Rebuild the binary and write it in a file",
|
||||
|
@ -97,7 +97,6 @@ class DLL_PUBLIC Binary : public LIEF::Binary {
|
||||
it_symbols get_dynamic_symbols(void);
|
||||
it_const_symbols get_dynamic_symbols(void) const;
|
||||
|
||||
|
||||
//! @brief Return symbols which are exported by the binary
|
||||
it_exported_symbols get_exported_symbols(void);
|
||||
it_const_exported_symbols get_exported_symbols(void) const;
|
||||
@ -346,6 +345,12 @@ class DLL_PUBLIC Binary : public LIEF::Binary {
|
||||
//! @brief Method so that the ``visitor`` can visit us
|
||||
virtual void accept(LIEF::Visitor& visitor) const override;
|
||||
|
||||
//! @brief Apply the given permutation on the dynamic symbols table
|
||||
//!
|
||||
//! To avoid override by the ELF::Builder, one should set ELF::Builder::empties_gnuhash
|
||||
//! to ``true``
|
||||
void permute_dynamic_symbols(const std::vector<size_t>& permutation);
|
||||
|
||||
size_t hash(const std::string& name);
|
||||
|
||||
virtual ~Binary(void);
|
||||
|
@ -1391,6 +1391,23 @@ bool Binary::has_dynamic_entry(DYNAMIC_TAGS tag) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void Binary::permute_dynamic_symbols(const std::vector<size_t>& permutation) {
|
||||
for (size_t i = 0; i < permutation.size(); ++i) {
|
||||
if (this->dynamic_symbols_[i]->has_version() and this->dynamic_symbols_[permutation[i]]->has_version()) {
|
||||
std::swap(this->symbol_version_table_[i], this->symbol_version_table_[permutation[i]]);
|
||||
std::swap(this->dynamic_symbols_[i], this->dynamic_symbols_[permutation[i]]);
|
||||
} else if (not this->dynamic_symbols_[i]->has_version() and not this->dynamic_symbols_[permutation[i]]->has_version()) {
|
||||
std::swap(this->dynamic_symbols_[i], this->dynamic_symbols_[permutation[i]]);
|
||||
} else if (permutation[i] == i) {
|
||||
continue;
|
||||
} else {
|
||||
LOG(ERROR) << "Can't apply permutation at index " << std::dec << i;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
LIEF::Header Binary::get_abstract_header(void) const {
|
||||
LIEF::Header header;
|
||||
const std::pair<ARCHITECTURES, std::set<MODES>>& am = this->get_header().abstract_architecture();
|
||||
@ -1403,6 +1420,8 @@ LIEF::Header Binary::get_abstract_header(void) const {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void Binary::accept(LIEF::Visitor&) const {
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,25 @@
|
||||
#!/usr/bin/env python
|
||||
import unittest
|
||||
import lief
|
||||
import tempfile
|
||||
import sys
|
||||
import subprocess
|
||||
import stat
|
||||
import os
|
||||
import logging
|
||||
import random
|
||||
|
||||
|
||||
from subprocess import Popen
|
||||
|
||||
from unittest import TestCase
|
||||
from utils import get_sample
|
||||
|
||||
class TestELF(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.logger = logging.getLogger(__name__)
|
||||
|
||||
def test_rpath(self):
|
||||
etterlog = lief.parse(get_sample('ELF/ELF64_x86-64_binary_etterlog.bin'))
|
||||
|
||||
@ -59,6 +72,41 @@ class TestELF(TestCase):
|
||||
0x12F7C433, 0xEB01FAB6, 0xECD54543, 0xAD3C9892, 0x72632CCF, 0x12F7A2B3, 0x7C92E3BB, 0x7C96F087]
|
||||
self.assertEqual(hash_values, hash_values_test)
|
||||
|
||||
def test_permutation(self):
|
||||
samples = [
|
||||
"ELF/ELF64_x86-64_binary_ls.bin",
|
||||
"ELF/ELF64_x86-64_binary_gcc.bin",
|
||||
"ELF/ELF64_x86-64_binary_openssl.bin",
|
||||
]
|
||||
tmp_dir = tempfile.mkdtemp(suffix='_lief_test_permutation')
|
||||
for sample in samples:
|
||||
binary = lief.parse(get_sample(sample))
|
||||
dynamic_symbols = binary.dynamic_symbols
|
||||
|
||||
gnu_hash_table = binary.gnu_hash
|
||||
|
||||
idx = gnu_hash_table.symbol_index
|
||||
|
||||
permutation = [i for i in range(1, len(dynamic_symbols))]
|
||||
random.shuffle(permutation)
|
||||
permutation = [0] + permutation
|
||||
|
||||
builder = lief.ELF.Builder(binary)
|
||||
builder.empties_gnuhash(True)
|
||||
builder.build()
|
||||
output = os.path.join(tmp_dir, "{}.permutated".format(binary.name))
|
||||
binary.write(output)
|
||||
if not sys.platform.startswith("linux"):
|
||||
return
|
||||
|
||||
st = os.stat(output)
|
||||
os.chmod(output, st.st_mode | stat.S_IEXEC)
|
||||
|
||||
p = Popen([output, "--help"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
stdout, _ = p.communicate()
|
||||
self.logger.debug(stdout.decode("utf8"))
|
||||
self.assertEqual(p.returncode, 0)
|
||||
|
||||
|
||||
|
||||
|
||||
@ -68,5 +116,13 @@ class TestELF(TestCase):
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main(verbosity = 2)
|
||||
|
||||
root_logger = logging.getLogger()
|
||||
root_logger.setLevel(logging.DEBUG)
|
||||
|
||||
ch = logging.StreamHandler()
|
||||
ch.setLevel(logging.DEBUG)
|
||||
root_logger.addHandler(ch)
|
||||
|
||||
unittest.main(verbosity=2)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user