Skip to content

Commit 0234e3b

Browse files
committed
Parse the PE Load Configuration structure
1 parent e1d2681 commit 0234e3b

File tree

74 files changed

+4519
-99
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+4519
-99
lines changed

Acknowledgements

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ LIEF makes use of the following open source projects:
1313
- filesystem - https://github.com/wjakob/filesystem
1414
- utf8-cpp - https://sourceforge.net/projects/utfcpp/
1515
- llvm - http://llvm.org/ - For the formats enums and structures
16+
- virtualbox - https://www.virtualbox.org/ - For the PE 'LoadConfiguration' structures
1617

1718
The logo is designed by Freepik

api/python/PE/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
set(LIEF_PYTHON_PE_SRC
22
"${CMAKE_CURRENT_LIST_DIR}/pyUtils.cpp"
3+
"${CMAKE_CURRENT_LIST_DIR}/objects/init_load_configurations.cpp"
34

45
"${CMAKE_CURRENT_LIST_DIR}/objects/pyResourceNode.cpp"
56
"${CMAKE_CURRENT_LIST_DIR}/objects/pyResourceData.cpp"
@@ -20,6 +21,7 @@ set(LIEF_PYTHON_PE_SRC
2021
"${CMAKE_CURRENT_LIST_DIR}/objects/signature/pyContentInfo.cpp"
2122
"${CMAKE_CURRENT_LIST_DIR}/objects/signature/pySignature.cpp"
2223

24+
"${CMAKE_CURRENT_LIST_DIR}/objects/pyCodeIntegrity.cpp"
2325
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDataDirectory.cpp"
2426
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDosHeader.cpp"
2527
"${CMAKE_CURRENT_LIST_DIR}/objects/pyRichHeader.cpp"
@@ -54,4 +56,7 @@ target_include_directories(pyLIEF PUBLIC "${CMAKE_CURRENT_LIST_DIR}")
5456
target_sources(pyLIEF PRIVATE "${LIEF_PYTHON_PE_SRC}" "${LIEF_PYTHON_PE_HDR}")
5557

5658

59+
include("${CMAKE_CURRENT_LIST_DIR}/objects/LoadConfigurations/CMakeLists.txt")
60+
61+
5762

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
set(LIEF_PYTHON_PE_LOAD_CONFIGURE_SRC
2+
"${CMAKE_CURRENT_LIST_DIR}/pyLoadConfiguration.cpp"
3+
"${CMAKE_CURRENT_LIST_DIR}/pyLoadConfigurationV0.cpp"
4+
"${CMAKE_CURRENT_LIST_DIR}/pyLoadConfigurationV1.cpp"
5+
"${CMAKE_CURRENT_LIST_DIR}/pyLoadConfigurationV2.cpp"
6+
"${CMAKE_CURRENT_LIST_DIR}/pyLoadConfigurationV3.cpp"
7+
"${CMAKE_CURRENT_LIST_DIR}/pyLoadConfigurationV4.cpp"
8+
"${CMAKE_CURRENT_LIST_DIR}/pyLoadConfigurationV5.cpp"
9+
"${CMAKE_CURRENT_LIST_DIR}/pyLoadConfigurationV6.cpp"
10+
"${CMAKE_CURRENT_LIST_DIR}/pyLoadConfigurationV7.cpp"
11+
)
12+
13+
source_group("Source Files\\PE\\Load Configuration" FILES ${LIEF_PYTHON_PE_LOAD_CONFIGURE_SRC})
14+
15+
target_sources(pyLIEF PRIVATE "${LIEF_PYTHON_PE_LOAD_CONFIGURE_SRC}")
16+
17+
18+
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/* Copyright 2017 R. Thomas
2+
* Copyright 2017 Quarkslab
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
#include "pyPE.hpp"
17+
18+
#include "LIEF/visitors/Hash.hpp"
19+
#include "LIEF/PE/LoadConfigurations.hpp"
20+
21+
#include <string>
22+
#include <sstream>
23+
24+
template<class T>
25+
using getter_t = T (LoadConfiguration::*)(void) const;
26+
27+
template<class T>
28+
using setter_t = void (LoadConfiguration::*)(T);
29+
30+
void init_PE_LoadConfiguration_class(py::module& m) {
31+
py::class_<LoadConfiguration>(m, "LoadConfiguration",
32+
"Class modeling the default PE's ``LoadConfiguration``\n\n"
33+
"It's the base class for any future version of the structure"
34+
)
35+
.def(py::init<>())
36+
37+
.def_property_readonly("version",
38+
&LoadConfiguration::version,
39+
"(SDK) Version of the structure. (" RST_CLASS_REF(lief.PE.WIN_VERSION) ")")
40+
41+
.def_property("characteristics",
42+
static_cast<getter_t<uint32_t>>(&LoadConfiguration::characteristics),
43+
static_cast<setter_t<uint32_t>>(&LoadConfiguration::characteristics),
44+
"Characteristics of the structure.")
45+
46+
.def_property("timedatestamp",
47+
static_cast<getter_t<uint32_t>>(&LoadConfiguration::timedatestamp),
48+
static_cast<setter_t<uint32_t>>(&LoadConfiguration::timedatestamp),
49+
"Date and time stamp value")
50+
51+
.def_property("major_version",
52+
static_cast<getter_t<uint16_t>>(&LoadConfiguration::major_version),
53+
static_cast<setter_t<uint16_t>>(&LoadConfiguration::major_version),
54+
"Major Version")
55+
56+
.def_property("minor_version",
57+
static_cast<getter_t<uint16_t>>(&LoadConfiguration::minor_version),
58+
static_cast<setter_t<uint16_t>>(&LoadConfiguration::minor_version),
59+
"Minor version")
60+
61+
.def_property("global_flags_clear",
62+
static_cast<getter_t<uint32_t>>(&LoadConfiguration::global_flags_clear),
63+
static_cast<setter_t<uint32_t>>(&LoadConfiguration::global_flags_clear),
64+
"The global loader flags to clear for this process as the loader start the process.")
65+
66+
.def_property("global_flags_set",
67+
static_cast<getter_t<uint32_t>>(&LoadConfiguration::global_flags_set),
68+
static_cast<setter_t<uint32_t>>(&LoadConfiguration::global_flags_set),
69+
"The global loader flags to set for this process as the loader starts the process.")
70+
71+
.def_property("critical_section_default_timeout",
72+
static_cast<getter_t<uint32_t>>(&LoadConfiguration::critical_section_default_timeout),
73+
static_cast<setter_t<uint32_t>>(&LoadConfiguration::critical_section_default_timeout),
74+
"The default timeout value to use for is process’s critical sections that are abandoned.")
75+
76+
.def_property("decommit_free_block_threshold",
77+
static_cast<getter_t<uint64_t>>(&LoadConfiguration::decommit_free_block_threshold),
78+
static_cast<setter_t<uint64_t>>(&LoadConfiguration::decommit_free_block_threshold),
79+
"Memory that must be freed before it is returned to the system, in bytes.")
80+
81+
.def_property("decommit_total_free_threshold",
82+
static_cast<getter_t<uint64_t>>(&LoadConfiguration::decommit_total_free_threshold),
83+
static_cast<setter_t<uint64_t>>(&LoadConfiguration::decommit_total_free_threshold),
84+
"Total amount of free memory, in bytes")
85+
86+
.def_property("lock_prefix_table",
87+
static_cast<getter_t<uint64_t>>(&LoadConfiguration::lock_prefix_table),
88+
static_cast<setter_t<uint64_t>>(&LoadConfiguration::lock_prefix_table),
89+
"The **VA** of a list of addresses where the ``LOCK`` prefix "
90+
"is used so that they can be replaced with ``NOP`` on single processor machines.")
91+
92+
.def_property("maximum_allocation_size",
93+
static_cast<getter_t<uint64_t>>(&LoadConfiguration::maximum_allocation_size),
94+
static_cast<setter_t<uint64_t>>(&LoadConfiguration::maximum_allocation_size),
95+
"Maximum allocation size, in bytes.")
96+
97+
.def_property("virtual_memory_threshold",
98+
static_cast<getter_t<uint64_t>>(&LoadConfiguration::virtual_memory_threshold),
99+
static_cast<setter_t<uint64_t>>(&LoadConfiguration::virtual_memory_threshold),
100+
"Maximum virtual memory size, in bytes.")
101+
102+
.def_property("process_affinity_mask",
103+
static_cast<getter_t<uint64_t>>(&LoadConfiguration::process_affinity_mask),
104+
static_cast<setter_t<uint64_t>>(&LoadConfiguration::process_affinity_mask),
105+
"Setting this field to a non-zero value is equivalent to calling "
106+
"``SetProcessAffinityMask`` with this value during process startup (.exe only)")
107+
108+
.def_property("process_heap_flags",
109+
static_cast<getter_t<uint32_t>>(&LoadConfiguration::process_heap_flags),
110+
static_cast<setter_t<uint32_t>>(&LoadConfiguration::process_heap_flags),
111+
"Process heap flags that correspond to the first argument of the "
112+
"``HeapCreate`` function. These flags apply to the process heap that is "
113+
"created during process startup.")
114+
115+
.def_property("csd_version",
116+
static_cast<getter_t<uint16_t>>(&LoadConfiguration::csd_version),
117+
static_cast<setter_t<uint16_t>>(&LoadConfiguration::csd_version),
118+
"The service pack version identifier.")
119+
120+
.def_property("reserved1",
121+
static_cast<getter_t<uint16_t>>(&LoadConfiguration::reserved1),
122+
static_cast<setter_t<uint16_t>>(&LoadConfiguration::reserved1),
123+
"Must be zero.")
124+
125+
.def_property("editlist",
126+
static_cast<getter_t<uint32_t>>(&LoadConfiguration::editlist),
127+
static_cast<setter_t<uint32_t>>(&LoadConfiguration::editlist),
128+
"Reserved for use by the system.")
129+
130+
.def_property("security_cookie",
131+
static_cast<getter_t<uint32_t>>(&LoadConfiguration::security_cookie),
132+
static_cast<setter_t<uint32_t>>(&LoadConfiguration::security_cookie),
133+
"A pointer to a cookie that is used by Visual C++ or GS implementation.")
134+
135+
.def("__eq__", &LoadConfiguration::operator==)
136+
.def("__ne__", &LoadConfiguration::operator!=)
137+
.def("__hash__",
138+
[] (const LoadConfiguration& config) {
139+
return LIEF::Hash::hash(config);
140+
})
141+
142+
143+
.def("__str__", [] (const LoadConfiguration& config)
144+
{
145+
std::ostringstream stream;
146+
stream << config;
147+
std::string str = stream.str();
148+
return str;
149+
});
150+
151+
152+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/* Copyright 2017 R. Thomas
2+
* Copyright 2017 Quarkslab
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
#include "pyPE.hpp"
17+
18+
#include "LIEF/visitors/Hash.hpp"
19+
#include "LIEF/PE/LoadConfigurations.hpp"
20+
21+
#include <string>
22+
#include <sstream>
23+
24+
template<class T>
25+
using getter_t = T (LoadConfigurationV0::*)(void) const;
26+
27+
template<class T>
28+
using setter_t = void (LoadConfigurationV0::*)(T);
29+
30+
void init_PE_LoadConfigurationV0_class(py::module& m) {
31+
py::class_<LoadConfigurationV0, LoadConfiguration>(m, "LoadConfigurationV0",
32+
"" RST_CLASS_REF(lief.PE.LoadConfiguration) " enhanced with SEH. \n\n"
33+
"It is associated with the " RST_CLASS_REF(lief.PE.WIN_VERSION) ": "
34+
":attr:`~lief.PE.WIN_VERSION.SEH`")
35+
36+
.def(py::init<>())
37+
38+
.def_property("se_handler_table",
39+
static_cast<getter_t<uint64_t>>(&LoadConfigurationV0::se_handler_table),
40+
static_cast<setter_t<uint64_t>>(&LoadConfigurationV0::se_handler_table),
41+
"The VA of the sorted table of RVAs of each valid, unique "
42+
"SE handler in the image.")
43+
44+
.def_property("se_handler_count",
45+
static_cast<getter_t<uint64_t>>(&LoadConfigurationV0::se_handler_count),
46+
static_cast<setter_t<uint64_t>>(&LoadConfigurationV0::se_handler_count),
47+
"The count of unique handlers in the table.")
48+
49+
50+
.def("__eq__", &LoadConfigurationV0::operator==)
51+
.def("__ne__", &LoadConfigurationV0::operator!=)
52+
.def("__hash__",
53+
[] (const LoadConfigurationV0& config) {
54+
return LIEF::Hash::hash(config);
55+
})
56+
57+
58+
.def("__str__", [] (const LoadConfigurationV0& config)
59+
{
60+
std::ostringstream stream;
61+
stream << config;
62+
std::string str = stream.str();
63+
return str;
64+
});
65+
66+
67+
}
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/* Copyright 2017 R. Thomas
2+
* Copyright 2017 Quarkslab
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
#include "pyPE.hpp"
17+
18+
#include "LIEF/visitors/Hash.hpp"
19+
#include "LIEF/PE/LoadConfigurations.hpp"
20+
21+
#include <string>
22+
#include <sstream>
23+
24+
template<class T>
25+
using getter_t = T (LoadConfigurationV1::*)(void) const;
26+
27+
template<class T>
28+
using setter_t = void (LoadConfigurationV1::*)(T);
29+
30+
void init_PE_LoadConfigurationV1_class(py::module& m) {
31+
py::class_<LoadConfigurationV1, LoadConfigurationV0>(m, "LoadConfigurationV1",
32+
"" RST_CLASS_REF(lief.PE.LoadConfigurationV0) " enhanced with *Control Flow Guard*. \n\n"
33+
"It is associated with the " RST_CLASS_REF(lief.PE.WIN_VERSION) ": "
34+
":attr:`~lief.PE.WIN_VERSION.WIN_8_1`"
35+
)
36+
.def(py::init<>())
37+
38+
.def_property("guard_cf_check_function_pointer",
39+
static_cast<getter_t<uint64_t>>(&LoadConfigurationV1::guard_cf_check_function_pointer),
40+
static_cast<setter_t<uint64_t>>(&LoadConfigurationV1::guard_cf_check_function_pointer),
41+
"The VA where Control Flow Guard check-function pointer is stored.")
42+
43+
.def_property("guard_cf_dispatch_function_pointer",
44+
static_cast<getter_t<uint64_t>>(&LoadConfigurationV1::guard_cf_dispatch_function_pointer),
45+
static_cast<setter_t<uint64_t>>(&LoadConfigurationV1::guard_cf_dispatch_function_pointer),
46+
"The VA where Control Flow Guard dispatch-function pointer is stored.")
47+
48+
.def_property("guard_cf_function_table",
49+
static_cast<getter_t<uint64_t>>(&LoadConfigurationV1::guard_cf_function_table),
50+
static_cast<setter_t<uint64_t>>(&LoadConfigurationV1::guard_cf_function_table),
51+
"The VA of the sorted table of RVAs of each Control Flow Guard function in the image.")
52+
53+
.def_property("guard_cf_function_count",
54+
static_cast<getter_t<uint64_t>>(&LoadConfigurationV1::guard_cf_function_count),
55+
static_cast<setter_t<uint64_t>>(&LoadConfigurationV1::guard_cf_function_count),
56+
"The count of unique RVAs in the :attr:`~lief.PE.LoadConfigurationV1.guard_cf_function_table`")
57+
58+
.def_property("guard_flags",
59+
static_cast<getter_t<uint32_t>>(&LoadConfigurationV1::guard_flags),
60+
static_cast<setter_t<uint32_t>>(&LoadConfigurationV1::guard_flags),
61+
"Control Flow Guard related flags.")
62+
63+
.def("has",
64+
static_cast<bool (LoadConfigurationV1::*)(GUARD_CF_FLAGS) const>(&LoadConfigurationV1::has),
65+
"Check if the given " RST_CLASS_REF(lief.PE.GUARD_CF_FLAGS) " is present in "
66+
":attr:`~lief.PE.LoadConfigurationV1.guard_flags`",
67+
"flag"_a)
68+
69+
.def_property_readonly("guard_cf_flags_list",
70+
&LoadConfigurationV1::guard_cf_flags_list,
71+
"Return list of " RST_CLASS_REF(lief.PE.GUARD_CF_FLAGS) " present in "
72+
":attr:`~lief.PE.LoadConfigurationV1.guard_flags`",
73+
py::return_value_policy::reference_internal)
74+
75+
.def("__eq__", &LoadConfigurationV1::operator==)
76+
.def("__ne__", &LoadConfigurationV1::operator!=)
77+
.def("__hash__",
78+
[] (const LoadConfigurationV1& config) {
79+
return LIEF::Hash::hash(config);
80+
})
81+
82+
83+
.def("__contains__",
84+
static_cast<bool (LoadConfigurationV1::*)(GUARD_CF_FLAGS) const>(&LoadConfigurationV1::has))
85+
86+
87+
.def("__str__", [] (const LoadConfigurationV1& config)
88+
{
89+
std::ostringstream stream;
90+
stream << config;
91+
std::string str = stream.str();
92+
return str;
93+
});
94+
95+
96+
}

0 commit comments

Comments
 (0)