access.c
来自「一个类似windows」· C语言 代码 · 共 647 行 · 第 1/2 页
C
647 行
/*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* INCLUDES ******************************************************************/
#include "precomp.h"
//#define NDEBUG
#include <debug.h>
/* DATA **********************************************************************/
BOOLEAN DllListInitialized;
LIST_ENTRY ImageLoadListHead;
/* FUNCTIONS *****************************************************************/
PVOID
IMAGEAPI
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;
/* Check if this entry is invalid */
if (DirectoryEntry >= OptionalHeader->NumberOfRvaAndSizes)
{
/* Nothing found */
*Size = 0;
return NULL;
}
/* Get the VA of the Directory Requested */
DirectoryEntryVA = OptionalHeader->DataDirectory[DirectoryEntry].VirtualAddress;
if (!DirectoryEntryVA)
{
/* It doesn't exist */
*Size = 0;
return NULL;
}
/* Get the size of the Directory Requested */
*Size = OptionalHeader->DataDirectory[DirectoryEntry].Size;
/* Check if it was mapped as an image or if the entry is within the headers */
if ((MappedAsImage) || (DirectoryEntryVA < OptionalHeader->SizeOfHeaders))
{
/* No header found */
if (FoundHeader) *FoundHeader = NULL;
/* And simply return the VA */
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)))
{
/* Return the section header */
if (FoundHeader) *FoundHeader = CurrentSection;
return ((PVOID)((ULONG_PTR)Base +
(DirectoryEntryVA - CurrentSection->VirtualAddress) +
CurrentSection->PointerToRawData));
}
/* Move to the next section */
CurrentSection++;
}
/* If we got here, then we didn't find anything */
return NULL;
}
/*
* @unimplemented
*/
DWORD
IMAGEAPI
GetTimestampForLoadedLibrary(HMODULE Module)
{
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0;
}
/*
* @unimplemented
*/
BOOL
IMAGEAPI
GetImageConfigInformation(PLOADED_IMAGE LoadedImage,
PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation)
{
UNIMPLEMENTED;
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
/*
* @implemented
*/
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;
}
/*
* @implemented
*/
PVOID
IMAGEAPI
ImageDirectoryEntryToData(PVOID Base,
BOOLEAN MappedAsImage,
USHORT DirectoryEntry,
PULONG Size)
{
/* Let the extended function handle it */
return ImageDirectoryEntryToDataEx(Base,
MappedAsImage,
DirectoryEntry,
Size,
NULL);
}
/*
* @implemented
*/
PVOID
IMAGEAPI
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;
/* Get the optional header ourselves */
NtHeader = ImageNtHeader(Base);
FileHeader = &NtHeader->FileHeader;
OptionalHeader = &NtHeader->OptionalHeader;
/* FIXME: Read image type and call appropriate function (32, 64, ROM) */
return ImageDirectoryEntryToData32(Base,
MappedAsImage,
DirectoryEntry,
Size,
FoundSection,
FileHeader,
OptionalHeader);
}
/*
* @implemented
*/
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;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?