// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file.
// This file implements PEImage, a generic class to manipulate PE files. // This file was adapted from GreenBorder's Code.
size_t directory_count = debug_directory_size / sizeof(IMAGE_DEBUG_DIRECTORY); for (size_t index = 0; index < directory_count; ++index) { const IMAGE_DEBUG_DIRECTORY& entry = debug_directory[index]; if (entry.Type != IMAGE_DEBUG_TYPE_CODEVIEW) continue; // Unsupported debugging info format. if (entry.SizeOfData < sizeof(PdbInfo)) continue; // The data is too small to hold PDB info. const PdbInfo* pdb_info = reinterpret_cast<const PdbInfo*>(RVAToAddr(entry.AddressOfRawData)); if (!pdb_info) continue; // The data is not present in a mapped section. if (pdb_info->Signature != kPdbInfoSignature) continue; // Unsupported PdbInfo signature
if (guid)
*guid = pdb_info->Guid; if (age)
*age = pdb_info->Age; if (pdb_filename) { const size_t length_max =
entry.SizeOfData - offsetof(PdbInfo, PdbFileName); constchar* eos = pdb_info->PdbFileName; for (constchar* const end = pdb_info->PdbFileName + length_max;
eos < end && *eos; ++eos)
;
*pdb_filename_length = eos - pdb_info->PdbFileName;
*pdb_filename = pdb_info->PdbFileName;
} returntrue;
} returnfalse;
}
for (UINT count = 0; count < num_funcs; count++) {
PVOID func = RVAToAddr(functions[count]); if (nullptr == func) continue;
// Check for a name.
LPCSTR name = nullptr;
UINT hint; for (hint = 0; hint < num_names; hint++) { if (ordinals[hint] == count) {
name = reinterpret_cast<LPCSTR>(RVAToAddr(names[hint])); break;
}
}
// check if VC7-style imports, using RVAs instead of // VC6-style addresses. bool rvas = (delay_descriptor->grAttrs & dlattrRva) != 0;
if (rvas) {
module_name = reinterpret_cast<LPCSTR>(RVAToAddr(delay_descriptor->rvaDLLName));
name_table = reinterpret_cast<PIMAGE_THUNK_DATA>(
RVAToAddr(delay_descriptor->rvaINT));
iat = reinterpret_cast<PIMAGE_THUNK_DATA>(
RVAToAddr(delay_descriptor->rvaIAT));
} else { // Values in IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT are 32-bit, even on 64-bit // platforms. See section 4.8 of PECOFF image spec rev 8.3.
module_name = reinterpret_cast<LPCSTR>( static_cast<uintptr_t>(delay_descriptor->rvaDLLName));
name_table = reinterpret_cast<PIMAGE_THUNK_DATA>( static_cast<uintptr_t>(delay_descriptor->rvaINT));
iat = reinterpret_cast<PIMAGE_THUNK_DATA>( static_cast<uintptr_t>(delay_descriptor->rvaIAT));
}
if (target_module_name == nullptr ||
(lstrcmpiA(module_name, target_module_name) == 0)) { if (target_module_name) { // Ensure all imports are properly loaded for the target module so that // the callback is operating on a fully-realized set of imports. // This call only loads the imports for the module where this code is // executing, so it is only helpful or meaningful to do this if the // current module is the module whose IAT we are enumerating. // Use the module_name as retrieved from the IAT because this method // is case sensitive. if (module_ == CURRENT_MODULE() && !LDR_IS_RESOURCE(module_)) { static base::NoDestructor<std::set<std::string>> loaded_dlls; // pair.second is true if this is a new element if (loaded_dlls.get()->emplace(module_name).second)
::__HrLoadAllImportsForDll(module_name);
}
}
if (!callback(*this, delay_descriptor, module_name, name_table, iat,
cookie)) returnfalse;
}
}
returntrue;
}
bool PEImage::EnumOneDelayImportChunk(EnumImportsFunction callback,
PImgDelayDescr delay_descriptor,
LPCSTR module_name,
PIMAGE_THUNK_DATA name_table,
PIMAGE_THUNK_DATA iat,
PVOID cookie) const { for (; name_table->u1.Ordinal; name_table++, iat++) {
LPCSTR name = nullptr;
WORD ordinal = 0;
WORD hint = 0;
// Get the section that this address belongs to.
PIMAGE_SECTION_HEADER section_header = GetImageSectionFromAddr(address); if (nullptr == section_header) returnfalse;
// Don't follow the virtual RVAToAddr, use the one on the base.
DWORD offset_within_section = static_cast<DWORD>(reinterpret_cast<uintptr_t>(address)) - static_cast<DWORD>(reinterpret_cast<uintptr_t>(
PEImage::RVAToAddr(section_header->VirtualAddress)));
// Does the image report that it includes this directory entry? if (directory >= nt_headers->OptionalHeader.NumberOfRvaAndSizes) return nullptr;
// Is there space for this directory entry in the optional header? if (nt_headers->FileHeader.SizeOfOptionalHeader <
(offsetof(IMAGE_OPTIONAL_HEADER, DataDirectory) +
(directory + 1) * sizeof(IMAGE_DATA_DIRECTORY))) { return nullptr;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.