Example #1
0
/*****************************************************
 *    ApplyPatchToFileByHandles (MSPATCHA.2)
 */
BOOL WINAPI ApplyPatchToFileByHandles(HANDLE patch_file, HANDLE old_file, HANDLE new_file, ULONG apply_flags)
{
    SAFE_READ Patch, OldFile;
    DWORD dwStatus;
    PATCH_HEADER Header;

    Patch.Root = Patch.Ptr = MapFile(patch_file, &Patch.Size);
    if (!Patch.Root)
    {
        SetLastError(ERROR_PATCH_CORRUPT);
        return FALSE;
    }

    /* Let's decode the header */
    dwStatus = ParseHeader(&Patch, &Header);
    if (dwStatus != STATUS_SUCCESS)
    {
        UnmapViewOfFile(Patch.Root);
        SetLastError(dwStatus);
        return FALSE;
    }

    OldFile.Root = OldFile.Ptr = MapFile(old_file, &OldFile.Size);
    if (OldFile.Root)
    {
        DWORD dwCrc;

        /* Verify the input file */
        dwCrc = RtlComputeCrc32(0, OldFile.Root, OldFile.Size);
        if (OldFile.Size == Header.OldSize && dwCrc == Header.OldCrc)
        {
            if (apply_flags & APPLY_OPTION_TEST_ONLY)
                dwStatus = STATUS_SUCCESS;
            else
                dwStatus = CreateNewFileFromPatch(&Header, &Patch, new_file);
        }
        else
        {
            dwStatus = ERROR_PATCH_WRONG_FILE;
        }
        UnmapViewOfFile(OldFile.Root);
    }
    else
    {
        dwStatus = GetLastError();
        if (dwStatus == STATUS_SUCCESS)
            dwStatus = ERROR_PATCH_NOT_AVAILABLE;
    }

    UnmapViewOfFile(Patch.Root);
    SetLastError(dwStatus);
    return dwStatus == STATUS_SUCCESS;
}
Example #2
0
/**
 * @name ParseHeader
 * Parse a Patch file header
 * @note The current implementation is far from complete!
 *
 * @param Patch
 * Buffer pointing to the raw patch data
 *
 * @param Header
 * The result of the parsed header
 *
 * @return STATUS_SUCCESS on success, an error code otherwise
 */
DWORD ParseHeader(SAFE_READ* Patch, PATCH_HEADER* Header)
{
    DWORD Crc, Unknown;
    int Delta;

    ZeroMemory(Header, sizeof(*Header));

    /* Validate the patch */
    Crc = RtlComputeCrc32(0, Patch->Root, Patch->Size);
    if (Crc != ~0)
        return ERROR_PATCH_CORRUPT;

    if (ReadDWord(Patch) != '91AP')
        return ERROR_PATCH_DECODE_FAILURE;

    /* Read the flags, warn about an unknown combination */
    Header->Flags = ReadDWord(Patch);
    if (Header->Flags ^ UNKNOWN_FLAGS_COMBINATION)
        ERR("Unknown flags: 0x%x, patch will most likely fail\n", Header->Flags ^ UNKNOWN_FLAGS_COMBINATION);

    /* 0x5bb3284e, 0x5bb33562, 0x5bb357b1 */
    Unknown = ReadDWord(Patch);
    TRACE("Unknown: 0x%x\n", Unknown);

    Header->OutputSize = DecodeDWord(Patch);
    Header->OutputCrc = ReadDWord(Patch);

    Unknown = ReadByte(Patch);
    if (Unknown != 1)
        ERR("Field after CRC is not 1 but %u\n", Unknown);

    Delta = DecodeInt(Patch);
    Header->OldSize = Header->OutputSize + Delta;
    Header->OldCrc = ReadDWord(Patch);

    Unknown = ReadUShort(Patch);
    if (Unknown != 0)
        ERR("Field1 after OldCrc is not 0 but %u\n", Unknown);

    Unknown = DecodeDWord(Patch);
    if (Unknown != 0)
        ERR("Field2 after OldCrc is not 0 but %u\n", Unknown);

    Header->DataSize = DecodeDWord(Patch);
                            /* Remaining data, minus the CRC appended */
    if (Header->DataSize != (Patch->Size - (Patch->Ptr - Patch->Root) - sizeof(DWORD)))
    {
        ERR("Unable to read header, check previous logging!\n");
        return ERROR_PATCH_DECODE_FAILURE;
    }
    return STATUS_SUCCESS;
}
Example #3
0
/*****************************************************
 *    GetFilePatchSignatureA (MSPATCHA.7)
 */
BOOL WINAPI GetFilePatchSignatureByHandle(HANDLE hFile, ULONG flags, PVOID data, ULONG ignore_range_count,
                                   PPATCH_IGNORE_RANGE ignore_range, ULONG retain_range_count,
                                   PPATCH_RETAIN_RANGE retain_range, ULONG bufsize, PVOID buffer)
{
    BOOL ret = FALSE;
    DWORD dwSize, ulCrc;
    PBYTE pData;

    if (flags)
        FIXME("Unhandled flags 0x%x\n", flags);
    if (ignore_range_count)
        FIXME("Unhandled ignore_range_count %u\n", ignore_range_count);
    if (retain_range_count)
        FIXME("Unhandled ignore_range_count %u\n", retain_range_count);

    if ((pData = MapFile(hFile, &dwSize)))
    {
        if (dwSize >= 2 && *(PWORD)pData == IMAGE_DOS_SIGNATURE)
        {
            FIXME("Potentially unimplemented case, normalized signature\n");
        }

        ulCrc = RtlComputeCrc32(0, pData, dwSize);
        if (bufsize >= SIGNATURE_MIN_SIZE)
        {
            char *pBuffer = buffer;
            pBuffer[8] = '\0';
            for (dwSize = 0; dwSize < 8; ++dwSize)
            {
                pBuffer[7 - dwSize] = szHexString[ulCrc & 0xf];
                ulCrc >>= 4;
            }
            ret = TRUE;
        }
        UnmapViewOfFile(pData);

        if (bufsize < SIGNATURE_MIN_SIZE)
            SetLastError(ERROR_INSUFFICIENT_BUFFER);
    }
Example #4
0
PVOID
NTAPI
INIT_FUNCTION
FindBitmapResource(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
                   IN ULONG ResourceId)
{
    UNICODE_STRING UpString = RTL_CONSTANT_STRING(L"ntoskrnl.exe");
    UNICODE_STRING MpString = RTL_CONSTANT_STRING(L"ntkrnlmp.exe");
    PLIST_ENTRY NextEntry, ListHead;
    PLDR_DATA_TABLE_ENTRY LdrEntry;
    PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry;
    LDR_RESOURCE_INFO ResourceInfo;
    NTSTATUS Status;
    PVOID Data = NULL;

    /* Loop the driver list */
    ListHead = &LoaderBlock->LoadOrderListHead;
    NextEntry = ListHead->Flink;
    while (NextEntry != ListHead)
    {
        /* Get the entry */
        LdrEntry = CONTAINING_RECORD(NextEntry,
                                     LDR_DATA_TABLE_ENTRY,
                                     InLoadOrderLinks);

        /* Check for a match */
        if ((RtlEqualUnicodeString(&LdrEntry->BaseDllName, &UpString, TRUE)) ||
            (RtlEqualUnicodeString(&LdrEntry->BaseDllName, &MpString, TRUE)))
        {
            /* Break out */
            break;
        }
    }

    /* Check if we found it */
    if (NextEntry != ListHead)
    {
        /* Try to find the resource */
        ResourceInfo.Type = 2; //RT_BITMAP;
        ResourceInfo.Name = ResourceId;
        ResourceInfo.Language = 0;
        Status = LdrFindResource_U(LdrEntry->DllBase,
                                   &ResourceInfo,
                                   RESOURCE_DATA_LEVEL,
                                   &ResourceDataEntry);
        if (NT_SUCCESS(Status))
        {
            /* Access the resource */
            ULONG Size = 0;
            Status = LdrAccessResource(LdrEntry->DllBase,
                                       ResourceDataEntry,
                                       &Data,
                                       &Size);
            if ((Data) && (ResourceId < 3))
            {
                KiBugCheckData[4] ^= RtlComputeCrc32(0, Data, Size);
            }
            if (!NT_SUCCESS(Status)) Data = NULL;
        }
    }

    /* Return the pointer */
    return Data;
}