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 + -
显示快捷键?