Skip to content

Commit 67d924a

Browse files
committed
Add constructor functions in the abstract layer
New API: * LIEF::ELF::Binary::get_relocation * LIEF::Binary::ctor_functions
1 parent 6e7e373 commit 67d924a

File tree

13 files changed

+1250
-1003
lines changed

13 files changed

+1250
-1003
lines changed

api/python/Abstract/objects/pyBinary.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,10 @@ void init_LIEF_Binary_class(py::module& m) {
195195
"",
196196
py::return_value_policy::reference)
197197

198+
.def_property_readonly("ctor_functions",
199+
&Binary::ctor_functions,
200+
"Constructor functions that are called prior any other functions")
201+
198202
.def("xref",
199203
&Binary::xref,
200204
"Return all **virtual address** that *use* the ``address`` given in parameter"

api/python/ELF/objects/pyBinary.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,25 @@ void create<Binary>(py::module& m) {
458458
py::return_value_policy::reference)
459459

460460

461+
.def("get_relocation",
462+
static_cast<no_const_func<Relocation*, const std::string&>>(&Binary::get_relocation),
463+
"Return the " RST_CLASS_REF(lief.ELF.Relocation) " associated with the given symbol name",
464+
"symbol_name"_a,
465+
py::return_value_policy::reference)
466+
467+
.def("get_relocation",
468+
static_cast<no_const_func<Relocation*, const Symbol&>>(&Binary::get_relocation),
469+
"Return the " RST_CLASS_REF(lief.ELF.Relocation) " associated with the given " RST_CLASS_REF(lief.ELF.Symbol) "",
470+
"symbol"_a,
471+
py::return_value_policy::reference)
472+
473+
.def("get_relocation",
474+
static_cast<no_const_func<Relocation*, uint64_t>>(&Binary::get_relocation),
475+
"Return the " RST_CLASS_REF(lief.ELF.Relocation) " associated with the given address",
476+
"address"_a,
477+
py::return_value_policy::reference)
478+
479+
461480

462481
.def(py::self += Segment())
463482
.def(py::self += Section())

examples/python/elf_reader.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,16 @@ def print_notes(binary):
405405
print("\n")
406406

407407

408+
@exceptions_handler(Exception)
409+
def print_ctor(binary):
410+
print("== Constructors ==\n")
411+
412+
print("Functions: ({:d})".format(len(binary.ctor_functions)))
413+
for idx, address in enumerate(binary.ctor_functions):
414+
print(" [{:d}] 0x{:x}".format(idx, address))
415+
416+
417+
408418
def main():
409419
optparser = OptionParser(
410420
usage='Usage: %prog [options] <elf-file>',
@@ -484,6 +494,10 @@ def main():
484494
default=False,
485495
help='Do not trunc symbol names ...')
486496

497+
optparser.add_option('--ctor',
498+
action='store_true', dest='show_ctor',
499+
help='Constructor functions')
500+
487501
options, args = optparser.parse_args()
488502

489503
if options.help or len(args) == 0:
@@ -539,6 +553,9 @@ def main():
539553
if options.show_notes or options.show_all:
540554
print_notes(binary)
541555

556+
if options.show_ctor or options.show_all:
557+
print_ctor(binary)
558+
542559

543560

544561

examples/python/macho_reader.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,15 @@ def print_encryption_info(binary):
632632
print("")
633633

634634

635+
@exceptions_handler(Exception)
636+
def print_ctor(binary):
637+
print("== Constructors ==\n")
638+
639+
print("Functions: ({:d})".format(len(binary.ctor_functions)))
640+
for idx, address in enumerate(binary.ctor_functions):
641+
print(" [{:d}] 0x{:x}".format(idx, address))
642+
643+
635644

636645
def main():
637646
parser = argparse.ArgumentParser(usage='%(prog)s [options] <macho-file>')
@@ -755,6 +764,10 @@ def main():
755764
action='store_true', dest='show_opcodes',
756765
help='Display the bind and rebase opcodes')
757766

767+
parser.add_argument('--ctor',
768+
action='store_true', dest='show_ctor',
769+
help='Constructor functions')
770+
758771
parser.add_argument("binary",
759772
metavar="<macho-file>",
760773
help='Target Mach-O File')
@@ -859,6 +872,9 @@ def main():
859872
if (args.show_export_trie or args.show_opcodes) and binary.has_dyld_info:
860873
print_export_trie(binary)
861874

875+
if args.show_ctor or args.show_all:
876+
print_ctor(binary)
877+
862878
sys.exit(EXIT_STATUS)
863879

864880

examples/python/pe_reader.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,15 @@ def print_load_configuration(binary):
433433

434434
print("")
435435

436+
437+
@exceptions_handler(Exception)
438+
def print_ctor(binary):
439+
print("== Constructors ==\n")
440+
441+
print("Functions: ({:d})".format(len(binary.ctor_functions)))
442+
for idx, address in enumerate(binary.ctor_functions):
443+
print(" [{:d}] 0x{:x}".format(idx, address))
444+
436445
def main():
437446
optparser = OptionParser(
438447
usage='Usage: %prog [options] <pe-file>',
@@ -500,6 +509,10 @@ def main():
500509
action='store_true', dest='show_loadconfig',
501510
help='Display load configuration')
502511

512+
optparser.add_option('--ctor',
513+
action='store_true', dest='show_ctor',
514+
help='Constructor functions')
515+
503516

504517

505518
options, args = optparser.parse_args()
@@ -557,5 +570,8 @@ def main():
557570
if (options.show_loadconfig or options.show_all) and binary.has_configuration:
558571
print_load_configuration(binary)
559572

573+
if options.show_ctor or options.show_all:
574+
print_ctor(binary)
575+
560576
if __name__ == "__main__":
561577
main()

include/LIEF/Abstract/Binary.hpp

Lines changed: 87 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -37,123 +37,128 @@ class LIEF_API Binary : public Object {
3737

3838
public:
3939

40-
//! Type of a virtual address
41-
enum class VA_TYPES {
42-
AUTO = 0, ///< Guess if it's relative or not
43-
RVA = 1, ///< Relative
44-
VA = 2, ///< Absolute
45-
};
40+
//! Type of a virtual address
41+
enum class VA_TYPES {
42+
AUTO = 0, ///< Guess if it's relative or not
43+
RVA = 1, ///< Relative
44+
VA = 2, ///< Absolute
45+
};
46+
47+
using ctor_t = std::vector<uint64_t>;
4648

4749
public:
48-
Binary(void);
49-
virtual ~Binary(void);
50+
Binary(void);
51+
virtual ~Binary(void);
52+
53+
Binary& operator=(const Binary&);
54+
Binary(const Binary&);
5055

51-
Binary& operator=(const Binary&);
52-
Binary(const Binary&);
56+
//! @brief Executable format (ELF, PE, Mach-O) of the underlying binary
57+
EXE_FORMATS format(void) const;
5358

54-
//! @brief Executable format (ELF, PE, Mach-O) of the underlying binary
55-
EXE_FORMATS format(void) const;
59+
//! @brief Return the abstract header of the binary
60+
Header header(void) const;
5661

57-
//! @brief Return the abstract header of the binary
58-
Header header(void) const;
62+
//! @brief Return list of symbols whose elements **can** be modified
63+
it_symbols symbols(void);
5964

60-
//! @brief Return list of symbols whose elements **can** be modified
61-
it_symbols symbols(void);
65+
//! @brief Return list of symbols whose elements **can't** be modified
66+
it_const_symbols symbols(void) const;
6267

63-
//! @brief Return list of symbols whose elements **can't** be modified
64-
it_const_symbols symbols(void) const;
68+
//! @brief Check if a Symbol with the given name exists
69+
bool has_symbol(const std::string& name) const;
6570

66-
//! @brief Check if a Symbol with the given name exists
67-
bool has_symbol(const std::string& name) const;
71+
//! @brief Return the Symbol with the given name
72+
const Symbol& get_symbol(const std::string& name) const;
6873

69-
//! @brief Return the Symbol with the given name
70-
const Symbol& get_symbol(const std::string& name) const;
74+
Symbol& get_symbol(const std::string& name);
7175

72-
Symbol& get_symbol(const std::string& name);
76+
//! @brief Returns binary's sections
77+
it_sections sections(void);
78+
it_const_sections sections(void) const;
7379

74-
//! @brief Returns binary's sections
75-
it_sections sections(void);
76-
it_const_sections sections(void) const;
80+
//! @brief Returns binary's relocations
81+
it_relocations relocations(void);
82+
it_const_relocations relocations(void) const;
7783

78-
//! @brief Returns binary's relocations
79-
it_relocations relocations(void);
80-
it_const_relocations relocations(void) const;
84+
//! @brief Binary's entrypoint (if any)
85+
virtual uint64_t entrypoint(void) const = 0;
8186

82-
//! @brief Binary's entrypoint (if any)
83-
virtual uint64_t entrypoint(void) const = 0;
87+
//! @brief Binary's name
88+
const std::string& name(void) const;
8489

85-
//! @brief Binary's name
86-
const std::string& name(void) const;
90+
//! @brief Binary's original size
91+
uint64_t original_size(void) const;
8792

88-
//! @brief Binary's original size
89-
uint64_t original_size(void) const;
93+
//! @brief Return functions's name exported by the binary
94+
std::vector<std::string> exported_functions(void) const;
9095

91-
//! @brief Return functions's name exported by the binary
92-
std::vector<std::string> exported_functions(void) const;
96+
//! @brief Return libraries which are imported by the binary
97+
std::vector<std::string> imported_libraries(void) const;
9398

94-
//! @brief Return libraries which are imported by the binary
95-
std::vector<std::string> imported_libraries(void) const;
99+
//! @brief Return functions's name imported by the binary
100+
std::vector<std::string> imported_functions(void) const;
96101

97-
//! @brief Return functions's name imported by the binary
98-
std::vector<std::string> imported_functions(void) const;
102+
//! @brief Return the address of the given function name
103+
virtual uint64_t get_function_address(const std::string& func_name) const;
99104

100-
//! @brief Return the address of the given function name
101-
virtual uint64_t get_function_address(const std::string& func_name) const;
105+
//! @brief Method so that a ``visitor`` can visit us
106+
virtual void accept(Visitor& visitor) const override;
102107

103-
//! @brief Method so that a ``visitor`` can visit us
104-
virtual void accept(Visitor& visitor) const override;
108+
std::vector<uint64_t> xref(uint64_t address) const;
105109

106-
std::vector<uint64_t> xref(uint64_t address) const;
110+
//! @brief Patch the content at virtual address @p address with @p patch_value
111+
//!
112+
//! @param[in] address Address to patch
113+
//! @param[in] patch_value Patch to apply
114+
virtual void patch_address(uint64_t address, const std::vector<uint8_t>& patch_value, VA_TYPES addr_type = VA_TYPES::AUTO) = 0;
107115

108-
//! @brief Patch the content at virtual address @p address with @p patch_value
109-
//!
110-
//! @param[in] address Address to patch
111-
//! @param[in] patch_value Patch to apply
112-
virtual void patch_address(uint64_t address, const std::vector<uint8_t>& patch_value, VA_TYPES addr_type = VA_TYPES::AUTO) = 0;
116+
//! @brief Patch the address with the given value
117+
//!
118+
//! @param[in] address Address to patch
119+
//! @param[in] patch_value Patch to apply
120+
//! @param[in] size Size of the value in **bytes** (1, 2, ... 8)
121+
virtual void patch_address(uint64_t address, uint64_t patch_value, size_t size = sizeof(uint64_t), VA_TYPES addr_type = VA_TYPES::AUTO) = 0;
113122

114-
//! @brief Patch the address with the given value
115-
//!
116-
//! @param[in] address Address to patch
117-
//! @param[in] patch_value Patch to apply
118-
//! @param[in] size Size of the value in **bytes** (1, 2, ... 8)
119-
virtual void patch_address(uint64_t address, uint64_t patch_value, size_t size = sizeof(uint64_t), VA_TYPES addr_type = VA_TYPES::AUTO) = 0;
123+
//! @brief Return the content located at virtual address
124+
virtual std::vector<uint8_t> get_content_from_virtual_address(uint64_t virtual_address, uint64_t size, VA_TYPES addr_type = VA_TYPES::AUTO) const = 0;
120125

121-
//! @brief Return the content located at virtual address
122-
virtual std::vector<uint8_t> get_content_from_virtual_address(uint64_t virtual_address, uint64_t size, VA_TYPES addr_type = VA_TYPES::AUTO) const = 0;
126+
//! @brief Change binary's name
127+
void name(const std::string& name);
123128

124-
//! @brief Change binary's name
125-
void name(const std::string& name);
129+
//! @brief Change binary's original size.
130+
//!
131+
//! @warning
132+
//! Should be used carefully because some optimizations can be
133+
//! done with this value
134+
void original_size(uint64_t size);
126135

127-
//! @brief Change binary's original size.
128-
//!
129-
//! @warning
130-
//! Should be used carefully because some optimizations can be
131-
//! done with this value
132-
void original_size(uint64_t size);
136+
//! @brief Check if the binary is position independent
137+
virtual bool is_pie(void) const = 0;
133138

134-
//! @brief Check if the binary is position independent
135-
virtual bool is_pie(void) const = 0;
139+
//! @brief Check if the binary uses ``NX`` protection
140+
virtual bool has_nx(void) const = 0;
136141

137-
//! @brief Check if the binary uses ``NX`` protection
138-
virtual bool has_nx(void) const = 0;
142+
//! Constructor functions that are called prior any other functions
143+
virtual LIEF::Binary::ctor_t ctor_functions(void) const = 0;
139144

140-
virtual std::ostream& print(std::ostream& os) const;
145+
virtual std::ostream& print(std::ostream& os) const;
141146

142-
LIEF_API friend std::ostream& operator<<(std::ostream& os, const Binary& binary);
147+
LIEF_API friend std::ostream& operator<<(std::ostream& os, const Binary& binary);
143148

144149
protected:
145-
std::string name_;
150+
std::string name_;
146151

147-
uint64_t original_size_;
152+
uint64_t original_size_;
148153

149-
virtual Header get_abstract_header(void) const = 0;
150-
virtual symbols_t get_abstract_symbols(void) = 0;
151-
virtual sections_t get_abstract_sections(void) = 0;
152-
virtual relocations_t get_abstract_relocations(void) = 0;
154+
virtual Header get_abstract_header(void) const = 0;
155+
virtual symbols_t get_abstract_symbols(void) = 0;
156+
virtual sections_t get_abstract_sections(void) = 0;
157+
virtual relocations_t get_abstract_relocations(void) = 0;
153158

154-
virtual std::vector<std::string> get_abstract_exported_functions(void) const = 0;
155-
virtual std::vector<std::string> get_abstract_imported_functions(void) const = 0;
156-
virtual std::vector<std::string> get_abstract_imported_libraries(void) const = 0;
159+
virtual std::vector<std::string> get_abstract_exported_functions(void) const = 0;
160+
virtual std::vector<std::string> get_abstract_imported_functions(void) const = 0;
161+
virtual std::vector<std::string> get_abstract_imported_libraries(void) const = 0;
157162

158163

159164
};

0 commit comments

Comments
 (0)