libPeConv
A library to load, manipulate, dump PE files.
Loading...
Searching...
No Matches
caves.cpp
Go to the documentation of this file.
1#include "peconv/caves.h"
3#include "peconv/util.h"
4
5using namespace peconv;
6
7#ifdef _DEBUG
8#include <iostream>
9#endif
10
11PBYTE peconv::find_ending_cave(BYTE*modulePtr, size_t moduleSize, const DWORD minimal_size, const DWORD req_charact)
12{
13 size_t sec_count = peconv::get_sections_count(modulePtr, moduleSize);
14 if (sec_count == 0) return nullptr;
15
16 size_t last_sec = sec_count - 1;
17 PIMAGE_SECTION_HEADER section_hdr = peconv::get_section_hdr(modulePtr, moduleSize, last_sec);
18 if (section_hdr == nullptr) return nullptr;
19 if (!(section_hdr->Characteristics & req_charact)) return nullptr;
20
21 DWORD raw_size = section_hdr->SizeOfRawData;
22 DWORD virtual_size = (DWORD)moduleSize - section_hdr->VirtualAddress;
23
24 if (raw_size >= virtual_size) {
25#ifdef _DEBUG
26 std::cout << "Last section's raw_size: " << std::hex << raw_size << " >= virtual_size: " << virtual_size << std::endl;
27#endif
28 return nullptr;
29 }
30 DWORD cave_size = virtual_size - raw_size;
31 if (cave_size < minimal_size) {
32#ifdef _DEBUG
33 std::cout << "Cave is too small" << std::endl;
34#endif
35 return nullptr;
36 }
37 PBYTE cave_ptr = modulePtr + section_hdr->VirtualAddress + section_hdr->SizeOfRawData;
38 if (!validate_ptr(modulePtr, moduleSize, cave_ptr, minimal_size)) {
39#ifdef _DEBUG
40 std::cout << "Invalid cave pointer" << std::endl;
41#endif
42 return nullptr;
43 }
44 section_hdr->SizeOfRawData += minimal_size; //book this cave
45 return cave_ptr;
46}
47
48PBYTE peconv::find_alignment_cave(BYTE* modulePtr, size_t moduleSize, const DWORD minimal_size, const DWORD req_charact)
49{
50 DWORD alignment = peconv::get_sec_alignment(modulePtr, true);
51 if (alignment == 0) return nullptr;
52
53 size_t sec_count = peconv::get_sections_count(modulePtr, moduleSize);
54 for (size_t i = 0; i < sec_count; i++) {
55 PIMAGE_SECTION_HEADER section_hdr = peconv::get_section_hdr(modulePtr, moduleSize, i);
56 if (section_hdr == nullptr) continue;
57 if (!(section_hdr->Characteristics & req_charact)) continue;
58
59 DWORD rem = section_hdr->SizeOfRawData % alignment;
60 if (rem == 0) continue;
61
62 DWORD div = (section_hdr->SizeOfRawData / alignment) + 1;
63 DWORD new_size = div * alignment;
64 DWORD cave_size = new_size - section_hdr->SizeOfRawData;
65 if (cave_size < minimal_size) {
66#ifdef __DEBUG
67 std::cout << "Cave is too small" << std::endl;
68#endif
69 continue;
70 }
71 DWORD sec_start = section_hdr->PointerToRawData;
72 if (sec_start == 0) continue;
73
74 DWORD sec_end = sec_start + section_hdr->SizeOfRawData;
75#ifdef _DEBUG
76 std::cout << "section: " << std::hex << sec_start << " : " << sec_end << std::endl;
77#endif
78 PBYTE cave_ptr = modulePtr + sec_end;
79 if (!validate_ptr(modulePtr, moduleSize, cave_ptr, minimal_size)) {
80#ifdef _DEBUG
81 std::cout << "Invalid cave pointer" << std::endl;
82#endif
83 continue;
84 }
85 section_hdr->SizeOfRawData += minimal_size; //book this cave
86 return cave_ptr;
87 }
88#ifdef _DEBUG
89 std::cout << "Cave not found" << std::endl;
90#endif
91 return nullptr;
92}
93
94PBYTE peconv::find_padding_cave(BYTE* modulePtr, size_t moduleSize, const size_t minimal_size, const DWORD req_charact)
95{
96 size_t sec_count = peconv::get_sections_count(modulePtr, moduleSize);
97 for (size_t i = 0; i < sec_count; i++) {
98 PIMAGE_SECTION_HEADER section_hdr = peconv::get_section_hdr(modulePtr, moduleSize, i);
99 if (section_hdr == nullptr) continue;
100 if (!(section_hdr->Characteristics & req_charact)) continue;
101
102 if (section_hdr->SizeOfRawData < minimal_size) continue;
103
104 // we will be searching in the loaded, virtual image:
105 DWORD sec_start = section_hdr->VirtualAddress;
106 if (sec_start == 0) continue;
107
108 DWORD sec_end = sec_start + section_hdr->SizeOfRawData;
109#ifdef _DEBUG
110 std::cout << "section: " << std::hex << sec_start << " : " << sec_end << std::endl;
111#endif
112 //offset from the end of the section:
113 size_t cave_offset = section_hdr->SizeOfRawData - minimal_size;
114 PBYTE cave_ptr = modulePtr + sec_start + cave_offset;
115 if (!validate_ptr(modulePtr, moduleSize, cave_ptr, minimal_size)) {
116#ifdef _DEBUG
117 std::cout << "Invalid cave pointer" << std::endl;
118#endif
119 continue;
120 }
121 bool found = false;
122 if (is_padding(cave_ptr, minimal_size, 0)) {
123 found = true;
124 }
125 //if the section is code, check also code padding:
126 if (section_hdr->Characteristics & IMAGE_SCN_MEM_EXECUTE) {
127 if (is_padding(cave_ptr, minimal_size, 0xCC)) {
128 found = true;
129 }
130 }
131 if (found) {
132 return cave_ptr;
133 }
134 }
135#ifdef _DEBUG
136 std::cout << "Cave not found" << std::endl;
137#endif
138 return nullptr;
139}
Functions related to finding caves in the loaded PE file.
PBYTE find_alignment_cave(BYTE *modulePtr, size_t moduleSize, const DWORD cave_size, const DWORD req_charact=IMAGE_SCN_MEM_READ)
Definition caves.cpp:48
bool validate_ptr(IN const void *buffer_bgn, IN size_t buffer_size, IN const void *field_bgn, IN size_t field_size)
PIMAGE_SECTION_HEADER get_section_hdr(IN const BYTE *pe_buffer, IN const size_t buffer_size, IN size_t section_num)
bool is_padding(const BYTE *cave_ptr, size_t cave_size, const BYTE padding_char)
Definition util.cpp:100
PBYTE find_ending_cave(BYTE *module_ptr, size_t module_size, const DWORD cave_size, const DWORD cave_charact=IMAGE_SCN_MEM_READ)
Definition caves.cpp:11
DWORD get_sec_alignment(IN const BYTE *modulePtr, IN bool is_raw)
size_t get_sections_count(IN const BYTE *buffer, IN const size_t buffer_size)
PBYTE find_padding_cave(BYTE *modulePtr, size_t moduleSize, const size_t minimal_size, const DWORD req_charact=IMAGE_SCN_MEM_READ)
Definition caves.cpp:94
Wrappers over various fields in the PE header. Read, write, parse PE headers.
Miscellaneous utility functions.