tabla de procesador en la tabla de direcciones de importación?
-
26-09-2019 - |
Pregunta
¿Qué es una tabla golpe seco en relación con la tabla de direcciones de importación que se utiliza en los archivos EXE a las funciones de importación utilizadas en archivos DLL externa?
¿Es esta tabla golpe seco sólo una tabla que contiene '' Thunks a otras funciones?
Solución
Procesadores son un parte de la tabla de importación (IMAGE_DIRECTORY_ENTRY_IMPORT
) y Delay Tabla Importación (IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT
). Se describen http://msdn.microsoft.com/en-us/library /ms809762.aspx .
Voy a mirar a mi código fuente antigua y publicará más adelante un código de trabajo que volcar esta información vinculante tablas inclusiva.
ACTUALIZADO:
Aquí hay un código que me gustan en una de mi viejo programa. Se admite solamente PE de 32 bits, pero puede ser fácil modificado para 64 bits. Por cierto se puede ver, que volcado de prueba information.To esta unen el PE también vinculante que desea volcar con respecto a bind.exe (uso, por ejemplo, bind.exe -u -v Test.dll
).
El código consta de aproximadamente 1000 líneas, así que no podía publicar aquí. Recibo un mensaje de error
¡Huy! Tu edición no pudo presentarse porque:
- cuerpo se limita a 30000 caracteres; que ha introducido 55095
Así que lo puso aquí: http: //www.ok-soft -gmbh.com/ForStackOverflow/PEInfo.c . Espero que el código le ayudará a mejor como una descripción larga.
ACTUALIZADO 2 : Veo que mi viejo respuesta no es buena para la búsqueda del motor. Por lo que incluye la parte del código de PEInfo.c
(el DumpImports
funciones y DumpExports
) a continuación:
void MakeIdent (UINT nOffset)
{
for (; nOffset; nOffset--)
printf (" "); // 4 blanks
}
void DumpDword (UINT nOffset, LPCSTR pszPrefix, DWORD dw)
{
MakeIdent(nOffset);
if (dw < 100)
printf ("%s: %d\n", pszPrefix, dw);
else if (dw%(256*256) == 0)
printf ("%s: 0x%X\n", pszPrefix, dw);
else
printf ("%s: %d (0x%X)\n", pszPrefix, dw, dw);
}
void DumpTimeDateStamp (UINT nOffset, LPCSTR pszTimeDateStampPrefix, DWORD dwTimeDateStamp)
{
//struct tm tmTime;//= localtime_s ((time_t *)&dwTimeDateStamp);
//errno_t err = localtime_s (&tmTime, ((time_t *)&dwTimeDateStamp));
struct tm *ptmTime = _localtime32 ((__time32_t *)&dwTimeDateStamp);
SYSTEMTIME stSystemTime;
static CHAR szString[128];
stSystemTime.wYear = (WORD)(1900 + ptmTime->tm_year);
stSystemTime.wMonth = (WORD)(ptmTime->tm_mon + 1);
stSystemTime.wDay = (WORD)ptmTime->tm_mday;
stSystemTime.wDayOfWeek = (WORD)(ptmTime->tm_wday + 1);
stSystemTime.wHour = (WORD)ptmTime->tm_hour;
stSystemTime.wMinute = (WORD)ptmTime->tm_min;
stSystemTime.wSecond = (WORD)ptmTime->tm_sec;
stSystemTime.wMilliseconds = 0;
MakeIdent(nOffset);
printf ("%s: 0x%8X (", pszTimeDateStampPrefix, dwTimeDateStamp);
if (GetDateFormatA (LOCALE_USER_DEFAULT, 0, &stSystemTime, NULL,
szString, sizeof(szString)/sizeof(TCHAR)) != 0) {
printf (szString);
}
if (GetTimeFormatA (LOCALE_USER_DEFAULT, 0, &stSystemTime, NULL,
szString, sizeof(szString)/sizeof(TCHAR)) != 0) {
if (szString[0] != 0)
printf (" ");
printf (szString);
}
printf (")\n");
}
void DumpImports (UINT nOffset, IMAGE_OPTIONAL_HEADER32 *pOptionalHeader, PBYTE pbyFile,
IMAGE_SECTION_HEADER *pSectionHeader, IMAGE_NT_HEADERS32 *pNtHeader) // header of the section, which contains export section
{
IMAGE_IMPORT_DESCRIPTOR *pImportDescriptor = (IMAGE_IMPORT_DESCRIPTOR *)((PBYTE)pbyFile + pSectionHeader->PointerToRawData +
pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress - pSectionHeader->VirtualAddress);
DWORD dwBoundImportVA = pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress;
IMAGE_BOUND_IMPORT_DESCRIPTOR *pFirstBoundImportDescriptor = NULL, *pBoundImportDescriptor;
//DumpDword (nOffset, TEXT("Characteristics"), pImportDescriptor->Characteristics);
if (dwBoundImportVA) {
UINT i;
IMAGE_SECTION_HEADER *pFirstSectionHeader = (IMAGE_SECTION_HEADER *)((PBYTE)pOptionalHeader + //sizeof(IMAGE_OPTIONAL_HEADER32));
pNtHeader->FileHeader.SizeOfOptionalHeader);
for (i=0; i<pNtHeader->FileHeader.NumberOfSections; i++) {
if (pFirstSectionHeader[i].VirtualAddress <= dwBoundImportVA &&
dwBoundImportVA < pFirstSectionHeader[i].VirtualAddress + pFirstSectionHeader[i].Misc.VirtualSize) {
pFirstBoundImportDescriptor = (IMAGE_BOUND_IMPORT_DESCRIPTOR *)((PBYTE)pbyFile + pFirstSectionHeader[i].PointerToRawData +
dwBoundImportVA - pFirstSectionHeader[i].VirtualAddress);
break;
}
}
if (i >= pNtHeader->FileHeader.NumberOfSections)
pFirstBoundImportDescriptor = (IMAGE_BOUND_IMPORT_DESCRIPTOR *)((PBYTE)pbyFile + dwBoundImportVA);
}
for (;pImportDescriptor->Characteristics; pImportDescriptor++) {
IMAGE_THUNK_DATA *pOriginalFirstThunk = (IMAGE_THUNK_DATA *)((PBYTE)pbyFile + pSectionHeader->PointerToRawData +
pImportDescriptor->OriginalFirstThunk - pSectionHeader->VirtualAddress);
IMAGE_THUNK_DATA *pFirstThunk = (IMAGE_THUNK_DATA *)((PBYTE)pbyFile + pSectionHeader->PointerToRawData +
pImportDescriptor->FirstThunk - pSectionHeader->VirtualAddress);
IMAGE_THUNK_DATA *pOriginalThunk, *pThunk;
MakeIdent(nOffset);
printf ("%s ", pbyFile + pSectionHeader->PointerToRawData + pImportDescriptor->Name - pSectionHeader->VirtualAddress);
//DumpDword (nOffset, TEXT("Ordinal Base"), pExportDirectory->Base);
if (pImportDescriptor->TimeDateStamp == 0) {
//MakeIdent(nOffset);
printf ("(DLL is Not bound)\n");
}
else if (pImportDescriptor->TimeDateStamp == -1) {
//if bound, and real date\time stamp
// // in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
//MakeIdent(nOffset);
printf ("(DLL bound with New BIND)\n");
}
else {
//MakeIdent(nOffset);
printf ("(DLL bound with Old BIND) ");
DumpTimeDateStamp (nOffset, "TimeDateStamp", pImportDescriptor->TimeDateStamp);
}
MakeIdent(nOffset+1);
if (pImportDescriptor->TimeDateStamp) // if bound
printf (TEXT(" Ordinal hint BoundAddrs Name\n"));
else
printf (TEXT(" Ordinal hint Name\n"));
for (pOriginalThunk=pOriginalFirstThunk, pThunk=pFirstThunk; pOriginalThunk->u1.AddressOfData; pOriginalThunk++, pThunk++) {
if (IMAGE_SNAP_BY_ORDINAL32(pOriginalThunk->u1.Ordinal)) {
MakeIdent(nOffset+1);
// Ordinal
if (pImportDescriptor->TimeDateStamp)
printf (TEXT("%4u (0x%04X) 0x%08X\n"),
pOriginalThunk->u1.Ordinal & ~IMAGE_ORDINAL_FLAG32,
pOriginalThunk->u1.Ordinal^IMAGE_ORDINAL_FLAG32,
pThunk->u1.AddressOfData);
else
// pThunk->u1.AddressOfData == pOriginalThunk->u1.Ordinal so don't print it
printf (TEXT("%4u (0x%04X)\n"),
pOriginalThunk->u1.Ordinal & ~IMAGE_ORDINAL_FLAG32,
pOriginalThunk->u1.Ordinal^IMAGE_ORDINAL_FLAG32);
}
else {
IMAGE_IMPORT_BY_NAME *pImportByName = (IMAGE_IMPORT_BY_NAME *) (pOriginalThunk->u1.AddressOfData +
(PBYTE)pbyFile + pSectionHeader->PointerToRawData - pSectionHeader->VirtualAddress);
MakeIdent(nOffset+1);
// Hint - Index into the Export Name Pointer Table. A match is attempted first with this value.
// If it fails, a binary search is performed on the DLL’s Export Name Pointer Table.
if (pImportDescriptor->TimeDateStamp) // if bound
printf (TEXT("%18u (0x%04X) 0x%08X %hs\n"), pImportByName->Hint, pImportByName->Hint, pThunk->u1.AddressOfData,
pImportByName->Name);
else
printf (TEXT("%18u (0x%04X) %hs\n"), pImportByName->Hint, pImportByName->Hint, pImportByName->Name);
}
}
}
if (pFirstBoundImportDescriptor) {
MakeIdent(nOffset);
printf ("PE Header contains the following bound import information:\n");
for (pBoundImportDescriptor=pFirstBoundImportDescriptor; pBoundImportDescriptor->TimeDateStamp;
pBoundImportDescriptor = (IMAGE_BOUND_IMPORT_DESCRIPTOR *)((PBYTE)(pBoundImportDescriptor+1) + pBoundImportDescriptor->NumberOfModuleForwarderRefs*sizeof(IMAGE_BOUND_FORWARDER_REF))) {
PSTR pszDllName = (PSTR) ((DWORD)pFirstBoundImportDescriptor + pBoundImportDescriptor->OffsetModuleName);
IMAGE_BOUND_FORWARDER_REF *pRef = (IMAGE_BOUND_FORWARDER_REF *)(pBoundImportDescriptor+1);
MakeIdent(nOffset+1);
printf ("Bound to %hs", pszDllName);
DumpTimeDateStamp (0, "", pBoundImportDescriptor->TimeDateStamp);
if (pBoundImportDescriptor->NumberOfModuleForwarderRefs) {
UINT i;
for (i=0;i<pBoundImportDescriptor->NumberOfModuleForwarderRefs;i++) {
PSTR pszDllName = (PSTR) ((DWORD)pFirstBoundImportDescriptor + pRef->OffsetModuleName);
MakeIdent(nOffset+2);
printf ("Contained forwarders bound to %hs", pszDllName);
DumpTimeDateStamp (0, "", pRef->TimeDateStamp);
}
}
}
}
}
void DumpExports (UINT nOffset, IMAGE_OPTIONAL_HEADER32 *pOptionalHeader, PBYTE pbyFile,
IMAGE_SECTION_HEADER *pSectionHeader) // header of the section, which contains export section
{
UINT i;
UINT iNames;
PDWORD pdwAddressOfFunctions;
PWORD pwOrdinals;
PDWORD pdwNameRVA;
IMAGE_EXPORT_DIRECTORY *pExportDirectory = (IMAGE_EXPORT_DIRECTORY *)((PBYTE)pbyFile + pSectionHeader->PointerToRawData +
pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress - pSectionHeader->VirtualAddress);
DWORD dwVAExportStart = pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
DWORD dwVAExportEnd = pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress +
pOptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
DumpDword (nOffset, TEXT("Characteristics"), pExportDirectory->Characteristics);
DumpTimeDateStamp (nOffset, "TimeDateStamp", pExportDirectory->TimeDateStamp);
MakeIdent(nOffset);
printf ("DllName: %s\n", pbyFile + pSectionHeader->PointerToRawData + pExportDirectory->Name - pSectionHeader->VirtualAddress);
DumpDword (nOffset, TEXT("Ordinal Base"), pExportDirectory->Base);
MakeIdent(nOffset);
printf (TEXT("Version: %d.%d\n"), pExportDirectory->MajorVersion, pExportDirectory->MinorVersion);
DumpDword (nOffset, TEXT("Number of exported functions"), pExportDirectory->NumberOfFunctions);
DumpDword (nOffset, TEXT("Number of functions exported by name"), pExportDirectory->NumberOfNames);
MakeIdent(nOffset+1);
printf (TEXT("Ordn hint RVA Name\n"));
pdwAddressOfFunctions = (PDWORD)(pbyFile + pSectionHeader->PointerToRawData + pExportDirectory->AddressOfFunctions - pSectionHeader->VirtualAddress);
pwOrdinals = (PWORD)(pbyFile + pSectionHeader->PointerToRawData + pExportDirectory->AddressOfNameOrdinals - pSectionHeader->VirtualAddress);
pdwNameRVA = (PDWORD)(pbyFile + pSectionHeader->PointerToRawData + pExportDirectory->AddressOfNames - pSectionHeader->VirtualAddress);
for (iNames = 0; iNames < pExportDirectory->NumberOfNames; iNames++) {
MakeIdent(nOffset+1);
// AddressOfFunctions MUST be ouf of Export Directory. If it is not so, it is a Forwarding entry
if (pdwAddressOfFunctions[pwOrdinals[iNames]] < dwVAExportStart ||
pdwAddressOfFunctions[pwOrdinals[iNames]] > dwVAExportEnd)
// AddressOfFunctions is normaly in .text section and export table in .edata or .rdata section, so
// AddressOfFunctions must be not in Export Directory
printf("%4u %4u %08X %s\n",
pwOrdinals[iNames] + pExportDirectory->Base, iNames, pdwAddressOfFunctions[pwOrdinals[iNames]],
(pbyFile + pSectionHeader->PointerToRawData + pdwNameRVA[iNames] - pSectionHeader->VirtualAddress));
else
printf("%4u %4u %s (forwarded to %s)\n",
pwOrdinals[iNames] + pExportDirectory->Base, iNames,
(pbyFile + pSectionHeader->PointerToRawData + pdwNameRVA[iNames] - pSectionHeader->VirtualAddress),
(PSTR)(pbyFile + pSectionHeader->PointerToRawData + pdwAddressOfFunctions[pwOrdinals[iNames]] - pSectionHeader->VirtualAddress));
}
// print functions exported by ordinal
for (i = 0; i < pExportDirectory->NumberOfFunctions; i++) {
if (pdwAddressOfFunctions[i] != 0) {
// if EXPORTS in DEF-file look like
//
// EXPORTS
// Message1 @100
// Message2 @200
// Message3 @300
// Message4 @400
// Message5 @500
// it will be added in export section 401 (500-100+1) entries. 5 from there with not 0 address and the rest
// empty entries with 0
// we will dump only not empty entries
UINT iNames;
WORD wOrdinal = (WORD)(i + pExportDirectory->Base);
// try to find (i + pExportDirectory->Base) ordinal in the list of pwOrdinals
for (iNames = 0; iNames<pExportDirectory->NumberOfNames; iNames++) {
if (pdwAddressOfFunctions[pwOrdinals[iNames]] == pdwAddressOfFunctions[i])
break;
}
if (iNames >= pExportDirectory->NumberOfNames) {
// if not found as exported by name, print it here
MakeIdent(nOffset+1);
if (pdwAddressOfFunctions[i] < pSectionHeader->VirtualAddress ||
pdwAddressOfFunctions[i] > pSectionHeader->VirtualAddress + pSectionHeader->Misc.VirtualSize)
printf("%4u %08X [NONAME]\n", wOrdinal, pdwAddressOfFunctions[i]);
else
printf("%4u [NONAME] (forwarded to %s)\n",
wOrdinal, (PSTR)(pbyFile + pSectionHeader->PointerToRawData + pdwAddressOfFunctions[i] - pSectionHeader->VirtualAddress));
}
}
}
}