📄 modify.c
字号:
/* 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;
}
static 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;
}
static 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)
{
/* If we have a descriptor */
if (BoundImportDescriptor)
{
/* Zero the timestamp */
BoundImportDescriptor->TimeDateStamp = 0;
}
/* Quit the loop */
break;
}
/* Move on */
TempThunk++;
TempBoundThunk++;
}
/* Load the Second Thunk Array */
TempThunk = ImageRvaToVa(File->FileHeader,
File->MappedAddress,
(ULONG)Imports->FirstThunk,
&File->LastRvaSection);
if (TempThunk)
{
/* Check if the forwarder chain changed */
if (TopForwarderChain != -1)
{
/* It did. Update the chain and let caller know */
*ForwarderChain = -1;
*UpdateImage = TRUE;
}
/* Check if we're not pointing at the new top chain */
if (Imports->ForwarderChain != TopForwarderChain)
{
/* Update it, and let the caller know */
Imports->ForwarderChain = TopForwarderChain;
*UpdateImage = TRUE;
}
/* Check if thunks have changed */
if (memcmp(TempThunk, BoundThunks, SizeOfThunks))
{
/* Copy the Pointers and let caller know */
DPRINT("Copying Bound Thunks\n");
RtlCopyMemory(TempThunk, BoundThunks, SizeOfThunks);
*UpdateImage = TRUE;
}
/* Check if we have no bound entries */
if (!TopBoundDescriptor)
{
/* Check if the timestamp is different */
if (Imports->TimeDateStamp != FileHeader->TimeDateStamp)
{
/* Update it, and let the caller knmow */
Imports->TimeDateStamp = FileHeader->TimeDateStamp;
*UpdateImage = TRUE;
}
}
else if ((Imports->TimeDateStamp != 0xFFFFFFFF))
{
/* Invalidate the timedate stamp */
Imports->TimeDateStamp = 0xFFFFFFFF;
}
}
/* Free the Allocated Memory */
HeapFree(IMAGEHLP_hHeap, 0, BoundThunks);
DPRINT("Moving to next File\n");
Imports++;
}
}
/* Create the Bound Import Table */
DPRINT("Creating Bound Import Section\n");
BoundImportTable = BindpCreateNewImportSection(&TopBoundDescriptor,
&BoundImportTableSize);
/* Check if the import table changed */
if (OldBoundImportTableSize != BoundImportTableSize)
{
/* Let the caller know */
*UpdateImage = TRUE;
}
/*
* At this point, check if anything that we've done until now has resulted
* in the image being touched. If not, then we'll simply return to caller.
*/
if (!(*UpdateImage)) return;
/* Check if we have a new table */
if (BoundImportTable)
{
/* Zero it out */
OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -