libPeConv
A library to load, manipulate, dump PE files.
Loading...
Searching...
No Matches
libpeconv
src
util.cpp
Go to the documentation of this file.
1
#include "
peconv/util.h
"
2
#include <iostream>
3
4
#define USE_OLD_BADPTR
5
6
namespace
peconv
{
7
8
HMODULE
g_kernel32Hndl
=
nullptr
;
9
HMODULE
g_ntdllHndl
=
nullptr
;
10
11
HMODULE
get_kernel32_hndl
()
12
{
13
if
(
g_kernel32Hndl
==
nullptr
) {
14
g_kernel32Hndl
=
LoadLibraryA
(
"kernel32.dll"
);
15
}
16
return
g_kernel32Hndl
;
17
}
18
19
HMODULE
get_ntdll_hndl
()
20
{
21
if
(
g_ntdllHndl
==
nullptr
) {
22
g_ntdllHndl
=
LoadLibraryA
(
"ntdll.dll"
);
23
}
24
return
g_ntdllHndl
;
25
}
26
};
27
28
DWORD
ntdll_get_process_id
(
HANDLE
hProcess
)
29
{
30
#if !defined PROCESSINFOCLASS
31
typedef
LONG
PROCESSINFOCLASS
;
32
#endif
33
34
NTSTATUS
(
WINAPI
*
_ZwQueryInformationProcess
)(
35
IN
HANDLE
ProcessHandle
,
36
IN
PROCESSINFOCLASS
ProcessInformationClass
,
37
OUT
PVOID
ProcessInformation
,
38
IN
ULONG
ProcessInformationLength
,
39
OUT
PULONG
ReturnLength
40
) =
NULL
;
41
42
HINSTANCE
hNtDll
=
peconv::get_ntdll_hndl
();
43
if
(!
hNtDll
) {
44
return
0;
45
}
46
47
FARPROC
procPtr
=
GetProcAddress
(
hNtDll
,
"ZwQueryInformationProcess"
);
48
if
(!
procPtr
) {
49
return
0;
50
}
51
52
_ZwQueryInformationProcess
= (
NTSTATUS
(
WINAPI
*)(
53
HANDLE
,
54
PROCESSINFOCLASS
,
55
PVOID
,
56
ULONG
,
57
PULONG
)
58
)
procPtr
;
59
60
typedef
struct
_PROCESS_BASIC_INFORMATION
{
61
PVOID
Reserved1
;
62
PVOID
PebBaseAddress
;
63
PVOID
Reserved2[2];
64
ULONG_PTR
UniqueProcessId
;
65
PVOID
Reserved3;
66
}
PROCESS_BASIC_INFORMATION
;
67
68
PROCESS_BASIC_INFORMATION
pbi
= { 0 };
69
if
(
_ZwQueryInformationProcess
(
hProcess
, 0, &
pbi
,
sizeof
(
PROCESS_BASIC_INFORMATION
),
NULL
) ==
S_OK
) {
70
const
DWORD
pid
=
static_cast<
DWORD
>
(
pbi
.UniqueProcessId);
71
return
pid
;
72
}
73
return
0;
74
}
75
76
DWORD
peconv::get_process_id
(
HANDLE
hProcess
)
77
{
78
static
DWORD
(
WINAPI
*
_GetProcessId
)(
IN
HANDLE
Process
) =
nullptr
;
79
80
DWORD
processID
= 0;
81
if
(!
_GetProcessId
) {
82
HMODULE
kernelLib
=
peconv::get_kernel32_hndl
();
83
if
(
kernelLib
) {
84
FARPROC
procPtr
=
GetProcAddress
(
kernelLib
,
"GetProcessId"
);
85
if
(
procPtr
) {
86
_GetProcessId
= (
DWORD
(
WINAPI
*) (
IN
HANDLE
))
procPtr
;
87
}
88
}
89
}
90
if
(
_GetProcessId
) {
91
processID
=
_GetProcessId
(
hProcess
);
92
}
93
if
(
processID
== 0) {
94
//could not retrieve Pid using GetProcessId, try using NTDLL:
95
processID
=
ntdll_get_process_id
(
hProcess
);
96
}
97
return
processID
;
98
}
99
100
bool
peconv::is_padding
(
const
BYTE
*
cave_ptr
,
size_t
cave_size
,
const
BYTE
padding
)
101
{
102
for
(
size_t
i
= 0;
i
<
cave_size
;
i
++) {
103
if
(
cave_ptr
[
i
] !=
padding
) {
104
return
false
;
105
}
106
}
107
return
true
;
108
}
109
110
bool
peconv::is_mem_accessible
(
LPCVOID
areaStart
,
SIZE_T
areaSize
,
DWORD
dwAccessRights
)
111
{
112
if
(!
areaSize
)
return
false
;
// zero-sized areas are not allowed
113
114
const
DWORD
dwForbiddenArea
=
PAGE_GUARD
|
PAGE_NOACCESS
;
115
116
MEMORY_BASIC_INFORMATION
mbi
= { 0 };
117
const
size_t
mbiSize
=
sizeof
(
MEMORY_BASIC_INFORMATION
);
118
119
SIZE_T
sizeToCheck
=
areaSize
;
120
LPCVOID
areaPtr
=
areaStart
;
121
122
while
(
sizeToCheck
> 0) {
123
//reset area
124
memset
(&
mbi
, 0,
mbiSize
);
125
126
// query the next area
127
if
(
VirtualQuery
(
areaPtr
, &
mbi
,
mbiSize
) !=
mbiSize
) {
128
return
false
;
// could not query the area, assume it is bad
129
}
130
// check the privileges
131
bool
isOk
= (
mbi
.State &
MEM_COMMIT
)
// memory allocated and
132
&& !(
mbi
.Protect &
dwForbiddenArea
)
// access to page allowed and
133
&& (
mbi
.Protect &
dwAccessRights
);
// the required rights
134
if
(!
isOk
) {
135
return
false
;
//invalid access
136
}
137
SIZE_T
offset
= (
ULONG_PTR
)
areaPtr
- (
ULONG_PTR
)
mbi
.BaseAddress;
138
SIZE_T
queriedSize
=
mbi
.RegionSize -
offset
;
139
if
(
queriedSize
>=
sizeToCheck
) {
140
return
true
;
// it is fine
141
}
142
// move to the next region
143
sizeToCheck
-=
queriedSize
;
144
areaPtr
=
LPCVOID
((
ULONG_PTR
)
areaPtr
+
queriedSize
);
145
}
146
// by default assume it is inaccessible
147
return
false
;
148
}
149
150
bool
peconv::is_bad_read_ptr
(
LPCVOID
areaStart
,
SIZE_T
areaSize
)
151
{
152
#ifdef USE_OLD_BADPTR
// classic IsBadReadPtr is much faster than the version using VirtualQuery
153
return
(
IsBadReadPtr
(
areaStart
,
areaSize
)) ?
true
:
false
;
154
#else
155
const
DWORD
dwReadRights
=
PAGE_READONLY
|
PAGE_READWRITE
|
PAGE_WRITECOPY
|
PAGE_EXECUTE_READ
|
PAGE_EXECUTE_READWRITE
|
PAGE_EXECUTE_WRITECOPY
;
156
bool
isAccessible
=
peconv::is_mem_accessible
(
areaStart
,
areaSize
,
dwReadRights
);
157
if
(
isAccessible
) {
158
// the area has read access rights: not a bad read pointer
159
return
false
;
160
}
161
return
true
;
162
#endif
163
}
parse_delayed_desc
bool parse_delayed_desc(BYTE *modulePtr, const size_t moduleSize, const ULONGLONG img_base, LPSTR lib_name, const T_FIELD ordinal_flag, IMAGE_DELAYLOAD_DESCRIPTOR *desc, peconv::t_function_resolver *func_resolver)
Definition
delayed_imports_loader.cpp:26
peconv
Definition
buffer_util.h:15
peconv::get_process_id
DWORD get_process_id(HANDLE hProcess)
Definition
util.cpp:76
peconv::is_mem_accessible
bool is_mem_accessible(LPCVOID areaStart, SIZE_T areaSize, DWORD accessRights)
Definition
util.cpp:110
peconv::g_ntdllHndl
HMODULE g_ntdllHndl
Definition
util.cpp:9
peconv::is_padding
bool is_padding(const BYTE *cave_ptr, size_t cave_size, const BYTE padding_char)
Definition
util.cpp:100
peconv::get_kernel32_hndl
HMODULE get_kernel32_hndl()
Definition
util.cpp:11
peconv::is_bad_read_ptr
bool is_bad_read_ptr(LPCVOID areaStart, SIZE_T areaSize)
Definition
util.cpp:150
peconv::g_kernel32Hndl
HMODULE g_kernel32Hndl
Definition
util.cpp:8
peconv::get_ntdll_hndl
HMODULE get_ntdll_hndl()
Definition
util.cpp:19
ntdll_get_process_id
DWORD ntdll_get_process_id(HANDLE hProcess)
Definition
util.cpp:28
util.h
Miscellaneous utility functions.
Generated on Thu Apr 11 2024 16:32:36 for libPeConv by
1.10.0