Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add PE exception info #876

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/LIEF/PE/Binary.hpp
Expand Up @@ -25,6 +25,7 @@
#include "LIEF/PE/Import.hpp"
#include "LIEF/PE/DelayImport.hpp"
#include "LIEF/PE/TLS.hpp"
#include "LIEF/PE/Exception.hpp"
#include "LIEF/PE/Export.hpp"
#include "LIEF/PE/Debug.hpp"
#include "LIEF/PE/Symbol.hpp"
Expand Down Expand Up @@ -78,6 +79,8 @@ class LIEF_API Binary : public LIEF::Binary {
//! Internal container for storing PE's Import
using imports_t = std::vector<Import>;

using exceptions_t = std::vector<Exception>;

//! Iterator that output Import&
using it_imports = ref_iterator<imports_t&>;

Expand Down Expand Up @@ -286,6 +289,8 @@ class LIEF_API Binary : public LIEF::Binary {
Export& get_export();
const Export& get_export() const;

Exception get_exception(uint64_t address);

//! Return binary Symbols
std::vector<Symbol>& symbols();
const std::vector<Symbol>& symbols() const;
Expand Down Expand Up @@ -561,6 +566,7 @@ class LIEF_API Binary : public LIEF::Binary {
imports_t imports_;
delay_imports_t delay_imports_;
Export export_;
exceptions_t exceptions_;
debug_entries_t debug_;
uint64_t overlay_offset_ = 0;
std::vector<uint8_t> overlay_;
Expand Down
122 changes: 122 additions & 0 deletions include/LIEF/PE/Exception.hpp
@@ -0,0 +1,122 @@
#ifndef LIEF_PE_EXCEPTION_H_
#define LIEF_PE_EXCEPTION_H_

#include "LIEF/Abstract/Function.hpp"
namespace LIEF {
namespace PE {
namespace details {

enum unwind_info_version
{
version_v1 = 1,
version_v2 = 2,
};

enum unwind_code_opcode {
UWOP_PUSH_NONVOL = 0,
UWOP_ALLOC_LARGE = 1,
UWOP_ALLOC_SMALL = 2,
UWOP_SET_FPREG = 3,
UWOP_SAVE_NONVOL = 4,
UWOP_SAVE_NONVOL_FAR = 5,
UWOP_EPILOG = 6,
UWOP_SAVE_XMM128 = 8,
UWOP_SAVE_XMM128_FAR = 9,
UWOP_PUSH_MACHFRAME = 10
};

enum unwind_info_reg
{
x86_64_RAX = 0,
x86_64_RCX,
x86_64_RDX,
x86_64_RBX,
x86_64_RSP,
x86_64_RBP,
x86_64_RSI,
x86_64_RDI,
x86_64_R8,
x86_64_R9,
x86_64_R10,
x86_64_R11,
x86_64_R12,
x86_64_R13,
x86_64_R14,
x86_64_R15,
x86_64_XMM0,
x86_64_XMM1,
x86_64_XMM2,
x86_64_XMM3,
x86_64_XMM4,
x86_64_XMM5,
x86_64_XMM6,
x86_64_XMM7,
x86_64_XMM8,
x86_64_XMM9,
x86_64_XMM10,
x86_64_XMM11,
x86_64_XMM12,
x86_64_XMM13,
x86_64_XMM14,
x86_64_XMM15
};




enum class unwind_operation
{
push,
alloc,
frame,
mov

};

enum class exception_handle_flag:uint64_t
{
exception_handle = 1 << 0,
termination_handle = 1 << 1,
};

struct unwind_info
{
size_t offset;
unwind_operation operation;
size_t reg;
size_t reg_offset;

};

class Unwind
{
public:
using unwinds = std::vector<unwind_info>;

size_t prelog_size;
size_t frame_reg;
size_t frame_offset;
unwinds unwinds_;

};
}


class LIEF_API Exception : public LIEF::Function
{
public:
using handle_flags_t = std::vector< details::exception_handle_flag>;
Exception(uint64_t address,uint64_t end);
using exceptions_t = std::vector<Exception>;
details::Unwind unwind;
handle_flags_t handle_flag;
size_t handle_rva;
size_t info_rva;



};


}}
#endif // !LIEF_PE_EXCEPTION_H_
5 changes: 4 additions & 1 deletion include/LIEF/PE/Parser.hpp
Expand Up @@ -26,7 +26,7 @@

#include "LIEF/Abstract/Parser.hpp"
#include "LIEF/PE/enums.hpp"

#include "LIEF/PE/Exception.hpp"
struct Profiler;

namespace LIEF {
Expand Down Expand Up @@ -103,6 +103,9 @@ class LIEF_API Parser : public LIEF::Parser {
ok_error_t parse_exports();
ok_error_t parse_sections();

ok_error_t parse_exception_unwind(uint64_t unwind_info_rva, Exception& exception);
ok_error_t parse_exceptions();

template<typename PE_T>
ok_error_t parse_headers();

Expand Down
6 changes: 6 additions & 0 deletions include/LIEF/PE/enums.hpp
Expand Up @@ -1325,6 +1325,12 @@ enum class SIG_ATTRIBUTE_TYPES {
PKCS9_SIGNING_TIME,
};

enum class UNWIND_HANDLE_TYPE :uint8_t {
FLAG_INVALID = 0x0,
FLAG_EHANDLER = 0x1,
FLAG_UHANDLER = 0x2,
FLAG_CHAININFO = 0x4,
};

static const RESOURCE_TYPES resource_types_array[] = {
RESOURCE_TYPES::CURSOR,
Expand Down
11 changes: 11 additions & 0 deletions src/PE/Binary.cpp
Expand Up @@ -881,6 +881,17 @@ const Export& Binary::get_export() const {
return export_;
}

// Exception
Exception Binary::get_exception(uint64_t address)
{
for (const auto& x : exceptions_)
if (x.address() <= address && x.address() + x.size() >= address)
return x;
return Exception(address,address);
}



/////////////////////////////////////
//
// Methods to manage Resources
Expand Down
2 changes: 2 additions & 0 deletions src/PE/CMakeLists.txt
Expand Up @@ -12,6 +12,7 @@ set(LIEF_PE_SRC
"${CMAKE_CURRENT_LIST_DIR}/DelayImportEntry.cpp"
"${CMAKE_CURRENT_LIST_DIR}/DosHeader.cpp"
"${CMAKE_CURRENT_LIST_DIR}/EnumToString.cpp"
"${CMAKE_CURRENT_LIST_DIR}/Exception.cpp"
"${CMAKE_CURRENT_LIST_DIR}/Export.cpp"
"${CMAKE_CURRENT_LIST_DIR}/ExportEntry.cpp"
"${CMAKE_CURRENT_LIST_DIR}/Header.cpp"
Expand Down Expand Up @@ -92,6 +93,7 @@ set(LIEF_PE_INCLUDE_FILES
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/DelayImportEntry.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/DosHeader.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/EnumToString.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/Exception.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/Export.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/ExportEntry.hpp"
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/PE/Header.hpp"
Expand Down
13 changes: 13 additions & 0 deletions src/PE/Convert.cpp
Expand Up @@ -20,5 +20,18 @@
namespace LIEF {
namespace Convert {
// TODO: Implement endian convert
template<>
void swap_endian<LIEF::PE::details::pe_unwind_info>(LIEF::PE::details::pe_unwind_info*) {

}
template<>
void swap_endian<LIEF::PE::details::pe_unwind_code>(LIEF::PE::details::pe_unwind_code*) {

}
template<>
void swap_endian<LIEF::PE::details::pe_exception_entry_x64>(LIEF::PE::details::pe_exception_entry_x64*) {

}

}
}
18 changes: 18 additions & 0 deletions src/PE/Exception.cpp
@@ -0,0 +1,18 @@
#include "LIEF/PE/Exception.hpp"


namespace LIEF {
namespace PE {
namespace details {

}


Exception::Exception(uint64_t address, uint64_t end) :
Function{address }
{
size(end - address);
}
}}