添加项目文件。
This commit is contained in:
178
Etw Syscall/libpeconv-master/libpeconv/src/peb_lookup.cpp
Normal file
178
Etw Syscall/libpeconv-master/libpeconv/src/peb_lookup.cpp
Normal file
@@ -0,0 +1,178 @@
|
||||
#include "ntddk.h"
|
||||
|
||||
#include <peconv/peb_lookup.h>
|
||||
|
||||
class SectionLocker {
|
||||
public:
|
||||
SectionLocker(RTL_CRITICAL_SECTION &_section)
|
||||
: section(_section)
|
||||
{
|
||||
RtlEnterCriticalSection(§ion);
|
||||
}
|
||||
|
||||
~SectionLocker()
|
||||
{
|
||||
RtlLeaveCriticalSection(§ion);
|
||||
}
|
||||
|
||||
protected:
|
||||
RTL_CRITICAL_SECTION §ion;
|
||||
};
|
||||
|
||||
//here we don't want to use any functions imported form extenal modules
|
||||
|
||||
typedef struct _LDR_MODULE {
|
||||
LIST_ENTRY InLoadOrderModuleList;// +0x00
|
||||
LIST_ENTRY InMemoryOrderModuleList;// +0x08
|
||||
LIST_ENTRY InInitializationOrderModuleList;// +0x10
|
||||
void* BaseAddress; // +0x18
|
||||
void* EntryPoint; // +0x1c
|
||||
ULONG SizeOfImage;
|
||||
UNICODE_STRING FullDllName;
|
||||
UNICODE_STRING BaseDllName;
|
||||
ULONG Flags;
|
||||
SHORT LoadCount;
|
||||
SHORT TlsIndex;
|
||||
HANDLE SectionHandle;
|
||||
ULONG CheckSum;
|
||||
ULONG TimeDateStamp;
|
||||
} LDR_MODULE, *PLDR_MODULE;
|
||||
|
||||
inline PPEB get_peb()
|
||||
{
|
||||
#if defined(_WIN64)
|
||||
return (PPEB)__readgsqword(0x60);
|
||||
#else
|
||||
return (PPEB)__readfsdword(0x30);
|
||||
/*
|
||||
//alternative way to fetch it:
|
||||
LPVOID PEB = NULL;
|
||||
__asm {
|
||||
mov eax, fs:[30h]
|
||||
mov PEB, eax
|
||||
};
|
||||
return (PPEB)PEB;
|
||||
|
||||
or:
|
||||
LPVOID PEB = RtlGetCurrentPeb();
|
||||
*/
|
||||
#endif
|
||||
}
|
||||
|
||||
inline WCHAR to_lowercase(WCHAR c1)
|
||||
{
|
||||
if (c1 <= L'Z' && c1 >= L'A') {
|
||||
c1 = (c1 - L'A') + L'a';
|
||||
}
|
||||
return c1;
|
||||
}
|
||||
|
||||
bool is_wanted_module(LPWSTR curr_name, LPWSTR wanted_name)
|
||||
{
|
||||
if (wanted_name == NULL || curr_name == NULL) return false;
|
||||
|
||||
WCHAR *curr_end_ptr = curr_name;
|
||||
while (*curr_end_ptr != L'\0') {
|
||||
curr_end_ptr++;
|
||||
}
|
||||
if (curr_end_ptr == curr_name) return false;
|
||||
|
||||
WCHAR *wanted_end_ptr = wanted_name;
|
||||
while (*wanted_end_ptr != L'\0') {
|
||||
wanted_end_ptr++;
|
||||
}
|
||||
if (wanted_end_ptr == wanted_name) return false;
|
||||
|
||||
while ((curr_end_ptr != curr_name) && (wanted_end_ptr != wanted_name)) {
|
||||
|
||||
if (to_lowercase(*wanted_end_ptr) != to_lowercase(*curr_end_ptr)) {
|
||||
return false;
|
||||
}
|
||||
wanted_end_ptr--;
|
||||
curr_end_ptr--;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
HMODULE peconv::get_module_via_peb(IN OPTIONAL LPWSTR module_name)
|
||||
{
|
||||
PPEB peb = get_peb();
|
||||
if (!peb) {
|
||||
return NULL;
|
||||
}
|
||||
SectionLocker locker(*peb->LoaderLock);
|
||||
LIST_ENTRY head = peb->Ldr->InLoadOrderModuleList;
|
||||
|
||||
const PLDR_MODULE first_module = *((PLDR_MODULE *)(&head));
|
||||
PLDR_MODULE curr_module = first_module;
|
||||
if (!module_name) {
|
||||
return (HMODULE)(curr_module->BaseAddress);
|
||||
}
|
||||
|
||||
// it is a cyclic list, so if the next record links to the initial one, it means we went throught the full loop
|
||||
do {
|
||||
// this should also work as a terminator, because the BaseAddress of the last module in the cycle is NULL
|
||||
if (curr_module == NULL || curr_module->BaseAddress == NULL) {
|
||||
break;
|
||||
}
|
||||
if (is_wanted_module(curr_module->BaseDllName.Buffer, module_name)) {
|
||||
return (HMODULE)(curr_module->BaseAddress);
|
||||
}
|
||||
curr_module = (PLDR_MODULE)curr_module->InLoadOrderModuleList.Flink;
|
||||
|
||||
} while (curr_module != first_module);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t peconv::get_module_size_via_peb(IN OPTIONAL HMODULE hModule)
|
||||
{
|
||||
PPEB peb = get_peb();
|
||||
if (!peb) {
|
||||
return 0;
|
||||
}
|
||||
SectionLocker locker(*peb->LoaderLock);
|
||||
LIST_ENTRY head = peb->Ldr->InLoadOrderModuleList;
|
||||
|
||||
const PLDR_MODULE first_module = *((PLDR_MODULE *)(&head));
|
||||
PLDR_MODULE curr_module = first_module;
|
||||
if (!hModule) {
|
||||
return (size_t)(curr_module->SizeOfImage);
|
||||
}
|
||||
|
||||
// it is a cyclic list, so if the next record links to the initial one, it means we went throught the full loop
|
||||
do {
|
||||
// this should also work as a terminator, because the BaseAddress of the last module in the cycle is NULL
|
||||
if (curr_module == NULL || curr_module->BaseAddress == NULL) {
|
||||
break;
|
||||
}
|
||||
if (hModule == (HMODULE)(curr_module->BaseAddress)) {
|
||||
return (size_t)(curr_module->SizeOfImage);
|
||||
}
|
||||
curr_module = (PLDR_MODULE)curr_module->InLoadOrderModuleList.Flink;
|
||||
|
||||
} while (curr_module != first_module);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool peconv::set_main_module_in_peb(HMODULE module_ptr)
|
||||
{
|
||||
PPEB peb = get_peb();
|
||||
if (peb == NULL) {
|
||||
return false;
|
||||
}
|
||||
SectionLocker locker(*peb->FastPebLock);
|
||||
peb->ImageBaseAddress = module_ptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
HMODULE peconv::get_main_module_via_peb()
|
||||
{
|
||||
PPEB peb = get_peb();
|
||||
if (peb == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
SectionLocker locker(*peb->FastPebLock);
|
||||
return (HMODULE) peb->ImageBaseAddress;
|
||||
}
|
||||
Reference in New Issue
Block a user