modify.c

来自「一个类似windows」· C语言 代码 · 共 1,061 行 · 第 1/3 页

C
1,061
字号
        /* Update the string pointer */
        ForwarderString = ImageRvaToVa(Library->FileHeader, 
                                       Library->MappedAddress, 
                                       AddressOfPointers[OrdinalNumber], 
                                       &Library->LastRvaSection); 
        goto NextForwarder;
    }
    else
    {
        /* Update the pointer and return success */
        ForwarderString = (PUCHAR)ForwardedAddress;
        *ForwarderBound = TRUE;
    }

    /* Return the pointer */
    return ForwarderString;
}

BOOL
IMAGEAPI
BindpLookupThunk(PIMAGE_THUNK_DATA Thunk,
                 PLOADED_IMAGE Image,
                 PIMAGE_THUNK_DATA BoundThunk,
                 PIMAGE_THUNK_DATA ThunkFunction,
                 PLOADED_IMAGE Library,
                 PIMAGE_EXPORT_DIRECTORY Exports,
                 PIMPORT_DESCRIPTOR BoundImportDescriptor,
                 LPSTR DllPath,
                 PULONG *Forwarders)
{
    PULONG AddressOfNames;
    PUSHORT AddressOfOrdinals;
    PULONG AddressOfPointers;
    PIMAGE_IMPORT_BY_NAME ImportName;
    ULONG OrdinalNumber = 0;
    USHORT HintIndex;
    LPSTR ExportName;
    ULONG_PTR ExportsBase;
    ULONG ExportSize;
    UCHAR NameBuffer[32];
    PIMAGE_OPTIONAL_HEADER OptionalHeader = NULL;
    PIMAGE_OPTIONAL_HEADER LibraryOptionalHeader = NULL;
    BOOL ForwarderBound = FALSE;
    PUCHAR ForwarderName;
    DPRINT("Binding a Thunk\n");

    /* Get the Pointers to the Tables */
    AddressOfNames = ImageRvaToVa(Library->FileHeader,
                                  Library->MappedAddress,
                                  Exports->AddressOfNames,
                                  &Library->LastRvaSection);
    AddressOfOrdinals = ImageRvaToVa(Library->FileHeader,
                                     Library->MappedAddress, 
                                     Exports->AddressOfNameOrdinals, 
                                     &Library->LastRvaSection);
    AddressOfPointers = ImageRvaToVa(Library->FileHeader, 
                                     Library->MappedAddress, 
                                     Exports->AddressOfFunctions, 
                                     &Library->LastRvaSection);

    /* Get the Optional Headers */
    OptionalHeader = &Image->FileHeader->OptionalHeader;
    LibraryOptionalHeader = &Library->FileHeader->OptionalHeader;
    
    /* Import by Ordinal */
    if (IMAGE_SNAP_BY_ORDINAL(Thunk->u1.Ordinal) == TRUE)
    {
        /* Get the ordinal number and pointer to the name */
        OrdinalNumber = (IMAGE_ORDINAL(Thunk->u1.Ordinal) - Exports->Base);
        ImportName = (PIMAGE_IMPORT_BY_NAME)NameBuffer;

        /* Setup the name for this ordinal */
        sprintf(ImportName->Name, "Ordinal%lx\n", OrdinalNumber);
    }
    else
    {    
        /* Import by Name, get the data */
        ImportName = ImageRvaToVa(Image->FileHeader,
                                  Image->MappedAddress, 
                                  (ULONG)Thunk->u1.AddressOfData, 
                                  &Image->LastRvaSection);

        /* Get the hint and see if we can use it */
        OrdinalNumber = (USHORT)(Exports->NumberOfFunctions + 1);
        HintIndex = ImportName->Hint;
        if (HintIndex < Exports->NumberOfNames)
        {
            /* Hint seems valid, get the export name */
            ExportName = ImageRvaToVa(Library->FileHeader,
                                      Library->MappedAddress, 
                                      (ULONG)AddressOfNames[HintIndex], 
                                      &Library->LastRvaSection);
            /* Check if it's the one we want */
            if (!strcmp(ImportName->Name, ExportName))
            {
                OrdinalNumber = AddressOfOrdinals[HintIndex];
            }
        }

        /* If the ordinal isn't valid, we'll have to do a long loop */
        if (OrdinalNumber >= Exports->NumberOfFunctions)
        {
            for (HintIndex = 0; HintIndex < Exports->NumberOfNames; HintIndex++)
            {
                /* Get the Export Name */
                ExportName = ImageRvaToVa(Library->FileHeader,
                                          Library->MappedAddress, 
                                          (ULONG)AddressOfNames[HintIndex], 
                                          &Library->LastRvaSection);
            
                /* Check if it's the one we want */
                if (!strcmp(ImportName->Name, ExportName))
                {
                    OrdinalNumber = AddressOfOrdinals[HintIndex];
                    break;
                }
            }

            /* Make sure it's valid now */
            if (OrdinalNumber >= Exports->NumberOfFunctions) return FALSE;
        }
    }

    /* Write the Pointer */
    ThunkFunction->u1.Function = AddressOfPointers[OrdinalNumber] +
                                 LibraryOptionalHeader->ImageBase;

    /* Load DLL's Exports */
    ExportsBase = (ULONG_PTR)ImageDirectoryEntryToData(Library->MappedAddress,
                                                       TRUE, 
                                                       IMAGE_DIRECTORY_ENTRY_EXPORT,
                                                       &ExportSize) -
                  (ULONG_PTR)Library->MappedAddress;
    
    /* RVA to VA */
    ExportsBase += LibraryOptionalHeader->ImageBase;

    /* Check if the Export is forwarded (meaning that it's pointer is inside the Export Table) */
    if ((ThunkFunction->u1.Function > ExportsBase) &&
        (ThunkFunction->u1.Function < ExportsBase + ExportSize))
    {
        /* Make sure we have a descriptor */
        if (BoundImportDescriptor)
        {
            DPRINT("This Thunk is a forward...calling forward thunk bounder\n");

            /* Get the VA of the pointer containg the name */
            ForwarderName = ImageRvaToVa(Library->FileHeader,
                                         Library->MappedAddress,
                                         AddressOfPointers[OrdinalNumber],
                                         &Library->LastRvaSection);

            /* Replace the Forwarder String by the actual name */
            ThunkFunction->u1.ForwarderString =
                PtrToUlong(BindpAddForwarderReference(Image->ModuleName,
                                                      ImportName->Name,
                                                      BoundImportDescriptor,
                                                      DllPath,
                                                      ForwarderName,
                                                      &ForwarderBound));
        }

        /* Check if it wasn't bound */
        if (!ForwarderBound)
        {
            /* Set the chain to the ordinal to reflect this */
            **Forwarders = (ULONG)(ThunkFunction - BoundThunk);
            *Forwarders = (PULONG)&ThunkFunction->u1.Ordinal;
        }
    }

    /* Return Success */
    return TRUE;
}

PIMPORT_DESCRIPTOR
IMAGEAPI
BindpAddImportDescriptor(PIMPORT_DESCRIPTOR *BoundImportDescriptor,
                         PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor,
                         LPSTR DllName,
                         PLOADED_IMAGE Image)
{
    PIMPORT_DESCRIPTOR Descriptor, *NextDescriptor;

    /* Loop descriptors and check if this library has already been bound */
    NextDescriptor = BoundImportDescriptor;
    while ((Descriptor = *NextDescriptor))
    {
        /* Compare the names and return the descriptor if found */
        if (!_stricmp(Descriptor->ModuleName, DllName)) return Descriptor;
        
        /* Move to the next one */
        NextDescriptor = &Descriptor->Next;
    }

    /* Allocate a new descriptor */
    Descriptor = HeapAlloc(IMAGEHLP_hHeap,
                           HEAP_ZERO_MEMORY,
                           sizeof(IMPORT_DESCRIPTOR));

    /* Set its Data and check if we have a valid loaded image */
    Descriptor->ModuleName = BindpCaptureImportModuleName(DllName);
    *NextDescriptor = Descriptor;
    if (Image)
    {
        /* Save the time stamp */
        Descriptor->TimeDateStamp = Image->FileHeader->FileHeader.TimeDateStamp;
    }
    
    /* Return the descriptor */
    return Descriptor;
}

VOID
IMAGEAPI
BindpWalkAndProcessImports(PLOADED_IMAGE File,
                           LPSTR DllPath,
                           PBOOLEAN UpdateImage)
{
    PIMAGE_IMPORT_DESCRIPTOR Imports;
    PIMAGE_EXPORT_DIRECTORY Exports;
    ULONG SizeOfImports;
    ULONG SizeOfExports;
    ULONG SizeOfThunks;
    PIMAGE_OPTIONAL_HEADER OptionalHeader;
    PIMAGE_FILE_HEADER FileHeader;
    LPSTR ImportedLibrary;
    PLOADED_IMAGE LoadedLibrary;
    ULONG TopForwarderChain;
    PULONG ForwarderChain;
    PIMPORT_DESCRIPTOR TopBoundDescriptor = NULL, BoundImportDescriptor;
    PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportTable, OldBoundImportTable;
    PIMAGE_THUNK_DATA Thunks, TempThunk;
    PIMAGE_THUNK_DATA BoundThunks, TempBoundThunk;
    ULONG ThunkCount = 0;
    ULONG Thunk;
    ULONG BoundImportTableSize, OldBoundImportTableSize;
    ULONG VirtBytesFree, HeaderBytesFree, FirstFreeByte, PhysBytesFree;
    BOOL ThunkStatus;
    DPRINT("BindpWalkAndBindImports Called\n");

    /* Assume untouched image */
    *UpdateImage = FALSE;

    /* Load the Import Descriptor */
    Imports = ImageDirectoryEntryToData(File->MappedAddress,
                                        FALSE, 
                                        IMAGE_DIRECTORY_ENTRY_IMPORT, 
                                        &SizeOfImports);
    if (!Imports) return;

    /* Read the File Header */
    FileHeader = &File->FileHeader->FileHeader;
    OptionalHeader = &File->FileHeader->OptionalHeader;

    /* Get the old Bound Import Table, if any */
    OldBoundImportTable = ImageDirectoryEntryToData(File->MappedAddress,
                                                    FALSE,
                                                    IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT,
                                                    &OldBoundImportTableSize);

    /* For each Import */
    while(Imports)
    {
        /* Make sure we have a name */
        if (!Imports->Name) break;

        /* Which DLL is being Imported */
        ImportedLibrary = ImageRvaToVa(File->FileHeader, 
                                       File->MappedAddress, 
                                       Imports->Name, 
                                       &File->LastRvaSection);
        if (ImportedLibrary)
        {
            DPRINT("Loading Imported DLL: %s \n", ImportedLibrary);
            
            /* Load the DLL */
            LoadedLibrary = ImageLoad(ImportedLibrary, DllPath);
            if (!LoadedLibrary)
            {
                /* Create the descriptor, even if we failed */
                BindpAddImportDescriptor(&TopBoundDescriptor,
                                         Imports,
                                         ImportedLibrary,
                                         LoadedLibrary);

                /* Move on the next file */
                Imports++;
                continue;
            }

            /* Now load the Exports */
            DPRINT("DLL Loaded at: %p \n", LoadedLibrary->MappedAddress);
            Exports = ImageDirectoryEntryToData(LoadedLibrary->MappedAddress, 
                                                FALSE, 
                                                IMAGE_DIRECTORY_ENTRY_EXPORT, 
                                                &SizeOfExports);

            /* Move on, if we don't have exports */
            if (!Exports) continue;

            /* And load the Thunks */
            Thunks = ImageRvaToVa(File->FileHeader, 
                                  File->MappedAddress, 
                                  (ULONG)Imports->OriginalFirstThunk, 
                                  &File->LastRvaSection);

            /* No actual Exports (UPX Packer can do this */
            if (!(Thunks) || !(Thunks->u1.Function)) continue;
        
            /* Create Bound Import Descriptor */
            DPRINT("Creating Bound Descriptor for this DLL\n");
            BoundImportDescriptor = BindpAddImportDescriptor(&TopBoundDescriptor,
                                                             Imports,
                                                             ImportedLibrary,
                                                             LoadedLibrary);

            /* Count how many Thunks we have */
            ThunkCount = 0;
            TempThunk = Thunks;
            while (TempThunk->u1.AddressOfData)
            {
                ThunkCount++;
                TempThunk++;
            }

            /* Allocate Memory for the Thunks we will Bind */
            SizeOfThunks = ThunkCount * sizeof(*TempBoundThunk);
            BoundThunks = HeapAlloc(IMAGEHLP_hHeap,
                                    HEAP_ZERO_MEMORY,
                                    SizeOfThunks);

            /* Setup the initial data pointers */
            DPRINT("Binding Thunks\n");
            TempThunk = Thunks;
            TempBoundThunk = BoundThunks;
            TopForwarderChain = -1;
            ForwarderChain = &TopForwarderChain;

            /* Loop for every thunk */
            for (Thunk = 0; Thunk < ThunkCount; Thunk++)
            {
                /* Bind it */
                ThunkStatus = BindpLookupThunk(TempThunk,
                                               File,
                                               BoundThunks,
                                               TempBoundThunk,
                                               LoadedLibrary,
                                               Exports,
                                               BoundImportDescriptor,
                                               DllPath,
                                               &ForwarderChain);
                /* Check if binding failed */
                if (!ThunkStatus)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?