libpe Biblioteca de análisis de Binarios PE32/PE32+
Biblioteca para analizar las estructuras internas de archivos binarios PE32/PE32+
Introducción
libpe es una biblioteca liviana y muy rápida para analizar binarios PE32(x86) y PE32+(x64), implementada como un módulo C++20.
Tabla de contenidos
- Características
- Uso
- Métodos de claseExpandir
- AbrirArchivo
- CerrarArchivo
- ObtenerEncabezadoDOS
- ObtenerEncabezadoRich
- ObtenerEncabezadoNT
- ObtenerDirectoriosDatos
- ObtenerEncabezadosSecciones
- ObtenerExportación
- ObtenerImportación
- ObtenerRecursos
- ObtenerExcepciones
- ObtenerSeguridad
- ObtenerReubicaciones
- ObtenerDepuración
- ObtenerTLS
- ObtenerConfigCarga
- ObtenerImportaciónEnlazada
- ObtenerImportaciónDiferida
- ObtenerDescriptorCOM
- Métodos auxiliaresExpandir
- MapeosExpandir
- MapearMaquinaEncabArchivo
- MapearCaractEncabArchivo
- MapearMagicEncabOpc
- MapearSubsistemaEncabOpc
- MapearCaractDobleEjecEncabOpc
- MapearCaractEncabSeccion
- MapearIDRecurso
- MapearRevisionCertWin
- MapearTipoCertWin
- MapearTipoReubicación
- MapearTipoDepuración
- MapearCaractTLS
- MapearBanderasGuardiaLCD
- MapearBanderasCOR20
- Licencia
Características
- Funciona con binarios PE32(x86) y PE32+(x64)
- Obtiene todas las estructuras de datos PE32/PE32+:
- Encabezado MSDOS
- Encabezado “Rich”
- Encabezados NT/Archivo/Opcionales
- Directorios de datos
- Secciones
- Tabla de exportación
- Tabla de importación
- Tabla de recursos
- Tabla de excepciones
- Tabla de seguridad
- Tabla de reubicaciones
- Tabla de depuración
- Tabla de TLS
- Directorio de configuración de carga
- Tabla de importación enlazada
- Tabla de importación diferida
- Tabla COM
Pepper es una de las aplicaciones que se crean sobre la libpe
.
Uso
import libpe; int main() { libpe::Clibpe pe(L"C:\\myFile.exe"); //o pe.OpenFile(L"C:\\myFile.exe"); const auto peImp = pe.GetImport(); if(peImp) { ... } ... }
Métodos
OpenFile
auto OpenFile(const wchar_t* pwszFile)->int;
Abre un archivo para su posterior procesamiento, hasta que se llame a CloseFile
o el objeto Clibpe
sale del ámbito y el archivo se cierra automáticamente en el destructor.
libpe::Clibpe pe; if(pe.OpenFile(L"C:\\MyFile.exe") == PEOK) { ... }
CloseFile();
void CloseFile();
Cierra explícitamente el archivo que se abrió previamente con OpenFile(const wchar_t*)
. Este método se invoca automáticamente en el destructor de Clibpe
.
GetDOSHeader
[[nodiscard]] auto GetDOSHeader()const->std::optional<IMAGE_DOS_HEADER>;
Devuelve el encabezado estándar MSDOS de un archivo.
GetRichHeader
[[nodiscard]] auto GetRichHeader()const->std::optional<PERICHHDR_VEC>;
Devuelve una matriz de las estructuras no oficiales y no documentadas llamadas «Rich».
struct PERICHHDR { DWORD dwOffset; //Desplazamiento en bruto del archivo de la entrada. WORD wId; //Id de la entrada. WORD wVersion; //Versión de la entrada. DWORD dwCount; //Cantidad de ocurrencias. }; using PERICHHDR_VEC = std::vector<PERICHHDR>;
GetNTHeader
[[nodiscard]] auto GetNTHeader()const->std::optional<PENTHDR>;
Devuelve el encabezado NT de un archivo.
struct PENTHDR { DWORD dwOffset; //Desplazamiento en bruto del encabezado del archivo. union UNPENTHDR { //Unión de encabezado NT de x86 o x64. IMAGE_NT_HEADERS32 stNTHdr32; //Encabezado x86. IMAGE_NT_HEADERS64 stNTHdr64; //Encabezado x64. } unHdr; };
GetDataDirs
[[nodiscard]] auto GetDataDirs()const->std::optional<PEDATADIR_VEC>;
Devuelve una matriz de las directivas de datos del archivo struct
.
struct PEDATADIR { IMAGE_DATA_DIRECTORY stDataDir; //Encabezado estándar. std::string strSection; //Nombre de la sección en la que reside este directorio (apunta a). }; using PEDATADIR_VEC = std::vector<PEDATADIR>;
GetSecHeaders
[[nodiscard]] auto GetSecHeaders()const->std::optional<PESECHDR_VEC>;
Devuelve una matriz de los encabezados de secciones del archivo struct
.
struct PESECHDR { DWORD dwOffset; //Desplazamiento en bruto del descriptor de encabezado de esta sección. IMAGE_SECTION_HEADER stSecHdr; //Encabezado estándar de sección. std::string strSecName; //Nombre completo de la sección. }; using PESECHDR_VEC = std::vector<PESECHDR>;
GetExport
[[nodiscard]] auto GetExport()const->std::optional<PEEXPORT>;
Devuelve la información de Export del archivo.
struct PEEXPORTFUNC { DWORD dwFuncRVA; //RVA de la función. DWORD dwOrdinal; //Ordinal de la función. DWORD dwNameRVA; //RVA del nombre. std::string strFuncName; //Nombre de la función. std::string strForwarderName; //Nombre del reenviador de la función. }; struct PEEXPORT { DWORD dwOffset; //Desplazamiento en bruto del descriptor del encabezado de exportación del archivo. IMAGE_EXPORT_DIRECTORY stExportDesc; //Descriptor estándar del encabezado de exportación. std::string strModuleName; //Nombre real del módulo. std::vector<PEEXPORTFUNC> vecFuncs; //Matriz de la estructura de las funciones exportadas. };
Ejemplo:
libpe::Clibpe pe(L"RUTA_DEL_ARCHIVO_PE"); const auto peExport = pe.GetExport(); if (!peExport) { return; } peExport->stExportDesc; //Estructura IMAGE_EXPORT_DIRECTORY. peExport->strModuleName; //Nombre del módulo de exportación. peExport->vecFuncs; //Vector de funciones exportadas. for (const auto& itFuncs : peExport->vecFuncs) { itFuncs.strFuncName; //Nombre de la función. itFuncs.dwOrdinal; //Ordinal. itFuncs.dwFuncRVA; //RVA de la función. itFuncs.strForwarderName; //Nombre del reenviador. }
GetImport
[[nodiscard]] auto GetImport()const->std::optional<PEIMPORT_VEC>;
Devuelve una matriz de entradas de la tabla de importación del archivo.
struct PEIMPORTFUNC { union UNPEIMPORTTHUNK { IMAGE_THUNK_DATA32 stThunk32; //Puntero estándar x86. IMAGE_THUNK_DATA64 stThunk64; //Puntero estándar x64. } unThunk; IMAGE_IMPORT_BY_NAME stImpByName; //Estructura estándar IMAGE_IMPORT_BY_NAME. std::string strFuncName; //Nombre de la función. }; struct PEIMPORT { DWORD dwOffset; //Desplazamiento en bruto del descriptor de importación del archivo. IMAGE_IMPORT_DESCRIPTOR stImportDesc; //Descriptor estándar de importación. std::string strModuleName; //Nombre del módulo importado. std::vector<PEIMPORTFUNC> vecImportFunc; //Matriz de funciones importadas. }; using PEIMPORT_VEC = std::vector<PEIMPORT>;
Ejemplo:
libpe::Clibpe pe(L"C:\\Windows\\notepad.exe"); const auto peImp = pe.GetImport(); if (!peImp) { return -1; } for (const auto& itModule : *peImp) { //Recorre todas las importaciones que //contiene este archivo PE. std::cout << std::format("{}, Funciones importadas: {}\r\n", itModule.strModuleName, itModule.vecImportFunc.size()); for (const auto& itFuncs : itModule.vecImportFunc) { //Recorre todas //las funciones importadas del módulo itModule. itFuncs.strFuncName; //Nombre de la función importada. itFuncs.stImpByName; //Estructura IMAGE_IMPORT_BY_NAME de esta función. itFuncs.unThunk.stThunk32; //Unión de IMAGE_THUNK_DATA32 o //IMAGE_THUNK_DATA64 (dependiendo del tipo de PE). } }
GetResources
[[nodiscard]] auto GetResources()const->std::optional<PERESROOT>;
Devuelve todos los recursos del archivo.
Ejemplo:
El siguiente fragmento de código recopila los tipos y nombres de todos los recursos que posee el archivo PE y los imprime en std::wcout
estándar.
#include <format> #include <iostream> #include <string> import libpe; using namespace libpe; int main() { libpe::Clibpe pe; if (pe.OpenFile(L"C:\\Windows\\notepad.exe") != PEOK) { return -1; } const auto peResRoot = pe.GetResources(); if (!peResRoot) { return -1; } std::wstring wstrResData; //Esta wstring contendrá todos los recursos por nombre. for (const auto& iterRoot : peResRoot->vecResData) { //Bucle principal para extraer recursos. auto ilvlRoot = 0; auto pResDirEntry = &iterRoot.stResDirEntry; //Entrada de directorio de recursos ROOT. if (pResDirEntry->NameIsString) { wstrResData += std::format(L"Entrada: {} [Nombre: {}]\r\n", ilvlRoot, iterRoot.wstrResName); } else { if (const auto iter = MapResID.find(pResDirEntry->Id); iter != MapResID.end()) { wstrResData += std::format(L"Entrada: {} [Id: {}, {}]\r\n", ilvlRoot, pResDirEntry->Id, iter->second); } else { wstrResData += std::format(L"Entrada: {} [Id: {}]\r\n", ilvlRoot, pResDirEntry->Id); } } if (pResDirEntry->DataIsDirectory) { auto ilvl2 = 0; auto pstResLvL2 = &iterRoot.stResLvL2; for (const auto& iterLvL2 : pstResLvL2->vecResData) { pResDirEntry = &iterLvL2.stResDirEntry; //Entrada de directorio de recursos LEVEL 2. if (pResDirEntry->NameIsString) { wstrResData += std::format (L" Entrada: {}, Nombre: {}\r\n", ilvl2, iterLvL2.wstrResName); } else { wstrResData += std::format (L" Entrada: {}, Id: {}\r\n", ilvl2, pResDirEntry->Id); } if (pResDirEntry->DataIsDirectory) { auto ilvl3 = 0; auto pstResLvL3 = &iterLvL2.stResLvL3; for (const auto& iterLvL3 : pstResLvL3->vecResData) { pResDirEntry = &iterLvL3.stResDirEntry; //Entrada de directorio de recursos LEVEL 3. if (pResDirEntry->NameIsString) { wstrResData += std::format (L" Entrada: {}, Nombre: {}\r\n", ilvl3, iterLvL3.wstrResName); } else { wstrResData += std::format (L" Entrada: {}, idioma: {}\r\n", ilvl3, pResDirEntry->Id); } ++ilvl3; } } ++ilvl2; } } ++ilvlRoot; } std::wcout << wstrResData;
GetExceptions
[[nodiscard]] auto GetExceptions()const->std::optional<PEEXCEPTION_VEC>;
Devuelve una matriz de entradas de Excepción del archivo.
struct PEEXCEPTION { DWORD dwOffset; //Desplazamiento bruto del archivo //del descriptor de excepciones. _IMAGE_RUNTIME_FUNCTION_ENTRY stRuntimeFuncEntry; //Encabezado estándar //_IMAGE_RUNTIME_FUNCTION_ENTRY. }; using PEEXCEPTION_VEC = std::vector<PEEXCEPTION>;
GetSecurity
[[nodiscard]] auto GetSecurity()const->std::optional<PESECURITY_VEC>;
Devuelve una matriz de entradas de Seguridad del archivo.
struct PEWIN_CERTIFICATE { //Réplica completa de la estructura WIN_CERTIFICATE //de <WinTrust.h>. DWORD dwLength; WORD wRevision; WORD wCertificateType; BYTE bCertificate[1]; }; struct PESECURITY { DWORD dwOffset; //Desplazamiento bruto del archivo de este descriptor de seguridad. PEWIN_CERTIFICATE stWinSert; //Estructura estándar WIN_CERTIFICATE. }; using PESECURITY_VEC = std::vector<PESECURITY>;
GetRelocations
[[nodiscard]] auto GetRelocations()const->std::optional<PERELOC_VEC>;
Devuelve una matriz de información de reubicación del archivo.
struct PERELOCDATA { DWORD dwOffset; //Desplazamiento bruto del archivo del descriptor de datos de reubicación. WORD wRelocType; //Tipo de reubicación. WORD wRelocOffset; //Desplazamiento de reubicación (desplazamiento de la reubicación que se debe aplicar). }; struct PERELOC { DWORD dwOffset; //Desplazamiento bruto del archivo del descriptor de //reubicación. IMAGE_BASE_RELOCATION stBaseReloc; //Encabezado estándar IMAGE_BASE_RELOCATION. std::vector<PERELOCDATA> vecRelocData; //Matriz de la estructura de datos de reubicación. }; using PERELOC_VEC = std::vector<PERELOC>;
GetDebug
[[nodiscard]] auto GetDebug()const->std::optional<PEDEBUG_VEC>;
Devuelve una matriz de entradas de Depuración del archivo.
struct PEDEBUGDBGHDR { //dwHdr[6] es una matriz de los primeros seis DWORD de los datos de IMAGE_DEBUG_DIRECTORY::PointerToRawData (encabezado de información de depuración). //Su significado varía según el valor de dwHdr[0] (Firma). //Si dwHdr[0] == 0x53445352 (Ascii "RSDS") es un archivo de PDB 7.0: // Luego dwHdr[1]-dwHdr[4] es GUID (*((GUID*)&dwHdr[1])). dwHdr[5] es Contador/Edad. //Si dwHdr[0] == 0x3031424E (Ascii "NB10") es un archivo de PDB 2.0: // Luego dwHdr[1] es Desplazamiento. dwHdr[2] es Tiempo/Firma. dwHdr[3] es Contador/Edad. DWORD dwHdr[6]; std::string strPDBName; //Nombre/ruta del archivo PDB. }; struct PEDEBUG { DWORD dwOffset; //Desplazamiento bruto del archivo del descriptor de depuración. IMAGE_DEBUG_DIRECTORY stDebugDir; //Encabezado estándar IMAGE_DEBUG_DIRECTORY. PEDEBUGDBGHDR stDebugHdrInfo; //Encabezado de información de depuración. }; using PEDEBUG_VEC = std::vector<PEDEBUG>;
GetTLS
[[nodiscard]] auto GetTLS()const->std::optional<PETLS>;
Devuelve la información de Almacenamiento local de subprocesos del archivo.
struct PETLS { DWORD dwOffset; //Desplazamiento bruto del archivo del descriptor de encabezado de TLS. union UNPETLS { IMAGE_TLS_DIRECTORY32 stTLSDir32; //Encabezado estándar de TLS (x86). IMAGE_TLS_DIRECTORY64 stTLSDir64; //Encabezado de TLS (x64). } unTLS; std::vector<DWORD> vecTLSCallbacks; //Matriz de las devoluciones de llamada de TLS. };
GetLoadConfig
[[nodiscard]] auto GetLoadConfig() const -> std::optional<PELOADCONFIG>;
Devuelve la información del directorio Load Config del archivo.
struct PELOADCONFIG { DWORD dwOffset; //Desplazamiento del archivo de la LCD descriptor. union UNPELOADCONFIG { IMAGE_LOAD_CONFIG_DIRECTORY32 stLCD32; //Descriptor LCD x86. IMAGE_LOAD_CONFIG_DIRECTORY64 stLCD64; //Descriptor LCD x64. } unLCD; };
GetBoundImport
[[nodiscard]] auto GetBoundImport() const -> std::optional<PEBOUNDIMPORT_VEC>;
Devuelve un array de las entradas de Bound Import del archivo.
struct PEBOUNDFORWARDER { DWORD dwOffset; //Desplazamiento del archivo del descriptor Bound Forwarder. IMAGE_BOUND_FORWARDER_REF stBoundForwarder; //Estructura estándar IMAGE_BOUND_FORWARDER_REF. std::string strBoundForwarderName; //Nombre del bound forwarder. }; struct PEBOUNDIMPORT { DWORD dwOffset; //Desplazamiento del archivo del descriptor Bound Import. IMAGE_BOUND_IMPORT_DESCRIPTOR stBoundImpDesc; //Estructura estándar IMAGE_BOUND_IMPORT_DESCRIPTOR. std::string strBoundName; //Nombre del Bound Import. std::vector<PEBOUNDFORWARDER> vecBoundForwarder; //Array de estructuras Bound Forwarder. }; using PEBOUNDIMPORT_VEC = std::vector<PEBOUNDIMPORT>;
GetDelayImport
[[nodiscard]] auto GetDelayImport() const -> std::optional<PEDELAYIMPORT_VEC>;
Devuelve un array de las entradas de Delay Import del archivo.
struct PEDELAYIMPORTFUNC { union UNPEDELAYIMPORTTHUNK { struct x32 { IMAGE_THUNK_DATA32 stImportAddressTable; //Estructura Import Address Table x86. IMAGE_THUNK_DATA32 stImportNameTable; //Estructura Import Name Table x86. IMAGE_THUNK_DATA32 stBoundImportAddressTable; //Estructura Bound Import Address Table x86. IMAGE_THUNK_DATA32 stUnloadInformationTable; //Estructura Unload Information Table x86. } st32; struct x64 { IMAGE_THUNK_DATA64 stImportAddressTable; //Estructura Import Address Table x64. IMAGE_THUNK_DATA64 stImportNameTable; //Estructura Import Name Table x64. IMAGE_THUNK_DATA64 stBoundImportAddressTable; //Estructura Bound Import Address Table x64. IMAGE_THUNK_DATA64 stUnloadInformationTable; //Estructura Unload Information Table x64. } st64; } unThunk; IMAGE_IMPORT_BY_NAME stImpByName; //Estructura estándar IMAGE_IMPORT_BY_NAME. std::string strFuncName; //Nombre de la función. }; struct PEDELAYIMPORT { DWORD dwOffset; //Desplazamiento del archivo de este descriptor Delay Import. IMAGE_DELAYLOAD_DESCRIPTOR stDelayImpDesc; //Estructura estándar IMAGE_DELAYLOAD_DESCRIPTOR. std::string strModuleName; //Nombre del módulo de importación. std::vector<PEDELAYIMPORTFUNC> vecDelayImpFunc; //Array de funciones de Delay Import. }; using PEDELAYIMPORT_VEC = std::vector<PEDELAYIMPORT>;
GetCOMDescriptor
[[nodiscard]] auto GetCOMDescriptor() const -> std::optional<PECOMDESCRIPTOR>;
Obtiene la información de .NET del archivo.
struct PECOMDESCRIPTOR { DWORD dwOffset; //Desplazamiento del archivo del descriptor IMAGE_COR20_HEADER. IMAGE_COR20_HEADER stCorHdr; //Estructura estándar IMAGE_COR20_HEADER. };
Métodos Auxiliares
Estos métodos independientes no necesitan un objeto Clibpe
activo con un archivo abierto. En cambio, toman referencias a las estructuras obtenidas previamente.
GetFileType
[[nodiscard]] inline constexpr auto GetFileType(const PENTHDR& stNTHdr)->EFileType
Devuelve el tipo de archivo PE en forma de la enumeración EFileType
.
enum class EFileType : std::uint8_t { UNKNOWN = 0, PE32, PE64, PEROM };
GetImageBase
[[nodiscard]] inline constexpr auto GetImageBase(const PENTHDR& stNTHdr)->ULONGLONG
Devuelve la Base de la imagen del archivo.
GetOffsetFromRVA
[[nodiscard]] inline constexpr auto GetOffsetFromRVA (ULONGLONG ullRVA, const PESECHDR_VEC& vecSecHdr)->DWORD
Convierte la RVA del archivo en el desplazamiento físico en bruto del archivo en el disco.
FlatResources
[[nodiscard]] inline constexpr auto FlatResources(const PERESROOT& stResRoot)
Esta función es una versión ligera del método GetResources
. Toma la estructura PERESROOT
devuelta por el GetResources
, y devuelve un std::vector
de estructuras PERESFLAT
. PERESFLAT
es una estructura ligera que solo posee punteros a los datos reales de los recursos, a diferencia de la pesada PERESROOT
. FlatResources
aplana todos los recursos, haciendo más conveniente el acceso a ellos.
struct PERESFLAT { std::span<const std::byte> spnData { }; //Datos del recurso. std::wstring_view wsvTypeStr { }; //Nombre del tipo de recurso. std::wstring_view wsvNameStr { }; //Nombre del recurso (nombre del propio recurso). std::wstring_view wsvLangStr { }; //Nombre del idioma del recurso. WORD wTypeID { }; //ID del tipo de recurso //(RT_CURSOR, RT_BITMAP, etc...). WORD wNameID { }; //ID del nombre del recurso (ID del propio recurso). WORD wLangID { }; //ID del idioma del recurso. }; using PERESFLAT_VEC = std::vector<PERESFLAT>;
Maps
Un archivo PE consta de muchas estructuras, a su vez poseen muchos campos, algunos de los cuales tienen valores predefinidos.
Estos mapas sirven para facilitar la conversión de dichos campos a un formato legible para los humanos. Son simples mapas std::unordered_map<DWORD, std::wstring_view>
.
Hay que tener en cuenta que algunos campos solo pueden tener un valor, mientras que otros pueden combinar muchos valores mediante una operación de or |
a nivel de bits.
MapFileHdrMachine
Este mapa forma uno de los valores del campo Machine
de IMAGE_FILE_HEADER
de IMAGE_NT_HEADERS
.
MapFileHdrCharact
Este mapa forma uno o más valores del campo Characteristics
de IMAGE_FILE_HEADER
de IMAGE_NT_HEADERS
.
const auto pNTHdr = m_pLibpe->GetNTHeader(); const auto pDescr = &pNTHdr->unHdr.stNTHdr32.FileHeader; //Igual para x86/x64. std::wstring wstrCharact; for (const auto& flags : MapFileHdrCharact) { if (flags.first & pDescr->Characteristics) { wstrCharact += flags.second; wstrCharact += L"\n"; } }
MapOptHdrMagic
Este mapa forma uno de los valores del campo Magic
de IMAGE_OPTIONAL_HEADER
de IMAGE_NT_HEADERS
.
MapOptHdrSubsystem
Este mapa forma uno de los valores del campo Subsystem
de IMAGE_OPTIONAL_HEADER
de IMAGE_NT_HEADERS
.
MapOptHdrDllCharact
Este mapa forma uno o más valores del campo DllCharacteristics
de IMAGE_OPTIONAL_HEADER
de IMAGE_NT_HEADERS
.
const auto pNTHdr = m_pLibpe->GetNTHeader(); const auto pOptHdr = &pNTHdr->unHdr.stNTHdr32.OptionalHeader //Para x64: //pNTHdr->unHdr.stNTHdr64.OptionalHeader std::wstring wstrCharact; for (const auto& flags : MapOptHdrDllCharact) { if (flags.first & pOptHdr->DllCharacteristics) { wstrCharact += flags.second; wstrCharact += L"\n"; } }
MapSecHdrCharact
Este mapa forma uno o más valores del campo IMAGE_SECTION_HEADER::Characteristics
.
const auto pSecHeaders = m_pLibpe->GetSecHeaders(); std::wstring wstrCharact; auto IdOfSection = 0; //ID de la sección deseada. for (const auto& flags : MapSecHdrCharact) { if (flags.first & pSecHeaders->at(IdOfSection).stSecHdr.Characteristics) { wstrCharact += flags.second; wstrCharact += L"\n"; } }
MapResID
Este mapa forma uno de los valores del campo IMAGE_RESOURCE_DIRECTORY_ENTRY::Id
.
MapWinCertRevision
Este mapa forma uno de los valores del campo WIN_CERTIFICATE::wRevision
.
MapWinCertType
Este mapa forma uno de los valores del campo WIN_CERTIFICATE::wCertificateType
.
MapRelocType
Este mapa forma uno de los valores del campo PERELOCDATA::wRelocType
.
MapDbgType
Este mapa forma uno de los valores del campo IMAGE_DEBUG_DIRECTORY::Type
.
MapTLSCharact
Este mapa forma uno de los valores del campo IMAGE_TLS_DIRECTORY::Characteristics
.
MapLCDGuardFlags
Este mapa forma uno o más valores del campo IMAGE_LOAD_CONFIG_DIRECTORY::GuardFlags
.
const auto pLCD = m_pLibpe->GetLoadConfig(); const auto pPELCD = &pLCD->unLCD.stLCD32; //Para x64: pLCD->unLCD.stLCD64 std::wstring wstrGFlags; for (const auto& flags : MapLCDGuardFlags) { if (flags.first & pPELCD->GuardFlags) { wstrGFlags += flags.second; wstrGFlags += L"\n"; } }
MapCOR20Flags
Este mapa forma uno o más valores del campo IMAGE_COR20_HEADER::Flags
.
const auto pCOMDesc = m_pLibpe->GetCOMDescriptor(); std::wstring wstrFlags; for (const auto& flags : MapCOR20Flags) { if (flags.first & pCOMDesc->stCorHdr.Flags) { wstrFlags += flags.second; wstrFlags += L"\n"; } }
Leave a Reply