Skip to content
Permalink
Browse files
Parse PE Code View (PDB 7.0)
Resolve: #138
  • Loading branch information
romainthomas committed Feb 17, 2018
1 parent 6cb9519 commit eab4a76
Show file tree
Hide file tree
Showing 31 changed files with 936 additions and 37 deletions.
@@ -33,6 +33,8 @@ set(LIEF_PYTHON_PE_SRC
"${CMAKE_CURRENT_LIST_DIR}/objects/pyResourcesManager.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyHeader.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDebug.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyCodeView.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyCodeViewPDB.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pySection.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyExport.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyImport.cpp"
@@ -0,0 +1,51 @@
/* 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/CodeView.hpp"

#include <string>
#include <sstream>

template<class T>
using getter_t = T (CodeView::*)(void) const;

template<class T>
using setter_t = void (CodeView::*)(T);

void init_PE_CodeView_class(py::module& m) {
py::class_<CodeView>(m, "CodeView")
.def_property_readonly("cv_signature",
static_cast<getter_t<CODE_VIEW_SIGNATURES>>(&CodeView::cv_signature),
"Type of the code view (" RST_CLASS_REF(lief.PE.CODE_VIEW_SIGNATURES) ")")

.def("__eq__", &CodeView::operator==)
.def("__ne__", &CodeView::operator!=)
.def("__hash__",
[] (const CodeView& codeview) {
return LIEF::Hash::hash(codeview);
})

.def("__str__", [] (const CodeView& cv)
{
std::ostringstream stream;
stream << cv;
return stream.str();
});


}
@@ -0,0 +1,61 @@
/* 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/CodeViewPDB.hpp"

#include <string>
#include <sstream>

template<class T>
using getter_t = T (CodeViewPDB::*)(void) const;

template<class T>
using setter_t = void (CodeViewPDB::*)(T);

void init_PE_CodeViewPDB_class(py::module& m) {
py::class_<CodeViewPDB, CodeView>(m, "CodeViewPDB")
.def(py::init<>())

.def_property("signature",
static_cast<getter_t<CodeViewPDB::signature_t>>(&CodeViewPDB::signature),
static_cast<setter_t<CodeViewPDB::signature_t>>(&CodeViewPDB::signature))

.def_property("age",
static_cast<getter_t<uint32_t>>(&CodeViewPDB::age),
static_cast<setter_t<uint32_t>>(&CodeViewPDB::age))

.def_property("filename",
static_cast<getter_t<const std::string&>>(&CodeViewPDB::filename),
static_cast<setter_t<const std::string&>>(&CodeViewPDB::filename))

.def("__eq__", &CodeViewPDB::operator==)
.def("__ne__", &CodeViewPDB::operator!=)
.def("__hash__",
[] (const CodeViewPDB& codeview) {
return LIEF::Hash::hash(codeview);
})

.def("__str__", [] (const CodeViewPDB& cv)
{
std::ostringstream stream;
stream << cv;
return stream.str();
});


}
@@ -33,35 +33,54 @@ void init_PE_Debug_class(py::module& m) {

.def_property("characteristics",
static_cast<getter_t<uint32_t>>(&Debug::characteristics),
static_cast<setter_t<uint32_t>>(&Debug::characteristics))
static_cast<setter_t<uint32_t>>(&Debug::characteristics),
"Reserved should be 0")

.def_property("timestamp",
static_cast<getter_t<uint32_t>>(&Debug::timestamp),
static_cast<setter_t<uint32_t>>(&Debug::timestamp))
static_cast<setter_t<uint32_t>>(&Debug::timestamp),
"The time and date that the debug data was created.")

.def_property("major_version",
static_cast<getter_t<uint16_t>>(&Debug::major_version),
static_cast<setter_t<uint16_t>>(&Debug::major_version))
static_cast<setter_t<uint16_t>>(&Debug::major_version),
"The major version number of the debug data format.")

.def_property("minor_version",
static_cast<getter_t<uint16_t>>(&Debug::minor_version),
static_cast<setter_t<uint16_t>>(&Debug::minor_version))
static_cast<setter_t<uint16_t>>(&Debug::minor_version),
"The minor version number of the debug data format.")

.def_property("type",
static_cast<getter_t<DEBUG_TYPES>>(&Debug::type),
static_cast<setter_t<DEBUG_TYPES>>(&Debug::type))
static_cast<setter_t<DEBUG_TYPES>>(&Debug::type),
"The format (" RST_CLASS_REF(lief.PE.DEBUG_TYPES) ") of the debugging information")

.def_property("sizeof_data",
static_cast<getter_t<uint32_t>>(&Debug::sizeof_data),
static_cast<setter_t<uint32_t>>(&Debug::sizeof_data))
static_cast<setter_t<uint32_t>>(&Debug::sizeof_data),
"Size of the debug data")

.def_property("addressof_rawdata",
static_cast<getter_t<uint32_t>>(&Debug::addressof_rawdata),
static_cast<setter_t<uint32_t>>(&Debug::addressof_rawdata))
static_cast<setter_t<uint32_t>>(&Debug::addressof_rawdata),
"Address of the debug data relative to the image base")

.def_property("pointerto_rawdata",
static_cast<getter_t<uint32_t>>(&Debug::pointerto_rawdata),
static_cast<setter_t<uint32_t>>(&Debug::pointerto_rawdata))
static_cast<setter_t<uint32_t>>(&Debug::pointerto_rawdata),
"File offset of the debug data")

.def_property_readonly("has_code_view",
&Debug::has_code_view,
"Whether or not a code view is present")

.def_property_readonly("code_view",
static_cast<CodeView& (Debug::*)(void)>(&Debug::code_view),
"Return an object which subclass " RST_CLASS_REF(lief.PE.CodeView) " representing the code view \n\n"
"The subclassed object can be one of: \n\n"
" * " RST_CLASS_REF(lief.PE.CodeViewPDB) "\n",
py::return_value_policy::reference)

.def("__eq__", &Debug::operator==)
.def("__ne__", &Debug::operator!=)
@@ -54,6 +54,8 @@ void init_PE_module(py::module& m) {
init_PE_ExportEntry_class(LIEF_PE_module);
init_PE_Builder_class(LIEF_PE_module);
init_PE_Debug_class(LIEF_PE_module);
init_PE_CodeView_class(LIEF_PE_module);
init_PE_CodeViewPDB_class(LIEF_PE_module);
init_PE_CodeIntegrity_class(LIEF_PE_module);
init_PE_load_configurations(LIEF_PE_module);

@@ -48,6 +48,8 @@ void init_PE_Export_class(py::module&);
void init_PE_ExportEntry_class(py::module&);
void init_PE_Builder_class(py::module&);
void init_PE_Debug_class(py::module&);
void init_PE_CodeView_class(py::module&);
void init_PE_CodeViewPDB_class(py::module&);
void init_PE_CodeIntegrity_class(py::module&);
void init_PE_load_configurations(py::module&);

@@ -786,4 +786,12 @@ void init_PE_Structures_enum(py::module& m) {
.value(PY_ENUM(LIEF::PE::GUARD_RF_FLAGS::GRF_ENABLE))
.value(PY_ENUM(LIEF::PE::GUARD_RF_FLAGS::GRF_STRICT))
.export_values();

py::enum_<LIEF::PE::CODE_VIEW_SIGNATURES>(m, "CODE_VIEW_SIGNATURES")
.value(PY_ENUM(LIEF::PE::CODE_VIEW_SIGNATURES::CVS_UNKNOWN))
.value(PY_ENUM(LIEF::PE::CODE_VIEW_SIGNATURES::CVS_PDB_70))
.value(PY_ENUM(LIEF::PE::CODE_VIEW_SIGNATURES::CVS_PDB_20))
.value(PY_ENUM(LIEF::PE::CODE_VIEW_SIGNATURES::CVS_CV_50))
.value(PY_ENUM(LIEF::PE::CODE_VIEW_SIGNATURES::CVS_CV_41))
.export_values();
}
@@ -75,6 +75,31 @@ TLS

----------

Debug
*****

.. doxygenclass:: LIEF::PE::Debug
:project: lief

----------

Code View
*********

.. doxygenclass:: LIEF::PE::CodeView
:project: lief

----------

Code View PDB
*************

.. doxygenclass:: LIEF::PE::CodeViewPDB
:project: lief

----------


Symbol
*******

@@ -381,6 +381,28 @@ Debug

----------


Code View
*********

.. autoclass:: lief.PE.CodeView
:members:
:inherited-members:
:undoc-members:

----------


Code View PDB
**************

.. autoclass:: lief.PE.CodeViewPDB
:members:
:inherited-members:
:undoc-members:

----------

Code Integrity
**************

@@ -17,10 +17,12 @@
#include <memory>

#include <LIEF/PE.hpp>
#include <LIEF/logging.hpp>

using namespace LIEF::PE;

int main(int argc, char **argv) {
LIEF::Logger::set_level(LIEF::LOGGING_LEVEL::LOG_DEBUG);
std::cout << "PE Reader" << std::endl;
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << " <PE binary>" << std::endl;
@@ -273,6 +273,18 @@ def print_debug(binary):
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))

if debug.has_code_view:
code_view = debug.code_view
cv_signature = code_view.cv_signature

if cv_signature in (lief.PE.CODE_VIEW_SIGNATURES.PDB_70, lief.PE.CODE_VIEW_SIGNATURES.PDB_70):
sig_str = " ".join(map(lambda e : "{:02x}".format(e), code_view.signature))
print(format_str.format("Code View Signature:", str(cv_signature).split(".")[-1]))
print(format_str.format("Signature:", sig_str))
print(format_dec.format("Age:", code_view.age))
print(format_str.format("Filename:", code_view.filename))

print("")


@@ -20,6 +20,7 @@
#include "LIEF/PE/Parser.hpp"
#include "LIEF/PE/Builder.hpp"
#include "LIEF/PE/Binary.hpp"
#include "LIEF/PE/CodeViewPDB.hpp"
#include "LIEF/PE/signature/OIDToString.hpp"

#include "LIEF/PE/utils.hpp"
@@ -0,0 +1,61 @@
/* 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_CODE_VIEW_H_
#define LIEF_PE_CODE_VIEW_H_
#include <array>
#include <set>
#include <functional>
#include <algorithm>
#include <iostream>

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

#include "LIEF/PE/Structures.hpp"

namespace LIEF {
namespace PE {
class DLL_PUBLIC CodeView : public Visitable {
public:

CodeView(void);
CodeView(CODE_VIEW_SIGNATURES cv_signature);

CodeView(const CodeView&);
CodeView& operator=(const CodeView&);

virtual CodeView* clone(void) const = 0;

//! The Code View signature
CODE_VIEW_SIGNATURES cv_signature(void) const;

virtual void accept(Visitor& visitor) const override;

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

DLL_PUBLIC friend std::ostream& operator<<(std::ostream& os, const CodeView& entry);

virtual ~CodeView(void);

protected:
CODE_VIEW_SIGNATURES cv_signature_;
};

} // Namespace PE
} // Namespace LIEF

#endif

0 comments on commit eab4a76

Please sign in to comment.