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

📄 modify.c

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

#include "precomp.h"

//#define NDEBUG
#include <debug.h>
#define _WINNT_H
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);

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

CHAR BoundLibraries[4096];
LPSTR BoundLibrariesPointer;

/***********************************************************************
 *		BindImage (IMAGEHLP.@)
 */
BOOL WINAPI BindImage(
  LPSTR ImageName, LPSTR DllPath, LPSTR SymbolPath)
{
  return BindImageEx(0, ImageName, DllPath, SymbolPath, NULL);
}

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


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

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

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

⌨️ 快捷键说明

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