Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Parse the PE Load Configuration structure
  • Loading branch information
romainthomas committed Oct 6, 2017
1 parent e1d2681 commit 0234e3b
Show file tree
Hide file tree
Showing 74 changed files with 4,519 additions and 99 deletions.
1 change: 1 addition & 0 deletions Acknowledgements
Expand Up @@ -13,5 +13,6 @@ LIEF makes use of the following open source projects:
- filesystem - https://github.com/wjakob/filesystem
- utf8-cpp - https://sourceforge.net/projects/utfcpp/
- llvm - http://llvm.org/ - For the formats enums and structures
- virtualbox - https://www.virtualbox.org/ - For the PE 'LoadConfiguration' structures

The logo is designed by Freepik
5 changes: 5 additions & 0 deletions api/python/PE/CMakeLists.txt
@@ -1,5 +1,6 @@
set(LIEF_PYTHON_PE_SRC
"${CMAKE_CURRENT_LIST_DIR}/pyUtils.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/init_load_configurations.cpp"

"${CMAKE_CURRENT_LIST_DIR}/objects/pyResourceNode.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyResourceData.cpp"
Expand All @@ -20,6 +21,7 @@ set(LIEF_PYTHON_PE_SRC
"${CMAKE_CURRENT_LIST_DIR}/objects/signature/pyContentInfo.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/signature/pySignature.cpp"

"${CMAKE_CURRENT_LIST_DIR}/objects/pyCodeIntegrity.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDataDirectory.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDosHeader.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyRichHeader.cpp"
Expand Down Expand Up @@ -54,4 +56,7 @@ target_include_directories(pyLIEF PUBLIC "${CMAKE_CURRENT_LIST_DIR}")
target_sources(pyLIEF PRIVATE "${LIEF_PYTHON_PE_SRC}" "${LIEF_PYTHON_PE_HDR}")


include("${CMAKE_CURRENT_LIST_DIR}/objects/LoadConfigurations/CMakeLists.txt")



18 changes: 18 additions & 0 deletions api/python/PE/objects/LoadConfigurations/CMakeLists.txt
@@ -0,0 +1,18 @@
set(LIEF_PYTHON_PE_LOAD_CONFIGURE_SRC
"${CMAKE_CURRENT_LIST_DIR}/pyLoadConfiguration.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyLoadConfigurationV0.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyLoadConfigurationV1.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyLoadConfigurationV2.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyLoadConfigurationV3.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyLoadConfigurationV4.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyLoadConfigurationV5.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyLoadConfigurationV6.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyLoadConfigurationV7.cpp"
)

source_group("Source Files\\PE\\Load Configuration" FILES ${LIEF_PYTHON_PE_LOAD_CONFIGURE_SRC})

target_sources(pyLIEF PRIVATE "${LIEF_PYTHON_PE_LOAD_CONFIGURE_SRC}")



152 changes: 152 additions & 0 deletions api/python/PE/objects/LoadConfigurations/pyLoadConfiguration.cpp
@@ -0,0 +1,152 @@
/* 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/LoadConfigurations.hpp"

#include <string>
#include <sstream>

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

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

void init_PE_LoadConfiguration_class(py::module& m) {
py::class_<LoadConfiguration>(m, "LoadConfiguration",
"Class modeling the default PE's ``LoadConfiguration``\n\n"
"It's the base class for any future version of the structure"
)
.def(py::init<>())

.def_property_readonly("version",
&LoadConfiguration::version,
"(SDK) Version of the structure. (" RST_CLASS_REF(lief.PE.WIN_VERSION) ")")

.def_property("characteristics",
static_cast<getter_t<uint32_t>>(&LoadConfiguration::characteristics),
static_cast<setter_t<uint32_t>>(&LoadConfiguration::characteristics),
"Characteristics of the structure.")

.def_property("timedatestamp",
static_cast<getter_t<uint32_t>>(&LoadConfiguration::timedatestamp),
static_cast<setter_t<uint32_t>>(&LoadConfiguration::timedatestamp),
"Date and time stamp value")

.def_property("major_version",
static_cast<getter_t<uint16_t>>(&LoadConfiguration::major_version),
static_cast<setter_t<uint16_t>>(&LoadConfiguration::major_version),
"Major Version")

.def_property("minor_version",
static_cast<getter_t<uint16_t>>(&LoadConfiguration::minor_version),
static_cast<setter_t<uint16_t>>(&LoadConfiguration::minor_version),
"Minor version")

.def_property("global_flags_clear",
static_cast<getter_t<uint32_t>>(&LoadConfiguration::global_flags_clear),
static_cast<setter_t<uint32_t>>(&LoadConfiguration::global_flags_clear),
"The global loader flags to clear for this process as the loader start the process.")

.def_property("global_flags_set",
static_cast<getter_t<uint32_t>>(&LoadConfiguration::global_flags_set),
static_cast<setter_t<uint32_t>>(&LoadConfiguration::global_flags_set),
"The global loader flags to set for this process as the loader starts the process.")

.def_property("critical_section_default_timeout",
static_cast<getter_t<uint32_t>>(&LoadConfiguration::critical_section_default_timeout),
static_cast<setter_t<uint32_t>>(&LoadConfiguration::critical_section_default_timeout),
"The default timeout value to use for is process’s critical sections that are abandoned.")

.def_property("decommit_free_block_threshold",
static_cast<getter_t<uint64_t>>(&LoadConfiguration::decommit_free_block_threshold),
static_cast<setter_t<uint64_t>>(&LoadConfiguration::decommit_free_block_threshold),
"Memory that must be freed before it is returned to the system, in bytes.")

.def_property("decommit_total_free_threshold",
static_cast<getter_t<uint64_t>>(&LoadConfiguration::decommit_total_free_threshold),
static_cast<setter_t<uint64_t>>(&LoadConfiguration::decommit_total_free_threshold),
"Total amount of free memory, in bytes")

.def_property("lock_prefix_table",
static_cast<getter_t<uint64_t>>(&LoadConfiguration::lock_prefix_table),
static_cast<setter_t<uint64_t>>(&LoadConfiguration::lock_prefix_table),
"The **VA** of a list of addresses where the ``LOCK`` prefix "
"is used so that they can be replaced with ``NOP`` on single processor machines.")

.def_property("maximum_allocation_size",
static_cast<getter_t<uint64_t>>(&LoadConfiguration::maximum_allocation_size),
static_cast<setter_t<uint64_t>>(&LoadConfiguration::maximum_allocation_size),
"Maximum allocation size, in bytes.")

.def_property("virtual_memory_threshold",
static_cast<getter_t<uint64_t>>(&LoadConfiguration::virtual_memory_threshold),
static_cast<setter_t<uint64_t>>(&LoadConfiguration::virtual_memory_threshold),
"Maximum virtual memory size, in bytes.")

.def_property("process_affinity_mask",
static_cast<getter_t<uint64_t>>(&LoadConfiguration::process_affinity_mask),
static_cast<setter_t<uint64_t>>(&LoadConfiguration::process_affinity_mask),
"Setting this field to a non-zero value is equivalent to calling "
"``SetProcessAffinityMask`` with this value during process startup (.exe only)")

.def_property("process_heap_flags",
static_cast<getter_t<uint32_t>>(&LoadConfiguration::process_heap_flags),
static_cast<setter_t<uint32_t>>(&LoadConfiguration::process_heap_flags),
"Process heap flags that correspond to the first argument of the "
"``HeapCreate`` function. These flags apply to the process heap that is "
"created during process startup.")

.def_property("csd_version",
static_cast<getter_t<uint16_t>>(&LoadConfiguration::csd_version),
static_cast<setter_t<uint16_t>>(&LoadConfiguration::csd_version),
"The service pack version identifier.")

.def_property("reserved1",
static_cast<getter_t<uint16_t>>(&LoadConfiguration::reserved1),
static_cast<setter_t<uint16_t>>(&LoadConfiguration::reserved1),
"Must be zero.")

.def_property("editlist",
static_cast<getter_t<uint32_t>>(&LoadConfiguration::editlist),
static_cast<setter_t<uint32_t>>(&LoadConfiguration::editlist),
"Reserved for use by the system.")

.def_property("security_cookie",
static_cast<getter_t<uint32_t>>(&LoadConfiguration::security_cookie),
static_cast<setter_t<uint32_t>>(&LoadConfiguration::security_cookie),
"A pointer to a cookie that is used by Visual C++ or GS implementation.")

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


.def("__str__", [] (const LoadConfiguration& config)
{
std::ostringstream stream;
stream << config;
std::string str = stream.str();
return str;
});


}
67 changes: 67 additions & 0 deletions api/python/PE/objects/LoadConfigurations/pyLoadConfigurationV0.cpp
@@ -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/LoadConfigurations.hpp"

#include <string>
#include <sstream>

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

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

void init_PE_LoadConfigurationV0_class(py::module& m) {
py::class_<LoadConfigurationV0, LoadConfiguration>(m, "LoadConfigurationV0",
"" RST_CLASS_REF(lief.PE.LoadConfiguration) " enhanced with SEH. \n\n"
"It is associated with the " RST_CLASS_REF(lief.PE.WIN_VERSION) ": "
":attr:`~lief.PE.WIN_VERSION.SEH`")

.def(py::init<>())

.def_property("se_handler_table",
static_cast<getter_t<uint64_t>>(&LoadConfigurationV0::se_handler_table),
static_cast<setter_t<uint64_t>>(&LoadConfigurationV0::se_handler_table),
"The VA of the sorted table of RVAs of each valid, unique "
"SE handler in the image.")

.def_property("se_handler_count",
static_cast<getter_t<uint64_t>>(&LoadConfigurationV0::se_handler_count),
static_cast<setter_t<uint64_t>>(&LoadConfigurationV0::se_handler_count),
"The count of unique handlers in the table.")


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


.def("__str__", [] (const LoadConfigurationV0& config)
{
std::ostringstream stream;
stream << config;
std::string str = stream.str();
return str;
});


}
96 changes: 96 additions & 0 deletions api/python/PE/objects/LoadConfigurations/pyLoadConfigurationV1.cpp
@@ -0,0 +1,96 @@
/* 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/LoadConfigurations.hpp"

#include <string>
#include <sstream>

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

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

void init_PE_LoadConfigurationV1_class(py::module& m) {
py::class_<LoadConfigurationV1, LoadConfigurationV0>(m, "LoadConfigurationV1",
"" RST_CLASS_REF(lief.PE.LoadConfigurationV0) " enhanced with *Control Flow Guard*. \n\n"
"It is associated with the " RST_CLASS_REF(lief.PE.WIN_VERSION) ": "
":attr:`~lief.PE.WIN_VERSION.WIN_8_1`"
)
.def(py::init<>())

.def_property("guard_cf_check_function_pointer",
static_cast<getter_t<uint64_t>>(&LoadConfigurationV1::guard_cf_check_function_pointer),
static_cast<setter_t<uint64_t>>(&LoadConfigurationV1::guard_cf_check_function_pointer),
"The VA where Control Flow Guard check-function pointer is stored.")

.def_property("guard_cf_dispatch_function_pointer",
static_cast<getter_t<uint64_t>>(&LoadConfigurationV1::guard_cf_dispatch_function_pointer),
static_cast<setter_t<uint64_t>>(&LoadConfigurationV1::guard_cf_dispatch_function_pointer),
"The VA where Control Flow Guard dispatch-function pointer is stored.")

.def_property("guard_cf_function_table",
static_cast<getter_t<uint64_t>>(&LoadConfigurationV1::guard_cf_function_table),
static_cast<setter_t<uint64_t>>(&LoadConfigurationV1::guard_cf_function_table),
"The VA of the sorted table of RVAs of each Control Flow Guard function in the image.")

.def_property("guard_cf_function_count",
static_cast<getter_t<uint64_t>>(&LoadConfigurationV1::guard_cf_function_count),
static_cast<setter_t<uint64_t>>(&LoadConfigurationV1::guard_cf_function_count),
"The count of unique RVAs in the :attr:`~lief.PE.LoadConfigurationV1.guard_cf_function_table`")

.def_property("guard_flags",
static_cast<getter_t<uint32_t>>(&LoadConfigurationV1::guard_flags),
static_cast<setter_t<uint32_t>>(&LoadConfigurationV1::guard_flags),
"Control Flow Guard related flags.")

.def("has",
static_cast<bool (LoadConfigurationV1::*)(GUARD_CF_FLAGS) const>(&LoadConfigurationV1::has),
"Check if the given " RST_CLASS_REF(lief.PE.GUARD_CF_FLAGS) " is present in "
":attr:`~lief.PE.LoadConfigurationV1.guard_flags`",
"flag"_a)

.def_property_readonly("guard_cf_flags_list",
&LoadConfigurationV1::guard_cf_flags_list,
"Return list of " RST_CLASS_REF(lief.PE.GUARD_CF_FLAGS) " present in "
":attr:`~lief.PE.LoadConfigurationV1.guard_flags`",
py::return_value_policy::reference_internal)

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


.def("__contains__",
static_cast<bool (LoadConfigurationV1::*)(GUARD_CF_FLAGS) const>(&LoadConfigurationV1::has))


.def("__str__", [] (const LoadConfigurationV1& config)
{
std::ostringstream stream;
stream << config;
std::string str = stream.str();
return str;
});


}

0 comments on commit 0234e3b

Please sign in to comment.