modify.c
来自「一个类似windows」· C语言 代码 · 共 1,061 行 · 第 1/3 页
C
1,061 行
/* 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;
}
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;
/* 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;
}
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;
}
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)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?