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#include "peconv/logger.h"
5
6using namespace peconv;
7
8PBYTE peconv::find_ending_cave(BYTE*modulePtr, size_t moduleSize, const DWORD minimal_size, const DWORD req_charact, bool reserve)
9{
10 size_t sec_count = peconv::get_sections_count(modulePtr, moduleSize);
11 if (sec_count == 0) return nullptr;
12
13 size_t last_sec = sec_count - 1;
14 PIMAGE_SECTION_HEADER section_hdr = peconv::get_section_hdr(modulePtr, moduleSize, last_sec);
15 if (section_hdr == nullptr) return nullptr;
16 if (!(section_hdr->Characteristics & req_charact)) return nullptr;
17
18 DWORD raw_size = section_hdr->SizeOfRawData;
19 DWORD virtual_size = (DWORD)moduleSize - section_hdr->VirtualAddress;
20
21 if (raw_size >= virtual_size) {
22 LOG_INFO("Last section's raw_size: 0x%lx >= virtual_size: 0x%lx", raw_size, virtual_size);
23 return nullptr;
24 }
25 DWORD cave_size = virtual_size - raw_size;
26 if (cave_size < minimal_size) {
27 LOG_INFO("Cave is too small.");
28 return nullptr;
29 }
30 PBYTE cave_ptr = modulePtr + section_hdr->VirtualAddress + section_hdr->SizeOfRawData;
31 if (!validate_ptr(modulePtr, moduleSize, cave_ptr, minimal_size)) {
32 LOG_INFO("Invalid cave pointer.");
33 return nullptr;
34 }
35 if (reserve) {
36 section_hdr->SizeOfRawData += minimal_size; //book this cave
37 }
38 return cave_ptr;
39}
40
41PBYTE peconv::find_alignment_cave(BYTE* modulePtr, size_t moduleSize, const DWORD minimal_size, const DWORD req_charact, bool reserve)
42{
43 DWORD alignment = peconv::get_sec_alignment(modulePtr, true);
44 if (alignment == 0) return nullptr;
45
46 size_t sec_count = peconv::get_sections_count(modulePtr, moduleSize);
47 for (size_t i = 0; i < sec_count; i++) {
48 PIMAGE_SECTION_HEADER section_hdr = peconv::get_section_hdr(modulePtr, moduleSize, i);
49 if (section_hdr == nullptr) continue;
50 if (!(section_hdr->Characteristics & req_charact)) continue;
51
52 DWORD rem = section_hdr->SizeOfRawData % alignment;
53 if (rem == 0) continue;
54
55 DWORD div = (section_hdr->SizeOfRawData / alignment) + 1;
56 DWORD new_size = div * alignment;
57 DWORD cave_size = new_size - section_hdr->SizeOfRawData;
58 if (cave_size < minimal_size) {
59 LOG_INFO("Cave is too small.");
60 continue;
61 }
62 DWORD sec_start = section_hdr->PointerToRawData;
63 if (sec_start == 0) continue;
64
65 DWORD sec_end = sec_start + section_hdr->SizeOfRawData;
66 LOG_INFO("Section: 0x%lx : 0x%lx", sec_start, sec_end);
67 PBYTE cave_ptr = modulePtr + sec_end;
68 if (!validate_ptr(modulePtr, moduleSize, cave_ptr, minimal_size)) {
69 LOG_INFO("Invalid cave pointer.");
70 continue;
71 }
72 if (reserve) {
73 section_hdr->SizeOfRawData += minimal_size; //book this cave
74 }
75 return cave_ptr;
76 }
77 LOG_INFO("Cave not found.");
78 return nullptr;
79}
80
81PBYTE peconv::find_padding_cave(BYTE* modulePtr, size_t moduleSize, const size_t minimal_size, const DWORD req_charact)
82{
83 size_t sec_count = peconv::get_sections_count(modulePtr, moduleSize);
84 for (size_t i = 0; i < sec_count; i++) {
85 PIMAGE_SECTION_HEADER section_hdr = peconv::get_section_hdr(modulePtr, moduleSize, i);
86 if (section_hdr == nullptr) continue;
87 if (!(section_hdr->Characteristics & req_charact)) continue;
88
89 if (section_hdr->SizeOfRawData < minimal_size) continue;
90
91 // we will be searching in the loaded, virtual image:
92 DWORD sec_start = section_hdr->VirtualAddress;
93 if (sec_start == 0) continue;
94
95 DWORD sec_end = sec_start + section_hdr->SizeOfRawData;
96 LOG_INFO("Section: 0x%lx : 0x%lx", sec_start, sec_end);
97 //offset from the end of the section:
98 size_t cave_offset = section_hdr->SizeOfRawData - minimal_size;
99 PBYTE cave_ptr = modulePtr + sec_start + cave_offset;
100 if (!validate_ptr(modulePtr, moduleSize, cave_ptr, minimal_size)) {
101 LOG_INFO("Invalid cave pointer.");
102 continue;
103 }
104 bool found = false;
105 if (is_padding(cave_ptr, minimal_size, 0)) {
106 found = true;
107 }
108 //if the section is code, check also code padding:
109 if (section_hdr->Characteristics & IMAGE_SCN_MEM_EXECUTE) {
110 if (is_padding(cave_ptr, minimal_size, 0xCC)) {
111 found = true;
112 }
113 }
114 if (found) {
115 return cave_ptr;
116 }
117 }
118 LOG_INFO("Cave not found.");
119 return nullptr;
120}
Functions related to finding caves in the loaded PE file.
#define LOG_INFO(fmt,...)
Definition logger.h:50
PBYTE find_padding_cave(BYTE *module_ptr, size_t module_size, const size_t minimal_size, const DWORD req_charact=IMAGE_SCN_MEM_READ)
Definition caves.cpp:81
PBYTE find_ending_cave(BYTE *module_ptr, size_t module_size, const DWORD cave_size, const DWORD req_charact=IMAGE_SCN_MEM_READ, bool reserve=true)
Definition caves.cpp:8
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:106
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_alignment_cave(BYTE *module_ptr, size_t module_size, const DWORD cave_size, const DWORD req_charact=IMAGE_SCN_MEM_READ, bool reserve=true)
Definition caves.cpp:41
Wrappers over various fields in the PE header. Read, write, parse PE headers.
Miscellaneous utility functions.