10#pragma comment(lib,"psapi.lib")
19 if (my_name.length() == 0 || my_name.length() >
MAX_PATH) {
23 memcpy(this->
szModName, my_name.c_str(), my_name.length());
33 bool is_ok = _loadOriginal(
true);
36 is_ok = _loadOriginal(
false);
43 if (strlen(this->szModName) == 0) {
47 peconv::free_pe_buffer(original_module, original_size);
49 BOOL isRedirDisabled = FALSE;
59 original_module = peconv::load_pe_module(szModName, original_size,
false,
false);
62 if (isRedirDisabled) {
65 if (!original_module) {
68 this->is_dot_net = isDotNetManagedCode();
75 if (!original_module || !original_size) {
79 class CollectRelocField :
public peconv::RelocBlockCallback
82 CollectRelocField(
ModuleData &_mod, std::set<DWORD>& _fields)
83 : RelocBlockCallback(_mod.
is64bit()), mod(_mod), fields(_fields)
87 virtual bool processRelocField(ULONG_PTR relocField)
89 DWORD reloc_rva = mod.vaToRva(relocField, (ULONG_PTR)mod.original_module);
90 fields.insert(reloc_rva);
94 std::set<DWORD> &fields;
98 if (!peconv::has_valid_relocation_table(original_module, original_size)) {
102 CollectRelocField collector(*
this, fields_rvas);
103 if (!peconv::process_relocation_table(original_module, original_size, &collector)) {
107 if (fields_rvas.size()) {
115 if (!original_module || !original_size) {
118 if (!peconv::has_valid_import_table(original_module, original_size)) {
122 if (!peconv::collect_thunks(original_module, original_size, thunk_rvas)) {
126 if (thunk_rvas.size()) {
134 if (!original_module || !original_size) {
137 if (!peconv::has_valid_import_table(original_module, original_size)) {
141 if (!peconv::collect_imports(original_module, original_size, collection)) {
150 if (!original_module)
return false;
152 ULONGLONG original_base = peconv::get_image_base(original_module);
153 if (original_base == new_base) {
156 if (peconv::has_relocations(original_module)
157 && !peconv::relocate_module(original_module, original_size, new_base, original_base))
160 std::cerr <<
"[!] Relocating module failed!" << std::endl;
164 peconv::update_image_base(original_module, new_base);
172 std::string module_name = this->szModName;
175 size_t mod_name_len = module_name.length();
176 if (!is_same && mod_name_len > 0) {
179 memcpy(path_copy, this->szModName, mod_name_len);
183 this->switchToWow64Path();
192 BOOL isWow64 = FALSE;
206 const size_t len = path.length();
210 ::memcpy(szModName, path.c_str(), len);
217 if (!switchToWow64Path())
return false;
220 peconv::free_pe_buffer(original_module, original_size);
221 if (this->useCache) {
225 original_module = peconv::load_pe_module(szModName, original_size,
false,
false);
227 if (!original_module) {
228 std::cout <<
"[-] Failed to reload: " << szModName <<
"\n";
231 std::cout <<
"[+] Reloaded: " << szModName <<
"\n";
238 IMAGE_DATA_DIRECTORY* dotNetDir = peconv::get_directory_entry(this->original_module, IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR);
239 if (dotNetDir ==
nullptr) {
244 if (!peconv::get_dotnet_hdr(this->original_module, this->original_size, dotNetDir)){
248 std::cout <<
"This is a .NET module" << std::endl;
258 if (!GetModuleFileNameExA(processHandle, modBaseAddr, filename,
MAX_PATH)) {
263 if (expanded.length() == 0) {
272 if (GetMappedFileNameA(processHandle, modBaseAddr, filename,
MAX_PATH) == 0) {
276 if (expanded.length() == 0) {
284 if (!isFullImageLoaded()) {
287 if (!peconv::has_valid_import_table(imgBuffer, imgBufferSize)) {
291 if (!peconv::collect_imports(imgBuffer, imgBufferSize, collection)) {
300 this->isHdrReady =
false;
304 this->isHdrReady =
true;
310 if (this->isFullImageLoaded()) {
313 this->imgBuffer = peconv::alloc_pe_buffer(mod_size, PAGE_READWRITE);
314 this->imgBufferSize = peconv::read_remote_pe(this->processHandle, (PBYTE)this->modBaseAddr, mod_size, this->imgBuffer, mod_size);
315 if (this->imgBufferSize == mod_size) {
318 this->freeFullImage();
324 if (this->isFullImageLoaded()) {
327 size_t mod_size = this->getHdrImageSize();
328 if (_loadFullImage(mod_size)) {
332 mod_size = calcImgSize();
333 return _loadFullImage(mod_size);
338 if (!peconv::read_remote_pe_header(this->processHandle, (PBYTE)this->modBaseAddr, this->headerBuffer, peconv::MAX_HEADER_SIZE, this->isReflection)) {
346 if (!this->isInitialized())
return NULL;
348 PIMAGE_SECTION_HEADER section_hdr = peconv::get_section_hdr(headerBuffer, peconv::MAX_HEADER_SIZE, section_num);
349 if ((section_hdr == NULL) || section_hdr->SizeOfRawData == 0) {
352 return (ULONGLONG) modBaseAddr + section_hdr->VirtualAddress;
357 if (!this->isInitialized()) {
360 const DWORD ep_va = peconv::get_entry_point_rva(this->headerBuffer);
364 PIMAGE_SECTION_HEADER sec_hdr = peconv::get_section_hdr(this->headerBuffer, peconv::MAX_HEADER_SIZE, section_number);
368 if (ep_va >= sec_hdr->VirtualAddress
369 && ep_va < (sec_hdr->VirtualAddress + sec_hdr->Misc.VirtualSize))
380 ULONGLONG start_va = getRemoteSectionVa(section_number);
381 if (start_va == NULL) {
384 MEMORY_BASIC_INFORMATION page_info = { 0 };
386 SIZE_T out = VirtualQueryEx(processHandle, (LPCVOID) start_va, &page_info,
sizeof(page_info));
387 if (out !=
sizeof(page_info)) {
389 std::cerr <<
"Cannot retrieve remote section info" << std::endl;
394 std::cout << std::hex <<
"Sec: " << section_number <<
" VA: " << start_va <<
" t: " << page_info.Type <<
" p: " << page_info.Protect << std::endl;
407 if (allow_inaccessible) {
418 size_t sec_count = peconv::get_sections_count(this->headerBuffer, peconv::MAX_HEADER_SIZE);
419 for (
size_t i = 0; i < sec_count ; i++) {
420 if (isSectionExecutable(i, allow_data, allow_inaccessible)) {
430 if (!isHdrReady)
return 0;
static size_t calcImgSize(HANDLE processHandle, HMODULE modBaseAddr, BYTE *headerBuffer, size_t headerBufferSize, IMAGE_SECTION_HEADER *hdr_ptr=NULL)
Loads a module from the disk, corresponding to the module in the scanned process' memory.
bool autoswichIfWow64Mapping()
bool relocateToBase(ULONGLONG new_base)
bool loadRelocatedFields(std::set< DWORD > &fields_rvas)
bool _loadOriginal(bool disableFSredir)
bool loadImportsList(peconv::ImportsCollection &collection)
bool switchToMappedPath()
bool loadImportThunks(std::set< DWORD > &fields_rvas)
bool isDotNetManagedCode()
BYTE * loadCached(LPSTR szModName, size_t &original_size)
bool _loadFullImage(size_t v_size)
bool loadImportsList(peconv::ImportsCollection &collection)
static std::string getModuleName(HANDLE _processHandle, HMODULE _modBaseAddr)
bool hasExecutableSection(bool allow_data, bool allow_inaccessible)
bool isSectionExecutable(const size_t section_number, bool allow_data, bool allow_inaccessible)
static std::string getMappedName(HANDLE _processHandle, LPVOID _modBaseAddr)
ULONGLONG getRemoteSectionVa(const size_t section_num)
bool isSectionEntry(const size_t section_number)
pesieve::ModulesCache cache
std::string expand_path(const std::string &path)
std::string to_lowercase(std::string)
BOOL wow64_disable_fs_redirection(OUT PVOID *OldValue)
BOOL is_process_wow64(IN HANDLE processHandle, OUT BOOL *isProcWow64)
bool is_readable(DWORD mapping_type, DWORD protection)
std::string convert_to_win32_path(const std::string &path)
bool is_normal_inaccessible(DWORD state, DWORD mapping_type, DWORD protection)
BOOL(CALLBACK *_MiniDumpWriteDump)(HANDLE hProcess
bool is_executable(DWORD mapping_type, DWORD protection)
DWORD(__stdcall *_PssCaptureSnapshot)(HANDLE ProcessHandle
bool convert_to_wow64_path(char *szModName)
BOOL wow64_revert_fs_redirection(IN PVOID OldValue)