Skip to content

Commit

Permalink
Serialize PE object into json (resolve #18)
Browse files Browse the repository at this point in the history
  • Loading branch information
romainthomas committed Jun 14, 2017
1 parent 8473c8e commit 673f5a3
Show file tree
Hide file tree
Showing 19 changed files with 954 additions and 28 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ set(LIEF_SRC
"${CMAKE_CURRENT_SOURCE_DIR}/src/BinaryStream/BinaryStream.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/BinaryStream/VectorStream.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/visitors/elf_json.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/visitors/pe_json.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/visitors/json.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/visitors/hash.cpp")

Expand Down
36 changes: 36 additions & 0 deletions api/python/pyJson.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,42 @@ void init_json_functions(py::module& m) {
m.def("to_json", &LIEF::to_json_str<LIEF::ELF::SymbolVersionDefinition, LIEF::ELF::JsonVisitor>);
#endif


#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::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>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::Section, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::Relocation, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::RelocationEntry, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::Export, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::ExportEntry, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::TLS, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::Symbol, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::Debug, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::Import, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::ImportEntry, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::ResourceNode, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::ResourceData, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::ResourceDirectory, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::ResourcesManager, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::ResourceVersion, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::ResourceStringFileInfo, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::ResourceFixedFileInfo, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::ResourceVarFileInfo, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::LangCodeItem, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::ResourceIcon, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::ResourceDialog, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::ResourceDialogItem, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::Signature, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::x509, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::SignerInfo, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::ContentInfo, LIEF::PE::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::PE::AuthenticatedAttributes, LIEF::PE::JsonVisitor>);
#endif

m.def("to_json", &LIEF::to_json_str<LIEF::Binary>);
m.def("abstract_to_json", &LIEF::to_json_str<LIEF::Binary>);
m.def("to_json", &LIEF::to_json_str<LIEF::Header>);
Expand Down
43 changes: 43 additions & 0 deletions examples/python/pe_json.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Description
# -----------
# Print information about a PE binary in the JSON format
#
# python pe_json.py C:\\windows\\explorer.exe
#  
# {
# "dynamic_entries": [
# {
# "library": "libcap.so.2",
# "tag": "NEEDED",
# "value": 1
# },
# {
# "library": "libc.so.6",
# "tag": "NEEDED",
# "value": 74
# },
# ...


import argparse
import sys
import lief
import json



def main():
parser = argparse.ArgumentParser()
parser.add_argument('binary', help='PE binary')
args = parser.parse_args()

binary = lief.parse(args.binary)
json_data = json.loads(lief.to_json(binary))
print(json.dumps(json_data, sort_keys=True, indent=4))

if __name__ == "__main__":
sys.exit(main())

1 change: 1 addition & 0 deletions include/LIEF/PE.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "LIEF/PE/Parser.hpp"
#include "LIEF/PE/Builder.hpp"
#include "LIEF/PE/Binary.hpp"
#include "LIEF/PE/signature/OIDToString.hpp"

#include "LIEF/PE/utils.hpp"

Expand Down
2 changes: 1 addition & 1 deletion include/LIEF/PE/DataDirectory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,4 @@ class DLL_PUBLIC DataDirectory : public Visitable {
}
}

#endif /* DATADIRECTORY_H_ */
#endif /* LIEF_PE_DATADIRECTORY_H_ */
10 changes: 8 additions & 2 deletions include/LIEF/PE/ResourcesManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <set>

#include "LIEF/visibility.h"
#include "LIEF/Visitable.hpp"
#include "LIEF/BinaryStream/VectorStream.hpp"

#include "LIEF/PE/type_traits.hpp"
Expand All @@ -34,14 +35,14 @@ namespace PE {

//! @brief The Resource Manager provides an enhanced API to
//! manipulate the resource tree.
class DLL_PUBLIC ResourcesManager {
class DLL_PUBLIC ResourcesManager : public Visitable {
public:
ResourcesManager(void) = delete;
ResourcesManager(ResourceNode *rsrc);

ResourcesManager(const ResourcesManager&);
ResourcesManager& operator=(const ResourcesManager&);
~ResourcesManager(void);
virtual ~ResourcesManager(void);

// Enhancemed API to explore resource tree
// =======================================
Expand Down Expand Up @@ -115,6 +116,11 @@ class DLL_PUBLIC ResourcesManager {
//! @brief Print the resource tree to the given depth
std::string print(uint32_t depth = 0) const;

virtual void accept(Visitor& visitor) const override;

bool operator==(const ResourcesManager& rhs) const;
bool operator!=(const ResourcesManager& rhs) const;

DLL_PUBLIC friend std::ostream& operator<<(std::ostream& os, const ResourcesManager& m);

private:
Expand Down
3 changes: 1 addition & 2 deletions include/LIEF/PE/signature/x509.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class DLL_PUBLIC x509 : public Visitable {

public:
//! @brief Tuple (Year, Month, Day, Hour, Minute, Second)
using date_t = std::tuple<uint32_t, uint32_t, uint32_t, uint32_t, uint32_t, uint32_t>;
using date_t = std::array<int32_t, 6>;

x509(mbedtls_x509_crt* ca);
x509(const x509& other);
Expand Down Expand Up @@ -64,7 +64,6 @@ class DLL_PUBLIC x509 : public Visitable {
//! @brief Subject informations
std::string subject(void) const;


virtual void accept(Visitor& visitor) const override;

virtual ~x509(void);
Expand Down
34 changes: 34 additions & 0 deletions include/LIEF/Visitor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@
#include <string>
#include <functional>
#include <iostream>
#include <utility>

#include "LIEF/visibility.h"

#include "LIEF/PE/signature/types.hpp"

namespace LIEF {

// Forward declarations
Expand Down Expand Up @@ -87,6 +90,7 @@ class ResourceNode;
class ResourceData;
class ResourceDirectory;

class ResourcesManager;
class ResourceVersion;
class ResourceStringFileInfo;
class ResourceFixedFileInfo;
Expand All @@ -97,6 +101,11 @@ class ResourceIcon;
class ResourceDialog;
class ResourceDialogItem;

class Signature;
class x509;
class SignerInfo;
class ContentInfo;
class AuthenticatedAttributes;
}

namespace MachO {
Expand Down Expand Up @@ -258,6 +267,9 @@ class DLL_PUBLIC Visitor {
//! @brief Method to visit a LIEF::PE::Symbol
virtual void visit(const PE::Symbol& symbol);

//! @brief Method to visit a LIEF::PE::Section
virtual void visit(const PE::Section& section);

//! @brief Method to visit a LIEF::PE::Relocation
virtual void visit(const PE::Relocation& relocation);

Expand Down Expand Up @@ -288,6 +300,9 @@ class DLL_PUBLIC Visitor {
//! @brief Method to visit a LIEF::PE::ResourceDirectory
virtual void visit(const PE::ResourceDirectory& directory);

//! @brief Method to visit a LIEF::PE::ResourceVersion
virtual void visit(const PE::ResourcesManager& resources_manager);

//! @brief Method to visit a LIEF::PE::ResourceVersion
virtual void visit(const PE::ResourceVersion& resource_version);

Expand All @@ -312,6 +327,24 @@ class DLL_PUBLIC Visitor {
//! @brief Method to visit a LIEF::PE::ResourceDialogItem
virtual void visit(const PE::ResourceDialogItem& resource_dialogitem);

//! @brief Method to visit a LIEF::PE::Signature
virtual void visit(const PE::Signature& signature);

//! @brief Method to visit a LIEF::PE::x509
virtual void visit(const PE::x509& x509);

//! @brief Method to visit a LIEF::PE::SignerInfo
virtual void visit(const PE::SignerInfo& signer_info);

//! @brief Method to visit a LIEF::PE::ContentInfo
virtual void visit(const PE::ContentInfo& content_info);

//! @brief Method to visit a LIEF::PE::AuthenticatedAttributes
virtual void visit(const PE::AuthenticatedAttributes& authenticated_attributes);

//! @brief Method to visit a LIEF::PE::issuer_t
virtual void visit(const PE::issuer_t& issuer);

// MachO part
// ==========

Expand Down Expand Up @@ -357,6 +390,7 @@ class DLL_PUBLIC Visitor {


private:

std::set<size_t> visited_;
};

Expand Down
2 changes: 2 additions & 0 deletions include/LIEF/to_json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@

#include "LIEF/visitors/json.hpp"
#include "LIEF/visitors/elf_json.hpp"
#include "LIEF/visitors/pe_json.hpp"

#include "LIEF/Abstract/Abstract.hpp"
#include "LIEF/ELF.hpp"
#include "LIEF/PE.hpp"

namespace LIEF {
template<class T, class VISITOR = JsonVisitor>
Expand Down
74 changes: 74 additions & 0 deletions include/LIEF/visitors/pe_json.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/* 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_VISITOR_JSONS_H_
#define LIEF_PE_VISITOR_JSONS_H_

#include "LIEF/visibility.h"
#include "LIEF/visitors/json.hpp"

namespace LIEF {
namespace PE {
class DLL_PUBLIC JsonVisitor : public LIEF::JsonVisitor {
public:
using LIEF::JsonVisitor::JsonVisitor;
using LIEF::JsonVisitor::operator=;
using LIEF::JsonVisitor::visit;
using LIEF::JsonVisitor::get;

virtual void visit(const Binary& Binary) override;
virtual void visit(const DosHeader& dos_header) override;
virtual void visit(const Header& header) override;
virtual void visit(const OptionalHeader& optional_header) override;
virtual void visit(const DataDirectory& data_directory) override;
virtual void visit(const Section& section) override;
virtual void visit(const Relocation& relocation) override;
virtual void visit(const RelocationEntry& relocation_entry) override;
virtual void visit(const Export& export_) override;
virtual void visit(const ExportEntry& export_entry) override;
virtual void visit(const TLS& tls) override;
virtual void visit(const Symbol& Symbol) override;
virtual void visit(const Debug& debug) override;
virtual void visit(const Import& import) override;
virtual void visit(const ImportEntry& import_entry) override;
virtual void visit(const ResourceNode& resource_node) override;
virtual void visit(const ResourceData& resource_data) override;
virtual void visit(const ResourceDirectory& resource_directory) override;
virtual void visit(const ResourcesManager& resources_manager) override;
virtual void visit(const ResourceVersion& resource_version) override;
virtual void visit(const ResourceStringFileInfo& resource_sfi) override;
virtual void visit(const ResourceFixedFileInfo& resource_ffi) override;
virtual void visit(const ResourceVarFileInfo& resource_vfi) override;
virtual void visit(const LangCodeItem& resource_lci) override;
virtual void visit(const ResourceIcon& resource_icon) override;
virtual void visit(const ResourceDialog& dialog) override;
virtual void visit(const ResourceDialogItem& dialog_item) override;
virtual void visit(const Signature& signature) override;
virtual void visit(const x509& x509) override;
virtual void visit(const SignerInfo& signerinfo) override;
virtual void visit(const ContentInfo& contentinfo) override;
virtual void visit(const AuthenticatedAttributes& auth) override;


virtual void visit(const LIEF::Binary& binary) override;
virtual void visit(const LIEF::Symbol& symbol) override;
virtual void visit(const LIEF::Section& section) override;
};

}
}


#endif
35 changes: 35 additions & 0 deletions src/PE/ResourcesManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "easylogging++.h"

#include "LIEF/exception.hpp"
#include "LIEF/visitors/Hash.hpp"
#include "LIEF/utils.hpp"

#include "LIEF/BinaryStream/VectorStream.hpp"
Expand Down Expand Up @@ -1074,6 +1075,40 @@ void ResourcesManager::print_tree(

}

void ResourcesManager::accept(Visitor& visitor) const {
if (this->has_manifest()) {
visitor.visit(this->manifest());
}

if (this->has_version()) {
visitor(this->version());
}

if (this->has_icons()) {
for (const ResourceIcon& icon : this->icons()) {
visitor(icon);
}
}

if (this->has_dialogs()) {
for (const ResourceDialog& dialog : this->dialogs()) {
visitor(dialog);
}
}

}

bool ResourcesManager::operator==(const ResourcesManager& rhs) const {
size_t hash_lhs = Hash::hash(*this);
size_t hash_rhs = Hash::hash(rhs);
return hash_lhs == hash_rhs;
}

bool ResourcesManager::operator!=(const ResourcesManager& rhs) const {
return not (*this == rhs);
}


std::ostream& operator<<(std::ostream& os, const ResourcesManager& rsrc) {
os << rsrc.print(3);
os << std::endl;
Expand Down
4 changes: 4 additions & 0 deletions src/PE/signature/AuthenticatedAttributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ const std::string& AuthenticatedAttributes::more_info(void) const {
}

void AuthenticatedAttributes::accept(Visitor& visitor) const {
visitor.visit(this->content_type());
visitor.visit(this->message_digest());
visitor.visit(u16tou8(this->program_name()));
visitor.visit(this->more_info());
}

std::ostream& operator<<(std::ostream& os, const AuthenticatedAttributes& authenticated_attributes) {
Expand Down
Loading

0 comments on commit 673f5a3

Please sign in to comment.