Skip to content

Commit

Permalink
The load configuration directory is now parsed (in preparation for a
Browse files Browse the repository at this point in the history
plugin detecting exploit mitigation techniques - i.e. /GS and SafeSEH).
A unit test was added and the documentation was updated.
  • Loading branch information
JusticeRage committed May 13, 2016
1 parent 7c9cab4 commit 8b552a1
Show file tree
Hide file tree
Showing 10 changed files with 468 additions and 129 deletions.
64 changes: 64 additions & 0 deletions docs/writing-plugins.rst
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,70 @@ The function returns a shared vector containing pointers to instances of the fol
boost::uint32_t PointerToRawData;
std::string Filename;
} debug_directory_entry;
Thread Local Storage
--------------------

If TLS callbacks are defined in the binary, you can look them up with ``get_tls``::

auto ptls = pe.get_tls();
if (tls == nullptr) {
return; // No TLS callbacks or failed to parse them.
}
for (auto it = tls->Callbacks.begin() ; it != tls->Callbacks.end() ; ++it) {
std::cout << "Callback address: 0x" << std::hex << *it);
}
The object returned by this function is a pointer to an instance of the following structure::

typedef struct image_tls_directory_t
{
boost::uint64_t StartAddressOfRawData;
boost::uint64_t EndAddressOfRawData;
boost::uint64_t AddressOfIndex;
boost::uint64_t AddressOfCallbacks;
boost::uint32_t SizeOfZeroFill;
boost::uint32_t Characteristics;
std::vector<boost::uint64_t> Callbacks; // Non-standard!
} image_tls_directory;
It closely resembles the original IMAGE_TLS_DIRECTORY structure, but with a list of all the callback addresses already parsed and stored in the ``Callbacks`` vector for your convinience.

Load Configuration
------------------

You can query the load configuration of the PE with the following function::

auto pconfig = pe.get_config();
if (pconfig != nullptr && config->SecurityCookie == 0) {
std::cout << "/GS seems to be disabled!" << std::endl;
}
The structure returned by this function mirrors the one defined in the `MSDN <https://msdn.microsoft.com/en-us/library/windows/hardware/ff549596(v=vs.85).aspx>`_::

typedef struct image_load_config_directory_t
{
boost::uint32_t Size;
boost::uint32_t TimeDateStamp;
boost::uint16_t MajorVersion;
boost::uint16_t MinorVersion;
boost::uint32_t GlobalFlagsClear;
boost::uint32_t GlobalFlagsSet;
boost::uint32_t CriticalSectionDefaultTimeout;
boost::uint64_t DeCommitFreeBlockThreshold;
boost::uint64_t DeCommitTotalFreeThreshold;
boost::uint64_t LockPrefixTable;
boost::uint64_t MaximumAllocationSize;
boost::uint64_t VirtualMemoryThreshold;
boost::uint64_t ProcessAffinityMask;
boost::uint32_t ProcessHeapFlags;
boost::uint16_t CSDVersion;
boost::uint16_t Reserved1;
boost::uint64_t EditList;
boost::uint64_t SecurityCookie;
boost::uint64_t SEHandlerTable;
boost::uint64_t SEHandlerCount;
} image_load_config_directory;

Miscellaneous
-------------
Expand Down
1 change: 1 addition & 0 deletions include/dump.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ void dump_resources(const mana::PE& pe, io::OutputFormatter& formatter, bool com
void dump_version_info(const mana::PE& pe, io::OutputFormatter& formatter);
void dump_debug_info(const mana::PE& pe, io::OutputFormatter& formatter);
void dump_tls(const mana::PE& pe, io::OutputFormatter& formatter);
void dump_config(const mana::PE&pe, io::OutputFormatter& formatter);
void dump_summary(const mana::PE& pe, io::OutputFormatter& formatter);
void dump_hashes(const mana::PE& pe, io::OutputFormatter& formatter);

Expand Down
2 changes: 2 additions & 0 deletions include/manape/nt_values.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ extern const DECLSPEC flag_dict DEBUG_TYPES;
extern const DECLSPEC flag_dict BASE_RELOCATION_TYPES;
extern const DECLSPEC flag_dict WIN_CERTIFICATE_REVISIONS;
extern const DECLSPEC flag_dict WIN_CERTIFICATE_TYPES;
extern const DECLSPEC flag_dict GLOBAL_FLAGS;
extern const DECLSPEC flag_dict HEAP_FLAGS;

/**
* @brief Breaks down an integer given as input as a combination of flags.
Expand Down
42 changes: 28 additions & 14 deletions include/manape/pe.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ typedef boost::shared_ptr<const std::vector<pexported_function> > shared_exports
typedef boost::shared_ptr<const std::vector<pdebug_directory_entry> > shared_debug_info;
typedef boost::shared_ptr<const std::vector<pimage_base_relocation> > shared_relocations;
typedef boost::shared_ptr<const image_tls_directory> shared_tls;
typedef boost::shared_ptr<const image_load_config_directory> shared_config;
typedef boost::shared_ptr<const std::vector<pwin_certificate> > shared_certificates;
typedef boost::shared_ptr<std::string> pString;
typedef boost::shared_ptr<FILE> pFile;
Expand Down Expand Up @@ -165,6 +166,10 @@ class PE
return (_initialized && _tls) ? boost::make_shared<image_tls_directory>(*_tls) : shared_tls();
}

DECLSPEC shared_config get_config() const {
return (_initialized && _config) ? boost::make_shared<image_load_config_directory>(*_config) : shared_config();
}

DECLSPEC shared_certificates get_certificates() const {
return _initialized ? boost::make_shared<shared_certificates::element_type>(_certificates) :
boost::make_shared<shared_certificates::element_type>();
Expand Down Expand Up @@ -297,6 +302,14 @@ class PE
*/
bool _parse_tls();

/**
* @brief Parses the Configuration Table of a PE.
*
* Included in the _parse_directories call.
* /!\ This relies on the information gathered in _parse_pe_header.
*/
bool _parse_config();

/**
* @brief Parses the debug information of a PE.
*
Expand Down Expand Up @@ -378,20 +391,21 @@ class PE
-----------------------------------
Those fields that are extremely close to the PE format and offer little abstraction.
*/
boost::optional<dos_header> _h_dos;
boost::optional<pe_header> _h_pe;
boost::optional<image_optional_header> _ioh;
std::vector<pcoff_symbol> _coff_symbols; // This debug information is parsed (crudely) but
std::vector<pString> _coff_string_table; // not displayed, because that's IDA's job.
std::vector<pSection> _sections;
std::vector<pimage_library_descriptor> _imports;
boost::optional<image_export_directory> _ied;
std::vector<pexported_function> _exports;
std::vector<pResource> _resource_table;
std::vector<pdebug_directory_entry> _debug_entries;
std::vector<pimage_base_relocation> _relocations; // Not displayed either, because of how big it is.
boost::optional<image_tls_directory> _tls;
std::vector<pwin_certificate> _certificates;
boost::optional<dos_header> _h_dos;
boost::optional<pe_header> _h_pe;
boost::optional<image_optional_header> _ioh;
std::vector<pcoff_symbol> _coff_symbols; // This debug information is parsed (crudely) but
std::vector<pString> _coff_string_table; // not displayed, because that's IDA's job.
std::vector<pSection> _sections;
std::vector<pimage_library_descriptor> _imports;
boost::optional<image_export_directory> _ied;
std::vector<pexported_function> _exports;
std::vector<pResource> _resource_table;
std::vector<pdebug_directory_entry> _debug_entries;
std::vector<pimage_base_relocation> _relocations; // Not displayed either, because of how big it is.
boost::optional<image_tls_directory> _tls;
boost::optional<image_load_config_directory> _config;
std::vector<pwin_certificate> _certificates;
};


Expand Down

0 comments on commit 8b552a1

Please sign in to comment.