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 + -
显示快捷键?