Add support to access and disassemble COFF functions

This commit is contained in:
Romain Thomas
2025-06-14 07:32:21 +02:00
parent b9829e2142
commit 2babf12d93
19 changed files with 524 additions and 7 deletions
+1 -1
View File
@@ -295,7 +295,7 @@ void create<Binary>(nb::module_& m) {
);
}, "address"_a, nb::keep_alive<0, 1>(),
R"doc(
Disassemble code starting a the given virtual address.
Disassemble code starting at the given virtual address.
.. code-block:: python
+86
View File
@@ -12,6 +12,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <nanobind/stl/string.h>
#include <nanobind/stl/vector.h>
#include <nanobind/stl/unique_ptr.h>
#include "COFF/pyCOFF.hpp"
#include "LIEF/COFF/Binary.hpp"
#include "LIEF/COFF/Relocation.hpp"
@@ -19,6 +24,9 @@
#include "LIEF/COFF/Section.hpp"
#include "LIEF/COFF/String.hpp"
#include "LIEF/asm/Engine.hpp"
#include "LIEF/asm/Instruction.hpp"
#include <sstream>
#include <nanobind/stl/string.h>
@@ -46,6 +54,7 @@ void create<Binary>(nb::module_& m) {
init_ref_iterator<Binary::it_relocations>(bin, "it_relocations");
init_ref_iterator<it_symbols>(bin, "it_symbols");
init_ref_iterator<it_strings_table>(bin, "it_strings_table");
init_ref_iterator<Binary::it_functions>(bin, "it_functions");
bin
.def_prop_ro("header", nb::overload_cast<>(&Binary::header),
@@ -69,6 +78,11 @@ void create<Binary>(nb::module_& m) {
nb::keep_alive<0, 1>()
)
.def_prop_ro("functions",
nb::overload_cast<>(&Binary::functions),
"Iterator over the functions implemented in this COFF",
nb::keep_alive<0, 1>())
.def_prop_ro("string_table",
nb::overload_cast<>(&Binary::string_table),
"Iterator over the COFF's strings"_doc,
@@ -85,6 +99,78 @@ void create<Binary>(nb::module_& m) {
the table. Hence, the first string starts a the offset 4.
)doc"_doc, "offset"_a,
nb::rv_policy::reference_internal)
.def("find_function",
nb::overload_cast<const std::string&>(&Binary::find_function),
"Try to find the function (symbol) with the given name"_doc,
"name"_a, nb::rv_policy::reference_internal
)
.def("find_demangled_function",
nb::overload_cast<const std::string&>(&Binary::find_demangled_function),
"Try to find the function (symbol) with the given **demangled** name"_doc,
"name"_a, nb::rv_policy::reference_internal
)
.def("disassemble", [] (const Binary& self, const Symbol& function) {
auto insts = self.disassemble(function);
return nb::make_iterator<nb::rv_policy::reference_internal>(
nb::type<Binary>(), "instructions_it", insts);
}, "function"_a, nb::keep_alive<0, 1>(),
R"doc(
Disassemble code for the given symbol
.. code-block:: python
func = binary.find_demangled_function("int __cdecl my_function(int, int)");
insts = binary.disassemble("main");
for inst in insts:
print(inst)
.. seealso:: :class:`lief.assembly.Instruction`
)doc"_doc)
.def("disassemble", [] (const Binary& self, const std::string& function) {
auto insts = self.disassemble(function);
return nb::make_iterator<nb::rv_policy::reference_internal>(
nb::type<Binary>(), "instructions_it", insts);
}, "function_name"_a, nb::keep_alive<0, 1>(),
R"doc(
Disassemble code for the given symbol name
.. code-block:: python
insts = binary.disassemble("main");
for inst in insts:
print(inst)
.. seealso:: :class:`lief.assembly.Instruction`
)doc"_doc
)
.def("disassemble_from_bytes",
[] (const Binary& self, const nb::bytes& buffer, uint64_t address) {
auto insts = self.disassemble(
reinterpret_cast<const uint8_t*>(buffer.c_str()),
buffer.size(), address
);
return nb::make_iterator<nb::rv_policy::reference_internal>(
nb::type<Binary>(), "instructions_it", insts);
}, "buffer"_a, "address"_a = 0, nb::keep_alive<0, 1>(), nb::keep_alive<0, 2>(),
R"doc(
Disassemble code from the provided bytes
.. code-block:: python
raw = bytes(binary.get_section(".text").content)
insts = binary.disassemble_from_bytes(raw);
for inst in insts:
print(inst)
.. seealso:: :class:`lief.assembly.Instruction`
)doc"_doc
)
LIEF_DEFAULT_STR(Binary);
}
+1
View File
@@ -163,6 +163,7 @@ void create<Symbol>(nb::module_& m) {
.def_prop_ro("is_undefined", nb::overload_cast<>(&Symbol::is_undefined, nb::const_))
.def_prop_ro("is_function_line_info", nb::overload_cast<>(&Symbol::is_function_line_info, nb::const_))
.def_prop_ro("is_file_record", nb::overload_cast<>(&Symbol::is_file_record, nb::const_))
.def_prop_ro("is_function", nb::overload_cast<>(&Symbol::is_function, nb::const_))
.def_prop_ro("auxiliary_symbols", nb::overload_cast<>(&Symbol::auxiliary_symbols),
"Auxiliary symbols associated with this symbol."_doc)