📄 modify.c
字号:
/*
* 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 + -