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?

¿Fue útil?

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));
            }
        }
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top