mirror of
https://github.com/QuasarApp/LIEF.git
synced 2025-04-27 21:04:32 +00:00
Parse PE Rich Header (resolve #15)
This commit is contained in:
parent
f01eae3f73
commit
8ddc71d337
@ -20,6 +20,8 @@ set(LIEF_PYTHON_PE_SRC
|
||||
|
||||
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDataDirectory.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDosHeader.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/objects/pyRichHeader.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/objects/pyRichEntry.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/objects/pyBuilder.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/objects/pyOptionalHeader.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/objects/pyRelocationEntry.cpp"
|
||||
|
@ -93,6 +93,15 @@ void init_PE_Binary_class(py::module& m) {
|
||||
"" RST_CLASS_REF(lief.PE.TLS) " object (if present)",
|
||||
py::return_value_policy::reference)
|
||||
|
||||
.def_property("rich_header",
|
||||
static_cast<RichHeader& (Binary::*)(void)>(&Binary::rich_header),
|
||||
static_cast<void (Binary::*)(const RichHeader&)>(&Binary::rich_header),
|
||||
"" RST_CLASS_REF(lief.PE.RichHeader) " object (if present)",
|
||||
py::return_value_policy::reference)
|
||||
|
||||
.def_property_readonly("has_rich_header", &Binary::has_rich_header,
|
||||
"``True`` if the current binary has a " RST_CLASS_REF(lief.PE.RichHeader) " object")
|
||||
|
||||
.def_property_readonly("has_debug", &Binary::has_debug,
|
||||
"``True`` if the current binary has a " RST_CLASS_REF(lief.PE.Debug) " object")
|
||||
|
||||
|
67
api/python/PE/objects/pyRichEntry.cpp
Normal file
67
api/python/PE/objects/pyRichEntry.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pyPE.hpp"
|
||||
|
||||
#include "LIEF/visitors/Hash.hpp"
|
||||
#include "LIEF/PE/RichEntry.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
template<class T>
|
||||
using getter_t = T (RichEntry::*)(void) const;
|
||||
|
||||
template<class T>
|
||||
using setter_t = void (RichEntry::*)(T);
|
||||
|
||||
void init_PE_RichEntry_class(py::module& m) {
|
||||
py::class_<RichEntry>(m, "RichEntry")
|
||||
.def(py::init<>())
|
||||
.def(py::init<uint16_t, uint16_t, uint32_t>())
|
||||
|
||||
.def_property("id",
|
||||
static_cast<getter_t<uint16_t>>(&RichEntry::id),
|
||||
static_cast<setter_t<uint16_t>>(&RichEntry::id),
|
||||
"Type of the entry")
|
||||
|
||||
.def_property("build_id",
|
||||
static_cast<getter_t<uint16_t>>(&RichEntry::build_id),
|
||||
static_cast<setter_t<uint16_t>>(&RichEntry::build_id),
|
||||
"Builder number of the tool (if any)")
|
||||
|
||||
.def_property("count",
|
||||
static_cast<getter_t<uint32_t>>(&RichEntry::count),
|
||||
static_cast<setter_t<uint32_t>>(&RichEntry::count),
|
||||
"*Occurrence* count")
|
||||
|
||||
.def("__eq__", &RichEntry::operator==)
|
||||
.def("__ne__", &RichEntry::operator!=)
|
||||
.def("__hash__",
|
||||
[] (const RichEntry& entry) {
|
||||
return LIEF::Hash::hash(entry);
|
||||
})
|
||||
|
||||
.def("__str__", [] (const RichEntry& entry)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << entry;
|
||||
std::string str = stream.str();
|
||||
return str;
|
||||
});
|
||||
|
||||
|
||||
|
||||
}
|
76
api/python/PE/objects/pyRichHeader.cpp
Normal file
76
api/python/PE/objects/pyRichHeader.cpp
Normal file
@ -0,0 +1,76 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "pyPE.hpp"
|
||||
|
||||
#include "LIEF/visitors/Hash.hpp"
|
||||
#include "LIEF/PE/RichHeader.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
template<class T>
|
||||
using getter_t = T (RichHeader::*)(void) const;
|
||||
|
||||
template<class T>
|
||||
using setter_t = void (RichHeader::*)(T);
|
||||
|
||||
template<class T>
|
||||
using no_const_getter = T (RichHeader::*)(void);
|
||||
|
||||
void init_PE_RichHeader_class(py::module& m) {
|
||||
py::class_<RichHeader>(m, "RichHeader")
|
||||
.def(py::init<>())
|
||||
.def_property("key",
|
||||
static_cast<getter_t<uint32_t>>(&RichHeader::key),
|
||||
static_cast<setter_t<uint32_t>>(&RichHeader::key),
|
||||
"Key used to encode the header (xor operation)")
|
||||
|
||||
.def_property_readonly("entries",
|
||||
static_cast<no_const_getter<it_rich_entries>>(&RichHeader::entries),
|
||||
"Return binary's " RST_CLASS_REF(lief.PE.RichEntry) " within the header",
|
||||
py::return_value_policy::reference)
|
||||
|
||||
.def("add_entry",
|
||||
static_cast<void (RichHeader::*)(const RichEntry&)>(&RichHeader::add_entry),
|
||||
"Add a new " RST_CLASS_REF(lief.PE.RichEntry) "",
|
||||
"entry"_a)
|
||||
|
||||
.def("add_entry",
|
||||
static_cast<void (RichHeader::*)(uint16_t, uint16_t, uint32_t)>(&RichHeader::add_entry),
|
||||
"Add a new " RST_CLASS_REF(lief.PE.RichEntry) " given its "
|
||||
":attr:`~lief.PE.RichEntry.id`, "
|
||||
":attr:`~lief.PE.RichEntry.build_id`, "
|
||||
":attr:`~lief.PE.RichEntry.count`",
|
||||
"id"_a, "build_id"_a, "count"_a)
|
||||
|
||||
.def("__eq__", &RichHeader::operator==)
|
||||
.def("__ne__", &RichHeader::operator!=)
|
||||
.def("__hash__",
|
||||
[] (const RichHeader& rich_header) {
|
||||
return LIEF::Hash::hash(rich_header);
|
||||
})
|
||||
|
||||
.def("__str__", [] (const RichHeader& rich_header)
|
||||
{
|
||||
std::ostringstream stream;
|
||||
stream << rich_header;
|
||||
std::string str = stream.str();
|
||||
return str;
|
||||
});
|
||||
|
||||
|
||||
|
||||
}
|
@ -37,6 +37,8 @@ void init_PE_module(py::module& m) {
|
||||
init_PE_DataDirectory_class(LIEF_PE_module);
|
||||
init_PE_Header_class(LIEF_PE_module);
|
||||
init_PE_DosHeader_class(LIEF_PE_module);
|
||||
init_PE_RichHeader_class(LIEF_PE_module);
|
||||
init_PE_RichEntry_class(LIEF_PE_module);
|
||||
init_PE_OptionalHeader_class(LIEF_PE_module);
|
||||
init_PE_Section_class(LIEF_PE_module);
|
||||
init_PE_Import_class(LIEF_PE_module);
|
||||
|
@ -31,6 +31,8 @@ void init_PE_Binary_class(py::module&);
|
||||
void init_PE_DataDirectory_class(py::module&);
|
||||
void init_PE_Header_class(py::module&);
|
||||
void init_PE_DosHeader_class(py::module&);
|
||||
void init_PE_RichHeader_class(py::module&);
|
||||
void init_PE_RichEntry_class(py::module&);
|
||||
void init_PE_Section_class(py::module&);
|
||||
void init_PE_OptionalHeader_class(py::module&);
|
||||
void init_PE_Import_class(py::module&);
|
||||
|
@ -53,6 +53,7 @@ void init_LIEF_iterators(py::module& m) {
|
||||
init_ref_iterator<LIEF::PE::it_symbols>(m);
|
||||
init_ref_iterator<LIEF::PE::it_const_crt>(m);
|
||||
init_ref_iterator<LIEF::PE::it_childs>(m);
|
||||
init_ref_iterator<LIEF::PE::it_rich_entries>(m);
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -46,6 +46,8 @@ void init_json_functions(py::module& m) {
|
||||
#if defined(LIEF_PE_MODULE)
|
||||
m.def("to_json", &LIEF::to_json_str<LIEF::PE::Binary, LIEF::PE::JsonVisitor>);
|
||||
m.def("to_json", &LIEF::to_json_str<LIEF::PE::DosHeader, LIEF::PE::JsonVisitor>);
|
||||
m.def("to_json", &LIEF::to_json_str<LIEF::PE::RichHeader, LIEF::PE::JsonVisitor>);
|
||||
m.def("to_json", &LIEF::to_json_str<LIEF::PE::RichEntry, LIEF::PE::JsonVisitor>);
|
||||
m.def("to_json", &LIEF::to_json_str<LIEF::PE::Header, LIEF::PE::JsonVisitor>);
|
||||
m.def("to_json", &LIEF::to_json_str<LIEF::PE::OptionalHeader, LIEF::PE::JsonVisitor>);
|
||||
m.def("to_json", &LIEF::to_json_str<LIEF::PE::DataDirectory, LIEF::PE::JsonVisitor>);
|
||||
|
@ -288,6 +288,21 @@ Lang code item
|
||||
|
||||
----------
|
||||
|
||||
Rich Header
|
||||
***********
|
||||
|
||||
.. doxygenclass:: LIEF::PE::RichHeader
|
||||
:project: lief
|
||||
|
||||
----------
|
||||
|
||||
Rich Entry
|
||||
**********
|
||||
|
||||
.. doxygenclass:: LIEF::PE::RichEntry
|
||||
:project: lief
|
||||
|
||||
----------
|
||||
|
||||
Enums
|
||||
*****
|
||||
|
@ -341,6 +341,26 @@ Lang code item
|
||||
|
||||
----------
|
||||
|
||||
Rich Header
|
||||
***********
|
||||
|
||||
.. autoclass:: lief.PE.RichHeader
|
||||
:members:
|
||||
:inherited-members:
|
||||
:undoc-members:
|
||||
|
||||
----------
|
||||
|
||||
Rich Entry
|
||||
**********
|
||||
|
||||
.. autoclass:: lief.PE.RichEntry
|
||||
:members:
|
||||
:inherited-members:
|
||||
:undoc-members:
|
||||
|
||||
----------
|
||||
|
||||
Enums
|
||||
*****
|
||||
|
||||
|
@ -38,6 +38,10 @@ int main(int argc, char **argv) {
|
||||
std::cout << "== Optional Header ==" << std::endl;
|
||||
std::cout << binary->optional_header() << std::endl;
|
||||
|
||||
if (binary->has_rich_header()) {
|
||||
std::cout << "== Rich Header ==" << std::endl;
|
||||
std::cout << binary->rich_header() << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "== Data Directories ==" << std::endl;
|
||||
for (const DataDirectory& directory : binary->data_directories()) {
|
||||
|
@ -153,24 +153,21 @@ def print_symbols(binary):
|
||||
str(symbol.storage_class).split(".")[-1]))
|
||||
|
||||
def print_imports(binary):
|
||||
if binary.has_imports:
|
||||
print("== Imports ==")
|
||||
imports = binary.imports
|
||||
print("== Imports ==")
|
||||
imports = binary.imports
|
||||
|
||||
for import_ in imports:
|
||||
print(import_.name)
|
||||
entries = import_.entries
|
||||
f_value = " {:<33} 0x{:<14x} 0x{:<14x} 0x{:<16x}"
|
||||
for entry in entries:
|
||||
print(f_value.format(entry.name, entry.data, entry.iat_value, entry.hint))
|
||||
print("")
|
||||
for import_ in imports:
|
||||
print(import_.name)
|
||||
entries = import_.entries
|
||||
f_value = " {:<33} 0x{:<14x} 0x{:<14x} 0x{:<16x}"
|
||||
for entry in entries:
|
||||
print(f_value.format(entry.name, entry.data, entry.iat_value, entry.hint))
|
||||
print("")
|
||||
|
||||
def print_tls(binary):
|
||||
format_str = "{:<33} {:<30}"
|
||||
format_hex = "{:<33} 0x{:<28x}"
|
||||
format_dec = "{:<33} {:<30d}"
|
||||
if not binary.has_tls:
|
||||
return
|
||||
|
||||
print("== TLS ==")
|
||||
tls = binary.tls
|
||||
@ -192,27 +189,25 @@ def print_tls(binary):
|
||||
print("")
|
||||
|
||||
def print_relocations(binary):
|
||||
if binary.has_relocations:
|
||||
relocations = binary.relocations
|
||||
print("== Relocations ==")
|
||||
for relocation in relocations:
|
||||
entries = relocation.entries
|
||||
print(hex(relocation.virtual_address))
|
||||
for entry in entries:
|
||||
print(" 0x{:<8x} {:<8}".format(entry.position, str(entry.type).split(".")[-1]))
|
||||
print("")
|
||||
relocations = binary.relocations
|
||||
print("== Relocations ==")
|
||||
for relocation in relocations:
|
||||
entries = relocation.entries
|
||||
print(hex(relocation.virtual_address))
|
||||
for entry in entries:
|
||||
print(" 0x{:<8x} {:<8}".format(entry.position, str(entry.type).split(".")[-1]))
|
||||
print("")
|
||||
|
||||
def print_export(binary):
|
||||
if binary.has_exports:
|
||||
print("== Exports ==")
|
||||
exports = binary.get_export()
|
||||
entries = exports.entries
|
||||
f_value = "{:<20} 0x{:<10x} 0x{:<10x} 0x{:<6x} 0x{:<6x} 0x{:<10x}"
|
||||
print(f_value.format(exports.name, exports.export_flags, exports.timestamp, exports.major_version, exports.minor_version, exports.ordinal_base))
|
||||
for entry in entries:
|
||||
extern = "[EXTERN]" if entry.is_extern else ""
|
||||
print(" {:<20} 0x{:<6x} 0x{:<10x} {:<13}".format(entry.name[:20], entry.ordinal, entry.address, extern))
|
||||
print("")
|
||||
print("== Exports ==")
|
||||
exports = binary.get_export()
|
||||
entries = exports.entries
|
||||
f_value = "{:<20} 0x{:<10x} 0x{:<10x} 0x{:<6x} 0x{:<6x} 0x{:<10x}"
|
||||
print(f_value.format(exports.name, exports.export_flags, exports.timestamp, exports.major_version, exports.minor_version, exports.ordinal_base))
|
||||
for entry in entries:
|
||||
extern = "[EXTERN]" if entry.is_extern else ""
|
||||
print(" {:<20} 0x{:<6x} 0x{:<10x} {:<13}".format(entry.name[:20], entry.ordinal, entry.address, extern))
|
||||
print("")
|
||||
|
||||
|
||||
def print_debug(binary):
|
||||
@ -220,27 +215,23 @@ def print_debug(binary):
|
||||
format_hex = "{:<33} 0x{:<28x}"
|
||||
format_dec = "{:<33} {:<30d}"
|
||||
|
||||
if binary.has_debug:
|
||||
debug = binary.debug
|
||||
print("== Debug ==")
|
||||
print(format_hex.format("Characteristics:", debug.characteristics))
|
||||
print(format_hex.format("Timestamp:", debug.timestamp))
|
||||
print(format_dec.format("Major version:", debug.major_version))
|
||||
print(format_dec.format("Minor version:", debug.minor_version))
|
||||
print(format_str.format("type:", str(debug.type).split(".")[-1]))
|
||||
print(format_hex.format("Size of data:", debug.sizeof_data))
|
||||
print(format_hex.format("Address of raw data:", debug.addressof_rawdata))
|
||||
print(format_hex.format("Pointer to raw data:", debug.pointerto_rawdata))
|
||||
print("")
|
||||
debug = binary.debug
|
||||
print("== Debug ==")
|
||||
print(format_hex.format("Characteristics:", debug.characteristics))
|
||||
print(format_hex.format("Timestamp:", debug.timestamp))
|
||||
print(format_dec.format("Major version:", debug.major_version))
|
||||
print(format_dec.format("Minor version:", debug.minor_version))
|
||||
print(format_str.format("type:", str(debug.type).split(".")[-1]))
|
||||
print(format_hex.format("Size of data:", debug.sizeof_data))
|
||||
print(format_hex.format("Address of raw data:", debug.addressof_rawdata))
|
||||
print(format_hex.format("Pointer to raw data:", debug.pointerto_rawdata))
|
||||
print("")
|
||||
|
||||
def print_signature(binary):
|
||||
format_str = "{:<33} {:<30}"
|
||||
format_hex = "{:<33} 0x{:<28x}"
|
||||
format_dec = "{:<33} {:<30d}"
|
||||
|
||||
if not binary.has_signature:
|
||||
return
|
||||
|
||||
signature = binary.signature
|
||||
print("== Signature ==")
|
||||
print(format_dec.format("Version:", signature.version))
|
||||
@ -277,10 +268,18 @@ def print_signature(binary):
|
||||
print(format_str.format("Issuer:", issuer_str))
|
||||
print(format_str.format("Digest Algorithm:", oid_to_string(signer_info.digest_algorithm)))
|
||||
print(format_str.format("Signature algorithm:", oid_to_string(signer_info.signature_algorithm)))
|
||||
#print(format_str.format("Program name:", signer_info.authenticated_attributes.program_name))
|
||||
print(format_str.format("Program name:", signer_info.authenticated_attributes.program_name))
|
||||
print(format_str.format("Url:", signer_info.authenticated_attributes.more_info))
|
||||
print("")
|
||||
|
||||
def print_rich_header(binary):
|
||||
print("== Rich Header ==")
|
||||
header = binary.rich_header
|
||||
print("Key: 0x{:08x}".format(header.key))
|
||||
|
||||
for entry in header.entries:
|
||||
print(" - ID: {:04x} Build ID: {:04x} Count: {:d}".format(entry.id, entry.build_id, entry.count))
|
||||
|
||||
|
||||
def main():
|
||||
optparser = OptionParser(
|
||||
@ -316,6 +315,10 @@ def main():
|
||||
action='store_true', dest='show_relocs',
|
||||
help='Display the relocations (if present)')
|
||||
|
||||
optparser.add_option('-R', '--rich-header',
|
||||
action='store_true', dest='show_richheader',
|
||||
help='Display the Rich Header')
|
||||
|
||||
optparser.add_option('-S', '--section-headers', '--sections',
|
||||
action='store_true', dest='show_section_header',
|
||||
help="Display the sections' headers")
|
||||
@ -354,10 +357,10 @@ def main():
|
||||
if options.show_headers or options.show_all:
|
||||
print_header(binary)
|
||||
|
||||
if options.show_imports or options.show_all:
|
||||
if (options.show_imports or options.show_all) and binary.has_imports:
|
||||
print_imports(binary)
|
||||
|
||||
if options.show_relocs or options.show_all:
|
||||
if (options.show_relocs or options.show_all) and binary.has_relocations:
|
||||
print_relocations(binary)
|
||||
|
||||
if options.show_section_header or options.show_all:
|
||||
@ -366,17 +369,20 @@ def main():
|
||||
if options.show_symbols or options.show_all:
|
||||
print_symbols(binary)
|
||||
|
||||
if options.show_tls or options.show_all:
|
||||
if (options.show_tls or options.show_all) and binary.has_tls:
|
||||
print_tls(binary)
|
||||
|
||||
if options.show_export or options.show_all:
|
||||
if (options.show_export or options.show_all) and binary.has_exports:
|
||||
print_export(binary)
|
||||
|
||||
if options.show_debug or options.show_all:
|
||||
if (options.show_debug or options.show_all) and binary.has_debug:
|
||||
print_debug(binary)
|
||||
|
||||
if options.show_signature or options.show_all:
|
||||
if (options.show_signature or options.show_all) and binary.has_signature:
|
||||
print_signature(binary)
|
||||
|
||||
if (options.show_richheader or options.show_all) and binary.has_rich_header:
|
||||
print_rich_header(binary)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "LIEF/PE/Header.hpp"
|
||||
#include "LIEF/PE/OptionalHeader.hpp"
|
||||
#include "LIEF/PE/DosHeader.hpp"
|
||||
#include "LIEF/PE/RichHeader.hpp"
|
||||
#include "LIEF/PE/Section.hpp"
|
||||
#include "LIEF/PE/Import.hpp"
|
||||
#include "LIEF/PE/DataDirectory.hpp"
|
||||
@ -102,7 +103,6 @@ class DLL_PUBLIC Binary : public LIEF::Binary {
|
||||
//! @brief Compute the size of all headers
|
||||
uint32_t get_sizeof_headers(void) const;
|
||||
|
||||
|
||||
//! @brief Return a reference to the TLS object
|
||||
TLS& tls(void);
|
||||
const TLS& tls(void) const;
|
||||
@ -254,6 +254,19 @@ class DLL_PUBLIC Binary : public LIEF::Binary {
|
||||
//! @brief Update the DOS stub content
|
||||
void dos_stub(const std::vector<uint8_t>& content);
|
||||
|
||||
// Rich Header
|
||||
// -----------
|
||||
|
||||
//! @brief Return a reference to the RichHeader object
|
||||
RichHeader& rich_header(void);
|
||||
const RichHeader& rich_header(void) const;
|
||||
|
||||
//! @brief Set a RichHeader object in the current Binary
|
||||
void rich_header(const RichHeader& rich_header);
|
||||
|
||||
//! @brief Check if the current binary has a RichHeader object
|
||||
bool has_rich_header(void) const;
|
||||
|
||||
// =========================
|
||||
// Methods to manage Imports
|
||||
// =========================
|
||||
@ -365,9 +378,11 @@ class DLL_PUBLIC Binary : public LIEF::Binary {
|
||||
|
||||
PE_TYPE type_;
|
||||
DosHeader dos_header_;
|
||||
RichHeader rich_header_;
|
||||
Header header_;
|
||||
OptionalHeader optional_header_;
|
||||
|
||||
bool has_rich_header_;
|
||||
bool has_tls_;
|
||||
bool has_imports_;
|
||||
bool has_signature_;
|
||||
|
@ -85,6 +85,7 @@ class DLL_PUBLIC Parser : public LIEF::Parser {
|
||||
void build_signature(void);
|
||||
void build_overlay(void);
|
||||
void build_dos_stub(void);
|
||||
void build_rich_header(void);
|
||||
|
||||
ResourceNode* build_resource_node(
|
||||
const pe_resource_directory_table *directory_table,
|
||||
|
68
include/LIEF/PE/RichEntry.hpp
Normal file
68
include/LIEF/PE/RichEntry.hpp
Normal file
@ -0,0 +1,68 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_PE_RICH_ENTRY_H_
|
||||
#define LIEF_PE_RICH_ENTRY_H_
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
|
||||
#include "LIEF/Visitable.hpp"
|
||||
#include "LIEF/visibility.h"
|
||||
|
||||
#include "LIEF/PE/Structures.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
class DLL_PUBLIC RichEntry : public Visitable {
|
||||
public:
|
||||
|
||||
RichEntry(void);
|
||||
RichEntry(uint16_t id, uint16_t build_id, uint32_t count);
|
||||
RichEntry(const RichEntry& copy);
|
||||
RichEntry& operator=(const RichEntry& copy);
|
||||
virtual ~RichEntry(void);
|
||||
|
||||
//! @brief Entry type
|
||||
uint16_t id(void) const;
|
||||
|
||||
//! @brief Builder number of the tool (if any)
|
||||
uint16_t build_id(void) const;
|
||||
|
||||
//! @brief *Occurrence* count.
|
||||
uint32_t count(void) const;
|
||||
|
||||
void id(uint16_t id);
|
||||
void build_id(uint16_t build_id);
|
||||
void count(uint32_t count);
|
||||
|
||||
virtual void accept(Visitor& visitor) const override;
|
||||
|
||||
bool operator==(const RichEntry& rhs) const;
|
||||
bool operator!=(const RichEntry& rhs) const;
|
||||
|
||||
DLL_PUBLIC friend std::ostream& operator<<(std::ostream& os, const RichEntry& rich_entry);
|
||||
|
||||
private:
|
||||
uint16_t id_;
|
||||
uint16_t build_id_;
|
||||
uint32_t count_;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
70
include/LIEF/PE/RichHeader.hpp
Normal file
70
include/LIEF/PE/RichHeader.hpp
Normal file
@ -0,0 +1,70 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#ifndef LIEF_PE_RICH_HEADER_H_
|
||||
#define LIEF_PE_RICH_HEADER_H_
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
|
||||
#include "LIEF/Visitable.hpp"
|
||||
#include "LIEF/visibility.h"
|
||||
|
||||
#include "LIEF/PE/Structures.hpp"
|
||||
#include "LIEF/PE/type_traits.hpp"
|
||||
|
||||
#include "LIEF/PE/RichEntry.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
class DLL_PUBLIC RichHeader : public Visitable {
|
||||
public:
|
||||
|
||||
RichHeader(void);
|
||||
RichHeader(const RichHeader& copy);
|
||||
RichHeader& operator=(const RichHeader& copy);
|
||||
virtual ~RichHeader(void);
|
||||
|
||||
//! @brief Key used to encode the header (xor operation)
|
||||
uint32_t key(void) const;
|
||||
|
||||
//! @brief Return an iterator on the PE::RichEntry within the header
|
||||
it_rich_entries entries(void);
|
||||
|
||||
it_const_rich_entries entries(void) const;
|
||||
|
||||
void key(uint32_t key);
|
||||
|
||||
//! @brief Add a new PE::RichEntry
|
||||
void add_entry(const RichEntry& entry);
|
||||
void add_entry(uint16_t id, uint16_t build_id, uint32_t count);
|
||||
|
||||
virtual void accept(Visitor& visitor) const override;
|
||||
|
||||
bool operator==(const RichHeader& rhs) const;
|
||||
bool operator!=(const RichHeader& rhs) const;
|
||||
|
||||
DLL_PUBLIC friend std::ostream& operator<<(std::ostream& os, const RichHeader& rich_header);
|
||||
|
||||
private:
|
||||
uint32_t key_;
|
||||
rich_entries_t entries_;
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -4,6 +4,11 @@ static const int32_t MaxNumberOfSections16 = 65279;
|
||||
//! The PE signature bytes that follows the DOS stub header.
|
||||
static const char PE_Magic[] = { 'P', 'E', '\0', '\0' };
|
||||
|
||||
static const char Rich_Magic[] = {'R', 'i', 'c', 'h'};
|
||||
static const char DanS_Magic[] = {'D', 'a', 'n', 'S'};
|
||||
|
||||
static const uint32_t DanS_Magic_number = 0x536E6144;
|
||||
|
||||
static const char BigObjMagic[] = {
|
||||
'\xc7', '\xa1', '\xba', '\xd1', '\xee', '\xba', '\xa9', '\x4b',
|
||||
'\xaf', '\x20', '\xfa', '\xf6', '\x6a', '\xa4', '\xdc', '\xb8',
|
||||
|
@ -25,6 +25,7 @@ class DataDirectory;
|
||||
class Relocation;
|
||||
class Symbol;
|
||||
class ExportEntry;
|
||||
class RichEntry;
|
||||
|
||||
class Import;
|
||||
class ImportEntry;
|
||||
@ -73,6 +74,10 @@ using dialog_items_t = std::vector<ResourceDialogItem>;
|
||||
using it_dialog_items = ref_iterator<dialog_items_t&>;
|
||||
using it_const_dialog_items = const_ref_iterator<const dialog_items_t&>;
|
||||
|
||||
using rich_entries_t = std::vector<RichEntry>;
|
||||
using it_rich_entries = ref_iterator<rich_entries_t&>;
|
||||
using it_const_rich_entries = const_ref_iterator<const rich_entries_t&>;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -69,6 +69,8 @@ class Binary;
|
||||
class DosHeader;
|
||||
class Header;
|
||||
class OptionalHeader;
|
||||
class RichHeader;
|
||||
class RichEntry;
|
||||
|
||||
class DataDirectory;
|
||||
class Section;
|
||||
@ -252,6 +254,12 @@ class DLL_PUBLIC Visitor {
|
||||
//! @brief Method to visit a LIEF::PE::DosHeader
|
||||
virtual void visit(const PE::DosHeader& dos_header);
|
||||
|
||||
//! @brief Method to visit a LIEF::PE:RichHeader
|
||||
virtual void visit(const PE::RichHeader& rich_header);
|
||||
|
||||
//! @brief Method to visit a LIEF::PE:RichEntry
|
||||
virtual void visit(const PE::RichEntry& rich_entry);
|
||||
|
||||
//! @brief Method to visit a LIEF::PE::Header
|
||||
virtual void visit(const PE::Header& header);
|
||||
|
||||
|
@ -30,6 +30,8 @@ class DLL_PUBLIC JsonVisitor : public LIEF::JsonVisitor {
|
||||
|
||||
virtual void visit(const Binary& Binary) override;
|
||||
virtual void visit(const DosHeader& dos_header) override;
|
||||
virtual void visit(const RichHeader& rich_header) override;
|
||||
virtual void visit(const RichEntry& rich_entry) override;
|
||||
virtual void visit(const Header& header) override;
|
||||
virtual void visit(const OptionalHeader& optional_header) override;
|
||||
virtual void visit(const DataDirectory& data_directory) override;
|
||||
|
@ -49,8 +49,10 @@ static const std::map<MACHINE_TYPES, std::pair<ARCHITECTURES, std::set<MODES>>>
|
||||
|
||||
Binary::Binary(void) :
|
||||
dos_header_{},
|
||||
rich_header_{},
|
||||
header_{},
|
||||
optional_header_{},
|
||||
has_rich_header_{false},
|
||||
has_tls_{false},
|
||||
has_imports_{false},
|
||||
has_signature_{false},
|
||||
@ -266,6 +268,10 @@ const DataDirectory& Binary::data_directory(DATA_DIRECTORY index) const {
|
||||
}
|
||||
}
|
||||
|
||||
bool Binary::has_rich_header(void) const {
|
||||
return this->has_rich_header_;
|
||||
}
|
||||
|
||||
bool Binary::has_tls(void) const {
|
||||
return this->has_tls_;
|
||||
}
|
||||
@ -1034,6 +1040,24 @@ void Binary::dos_stub(const std::vector<uint8_t>& content) {
|
||||
this->dos_stub_ = content;
|
||||
}
|
||||
|
||||
// Rich Header
|
||||
// -----------
|
||||
RichHeader& Binary::rich_header(void) {
|
||||
return const_cast<RichHeader&>(static_cast<const Binary*>(this)->rich_header());
|
||||
}
|
||||
|
||||
const RichHeader& Binary::rich_header(void) const {
|
||||
if (not this->has_rich_header()) {
|
||||
throw not_found("Rich Header not found");
|
||||
}
|
||||
return this->rich_header_;
|
||||
}
|
||||
|
||||
void Binary::rich_header(const RichHeader& rich_header) {
|
||||
this->rich_header_ = rich_header;
|
||||
this->has_rich_header_ = true;
|
||||
}
|
||||
|
||||
// Resource manager
|
||||
// ===============
|
||||
|
||||
@ -1088,6 +1112,10 @@ void Binary::accept(Visitor& visitor) const {
|
||||
visitor(this->tls());
|
||||
}
|
||||
|
||||
if (this->has_rich_header()) {
|
||||
visitor(this->rich_header());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -1111,6 +1139,14 @@ std::ostream& Binary::print(std::ostream& os) const {
|
||||
os << std::endl;
|
||||
|
||||
|
||||
if (this->has_rich_header()) {
|
||||
os << "Rich Header" << std::endl;
|
||||
os << "===========" << std::endl;
|
||||
os << this->rich_header() << std::endl;
|
||||
os << std::endl;
|
||||
}
|
||||
|
||||
|
||||
os << "Header" << std::endl;
|
||||
os << "======" << std::endl;
|
||||
|
||||
|
@ -6,6 +6,8 @@ set(LIEF_PE_SRC
|
||||
"${CMAKE_CURRENT_LIST_DIR}/EnumToString.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/Header.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/DosHeader.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/RichHeader.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/RichEntry.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/ResourceDirectory.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/Import.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/ResourceNode.cpp"
|
||||
@ -64,6 +66,8 @@ set(LIEF_PE_INCLUDE_FILES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/DataDirectory.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/Debug.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/DosHeader.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/RichHeader.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/RichEntry.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/EnumToString.hpp"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/include/LIEF/PE/enums.hpp" # Do we want to do this since it's autogenerated?
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/Export.hpp"
|
||||
|
@ -96,6 +96,66 @@ void Parser::build_dos_stub(void) {
|
||||
}
|
||||
|
||||
|
||||
void Parser::build_rich_header(void) {
|
||||
LOG(DEBUG) << "Parsing Rich Header";
|
||||
const std::vector<uint8_t>& dos_stub = this->binary_->dos_stub();
|
||||
VectorStream stream{dos_stub};
|
||||
auto&& it_rich = std::search(
|
||||
std::begin(dos_stub),
|
||||
std::end(dos_stub),
|
||||
std::begin(Rich_Magic),
|
||||
std::end(Rich_Magic));
|
||||
|
||||
if (it_rich == std::end(dos_stub)) {
|
||||
LOG(DEBUG) << "Rich header not found";
|
||||
return;
|
||||
}
|
||||
|
||||
this->binary_->has_rich_header_ = true;
|
||||
|
||||
const uint64_t end_offset_rich_header = std::distance(std::begin(dos_stub), it_rich);
|
||||
LOG(DEBUG) << "Offset to rich header: " << std::hex << end_offset_rich_header;
|
||||
|
||||
const uint32_t xor_key = stream.read_integer<uint32_t>(end_offset_rich_header + sizeof(Rich_Magic));
|
||||
this->binary_->rich_header().key(xor_key);
|
||||
LOG(DEBUG) << "XOR Key: " << std::hex << xor_key;
|
||||
|
||||
|
||||
uint64_t curent_offset = end_offset_rich_header - sizeof(Rich_Magic);
|
||||
std::vector<uint32_t> values;
|
||||
values.reserve(dos_stub.size() / sizeof(uint32_t));
|
||||
|
||||
uint32_t count = 0;
|
||||
uint32_t value = 0;
|
||||
|
||||
while (value != DanS_Magic_number and count != DanS_Magic_number) {
|
||||
count = stream.read_integer<uint32_t>(curent_offset) ^ xor_key;
|
||||
curent_offset -= sizeof(uint32_t);
|
||||
|
||||
value = stream.read_integer<uint32_t>(curent_offset) ^ xor_key;
|
||||
curent_offset -= sizeof(uint32_t);
|
||||
|
||||
if (value == DanS_Magic_number or count == DanS_Magic_number) {
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t build_number = value & 0xFFFF;
|
||||
uint16_t id = (value >> 16) & 0xFFFF;
|
||||
|
||||
LOG(DEBUG) << "ID: " << std::hex << id << " "
|
||||
<< "Build Number: " << std::hex << build_number << " "
|
||||
<< "Count: " << std::dec << count;
|
||||
|
||||
this->binary_->rich_header().add_entry(id, build_number, count);
|
||||
}
|
||||
|
||||
LOG(DEBUG) << this->binary_->rich_header();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
|
@ -31,6 +31,12 @@ void Parser::build(void) {
|
||||
|
||||
this->build_dos_stub();
|
||||
|
||||
try {
|
||||
this->build_rich_header();
|
||||
} catch (const corrupted& e) {
|
||||
LOG(WARNING) << e.what();
|
||||
}
|
||||
|
||||
LOG(DEBUG) << "[+] Decomposing Sections";
|
||||
|
||||
try {
|
||||
|
91
src/PE/RichEntry.cpp
Normal file
91
src/PE/RichEntry.cpp
Normal file
@ -0,0 +1,91 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <iomanip>
|
||||
|
||||
#include "LIEF/visitors/Hash.hpp"
|
||||
|
||||
#include "LIEF/PE/RichEntry.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
RichEntry::~RichEntry(void) = default;
|
||||
RichEntry::RichEntry(const RichEntry& copy) = default;
|
||||
RichEntry& RichEntry::operator=(const RichEntry& copy) = default;
|
||||
|
||||
RichEntry::RichEntry(void) :
|
||||
id_{0},
|
||||
build_id_{0},
|
||||
count_{0}
|
||||
{}
|
||||
|
||||
RichEntry::RichEntry(uint16_t id, uint16_t build_id, uint32_t count) :
|
||||
id_{id},
|
||||
build_id_{build_id},
|
||||
count_{count}
|
||||
{}
|
||||
|
||||
|
||||
uint16_t RichEntry::id(void) const {
|
||||
return this->id_;
|
||||
}
|
||||
|
||||
uint16_t RichEntry::build_id(void) const {
|
||||
return this->build_id_;
|
||||
}
|
||||
|
||||
uint32_t RichEntry::count(void) const {
|
||||
return this->count_;
|
||||
}
|
||||
|
||||
void RichEntry::id(uint16_t id) {
|
||||
this->id_ = id;
|
||||
}
|
||||
|
||||
void RichEntry::build_id(uint16_t build_id) {
|
||||
this->build_id_ = build_id;
|
||||
}
|
||||
|
||||
void RichEntry::count(uint32_t count) {
|
||||
this->count_ = count;
|
||||
}
|
||||
|
||||
void RichEntry::accept(LIEF::Visitor& visitor) const {
|
||||
visitor.visit(this->id());
|
||||
visitor.visit(this->build_id());
|
||||
visitor.visit(this->count());
|
||||
}
|
||||
|
||||
bool RichEntry::operator==(const RichEntry& rhs) const {
|
||||
size_t hash_lhs = Hash::hash(*this);
|
||||
size_t hash_rhs = Hash::hash(rhs);
|
||||
return hash_lhs == hash_rhs;
|
||||
}
|
||||
|
||||
bool RichEntry::operator!=(const RichEntry& rhs) const {
|
||||
return not (*this == rhs);
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const RichEntry& rich_entry) {
|
||||
os << "ID: 0x" << std::hex << std::setw(4) << std::setfill('0') << rich_entry.id() << " ";
|
||||
os << "Build ID: 0x" << std::hex << std::setw(4) << std::setfill('0') << rich_entry.build_id() << " ";
|
||||
os << "Count: " << std::dec << std::setw(0) << rich_entry.count();
|
||||
return os;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
85
src/PE/RichHeader.cpp
Normal file
85
src/PE/RichHeader.cpp
Normal file
@ -0,0 +1,85 @@
|
||||
/* Copyright 2017 R. Thomas
|
||||
* Copyright 2017 Quarkslab
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include <iomanip>
|
||||
|
||||
#include "LIEF/visitors/Hash.hpp"
|
||||
|
||||
#include "LIEF/PE/RichHeader.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace PE {
|
||||
|
||||
RichHeader::~RichHeader(void) = default;
|
||||
RichHeader::RichHeader(const RichHeader& copy) = default;
|
||||
RichHeader& RichHeader::operator=(const RichHeader& copy) = default;
|
||||
|
||||
RichHeader::RichHeader(void) :
|
||||
key_{0},
|
||||
entries_{}
|
||||
{}
|
||||
|
||||
uint32_t RichHeader::key(void) const {
|
||||
return this->key_;
|
||||
}
|
||||
|
||||
it_rich_entries RichHeader::entries(void) {
|
||||
return {this->entries_};
|
||||
}
|
||||
|
||||
it_const_rich_entries RichHeader::entries(void) const {
|
||||
return {this->entries_};
|
||||
}
|
||||
|
||||
void RichHeader::key(uint32_t key) {
|
||||
this->key_ = key;
|
||||
}
|
||||
|
||||
void RichHeader::add_entry(const RichEntry& entry) {
|
||||
this->entries_.push_back(entry);
|
||||
}
|
||||
|
||||
void RichHeader::add_entry(uint16_t id, uint16_t build_id, uint32_t count) {
|
||||
this->entries_.emplace_back(id, build_id, count);
|
||||
}
|
||||
|
||||
void RichHeader::accept(LIEF::Visitor& visitor) const {
|
||||
visitor.visit(this->key());
|
||||
for (const RichEntry& entry : this->entries()) {
|
||||
visitor(entry);
|
||||
}
|
||||
}
|
||||
|
||||
bool RichHeader::operator==(const RichHeader& rhs) const {
|
||||
size_t hash_lhs = Hash::hash(*this);
|
||||
size_t hash_rhs = Hash::hash(rhs);
|
||||
return hash_lhs == hash_rhs;
|
||||
}
|
||||
|
||||
bool RichHeader::operator!=(const RichHeader& rhs) const {
|
||||
return not (*this == rhs);
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const RichHeader& rich_header) {
|
||||
os << "Key: " << std::hex << rich_header.key() << std::endl;
|
||||
for (const RichEntry& entry : rich_header.entries()) {
|
||||
os << " - " << entry << std::endl;
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -158,6 +158,14 @@ void Visitor::visit(const PE::DosHeader& dos_header) {
|
||||
dos_header.accept(*this);
|
||||
}
|
||||
|
||||
void Visitor::visit(const PE::RichHeader& rich_header) {
|
||||
rich_header.accept(*this);
|
||||
}
|
||||
|
||||
void Visitor::visit(const PE::RichEntry& rich_entry) {
|
||||
rich_entry.accept(*this);
|
||||
}
|
||||
|
||||
void Visitor::visit(const PE::Header& header) {
|
||||
header.accept(*this);
|
||||
}
|
||||
|
@ -29,6 +29,13 @@ void JsonVisitor::visit(const Binary& binary) {
|
||||
JsonVisitor dos_header_visitor;
|
||||
dos_header_visitor(binary.dos_header());
|
||||
|
||||
// Rich Header
|
||||
if (binary.has_rich_header()) {
|
||||
JsonVisitor visitor;
|
||||
visitor(binary.rich_header());
|
||||
this->node_["rich_header"] = visitor.get();
|
||||
}
|
||||
|
||||
// PE header
|
||||
JsonVisitor header_visitor;
|
||||
header_visitor(binary.header());
|
||||
@ -121,7 +128,7 @@ void JsonVisitor::visit(const Binary& binary) {
|
||||
// Signature
|
||||
if (binary.has_signature()) {
|
||||
JsonVisitor visitor;
|
||||
binary.signature().accept(visitor);
|
||||
visitor(binary.signature());
|
||||
this->node_["signature"] = visitor.get();
|
||||
}
|
||||
|
||||
@ -151,6 +158,24 @@ void JsonVisitor::visit(const DosHeader& dos_header) {
|
||||
this->node_["addressof_new_exeheader"] = dos_header.addressof_new_exeheader();
|
||||
}
|
||||
|
||||
void JsonVisitor::visit(const RichHeader& rich_header) {
|
||||
std::vector<json> entries;
|
||||
for (const RichEntry& entry : rich_header.entries()) {
|
||||
JsonVisitor visitor;
|
||||
visitor(entry);
|
||||
entries.emplace_back(visitor.get());
|
||||
}
|
||||
|
||||
this->node_["key"] = rich_header.key();
|
||||
this->node_["entries"] = entries;
|
||||
}
|
||||
|
||||
void JsonVisitor::visit(const RichEntry& rich_entry) {
|
||||
this->node_["id"] = rich_entry.id();
|
||||
this->node_["build_id"] = rich_entry.build_id();
|
||||
this->node_["count"] = rich_entry.count();
|
||||
}
|
||||
|
||||
void JsonVisitor::visit(const Header& header) {
|
||||
this->node_["signature"] = header.signature();
|
||||
this->node_["machine"] = to_string(header.machine());
|
||||
|
Loading…
x
Reference in New Issue
Block a user