windows - Udskrivning af navne på implicit forbundne dll'er fra .idata-sektionen i en bærbar eksekverbar

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg forsøger at skrive en kode, der skal udskrive navnene på alle de importerede dll'er i exe ved at bruge 'navn' -feltet i IMAGE\_IMPORT\_DESCRIPTOR strukturen i .idata-sektionen i exe, men programmet ser ud til at sidder fast i en uendelig sløjfe. Kan nogen fortælle mig, hvordan man får navnene trykt ud korrekt ...


    #include<iostream>
    #include<Windows.h>
    #include<stdio.h>
    #include<WinNT.h>

    int main()
    {
        FILE *fp; 
        int i;

        if((fp = fopen("c:\Linked List.exe","rb"))==NULL)
            std::cout<<"unable to open";


        IMAGE\_DOS\_HEADER imdh;
        fread(&imdh,sizeof(imdh),1,fp);
        fseek(fp,imdh.e\_lfanew,0);

        IMAGE\_NT\_HEADERS imnth;
        fread(&imnth,sizeof(imnth),1,fp);

        IMAGE\_SECTION\_HEADER *pimsh;
        pimsh = (IMAGE\_SECTION\_HEADER *)malloc(sizeof(IMAGE\_SECTION\_HEADER) * imnth.FileHeader.NumberOfSections);

        long t;

        fread(pimsh,sizeof(IMAGE\_SECTION\_HEADER),imnth.FileHeader.NumberOfSections,fp);

        for(i=0;i<imnth.FileHeader.NumberOfSections;i++)
        {
            if(!strcmp((char *)pimsh->Name,".idata"))
                t = pimsh->PointerToRawData;
            pimsh++;
        }

        fseek(fp,t,0);

        IMAGE\_IMPORT\_DESCRIPTOR iid;
        char c;

        while(1)
        {
            fread(&iid,sizeof(iid),1,fp);

            if(iid.Characteristics == NULL)
                break;

            t = ftell(fp);

            fseek(fp,(long)iid.Name,0);

            while(c=fgetc(fp))
                printf("\%c",c);
            printf("
");

            fseek(fp,t,0);

        }
    }

Bedste reference


Der er flere problemer.



  • Du kan ikke antage, at importafsnittet hedder '.idata'. Du skal finde importen ved hjælp af IMAGE\_OPTIONAL\_HEADER.DataDirectory[IMAGE\_DIRECTORY\_ENTRY\_IMPORT].

  • De fleste forskydninger i en PE-fil er relative virtuelle adresser (RVA'er), ikke filforskydninger. For at konvertere en RVA til en forskydning skal du bestemme, hvilken sektion den virtuelle adresse er i, og bereg derefter en forskydning baseret på hvor sektionen er i filen. Specifikt indeholder feltet IMAGE\_IMPORT\_DESCRIPTOR.Name en RVA, ikke en filforskydning.

  • Din kode bliver meget enklere (og hurtigere), hvis du bruger en hukommelseskortet fil i stedet for filen I/O.



Denne MSDN-artikel forklarer RVA'er, datakataloget osv. Det omfatter også pedump, et program med fuld kildekode til dumping PE-filer, hvilket er en nyttig reference. [6]

Andre referencer 1


Svaret fra mox er rigtigt på alle punkter, men jeg vil også gerne tilføje en anden løsning - indlæse filen som et billede for at læse dataene.

Dette opnås meget enkelt ved hjælp af LoadLibraryEx med kun en linje kode. [7]


Base = LoadLibraryEx("c:Linked List.exe", 0, DONT\_RESOLVE\_DLL\_REFERENCES);


Denne belastning og kortlægger din eksekverbar som et billede, så det er ikke nødvendigt at åbne/læse/kortlægge eller konvertere rva til rå forskydninger.


Med flag DONT\_RESOLVE\_DLL\_REFERENCES er billedet uninitialiseret, så alle importdata er uberørt, og indgangskoden kodes ikke ud. Den eksekverbare er kun kortlagt i hukommelsen.


Du kan simpelthen bruge Base + Rva for at finde importeret DLL-navn - eller andre typer PE-oplysninger.

Fri det eksekverbare billede efter brug med FreeLibrary (Base)