access.c

来自「一个类似windows」· C语言 代码 · 共 647 行 · 第 1/2 页

C
647
字号
}

/*
 * @implemented
 */
PIMAGE_SECTION_HEADER 
IMAGEAPI
ImageRvaToSection(IN PIMAGE_NT_HEADERS NtHeaders,
                  IN PVOID Base,
                  IN ULONG Rva)
{
    PIMAGE_SECTION_HEADER Section;
    ULONG i;

    /* Get the First Section */
    Section = IMAGE_FIRST_SECTION(NtHeaders);

    /* Look through each section */
    for (i = 0; i < NtHeaders->FileHeader.NumberOfSections; i++)
    {
        /* Check if the RVA is in between */
        if ((Rva >= Section->VirtualAddress) && 
            (Rva < (Section->VirtualAddress + Section->SizeOfRawData)))
        {
            /* Return this section */
            return Section;
        }

        /* Move to the next section */
        Section++;
    }

    /* Not Found */
    return NULL;
}

/*
 * @implemented
 */
PIMAGE_NT_HEADERS
IMAGEAPI
ImageNtHeader(PVOID Base)
{
    /* Let RTL do it */
    return RtlImageNtHeader(Base);
}

/*
 * @implemented
 */
PVOID 
IMAGEAPI 
ImageRvaToVa(IN PIMAGE_NT_HEADERS NtHeaders,
             IN PVOID Base,
             IN ULONG Rva,
             IN OUT PIMAGE_SECTION_HEADER *LastRvaSection OPTIONAL)
{
    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);
}

/*
 * @implemented
 */
BOOL
IMAGEAPI
ImageUnload(PLOADED_IMAGE LoadedImage)
{
    /* If the image list isn't empty, remove this entry */
    if (!IsListEmpty(&LoadedImage->Links)) RemoveEntryList(&LoadedImage->Links);

    /* Unmap and unload it */
    UnMapAndLoad(LoadedImage);

    /* Free the structure */
    HeapFree(IMAGEHLP_hHeap, 0, LoadedImage);

    /* Return success */
    return TRUE;
}

/*
 * @implemented
 */
BOOL
IMAGEAPI
MapAndLoad(LPSTR ImageName, 
           LPSTR DllPath, 
           PLOADED_IMAGE LoadedImage,
           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 */
    LoadedImage->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 */
    LoadedImage->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 */
    LoadedImage->SizeOfImage = GetFileSize(hFile, NULL);

    /* Get the Nt Header */
    NtHeader = ImageNtHeader(LoadedImage->MappedAddress);

    /* Allocate memory for the name and save it */
    LoadedImage->ModuleName = HeapAlloc(IMAGEHLP_hHeap,
                                        0,
                                        strlen(FileToOpen) + 16);
    strcpy(LoadedImage->ModuleName, FileToOpen);

    /* Save the NT Header */
    LoadedImage->FileHeader = NtHeader;

    /* Save the section data */
    LoadedImage->Sections = IMAGE_FIRST_SECTION(NtHeader);
    LoadedImage->NumberOfSections = NtHeader->FileHeader.NumberOfSections;

    /* Setup other data */
    LoadedImage->SizeOfImage = NtHeader->OptionalHeader.SizeOfImage;
    LoadedImage->Characteristics = NtHeader->FileHeader.Characteristics;
    LoadedImage->LastRvaSection = LoadedImage->Sections;
    LoadedImage->fSystemImage = FALSE; /* FIXME */
    LoadedImage->fDOSImage = FALSE; /* FIXME */
    InitializeListHead(&LoadedImage->Links);

    /* Check if it was read-only */
    if (ReadOnly)
    {
        /* It was, so close our handle and write it as invalid */
        CloseHandle(hFile);
        LoadedImage->hFile = INVALID_HANDLE_VALUE;
    }
    else
    {
        /* Write our file handle */
        LoadedImage->hFile = hFile;
    }

    /* Return Success */
    return TRUE;
}

/*
 * @unimplemented
 */
BOOL
IMAGEAPI
SetImageConfigInformation(PLOADED_IMAGE LoadedImage,
                          PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigInformation)
{
    UNIMPLEMENTED;
    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
    return FALSE;
}

/*
 * @implemented
 */
BOOL
IMAGEAPI
UnMapAndLoad(PLOADED_IMAGE Image)
{
    PIMAGE_NT_HEADERS NtHeader;
    DWORD HeaderCheckSum, CheckSum;

    /* Check if the image was read-only */
    if (Image->hFile == INVALID_HANDLE_VALUE)
    {
        /* We'll only unmap the view */
        UnmapViewOfFile(Image->MappedAddress);
    }
    else
    {
        /* Calculate the checksum */
        CheckSumMappedFile(Image->MappedAddress,
                           Image->SizeOfImage,
                           &HeaderCheckSum,
                           &CheckSum);

        /* Get the NT Header */
        NtHeader = Image->FileHeader;

        /* Write the new checksum to it */
        NtHeader->OptionalHeader.CheckSum = CheckSum;

        /* Now flush and unmap the image */
        FlushViewOfFile(Image->MappedAddress, Image->SizeOfImage);
        UnmapViewOfFile(Image->MappedAddress);

        /* Check if the size changed */
        if (Image->SizeOfImage != GetFileSize(Image->hFile, NULL))
        {
            /* Update the file pointer */
            SetFilePointer(Image->hFile, Image->SizeOfImage, NULL, FILE_BEGIN);
            SetEndOfFile(Image->hFile);
        }
    }

    /* Check if the image had a valid handle, and close it */
    if (Image->hFile != INVALID_HANDLE_VALUE) CloseHandle(Image->hFile);

    /* Return success */
    return TRUE;
}

BOOL
IMAGEAPI
UnloadAllImages(VOID)
{
    PLIST_ENTRY Head, Entry;
    PLOADED_IMAGE CurrentImage;

    /* Make sure we're initialized */
    if (!DllListInitialized) return TRUE;

    /* Get the list pointers and loop */
    Head = &ImageLoadListHead;
    Entry = Head->Flink;
    while (Entry != Head)
    {
        /* Get this image */
        CurrentImage = CONTAINING_RECORD(Entry, LOADED_IMAGE, Links);

        /* Move to the next entry */
        Entry = Entry->Flink;

        /* Unload it */
        ImageUnload(CurrentImage);
    }

    /* We are not initialized anymore */
    DllListInitialized = FALSE;
    return TRUE;
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?