⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modify.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* 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;
}

static PIMAGE_BOUND_IMPORT_DESCRIPTOR
IMAGEAPI
BindpCreateNewImportSection(PIMPORT_DESCRIPTOR *BoundImportDescriptor,
                            PULONG BoundImportsSize)
{
    ULONG BoundLibraryNamesSize = 0, BoundImportTableSize = 0;
    PBOUND_FORWARDER_REFS Forwarder, *NextForwarder;
    PIMPORT_DESCRIPTOR Descriptor, *NextDescriptor;
    LPSTR BoundLibraryNames;
    PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundTableEntry, BoundTable;
    PIMAGE_BOUND_FORWARDER_REF BoundForwarder;

    /* Zero the outoging size */
    *BoundImportsSize = 0;

    /* Loop the descriptors and forwarders to get the size */
    NextDescriptor = BoundImportDescriptor;
    while ((Descriptor = *NextDescriptor))
    {
        /* Add to the size of the Bound Import Table */
        BoundImportTableSize += sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR);

        /* Check Forwarders */
        NextForwarder = &Descriptor->Forwarders;
        while ((Forwarder = *NextForwarder))
        {
            /* Add to size of Bound Import Table */
            BoundImportTableSize += sizeof(IMAGE_BOUND_FORWARDER_REF);

            /* Next Forwarder */
            NextForwarder = &Forwarder->Next;
        }

        /* Read Next Internal Descriptor */
        NextDescriptor = &Descriptor->Next;
    }

    /* Add Terminator for PE Loader*/
    BoundImportTableSize += sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR);
    DPRINT("Table size: %lx\n", BoundImportTableSize);

    /* Name of Libraries Bound in Bound Import Table */
    BoundLibraryNamesSize = (ULONG)((ULONG_PTR)BoundLibrariesPointer -
                                    (ULONG_PTR)BoundLibraries);
    BoundLibrariesPointer = NULL;

    /* Size of the whole table, dword aligned */
    *BoundImportsSize = BoundImportTableSize + 
                        ((BoundLibraryNamesSize + sizeof(ULONG) - 1) &
                        ~(sizeof(ULONG) - 1));

    /* Allocate it */
    BoundTable = HeapAlloc(IMAGEHLP_hHeap, HEAP_ZERO_MEMORY, *BoundImportsSize);
    
    /* Pointer Library Names inside the Bound Import Table */
    BoundLibraryNames = (LPSTR)BoundTable + BoundImportTableSize;

    /* Copy the Library Names */
    RtlCopyMemory(BoundLibraryNames, BoundLibraries, BoundLibraryNamesSize);

    /* Now loop both tables */
    BoundTableEntry = BoundTable;
    NextDescriptor = BoundImportDescriptor;
    while ((Descriptor = *NextDescriptor))
    {
        /* Copy the data */
        BoundTableEntry->TimeDateStamp = Descriptor->TimeDateStamp;
        BoundTableEntry->OffsetModuleName = (USHORT)(BoundImportTableSize +
                                                     (Descriptor->ModuleName -
                                                      (ULONG_PTR)BoundLibraries));
        BoundTableEntry->NumberOfModuleForwarderRefs = Descriptor->ForwaderReferences;

        /* Now loop the forwarders */
        BoundForwarder = (PIMAGE_BOUND_FORWARDER_REF)BoundTableEntry + 1;
        NextForwarder = &Descriptor->Forwarders;
        while ((Forwarder = *NextForwarder))
        {
            /* Copy the data */
            BoundForwarder->TimeDateStamp = Forwarder->TimeDateStamp;
            BoundForwarder->OffsetModuleName = (USHORT)(BoundImportTableSize +
                                                       (Forwarder->ModuleName -
                                                       (ULONG_PTR)BoundLibraries));

            /* Move to the next new forwarder, and move to the next entry */
            BoundForwarder++;
            NextForwarder = &Forwarder->Next;
        }

        /* Move to next Bound Import Table Entry */
        BoundTableEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)BoundForwarder;

        /* Move to the next descriptor */
        NextDescriptor = &Descriptor->Next;
    }

    /* Loop the descriptors and forwarders to free them */
    NextDescriptor = BoundImportDescriptor;
    while ((Descriptor = *NextDescriptor))
    {
        /* Read next internal descriptor */
        *NextDescriptor = Descriptor->Next;

        /* Loop its forwarders */
        NextForwarder = &Descriptor->Forwarders;
        while ((Forwarder = *NextForwarder))
        {
            /* Next Forwarder */
            *NextForwarder = Forwarder->Next;

            /* Free it */
            HeapFree(IMAGEHLP_hHeap, 0, Forwarder);
        }

        /* Free it */
        HeapFree(IMAGEHLP_hHeap, 0, Descriptor);
    }

    /* Return the Bound Import Table */
    return BoundTable;
}

static 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)
                {
                    /* If we have a descriptor */
                    if (BoundImportDescriptor)
                    {
                        /* Zero the timestamp */
                        BoundImportDescriptor->TimeDateStamp = 0;
                    }

                    /* Quit the loop */
                    break;
                }

                /* Move on */
                TempThunk++;
                TempBoundThunk++;
            }

            /* Load the Second Thunk Array */
            TempThunk = ImageRvaToVa(File->FileHeader, 
                                     File->MappedAddress, 
                                     (ULONG)Imports->FirstThunk, 
                                     &File->LastRvaSection);
            if (TempThunk)
            {
                /* Check if the forwarder chain changed */
                if (TopForwarderChain != -1)
                {
                    /* It did. Update the chain and let caller know */
                    *ForwarderChain = -1;
                    *UpdateImage = TRUE;
                }

                /* Check if we're not pointing at the new top chain */
                if (Imports->ForwarderChain != TopForwarderChain)
                {
                    /* Update it, and let the caller know */
                    Imports->ForwarderChain = TopForwarderChain;
                    *UpdateImage = TRUE;
                }

                /* Check if thunks have changed */
                if (memcmp(TempThunk, BoundThunks, SizeOfThunks))
                {
                    /* Copy the Pointers and let caller know */
                    DPRINT("Copying Bound Thunks\n");
                    RtlCopyMemory(TempThunk, BoundThunks, SizeOfThunks);
                    *UpdateImage = TRUE;
                }

                /* Check if we have no bound entries */
                if (!TopBoundDescriptor)
                {
                    /* Check if the timestamp is different */
                    if (Imports->TimeDateStamp != FileHeader->TimeDateStamp)
                    {
                        /* Update it, and let the caller knmow */
                        Imports->TimeDateStamp = FileHeader->TimeDateStamp;
                        *UpdateImage = TRUE;
                    }
                }
                else if ((Imports->TimeDateStamp != 0xFFFFFFFF))
                {
                    /* Invalidate the timedate stamp */
                    Imports->TimeDateStamp = 0xFFFFFFFF;
                }
            }

            /* Free the Allocated Memory */
            HeapFree(IMAGEHLP_hHeap, 0, BoundThunks);

            DPRINT("Moving to next File\n");
            Imports++;
        }
    }

    /* Create the Bound Import Table */
    DPRINT("Creating Bound Import Section\n");
    BoundImportTable = BindpCreateNewImportSection(&TopBoundDescriptor,
                                                   &BoundImportTableSize);

    /* Check if the import table changed */
    if (OldBoundImportTableSize != BoundImportTableSize)
    {
        /* Let the caller know */
        *UpdateImage = TRUE;
    }

    /* 
     * At this point, check if anything that we've done until now has resulted
     * in the image being touched. If not, then we'll simply return to caller.
     */
    if (!(*UpdateImage)) return;

    /* Check if we have a new table */
    if (BoundImportTable)
    {
        /* Zero it out */
        OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;

⌨️ 快捷键说明

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