Implemented ImageLoad, MapAndLoad, ImageRvaToVa, ImageRvaToSection, ImageDirectoryEntryToData, GetImageUnusedHeaderBytes and BindImageEx

svn path=/trunk/; revision=10233
This commit is contained in:
Alex Ionescu
2004-07-20 16:48:18 +00:00
parent c5ad1ab780
commit 27a729d88d
4 changed files with 1118 additions and 126 deletions
+330 -107
View File
@@ -35,6 +35,20 @@ extern inline DWORD WINAPI GetLastError(void)
return ret;
}
#define InitializeListHead(ListHead) (\
(ListHead)->Flink = (ListHead)->Blink = (ListHead))
#define InsertTailList(ListHead,Entry) {\
PLIST_ENTRY _EX_Blink;\
PLIST_ENTRY _EX_ListHead;\
_EX_ListHead = (ListHead);\
_EX_Blink = _EX_ListHead->Blink;\
(Entry)->Flink = _EX_ListHead;\
(Entry)->Blink = _EX_Blink;\
_EX_Blink->Flink = (Entry);\
_EX_ListHead->Blink = (Entry);\
}
WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
/***********************************************************************
@@ -60,6 +74,8 @@ static LOADED_IMAGE IMAGEHLP_EmptyLoadedImage = {
};
extern HANDLE IMAGEHLP_hHeap;
BOOLEAN DllListInitialized;
LIST_ENTRY ImageLoadListHead;
/***********************************************************************
* EnumerateLoadedModules (IMAGEHLP.@)
@@ -103,55 +119,240 @@ BOOL WINAPI GetImageConfigInformation(
/***********************************************************************
* GetImageUnusedHeaderBytes (IMAGEHLP.@)
*/
DWORD WINAPI GetImageUnusedHeaderBytes(
PLOADED_IMAGE LoadedImage,
LPDWORD SizeUnusedHeaderBytes)
DWORD
WINAPI
GetImageUnusedHeaderBytes(
PLOADED_IMAGE LoadedImage,
LPDWORD SizeUnusedHeaderBytes
)
{
FIXME("(%p, %p): stub\n",
LoadedImage, SizeUnusedHeaderBytes
);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
DWORD FirstFreeByte;
PIMAGE_OPTIONAL_HEADER OptionalHeader32 = NULL;
PIMAGE_NT_HEADERS NtHeaders;
ULONG i;
/* Read the NT Headers */
NtHeaders = LoadedImage->FileHeader;
/* Find the first free byte, which is after all the headers and sections */
FirstFreeByte = (ULONG_PTR)NtHeaders - (ULONG_PTR)LoadedImage->MappedAddress +
FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader) +
NtHeaders->FileHeader.SizeOfOptionalHeader +
NtHeaders->FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
/* Get the Optional Header */
OptionalHeader32 = &LoadedImage->FileHeader->OptionalHeader;
/* There is the possibilty that one of the Data Directories is in the PE Header
itself, so we'll need to find such a case and add it to our PE used space */
for ( i = 0; i<OptionalHeader32->NumberOfRvaAndSizes; i++ ) {
/* If the VA is less then the size of headers, then the data is inside the PE header */
if (OptionalHeader32->DataDirectory[i].VirtualAddress < OptionalHeader32->SizeOfHeaders) {
/* However, make sure it's not 0, which means it doesnt actually exist */
if (OptionalHeader32->DataDirectory[i].VirtualAddress >= FirstFreeByte) {
/* Our first empty byte is after this Directory Data then */
FirstFreeByte = OptionalHeader32->DataDirectory[i].VirtualAddress +
OptionalHeader32->DataDirectory[i].Size;
}
}
}
/* Return the unused Header Bytes */
*SizeUnusedHeaderBytes = OptionalHeader32->SizeOfHeaders - FirstFreeByte;
/* And return the first free byte*/
return FirstFreeByte;
}
/***********************************************************************
* ImageDirectoryEntryToData (IMAGEHLP.@)
*/
PVOID WINAPI ImageDirectoryEntryToData(
PVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size)
PVOID
WINAPI
ImageDirectoryEntryToData(
PVOID Base,
BOOLEAN MappedAsImage,
USHORT DirectoryEntry,
PULONG Size
)
{
FIXME("(%p, %d, %hd, %p): stub\n",
Base, MappedAsImage, DirectoryEntry, Size
);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return NULL;
return ImageDirectoryEntryToDataEx(Base, MappedAsImage, DirectoryEntry, Size, NULL);
}
/***********************************************************************
* RosImageDirectoryEntryToDataEx (IMAGEHLP.@)
*/
PVOID
WINAPI
ImageDirectoryEntryToDataEx (
IN PVOID Base,
IN BOOLEAN MappedAsImage,
IN USHORT DirectoryEntry,
OUT PULONG Size,
OUT PIMAGE_SECTION_HEADER *FoundSection OPTIONAL
)
{
PIMAGE_NT_HEADERS NtHeader;
PIMAGE_FILE_HEADER FileHeader;
PIMAGE_OPTIONAL_HEADER OptionalHeader;
NtHeader = ImageNtHeader(Base);
FileHeader = &NtHeader->FileHeader;
OptionalHeader = &NtHeader->OptionalHeader;
return (ImageDirectoryEntryToData32(Base,
MappedAsImage,
DirectoryEntry,
Size,
FoundSection,
FileHeader,
OptionalHeader));
}
/***********************************************************************
* RosImageDirectoryEntryToDataEx (IMAGEHLP.@)
*/
PVOID
STDCALL
ImageDirectoryEntryToData32 (
PVOID Base,
BOOLEAN MappedAsImage,
USHORT DirectoryEntry,
PULONG Size,
PIMAGE_SECTION_HEADER *FoundHeader OPTIONAL,
PIMAGE_FILE_HEADER FileHeader,
PIMAGE_OPTIONAL_HEADER OptionalHeader
)
{
ULONG i;
PIMAGE_SECTION_HEADER CurrentSection;
ULONG DirectoryEntryVA;
/* Get the VA of the Directory Requested */
DirectoryEntryVA = OptionalHeader->DataDirectory[DirectoryEntry].VirtualAddress;
/* Get the size of the Directory Requested */
*Size = OptionalHeader->DataDirectory[DirectoryEntry].Size;
/* Return VA if Mapped as Image*/
if (MappedAsImage || DirectoryEntryVA < OptionalHeader->SizeOfHeaders) {
if (FoundHeader) {
*FoundHeader = NULL;
}
return (PVOID)((ULONG_PTR)Base + DirectoryEntryVA);
}
/* Read the first Section */
CurrentSection = (PIMAGE_SECTION_HEADER)((ULONG_PTR)OptionalHeader + FileHeader->SizeOfOptionalHeader);
/* Loop through every section*/
for (i=0; i<FileHeader->NumberOfSections; i++) {
/* If the Directory VA is located inside this section's VA, then this section belongs to this Directory */
if (DirectoryEntryVA >= CurrentSection->VirtualAddress &&
DirectoryEntryVA < CurrentSection->VirtualAddress + CurrentSection->SizeOfRawData) {
if (FoundHeader) {
*FoundHeader = CurrentSection;
}
//return( (PVOID)((ULONG_PTR)Base + (DirectoryAddress - NtSection->VirtualAddress) + NtSection->PointerToRawData) );
return ((PVOID)((ULONG_PTR)Base + (DirectoryEntryVA - CurrentSection->VirtualAddress) + CurrentSection->PointerToRawData));
}
++CurrentSection;
}
return(NULL);
}
/***********************************************************************
* ImageLoad (IMAGEHLP.@)
*/
PLOADED_IMAGE WINAPI ImageLoad(LPSTR DllName, LPSTR DllPath)
{
PLOADED_IMAGE pLoadedImage;
PLIST_ENTRY Head,Next;
PLOADED_IMAGE LoadedImage;
FIXME("(%s, %s): stub\n", DllName, DllPath);
pLoadedImage = HeapAlloc(IMAGEHLP_hHeap, 0, sizeof(LOADED_IMAGE));
if (pLoadedImage)
pLoadedImage->FileHeader = HeapAlloc(IMAGEHLP_hHeap, 0, sizeof(IMAGE_NT_HEADERS));
return pLoadedImage;
/* Initialize the List Head */
if (!DllListInitialized) {
InitializeListHead(&ImageLoadListHead);
DllListInitialized = TRUE;
}
/* Move to the Next DLL */
Head = &ImageLoadListHead;
Next = Head->Flink;
//FIXME("Trying to find library: %s in current ListHead \n", DllName);
/* Check if we already Loaded it */
while (Next != Head) {
/* Get the Loaded Image Structure */
LoadedImage = CONTAINING_RECORD(Next, LOADED_IMAGE, Links);
//FIXME("Found: %s in current ListHead \n", LoadedImage->ModuleName);
/* Check if the Names Match */
if (!lstrcmpi( DllName, LoadedImage->ModuleName )) {
//FIXME("Found it, returning it\n");
return LoadedImage;
}
/* Move to next Entry */
Next = Next->Flink;
//FIXME("Moving to next List Entry\n");
}
//FIXME("Didn't find it...allocating it for you now\n");
/* Allocate memory for the Structure, and write the Module Name under */
LoadedImage = HeapAlloc(IMAGEHLP_hHeap, 0, sizeof(*LoadedImage) + lstrlen(DllName) + 1);
/* Module Name will be after structure */
LoadedImage->ModuleName = (LPSTR)LoadedImage + 1;
/* Copy the Moduel Name */
lstrcpy(LoadedImage->ModuleName, DllName);
/* Now Load it and add it to our list*/
if (MapAndLoad(DllName, DllPath, LoadedImage, TRUE, TRUE)) {
InsertTailList(&ImageLoadListHead, &LoadedImage->Links);
return LoadedImage;
}
/* If we're here...there's been a failure */
HeapFree(IMAGEHLP_hHeap, 0, LoadedImage);
LoadedImage = NULL;
return LoadedImage;
}
/***********************************************************************
* ImageRvaToSection (IMAGEHLP.@)
*/
PIMAGE_SECTION_HEADER WINAPI ImageRvaToSection(
PIMAGE_NT_HEADERS NtHeaders, PVOID Base, ULONG Rva)
PIMAGE_SECTION_HEADER
WINAPI
ImageRvaToSection(
IN PIMAGE_NT_HEADERS NtHeaders,
IN PVOID Base,
IN ULONG Rva
)
{
FIXME("(%p, %p, %ld): stub\n", NtHeaders, Base, Rva);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return NULL;
PIMAGE_SECTION_HEADER Section;
ULONG i;
/* Get the First Section */
Section = IMAGE_FIRST_SECTION(NtHeaders);
/* Look through each section and check if the RVA is in between */
for (i=0; i < NtHeaders->FileHeader.NumberOfSections; i++) {
if (Rva >= Section->VirtualAddress && Rva < Section->VirtualAddress +
Section->SizeOfRawData) {
return Section;
}
++Section;
}
/* Not Found */
return NULL;
}
/***********************************************************************
@@ -160,22 +361,35 @@ PIMAGE_SECTION_HEADER WINAPI ImageRvaToSection(
PIMAGE_NT_HEADERS WINAPI ImageNtHeader(PVOID Base)
{
TRACE("(%p)\n", Base);
return (PIMAGE_NT_HEADERS)
((LPBYTE) Base + ((PIMAGE_DOS_HEADER) Base)->e_lfanew);
/* Just return the e_lfanew Offset VA */
return (PIMAGE_NT_HEADERS)((LPBYTE)Base +
((PIMAGE_DOS_HEADER)Base)->e_lfanew);
}
/***********************************************************************
* ImageRvaToVa (IMAGEHLP.@)
*/
PVOID WINAPI ImageRvaToVa(
PIMAGE_NT_HEADERS NtHeaders, PVOID Base, ULONG Rva,
PIMAGE_SECTION_HEADER *LastRvaSection)
PVOID
WINAPI
ImageRvaToVa(
IN PIMAGE_NT_HEADERS NtHeaders,
IN PVOID Base,
IN ULONG Rva,
IN OUT PIMAGE_SECTION_HEADER *LastRvaSection OPTIONAL
)
{
FIXME("(%p, %p, %ld, %p): stub\n",
NtHeaders, Base, Rva, LastRvaSection
);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return NULL;
PIMAGE_SECTION_HEADER Section;
/* Get the Section Associated */
Section = ImageRvaToSection(NtHeaders, Base, Rva);
/* Return it, if specified */
if (LastRvaSection) *LastRvaSection = Section;
/* Return the VA */
return (PVOID)((ULONG_PTR)Base + (Rva - Section->VirtualAddress) +
Section->PointerToRawData);
}
/***********************************************************************
@@ -225,97 +439,106 @@ BOOL WINAPI ImageUnload(PLOADED_IMAGE pLoadedImage)
* MapAndLoad (IMAGEHLP.@)
*/
BOOL WINAPI MapAndLoad(
LPSTR pszImageName, LPSTR pszDllPath, PLOADED_IMAGE pLoadedImage,
BOOL bDotDll, BOOL bReadOnly)
LPSTR ImageName,
LPSTR DllPath,
PLOADED_IMAGE LoadedImage,
BOOL DotDll,
BOOL ReadOnly)
{
CHAR szFileName[MAX_PATH];
HANDLE hFile = NULL;
HANDLE hFileMapping = NULL;
HMODULE hModule = NULL;
PIMAGE_NT_HEADERS pNtHeader = NULL;
PIMAGE_NT_HEADERS NtHeader = NULL;
ULONG Tried = 0;
UCHAR Buffer[MAX_PATH];
LPSTR FilePart;
LPSTR FileToOpen;
TRACE("(%s, %s, %p, %d, %d)\n", pszImageName, pszDllPath, pLoadedImage,
bDotDll, bReadOnly);
/* So we can add the DLL Path later */
FileToOpen = ImageName;
/* PathCombine(&szFileName, pszDllPath, pszImageName); */
/* PathRenameExtension(&szFileName, bDotDll?:"dll":"exe"); */
/* FIXME: Check if the file already loaded (use IMAGEHLP_pFirstLoadedImage) */
if(!(hFile = CreateFileA(
szFileName, GENERIC_READ, 1, /* FIXME: FILE_SHARE_READ not defined */
NULL, OPEN_EXISTING, 0, NULL)))
TryAgain:
/* Get a handle to the file */
if ((LoadedImage->hFile = CreateFileA (FileToOpen,
ReadOnly ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE,
ReadOnly ? FILE_SHARE_READ : FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL)) == INVALID_HANDLE_VALUE)
{
SetLastError(ERROR_FILE_NOT_FOUND);
goto Error;
/* It Failed, use the DLL Search Path then (make sure we haven't already) */
if (!Tried) {
Tried = SearchPath(DllPath, ImageName, DotDll ? ".dll" : ".exe", MAX_PATH, Buffer, &FilePart);
if (Tried) {
FileToOpen = Buffer;
goto TryAgain;
}
}
/* Fail */
return FALSE;
}
if(!(hFileMapping = CreateFileMappingA(
hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL)))
/* Create the File Mapping */
if (!(hFileMapping = CreateFileMappingA (LoadedImage->hFile,
NULL,
ReadOnly ? PAGE_READONLY : PAGE_READWRITE,
0,
0,
NULL)))
{
DWORD dwLastError = GetLastError();
WARN("CreateFileMapping: Error = %ld\n", dwLastError);
SetLastError(dwLastError);
goto Error;
}
CloseHandle(hFile);
hFile = NULL;
if(!(hModule = (HMODULE) MapViewOfFile(
hFileMapping, FILE_MAP_READ, 0, 0, 0)))
{
DWORD dwLastError = GetLastError();
WARN("MapViewOfFile: Error = %ld\n", dwLastError);
SetLastError(dwLastError);
goto Error;
}
CloseHandle(hFileMapping);
hFileMapping=NULL;
/* Get a pointer to the file */
if(!(LoadedImage->MappedAddress = MapViewOfFile(hFileMapping,
ReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE,
0,
0,
0)))
{
DWORD dwLastError = GetLastError();
SetLastError(dwLastError);
goto Error;
}
pLoadedImage = (PLOADED_IMAGE) HeapAlloc(
IMAGEHLP_hHeap, 0, sizeof(LOADED_IMAGE)
);
/* Close the handle to the map, we don't need it anymore */
CloseHandle(hFileMapping);
hFileMapping=NULL;
pNtHeader = ImageNtHeader((PVOID) hModule);
/* Get the Nt Header */
NtHeader = ImageNtHeader(LoadedImage->MappedAddress);
pLoadedImage->ModuleName = HeapAlloc(IMAGEHLP_hHeap, 0, strlen(pszDllPath)+1); /* FIXME: Correct? */
strcpy( pLoadedImage->ModuleName, pszDllPath );
pLoadedImage->hFile = hFile;
pLoadedImage->MappedAddress = (PUCHAR) hModule;
pLoadedImage->FileHeader = pNtHeader;
pLoadedImage->Sections = (PIMAGE_SECTION_HEADER)
((LPBYTE) &pNtHeader->OptionalHeader +
pNtHeader->FileHeader.SizeOfOptionalHeader);
pLoadedImage->NumberOfSections =
pNtHeader->FileHeader.NumberOfSections;
pLoadedImage->SizeOfImage =
pNtHeader->OptionalHeader.SizeOfImage;
pLoadedImage->Characteristics =
pNtHeader->FileHeader.Characteristics;
pLoadedImage->LastRvaSection = pLoadedImage->Sections;
/* Write data */
LoadedImage->ModuleName = HeapAlloc(IMAGEHLP_hHeap, 0, lstrlen(ImageName) + 1);
lstrcpy(LoadedImage->ModuleName, ImageName);
LoadedImage->FileHeader = NtHeader;
LoadedImage->Sections = (PIMAGE_SECTION_HEADER)
((LPBYTE)&NtHeader->OptionalHeader +
NtHeader->FileHeader.SizeOfOptionalHeader);
LoadedImage->NumberOfSections = NtHeader->FileHeader.NumberOfSections;
LoadedImage->SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
LoadedImage->Characteristics = NtHeader->FileHeader.Characteristics;
LoadedImage->LastRvaSection = LoadedImage->Sections;
LoadedImage->fSystemImage = FALSE; /* FIXME */
LoadedImage->fDOSImage = FALSE; /* FIXME */
pLoadedImage->fSystemImage = FALSE; /* FIXME */
pLoadedImage->fDOSImage = FALSE; /* FIXME */
/* Read only, so no sense in keeping the handle alive */
if (ReadOnly) CloseHandle(LoadedImage->hFile);
/* FIXME: Make thread safe */
pLoadedImage->Links.Flink = NULL;
pLoadedImage->Links.Blink = &IMAGEHLP_pLastLoadedImage->Links;
if(IMAGEHLP_pLastLoadedImage)
IMAGEHLP_pLastLoadedImage->Links.Flink = &pLoadedImage->Links;
IMAGEHLP_pLastLoadedImage = pLoadedImage;
if(!IMAGEHLP_pFirstLoadedImage)
IMAGEHLP_pFirstLoadedImage = pLoadedImage;
return TRUE;
/* Return Success */
return TRUE;
Error:
if(hModule)
UnmapViewOfFile((PVOID) hModule);
if(hFileMapping)
CloseHandle(hFileMapping);
if(hFile)
CloseHandle(hFile);
return FALSE;
if(LoadedImage->MappedAddress)
UnmapViewOfFile(LoadedImage->MappedAddress);
if(hFileMapping)
CloseHandle(hFileMapping);
if(LoadedImage->hFile)
CloseHandle(LoadedImage->hFile);
return FALSE;
}
/***********************************************************************
+2 -1
View File
@@ -28,7 +28,8 @@ DEFINES = \
TARGET_CFLAGS += \
$(DEFINES) \
-DDCX_USESTYLE=0x10000L \
-I$(PATH_TO_TOP)/include/wine
-I$(PATH_TO_TOP)/include/wine
TARGET_RCFLAGS += -D__REACTOS__ -D_WIN32_IE=0x600 -D_WIN32_WINNT=0x501
+780 -14
View File
@@ -31,19 +31,787 @@ WINE_DEFAULT_DEBUG_CHANNEL(imagehlp);
static WORD CalcCheckSum(DWORD StartValue, LPVOID BaseAddress, DWORD WordCount);
extern PIMAGE_NT_HEADERS WINAPI ImageNtHeader(PVOID Base);
/***********************************************************************
* BindImageEx (IMAGEHLP.@)
/* Internal Structures we use to keep track of the Bound Imports */
typedef struct _BOUND_FORWARDER_REFS {
ULONG TimeDateStamp;
LPSTR ModuleName;
} BOUND_FORWARDER_REFS, *PBOUND_FORWARDER_REFS;
typedef struct _BOUND_IMPORT_DESCRIPTOR {
LPSTR ModuleName;
ULONG TimeDateStamp;
USHORT ForwaderReferences;
PBOUND_FORWARDER_REFS Forwarders;
} BOUND_IMPORT_DESCRIPTOR, *PBOUND_IMPORT_DESCRIPTOR;
VOID
STDCALL
BindpWalkAndBindImports(
PLOADED_IMAGE File,
LPSTR DllPath
);
PBOUND_IMPORT_DESCRIPTOR
STDCALL
BindpCreateBoundImportDescriptor(
LPSTR LibraryName,
PLOADED_IMAGE Library,
PULONG BoundImportDescriptor
);
BOOL
STDCALL
BindpBindThunk(
PIMAGE_THUNK_DATA Thunk,
PLOADED_IMAGE Image,
PIMAGE_THUNK_DATA BoundThunk,
PLOADED_IMAGE LoadedLibrary,
PIMAGE_EXPORT_DIRECTORY Exports,
PBOUND_IMPORT_DESCRIPTOR BoundImportDescriptor,
LPSTR DllPath
);
PIMAGE_BOUND_IMPORT_DESCRIPTOR
STDCALL
BindpCreateBoundImportSection(
PULONG BoundImportDescriptor,
PULONG BoundImportsSize
);
ULONG
STDCALL
BindpAddBoundForwarder(
PBOUND_IMPORT_DESCRIPTOR BoundImportDescriptor,
LPSTR DllPath,
PUCHAR ForwarderString
);
UCHAR BoundLibraries[4096];
LPSTR BoundLibrariesPointer = BoundLibraries;
PULONG BoundImportDescriptors;
/*
* BindImageEx
*
* FUNCTION:
* Binds a PE Image File to its imported Libraries
* ARGUMENTS:
* Flags - Caller Specified Flags
* ImageName - Name of Imagefile to Bind
* DllPath - Path to search DLL Files in, can be NULL to use Default
* SymbolPath - Path to search Symbol Files in, can be NULL to use Default
* StatusRoutine - Callback routine to notify of Bind Events, can be NULL to disable.
*
* RETURNS:
* TRUE if Success.
*/
BOOL WINAPI BindImageEx(
DWORD Flags, LPSTR ImageName, LPSTR DllPath, LPSTR SymbolPath,
PIMAGEHLP_STATUS_ROUTINE StatusRoutine)
BOOL
WINAPI
BindImageEx(
IN DWORD Flags,
IN LPSTR ImageName,
IN LPSTR DllPath,
IN LPSTR SymbolPath,
IN PIMAGEHLP_STATUS_ROUTINE StatusRoutine
)
{
FIXME("(%ld, %s, %s, %s, %p): stub\n",
Flags, debugstr_a(ImageName), debugstr_a(DllPath),
debugstr_a(SymbolPath), StatusRoutine
);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
LOADED_IMAGE FileData;
PLOADED_IMAGE File;
ULONG CheckSum, HeaderSum, OldChecksum;
SYSTEMTIME SystemTime;
FILETIME LastWriteTime;
FIXME("BindImageEx Called for: %s \n", ImageName);
/* Set and Clear Buffer */
File = &FileData;
RtlZeroMemory(File, sizeof(*File));
/* Request Image Data */
if (MapAndLoad(ImageName, DllPath, File, TRUE, FALSE)) {
//FIXME("Image Mapped and Loaded\n");
/* Read Import Table */
BindpWalkAndBindImports(File, DllPath);
//FIXME("Binding Completed, getting Checksum\n");
/* Update Checksum */
OldChecksum = File->FileHeader->OptionalHeader.CheckSum;
CheckSumMappedFile (File->MappedAddress,
GetFileSize(File->hFile, NULL),
&HeaderSum,
&CheckSum);
File->FileHeader->OptionalHeader.CheckSum = CheckSum;
//FIXME("Saving Changes to file\n");
/* Save Changes */
UnmapViewOfFile(File->MappedAddress);
//FIXME("Setting time\n");
/* Save new Modified Time */
GetSystemTime(&SystemTime);
SystemTimeToFileTime(&SystemTime, &LastWriteTime);
SetFileTime(File->hFile, NULL, NULL, &LastWriteTime);
/* Close Handle */
CloseHandle(File->hFile);
}
FIXME("Done\n");
return TRUE;
}
/*
* BindpWalkAndBindImports
*
* FUNCTION:
* Does the actual Binding of the Imports and Forward-Referencing
*
* ARGUMENTS:
* File - Name of Imagefile to Bind
* DllPath - Path to search DLL Files in, can be NULL to use Default
*
* RETURNS:
* Nothing
*/
VOID
STDCALL
BindpWalkAndBindImports(
PLOADED_IMAGE File,
LPSTR DllPath
)
{
PIMAGE_IMPORT_DESCRIPTOR Imports;
PIMAGE_EXPORT_DIRECTORY Exports;
ULONG SizeOfImports;
ULONG SizeOfExports;
ULONG SizeOfThunks;
PIMAGE_OPTIONAL_HEADER OptionalHeader32 = NULL;
PIMAGE_FILE_HEADER FileHeader;
LPSTR ImportedLibrary;
PLOADED_IMAGE LoadedLibrary;
PBOUND_IMPORT_DESCRIPTOR BoundImportDescriptor = NULL;
PIMAGE_BOUND_IMPORT_DESCRIPTOR BoundImportTable;
PIMAGE_THUNK_DATA Thunks, TempThunk;
PIMAGE_THUNK_DATA BoundThunks, TempBoundThunk;
ULONG ThunkCount = 0;
ULONG Thunk;
ULONG BoundImportTableSize;
ULONG VirtBytesFree, HeaderBytesFree, FirstFreeByte, PhysBytesFree;
//FIXME("BindpWalkAndBindImports Called\n");
/* Load the Import Descriptor */
Imports = ImageDirectoryEntryToData (File->MappedAddress,
FALSE,
IMAGE_DIRECTORY_ENTRY_IMPORT,
&SizeOfImports);
/* Read the File Header */
FileHeader = &File->FileHeader->FileHeader;
OptionalHeader32 = &File->FileHeader->OptionalHeader;
/* Support for up to 32 imported DLLs */
BoundImportDescriptors = GlobalAlloc(GMEM_ZEROINIT, 32* sizeof(*BoundImportDescriptor));
//FIXME("BoundImportDescriptors Allocated\n");
/* For each Import */
for(; Imports->Name ; Imports++) {
/* Which DLL is being Imported */
ImportedLibrary = ImageRvaToVa (File->FileHeader,
File->MappedAddress,
Imports->Name,
&File->LastRvaSection);
FIXME("Loading Imported DLL: %s \n", ImportedLibrary);
/* Load the DLL */
LoadedLibrary = ImageLoad(ImportedLibrary, DllPath);
FIXME("DLL Loaded at: %p \n", LoadedLibrary->MappedAddress);
/* Now load the Exports */
Exports = ImageDirectoryEntryToData (LoadedLibrary->MappedAddress,
FALSE,
IMAGE_DIRECTORY_ENTRY_EXPORT,
&SizeOfExports);
/* 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) continue;
//FIXME("Creating Bound Descriptor for this DLL\n");
/* Create Bound Import Descriptor */
BoundImportDescriptor = BindpCreateBoundImportDescriptor (ImportedLibrary,
LoadedLibrary,
BoundImportDescriptors);
/* 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 = GlobalAlloc(GMEM_ZEROINIT, SizeOfThunks);
//FIXME("Binding Thunks\n");
/* Bind the Thunks */
TempThunk = Thunks;
TempBoundThunk = BoundThunks;
for (Thunk=0; Thunk < ThunkCount; Thunk++) {
BindpBindThunk (TempThunk,
File,
TempBoundThunk,
LoadedLibrary,
Exports,
BoundImportDescriptor,
DllPath);
TempThunk++;
TempBoundThunk++;
}
/* Load the Second Thunk Array */
TempThunk = ImageRvaToVa (File->FileHeader,
File->MappedAddress,
(ULONG)Imports->FirstThunk,
&File->LastRvaSection);
//FIXME("Copying Bound Thunks\n");
/* Copy the Pointers */
if (memcmp(TempThunk, BoundThunks, SizeOfThunks)) {
RtlCopyMemory(TempThunk, BoundThunks, SizeOfThunks);
}
/* Set the TimeStamp */
if (Imports->TimeDateStamp != 0xFFFFFFFF) {
Imports->TimeDateStamp = 0xFFFFFFFF;
}
/* Free the Allocated Memory */
GlobalFree(BoundThunks);
//FIXME("Moving to next File\n");
}
//FIXME("Creating Bound Import Section\n");
/* Create the Bound Import Table */
BoundImportTable = BindpCreateBoundImportSection(BoundImportDescriptors, &BoundImportTableSize);
/* Zero out the Bound Import Table */
File->FileHeader->OptionalHeader.DataDirectory
[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;
File->FileHeader->OptionalHeader.DataDirectory
[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;
/* Check if we have enough space */
FirstFreeByte = GetImageUnusedHeaderBytes(File, &VirtBytesFree);
HeaderBytesFree = File->Sections->VirtualAddress -
File->FileHeader->OptionalHeader.SizeOfHeaders + VirtBytesFree;
PhysBytesFree = File->Sections->PointerToRawData -
File->FileHeader->OptionalHeader.SizeOfHeaders + VirtBytesFree;
//FIXME("Calculating Space\n");
if (BoundImportTableSize > VirtBytesFree) {
if (BoundImportTableSize > HeaderBytesFree) {
FIXME("Not enough Space\n");
return; /* Fail...not enough space */
}
if (BoundImportTableSize <= PhysBytesFree) {
FIXME("Header Recalculation\n");
/* We have enough NULLs to add it, simply enlarge header data */
File->FileHeader->OptionalHeader.SizeOfHeaders = File->FileHeader->OptionalHeader.SizeOfHeaders -
VirtBytesFree +
BoundImportTableSize +
((File->FileHeader->OptionalHeader.FileAlignment - 1)
& ~(File->FileHeader->OptionalHeader.FileAlignment - 1));
} else {
FIXME("Header Resizing\n");
/* Resize the Headers */
//UNIMPLEMENTED
/* Recalculate Headers */
FileHeader = &File->FileHeader->FileHeader;
OptionalHeader32 = &File->FileHeader->OptionalHeader;
}
}
/* Set Bound Import Table Data */
File->FileHeader->OptionalHeader.DataDirectory
[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = FirstFreeByte;
File->FileHeader->OptionalHeader.DataDirectory
[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = BoundImportTableSize;
//FIXME("Copying Bound Import Table\n");
/* Copy the Bound Import Table */
RtlCopyMemory(File->MappedAddress + FirstFreeByte, BoundImportTable, BoundImportTableSize);
/* Free out local copy */
GlobalFree(BoundImportTable);
}
/*
* BindpCreateBoundImportSection
*
* FUNCTION:
* Creates a 32-bit PE Bound Import Table
*
* ARGUMENTS:
* BoundImportDescriptor - Pointer to the Bound Import Table
* BoundImportsSize - Size of the Bound Import Table
*
* RETURNS:
* PIMAGE_BOUND_IMPORT_DESCRIPTOR - The Bound Import Table
*/
PIMAGE_BOUND_IMPORT_DESCRIPTOR
STDCALL
BindpCreateBoundImportSection(
PULONG BoundImportDescriptor,
PULONG BoundImportsSize
)
{
ULONG BoundLibraryNamesSize, BoundImportTableSize;
PBOUND_FORWARDER_REFS BoundForwarder;
PBOUND_IMPORT_DESCRIPTOR CurrentBoundImportDescriptor;
PVOID BoundLibraryNames;
PIMAGE_BOUND_IMPORT_DESCRIPTOR CurrentBoundImportTableEntry, BoundImportTable;
PIMAGE_BOUND_FORWARDER_REF NewForwarder;
/* Zero the Sizes */
*BoundImportsSize = 0;
BoundLibraryNamesSize = 0;
BoundImportTableSize = 0;
/* Start with the first Internal Descriptor */
CurrentBoundImportDescriptor = (PBOUND_IMPORT_DESCRIPTOR)BoundImportDescriptor;
/* Loop through every Descriptor we loaded */
while (CurrentBoundImportDescriptor->ModuleName) {
/* Add to the size of the Bound Import Table */
BoundImportTableSize += sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR);
/* Check Forwarders */
BoundForwarder = CurrentBoundImportDescriptor->Forwarders;
while (BoundForwarder->ModuleName) {
/* Add to size of Bound Import Table */
BoundImportTableSize += sizeof(IMAGE_BOUND_FORWARDER_REF);
/* Next Forwarder */
BoundForwarder++;
}
/* Read Next Internal Descriptor */
CurrentBoundImportDescriptor++;
}
/* Add Terminator for PE Loader*/
BoundImportTableSize += sizeof(IMAGE_BOUND_IMPORT_DESCRIPTOR);
/* Name of Libraries Bound in Bound Import Table */
BoundLibraryNamesSize = ((ULONG)BoundLibrariesPointer - (ULONG)(&BoundLibraries));
/* Size of the whole table, dword aligned */
*BoundImportsSize = BoundImportTableSize +
((BoundLibraryNamesSize + sizeof(ULONG) - 1) & ~(sizeof(ULONG)-1));
/* Allocate it */
BoundImportTable = GlobalAlloc(GMEM_ZEROINIT, *BoundImportsSize);
/* Pointer Library Names inside the Bound Import Table */
BoundLibraryNames = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)((ULONG_PTR)BoundImportTable +
BoundImportTableSize);
/* Copy the Library Names */
RtlCopyMemory(BoundLibraryNames, BoundLibraries, BoundLibraryNamesSize);
/* Go back to first Internal Descriptor and load first entry in the Bound Import Table */
CurrentBoundImportTableEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)BoundImportTable;
CurrentBoundImportDescriptor = (PBOUND_IMPORT_DESCRIPTOR)BoundImportDescriptor;
/* Copy the data from our Internal Structure to the Bound Import Table */
while (CurrentBoundImportDescriptor->ModuleName) {
CurrentBoundImportTableEntry->TimeDateStamp = CurrentBoundImportDescriptor->TimeDateStamp;
CurrentBoundImportTableEntry->OffsetModuleName = (USHORT)(BoundImportTableSize +
(CurrentBoundImportDescriptor->ModuleName -
(LPSTR) BoundLibraries));
CurrentBoundImportTableEntry->NumberOfModuleForwarderRefs = CurrentBoundImportDescriptor->ForwaderReferences;
/* Copy the data from our Forwader Entries to the Bound Import Table */
NewForwarder = (PIMAGE_BOUND_FORWARDER_REF)(CurrentBoundImportTableEntry+1);
BoundForwarder = CurrentBoundImportDescriptor->Forwarders;
while (BoundForwarder->ModuleName) {
NewForwarder->TimeDateStamp =BoundForwarder->TimeDateStamp;
NewForwarder->OffsetModuleName = (USHORT)(BoundImportTableSize +
(BoundForwarder->ModuleName -
(LPSTR) BoundLibraries));
NewForwarder++;
BoundForwarder++;
}
/* Move to next Bound Import Table Entry */
CurrentBoundImportTableEntry = (PIMAGE_BOUND_IMPORT_DESCRIPTOR)NewForwarder;
/* move to next Internal Descriptor */
CurrentBoundImportDescriptor++;
}
/* Now put the pointer back at the beginning and clear the buffer */
RtlZeroMemory(BoundLibraries, 4096);
BoundLibrariesPointer = BoundLibraries;
return BoundImportTable;
}
/*
* BindpBindThunk
*
* FUNCTION:
* Finds the pointer of the Imported function, and writes it into the Thunk,
* thus making the Thunk Bound.
*
* ARGUMENTS:
* Thunk - Current Thunk in Unbound File
* File - File containing the Thunk
* BoundThunk - Pointer to the corresponding Bound Thunk
* LoadedLibrary - Library containing the Exported Function
* Exports - Export Directory of LoadedLibrary
* BoundImportDescriptor - Internal Bound Import Descriptor of LoadedLibrary
* DllPath - DLL Search Path
*
* RETURNS:
* TRUE if Suceeded
*/
BOOL
STDCALL
BindpBindThunk(
PIMAGE_THUNK_DATA Thunk,
PLOADED_IMAGE File,
PIMAGE_THUNK_DATA BoundThunk,
PLOADED_IMAGE LoadedLibrary,
PIMAGE_EXPORT_DIRECTORY Exports,
PBOUND_IMPORT_DESCRIPTOR BoundImportDescriptor,
LPSTR DllPath
)
{
PULONG AddressOfNames;
PUSHORT AddressOfOrdinals;
PULONG AddressOfPointers;
PIMAGE_IMPORT_BY_NAME ImportName;
ULONG OrdinalNumber = 0;
USHORT HintIndex;
LPSTR ExportName;
ULONG ExportsBase;
ULONG ExportSize;
UCHAR NameBuffer[32];
PIMAGE_OPTIONAL_HEADER OptionalHeader32 = NULL;
PIMAGE_OPTIONAL_HEADER LibraryOptionalHeader32 = NULL;
/* Get the Pointers to the Tables */
AddressOfNames = ImageRvaToVa (LoadedLibrary->FileHeader,
LoadedLibrary->MappedAddress,
Exports->AddressOfNames,
&LoadedLibrary->LastRvaSection);
AddressOfOrdinals = ImageRvaToVa (LoadedLibrary->FileHeader,
LoadedLibrary->MappedAddress,
Exports->AddressOfNameOrdinals,
&LoadedLibrary->LastRvaSection);
AddressOfPointers = ImageRvaToVa (LoadedLibrary->FileHeader,
LoadedLibrary->MappedAddress,
Exports->AddressOfFunctions,
&LoadedLibrary->LastRvaSection);
//FIXME("Binding a Thunk\n");
/* Get the Optional Header */
OptionalHeader32 = &File->FileHeader->OptionalHeader;
LibraryOptionalHeader32 = &LoadedLibrary->FileHeader->OptionalHeader;
/* Import by Ordinal */
if (IMAGE_SNAP_BY_ORDINAL(Thunk->u1.Ordinal) == TRUE) {
OrdinalNumber = (IMAGE_ORDINAL(Thunk->u1.Ordinal) - Exports->Base);
ImportName = (PIMAGE_IMPORT_BY_NAME)NameBuffer;
} else {
/* Import by Name */
ImportName = ImageRvaToVa (File->FileHeader,
File->MappedAddress,
(ULONG)Thunk->u1.AddressOfData,
&File->LastRvaSection);
for (HintIndex = 0; HintIndex < Exports->NumberOfNames; HintIndex++) {
/* Get the Export Name */
ExportName = ImageRvaToVa (LoadedLibrary->FileHeader,
LoadedLibrary->MappedAddress,
(ULONG)AddressOfNames[HintIndex],
&LoadedLibrary->LastRvaSection);
/* Check if it's the one we want */
if (!strcmp(ImportName->Name, ExportName)) {
OrdinalNumber = AddressOfOrdinals[HintIndex];
break;
}
}
}
/* Fail if we still didn't find anything */
if (!OrdinalNumber) return FALSE;
/* Write the Pointer */
(ULONG)BoundThunk->u1.Function = AddressOfPointers[OrdinalNumber] + LibraryOptionalHeader32->ImageBase;
/* Load DLL's Exports */
ExportsBase = (ULONG)ImageDirectoryEntryToData (LoadedLibrary->MappedAddress,
TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT,
&ExportSize) -
(ULONG_PTR)LoadedLibrary->MappedAddress;
/* RVA to VA */
ExportsBase += LibraryOptionalHeader32->ImageBase;
/* Check if the Export is forwarded (meaning that it's pointer is inside the Export Table) */
if ((ULONG)BoundThunk->u1.Function > ExportsBase && (ULONG)BoundThunk->u1.Function < (ExportsBase + ExportSize)) {
//FIXME("This Thunk is a forward...calling forward thunk bounder\n");
/* Replace the Forwarder String by the actual Pointer */
(ULONG)BoundThunk->u1.Function = BindpAddBoundForwarder (BoundImportDescriptor,
DllPath,
ImageRvaToVa (LoadedLibrary->FileHeader,
LoadedLibrary->MappedAddress,
AddressOfPointers[OrdinalNumber],
&LoadedLibrary->LastRvaSection));
}
/* Return Success */
return TRUE;
}
/*
* BindpAddBoundForwarder
*
* FUNCTION:
* Finds the pointer of the Forwarded function, and writes it into the Thunk,
* thus making the Thunk Bound.
*
* ARGUMENTS:
* BoundImportDescriptor - Internal Bound Import Descriptor of LoadedLibrary
* DllPath - DLL Search Path
* ForwarderString - Name of the Forwader String
*
* RETURNS:
* Pointer to the Forwaded Function.
*/
ULONG
STDCALL
BindpAddBoundForwarder(
PBOUND_IMPORT_DESCRIPTOR BoundImportDescriptor,
LPSTR DllPath,
PUCHAR ForwarderString
)
{
CHAR DllName[256];
PUCHAR TempDllName;
PLOADED_IMAGE LoadedLibrary;
ULONG DllNameSize;
USHORT OrdinalNumber;
USHORT HintIndex;
ULONG ExportSize;
PIMAGE_EXPORT_DIRECTORY Exports;
ULONG ExportsBase;
PULONG AddressOfNames;
PUSHORT AddressOfOrdinals;
PULONG AddressOfPointers;
LPSTR ExportName;
ULONG ForwardedAddress;
PBOUND_FORWARDER_REFS BoundForwarder;
PIMAGE_OPTIONAL_HEADER OptionalHeader32 = NULL;
NextForwarder:
/* Get the DLL Name */
TempDllName = ForwarderString;
while (*TempDllName && *TempDllName != '.') TempDllName++;
DllNameSize = (ULONG) (TempDllName - ForwarderString);
lstrcpyn(DllName, ForwarderString, DllNameSize + 1);
/* Append .DLL extension */
DllName[DllNameSize] = '\0';
strcat(DllName, ".DLL" );
/* Load it */
FIXME("Loading the Thunk Library: %s \n", DllName);
LoadedLibrary = ImageLoad(DllName, DllPath);
TempDllName += 1;
/* Return whatever we got back in case of failure*/
if (!LoadedLibrary) return (ULONG)ForwarderString;
FIXME("It Loaded at: %p \n", LoadedLibrary->MappedAddress);
/* Load Exports */
Exports = ImageDirectoryEntryToData(LoadedLibrary->MappedAddress, FALSE, IMAGE_DIRECTORY_ENTRY_EXPORT, &ExportSize);
/* Get the Pointers to the Tables */
AddressOfNames = ImageRvaToVa (LoadedLibrary->FileHeader,
LoadedLibrary->MappedAddress,
Exports->AddressOfNames,
&LoadedLibrary->LastRvaSection);
AddressOfOrdinals = ImageRvaToVa (LoadedLibrary->FileHeader,
LoadedLibrary->MappedAddress,
Exports->AddressOfNameOrdinals,
&LoadedLibrary->LastRvaSection);
AddressOfPointers = ImageRvaToVa (LoadedLibrary->FileHeader,
LoadedLibrary->MappedAddress,
Exports->AddressOfFunctions,
&LoadedLibrary->LastRvaSection);
/* Get the Optional Header */
OptionalHeader32 = &LoadedLibrary->FileHeader->OptionalHeader;
/* Get the Ordinal Number */
for (HintIndex = 0; HintIndex < Exports->NumberOfNames; HintIndex++) {
/* Get the Export Name */
ExportName = ImageRvaToVa (LoadedLibrary->FileHeader,
LoadedLibrary->MappedAddress,
AddressOfNames[HintIndex],
&LoadedLibrary->LastRvaSection);
/* Check if it matches */
if (!strcmp(TempDllName, ExportName)) {
OrdinalNumber = AddressOfOrdinals[HintIndex];
break;
}
}
do {
/* Get the Forwarded Address */
ForwardedAddress = AddressOfPointers[OrdinalNumber] + OptionalHeader32->ImageBase;
/* Load the First Bound Forward Structure */
BoundForwarder = BoundImportDescriptor->Forwarders;
/* Check if we already have the Module Name written */
while (BoundForwarder->ModuleName) {
if (!lstrcmpi(DllName, BoundForwarder->ModuleName)) break;
BoundForwarder++;
}
if (!BoundForwarder->ModuleName) {
/* Save Library Name in Bound Libraries Buffer */
strcat((char *)BoundLibrariesPointer, DllName);
/* Set Data */
BoundForwarder->ModuleName = BoundLibrariesPointer;
BoundForwarder->TimeDateStamp = LoadedLibrary->FileHeader->FileHeader.TimeDateStamp;
/* Next String */
BoundLibrariesPointer = BoundLibrariesPointer + strlen((char *)BoundLibrariesPointer) + 1;
BoundImportDescriptor->ForwaderReferences += 1;
}
/* Load DLL's Exports */
ExportsBase = (ULONG)ImageDirectoryEntryToData (LoadedLibrary->MappedAddress,
TRUE,
IMAGE_DIRECTORY_ENTRY_EXPORT,
&ExportSize) -
(ULONG_PTR)LoadedLibrary->MappedAddress;
ExportsBase += OptionalHeader32->ImageBase;
//FIXME("I've thunked it\n");
/* Is this yet another Forward? */
if (ForwardedAddress > ExportsBase && ForwardedAddress < (ExportsBase + ExportSize)) {
ForwarderString = ImageRvaToVa (LoadedLibrary->FileHeader,
LoadedLibrary->MappedAddress,
AddressOfPointers[OrdinalNumber],
&LoadedLibrary->LastRvaSection);
goto NextForwarder;
}
}
while (0);
return ForwardedAddress;
}
/*
* BindpCreateBoundImportDescriptor
*
* FUNCTION:
* Creates an Internal Structure for the Bound Library
*
* ARGUMENTS:
* LibraryName - Name of the Library
* Library - Loaded Library
* BoundImportDescriptor - Internal Bound Import Descriptor of Library
*
* RETURNS:
* PBOUND_IMPORT_DESCRIPTOR - Pointer to the Internal Bind Structure
*/
PBOUND_IMPORT_DESCRIPTOR
STDCALL
BindpCreateBoundImportDescriptor(
LPSTR LibraryName,
PLOADED_IMAGE Library,
PULONG BoundImportDescriptor
)
{
PBOUND_IMPORT_DESCRIPTOR CurrentBoundImportDescriptor;
/* Load the First Descriptor */
CurrentBoundImportDescriptor = (PBOUND_IMPORT_DESCRIPTOR)BoundImportDescriptor;
/* Check if we've already bound this library */
while (CurrentBoundImportDescriptor->ModuleName) {
if (!lstrcmpi(CurrentBoundImportDescriptor->ModuleName, LibraryName)) {
return CurrentBoundImportDescriptor;
}
CurrentBoundImportDescriptor++;
}
/* Save Library Name in Bound Libraries Buffer */
strcat((char *)BoundLibrariesPointer, LibraryName);
/* Set Data */
CurrentBoundImportDescriptor->ModuleName = BoundLibrariesPointer;
CurrentBoundImportDescriptor->TimeDateStamp = Library->FileHeader->FileHeader.TimeDateStamp;
/* Support for up to 32 Forwarded DLLs */
CurrentBoundImportDescriptor->Forwarders = GlobalAlloc(GMEM_ZEROINIT, 32* sizeof(BOUND_FORWARDER_REFS));
/* Next String */
BoundLibrariesPointer = BoundLibrariesPointer + strlen((char *)BoundLibrariesPointer) + 1;
return CurrentBoundImportDescriptor;
}
/***********************************************************************
@@ -92,9 +860,7 @@ PIMAGE_NT_HEADERS WINAPI CheckSumMappedFile(
DWORD CalcSum;
DWORD HdrSum;
FIXME("(%p, %ld, %p, %p): stub\n",
BaseAddress, FileLength, HeaderSum, CheckSum
);
FIXME("stub\n");
CalcSum = (DWORD)CalcCheckSum(0,
BaseAddress,
+6 -4
View File
@@ -75,7 +75,7 @@ extern "C" {
#define UNDNAME_NO_ARGUMENTS 8192
#define UNDNAME_NO_SPECIAL_SYMS 16384
#define _IMAGEHLPAPI DECLSPEC_IMPORT WINAPI
#define _IMAGEHLPAPI WINAPI
#ifndef RC_INVOKED
@@ -258,6 +258,8 @@ PLOADED_IMAGE _IMAGEHLPAPI ImageLoad(LPSTR,LPSTR);
BOOL _IMAGEHLPAPI ImageUnload(PLOADED_IMAGE);
PIMAGE_NT_HEADERS _IMAGEHLPAPI ImageNtHeader(IN PVOID);
PVOID _IMAGEHLPAPI ImageDirectoryEntryToData(IN PVOID,IN BOOLEAN,IN USHORT,OUT PULONG);
PVOID _IMAGEHLPAPI ImageDirectoryEntryToDataEx(IN PVOID Base, IN BOOLEAN MappedAsImage, IN USHORT DirectoryEntry, OUT PULONG Size, OUT PIMAGE_SECTION_HEADER *FoundSection OPTIONAL);
PVOID _IMAGEHLPAPI ImageDirectoryEntryToData32(PVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size, PIMAGE_SECTION_HEADER *FoundHeader OPTIONAL, PIMAGE_FILE_HEADER FileHeader, PIMAGE_OPTIONAL_HEADER OptionalHeader);
PIMAGE_SECTION_HEADER _IMAGEHLPAPI ImageRvaToSection(IN PIMAGE_NT_HEADERS,IN PVOID,IN ULONG);
PVOID _IMAGEHLPAPI ImageRvaToVa(IN PIMAGE_NT_HEADERS,IN PVOID,IN ULONG,IN OUT PIMAGE_SECTION_HEADER*);
BOOL _IMAGEHLPAPI MapAndLoad(LPSTR,LPSTR,PLOADED_IMAGE,BOOL,BOOL);
@@ -305,11 +307,11 @@ BOOL _IMAGEHLPAPI SymUnloadModule(IN HANDLE,IN DWORD);
BOOL _IMAGEHLPAPI SymUnDName(IN PIMAGEHLP_SYMBOL,OUT LPSTR,IN DWORD);
BOOL _IMAGEHLPAPI SymRegisterCallback(IN HANDLE,IN PSYMBOL_REGISTERED_CALLBACK,IN PVOID);
BOOL _IMAGEHLPAPI ImageGetDigestStream(IN HANDLE,IN DWORD,IN DIGEST_FUNCTION,IN DIGEST_HANDLE);
BOOL _IMAGEHLPAPI ImageAddCertificate(IN HANDLE,IN LPWIN_CERTIFICATE,OUT PDWORD);
//BOOL _IMAGEHLPAPI ImageAddCertificate(IN HANDLE,IN LPWIN_CERTIFICATE,OUT PDWORD);
BOOL _IMAGEHLPAPI ImageRemoveCertificate(IN HANDLE,IN DWORD);
BOOL _IMAGEHLPAPI ImageEnumerateCertificates(IN HANDLE,IN WORD,OUT PDWORD,IN OUT PDWORD OPTIONAL,IN OUT DWORD OPTIONAL);
BOOL _IMAGEHLPAPI ImageGetCertificateData(IN HANDLE,IN DWORD,OUT LPWIN_CERTIFICATE,IN OUT PDWORD);
BOOL _IMAGEHLPAPI ImageGetCertificateHeader(IN HANDLE,IN DWORD,IN OUT LPWIN_CERTIFICATE);
//BOOL _IMAGEHLPAPI ImageGetCertificateData(IN HANDLE,IN DWORD,OUT LPWIN_CERTIFICATE,IN OUT PDWORD);
//BOOL _IMAGEHLPAPI ImageGetCertificateHeader(IN HANDLE,IN DWORD,IN OUT LPWIN_CERTIFICATE);
BOOL _IMAGEHLPAPI CopyPdb(CHAR const*,CHAR const*,BOOL);
BOOL _IMAGEHLPAPI RemovePrivateCvSymbolicEx(PCHAR,ULONG,PCHAR*,ULONG*);