modify.c

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

C
1,061
字号
/*
 * IMAGEHLP library
 *
 * Copyright 1998 Patrik Stridvall
 * Copyright 2005 Alex Ionescu
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/* INCLUDES ******************************************************************/

#include "precomp.h"

//#define NDEBUG
#include <debug.h>

/* DATA **********************************************************************/

CHAR BoundLibraries[4096];
LPSTR BoundLibrariesPointer;

/* FUNCTIONS *****************************************************************/

LPSTR
IMAGEAPI
BindpCaptureImportModuleName(LPSTR ModuleName)
{
    LPSTR Name = BoundLibraries;

    /* Check if it hasn't been initialized yet */
    if (!BoundLibrariesPointer)
    {
        /* Start with a null char and set the pointer */
        *Name = ANSI_NULL;
        BoundLibrariesPointer = Name;
    }

    /* Loop the current buffer */
    while (*Name)
    {
        /* Try to match this DLL's name and return it */
        if (!_stricmp(Name, ModuleName)) return Name;

        /* Move on to the next DLL Name */
        Name += strlen(Name) + sizeof(CHAR);
    }

    /* If we got here, we didn't find one, so add this one to our buffer */
    strcpy(Name, ModuleName);

    /* Set the new position of the buffer, and null-terminate it */
    BoundLibrariesPointer = Name + strlen(Name) + sizeof(CHAR);
    *BoundLibrariesPointer = ANSI_NULL;

    /* Return the pointer to the name */
    return Name;
}

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;
}

PCHAR
IMAGEAPI
BindpAddForwarderReference(LPSTR ModuleName,
                           LPSTR ImportName,
                           PIMPORT_DESCRIPTOR BoundImportDescriptor,
                           LPSTR DllPath,
                           PCHAR ForwarderString,
                           PBOOL ForwarderBound)
{
    CHAR DllName[256];
    PCHAR TempDllName, FunctionName;
    PLOADED_IMAGE Library;
    SIZE_T DllNameSize;
    USHORT OrdinalNumber;
    USHORT HintIndex;
    ULONG ExportSize;
    PIMAGE_EXPORT_DIRECTORY Exports;
    ULONG_PTR ExportsBase;
    PULONG AddressOfNames;
    PUSHORT AddressOfOrdinals;
    PULONG AddressOfPointers;
    LPSTR ExportName;
    ULONG_PTR ForwardedAddress;
    PBOUND_FORWARDER_REFS Forwarder, *NextForwarder;
    PIMAGE_OPTIONAL_HEADER OptionalHeader = NULL;

NextForwarder:

    /* Get the DLL Name */
    TempDllName = ForwarderString;
    while (*TempDllName && *TempDllName != '.') TempDllName++;
    if (*TempDllName != '.') return ForwarderString;

    /* Get the size */
    DllNameSize = (SIZE_T)(TempDllName - ForwarderString);
    if (DllNameSize >= MAX_PATH) return ForwarderString;

    /* Now copy the name and append the extension */
    strncpy(DllName, ForwarderString, DllNameSize);
    DllName[DllNameSize] = ANSI_NULL;
    strcat(DllName, ".DLL");

    /* Load it */
    DPRINT("Loading the Thunk Library: %s \n", DllName);
    Library = ImageLoad(DllName, DllPath);
    if (!Library) return ForwarderString;

    /* Move past the name */
    DPRINT("It Loaded at: %p \n", Library->MappedAddress);
    FunctionName = TempDllName += 1;

    /* Load Exports */
    Exports = ImageDirectoryEntryToData(Library->MappedAddress,
                                        FALSE,
                                        IMAGE_DIRECTORY_ENTRY_EXPORT,
                                        &ExportSize);
    if (!Exports) return ForwarderString;

    /* Get the Optional Header */
    OptionalHeader = &Library->FileHeader->OptionalHeader;

    /* Check if we're binding by ordinal */
    if (*FunctionName == '#')
    {
        /* We are, get the number and validate it */
        OrdinalNumber = atoi(FunctionName + 1) - (USHORT)Exports->Base;
        if (OrdinalNumber >= Exports->NumberOfFunctions) return ForwarderString;
    }
    else
    {
        /* Binding by name... */
        OrdinalNumber = -1;
    }

    /* 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);

    /* Check if we're binding by name... */
    if (OrdinalNumber == 0xffff)
    {
        /* Do a full search for the ordinal */
        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(FunctionName, ExportName))
            {
                OrdinalNumber = AddressOfOrdinals[HintIndex];
                break;
            }
        }

        /* Make sure it's valid */
        if (HintIndex >= Exports->NumberOfNames) return ForwarderString;
    }

    /* Get the Forwarded Address */
    ForwardedAddress = AddressOfPointers[OrdinalNumber] +
                       OptionalHeader->ImageBase;

    /* Loop the forwarders to see if this DLL was already processed */
    NextForwarder = &BoundImportDescriptor->Forwarders;
    while ((Forwarder = *NextForwarder))
    {
        /* Check for a name match */
        if (!_stricmp(DllName, Forwarder->ModuleName)) break;

        /* Move to the next one */
        NextForwarder = &Forwarder->Next;
    }

    /* Check if we've went through them all without luck */
    if (!Forwarder)
    {
        /* Allocate a forwarder structure */
        Forwarder = HeapAlloc(IMAGEHLP_hHeap,
                              HEAP_ZERO_MEMORY,
                              sizeof(BOUND_FORWARDER_REFS));

        /* Set the name */
        Forwarder->ModuleName = BindpCaptureImportModuleName(DllName);        

        /* Increase the number of forwarders */
        BoundImportDescriptor->ForwaderReferences++;

        /* Link it */
        *NextForwarder = Forwarder;
    }

    /* Set the timestamp */
    Forwarder->TimeDateStamp = Library->FileHeader->FileHeader.TimeDateStamp;

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

    /* Is this yet another Forward? */
    DPRINT("I've thunked it\n");
    if ((ForwardedAddress > ExportsBase) &&
        (ForwardedAddress < (ExportsBase + ExportSize)))
    {

⌨️ 快捷键说明

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