📄 access.c
字号:
/*
* IMAGEHLP library
*
* Copyright 1998 Patrik Stridvall
*
* 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
*/
BOOLEAN DllListInitialized;
LIST_ENTRY ImageLoadListHead;
/***********************************************************************
* GetImageConfigInformation (IMAGEHLP.@)
*/
BOOL IMAGEAPI GetImageConfigInformation(
PLOADED_IMAGE LoadedImage,
PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation)
{
FIXME("(%p, %p): stub\n",
LoadedImage, ImageConfigInformation
);
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/***********************************************************************
* GetImageUnusedHeaderBytes (IMAGEHLP.@)
*/
DWORD IMAGEAPI GetImageUnusedHeaderBytes(
PLOADED_IMAGE LoadedImage,
LPDWORD SizeUnusedHeaderBytes)
{
SIZE_T FirstFreeByte;
PIMAGE_OPTIONAL_HEADER OptionalHeader = 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 */
OptionalHeader = &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 < OptionalHeader->NumberOfRvaAndSizes; i++)
{
/* If the VA is less then the size of headers, then the data is inside the PE header */
if (OptionalHeader->DataDirectory[i].VirtualAddress <
OptionalHeader->SizeOfHeaders)
{
/* However, make sure it's not 0, which means it doesnt actually exist */
if (OptionalHeader->DataDirectory[i].VirtualAddress >=
FirstFreeByte)
{
/* Our first empty byte is after this Directory Data then */
FirstFreeByte = OptionalHeader->DataDirectory[i].VirtualAddress +
OptionalHeader->DataDirectory[i].Size;
}
}
}
/* Return the unused Header Bytes */
*SizeUnusedHeaderBytes = OptionalHeader->SizeOfHeaders - (DWORD)FirstFreeByte;
/* And return the first free byte*/
return (DWORD)FirstFreeByte;
}
/***********************************************************************
* ImageLoad (IMAGEHLP.@)
*/
PLOADED_IMAGE IMAGEAPI ImageLoad(LPSTR DllName, LPSTR DllPath)
{
PLIST_ENTRY Head, Next;
PLOADED_IMAGE LoadedImage;
CHAR Drive[_MAX_DRIVE], Dir[_MAX_DIR], Filename[_MAX_FNAME], Ext[_MAX_EXT];
BOOL CompleteName = TRUE;
CHAR FullName[MAX_PATH];
/* Initialize the List Head */
if (!DllListInitialized)
{
InitializeListHead(&ImageLoadListHead);
DllListInitialized = TRUE;
}
/* Move to the Next DLL */
Head = &ImageLoadListHead;
Next = Head->Flink;
DPRINT("Trying to find library: %s in current ListHead \n", DllName);
/* Split the path */
_splitpath(DllName, Drive, Dir, Filename, Ext);
/* Check if we only got a name */
if (!strlen(Drive) && !strlen(Dir)) CompleteName = FALSE;
/* Check if we already Loaded it */
while (Next != Head)
{
/* Get the Loaded Image Structure */
LoadedImage = CONTAINING_RECORD(Next, LOADED_IMAGE, Links);
DPRINT("Found: %s in current ListHead \n", LoadedImage->ModuleName);
/* Check if we didn't have a complete name */
if (!CompleteName)
{
/* Split this module's name */
_splitpath(LoadedImage->ModuleName, NULL, NULL, Filename, Ext);
/* Use only the name and extension */
strcpy(FullName, Filename);
strcat(FullName, Ext);
}
else
{
/* Use the full untouched name */
strcpy(FullName, LoadedImage->ModuleName);
}
/* Check if the Names Match */
if (!_stricmp(DllName, FullName))
{
DPRINT("Found it, returning it\n");
return LoadedImage;
}
/* Move to next Entry */
Next = Next->Flink;
}
/* Allocate memory for the Structure, and write the Module Name under */
DPRINT("Didn't find it...allocating it for you now\n");
LoadedImage = HeapAlloc(IMAGEHLP_hHeap,
0,
sizeof(*LoadedImage) + strlen(DllName) + 1);
if (LoadedImage)
{
/* Module Name will be after structure */
LoadedImage->ModuleName = (LPSTR)(LoadedImage + 1);
/* Copy the Module Name */
strcpy(LoadedImage->ModuleName, DllName);
/* Now Load it */
if (MapAndLoad(DllName, DllPath, LoadedImage, TRUE, TRUE))
{
/* Add it to our list and return it */
InsertTailList(&ImageLoadListHead, &LoadedImage->Links);
return LoadedImage;
}
/* If we're here...there's been a failure */
HeapFree(IMAGEHLP_hHeap, 0, LoadedImage);
LoadedImage = NULL;
}
return LoadedImage;
}
/***********************************************************************
* ImageUnload (IMAGEHLP.@)
*/
BOOL IMAGEAPI ImageUnload(PLOADED_IMAGE pLoadedImage)
{
/* If the image list isn't empty, remove this entry */
if (!IsListEmpty(&pLoadedImage->Links)) RemoveEntryList(&pLoadedImage->Links);
/* Unmap and unload it */
UnMapAndLoad(pLoadedImage);
/* Free the structure */
HeapFree(IMAGEHLP_hHeap, 0, pLoadedImage);
/* Return success */
return TRUE;
}
/***********************************************************************
* MapAndLoad (IMAGEHLP.@)
*/
BOOL IMAGEAPI MapAndLoad(
LPSTR ImageName, LPSTR DllPath, PLOADED_IMAGE pLoadedImage,
BOOL DotDll, BOOL ReadOnly)
{
HANDLE hFile;
HANDLE hFileMapping;
ULONG Tried = 0;
UCHAR Buffer[MAX_PATH];
LPSTR FilePart;
LPSTR FileToOpen;
PIMAGE_NT_HEADERS NtHeader;
/* So we can add the DLL Path later */
FileToOpen = ImageName;
/* Assume failure */
pLoadedImage->hFile = INVALID_HANDLE_VALUE;
/* Start open loop */
while (TRUE)
{
/* Get a handle to the file */
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);
if (hFile == INVALID_HANDLE_VALUE)
{
/* Check if we already tried this once */
if (!Tried)
{
/* We didn't do do a path search now */
Tried = SearchPath(DllPath,
ImageName,
DotDll ? ".dll" : ".exe",
MAX_PATH,
Buffer,
&FilePart);
/* Check if it was successful */
if (Tried && (Tried < MAX_PATH))
{
/* Change the filename to use, and try again */
FileToOpen = Buffer;
continue;
}
}
/* Fail */
return FALSE;
}
/* Success, break out */
break;
}
/* Create the File Mapping */
hFileMapping = CreateFileMappingA(hFile,
NULL,
ReadOnly ? PAGE_READONLY :
PAGE_READWRITE,
0,
0,
NULL);
if (!hFileMapping)
{
/* Fail */
SetLastError(GetLastError());
CloseHandle(hFile);
return FALSE;
}
/* Get a pointer to the file */
pLoadedImage->MappedAddress = MapViewOfFile(hFileMapping,
ReadOnly ? FILE_MAP_READ :
FILE_MAP_WRITE,
0,
0,
0);
/* Close the handle to the map, we don't need it anymore */
CloseHandle(hFileMapping);
/* Write the image size */
pLoadedImage->SizeOfImage = GetFileSize(hFile, NULL);
/* Get the Nt Header */
NtHeader = ImageNtHeader(pLoadedImage->MappedAddress);
/* Allocate memory for the name and save it */
pLoadedImage->ModuleName = HeapAlloc(IMAGEHLP_hHeap,
0,
strlen(FileToOpen) + 16);
strcpy(pLoadedImage->ModuleName, FileToOpen);
/* Save the NT Header */
pLoadedImage->FileHeader = NtHeader;
/* Save the section data */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -