【发布时间】:2022-12-31 01:56:09
【问题描述】:
我想用windows的msdelta API打补丁,按照官方文档写了一个程序。但是程序总是返回错误,使用GetLastError函数返回0xd(The data is invalid.)。
C:\\Windows\\WinSxS\\amd64_microsoft-windows-win32k_31bf3856ad364e35_10.0.22621.674_none_1aec2f5c63bcf4f9\\win32k.sys 是一个 PE 文件,我使用十六进制编辑器 Hxd 检查了它的内容,以确保它是正确的 PE 文件。
C:\\Windows\\WinSxS\\amd64_microsoft-windows-win32k_31bf3856ad364e35_10.0.22621.674_none_1aec2f5c63bcf4f9\\r\\win32k.sys是补丁文件,我用hxd看他的内容发现它的前八个字节是91 8C DC 51 50 41 33 30,我知道91 8C DC 51是C:\\Windows\\WinSxS\\amd64_microsoft-windows-win32k_31bf3856ad364e35_10.0.22621.674_none_1aec2f5c63bcf4f9\\r\\win32k.sys的CRC32, 50 41 33 30意味着PA30,我猜这意味着它的文件格式。
#include <iostream>
#include <format>
#include <string>
#include <Windows.h>
#include <msdelta.h>
#pragma comment(lib, "msdelta.lib")
int main()
{
DWORD dwNumRead = 0;
HANDLE hSourceFile = CreateFileA(
"C:\\Windows\\WinSxS\\amd64_microsoft-windows-win32k_31bf3856ad364e35_10.0.22621.674_none_1aec2f5c63bcf4f9\\win32k.sys",
FILE_GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hSourceFile == INVALID_HANDLE_VALUE)
{
std::cout << std::format("Cannot open file.") << std::endl;
return 0;
}
DWORD dwSourceBuferSize = GetFileSize(hSourceFile, NULL);
LPVOID pSourceBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSourceBuferSize);
ReadFile(
hSourceFile,
pSourceBuffer,
dwSourceBuferSize,
&dwNumRead,
NULL
);
if (dwNumRead != dwSourceBuferSize)
{
std::cout << std::format("Cannot read file.") << std::endl;
return 0;
}
DELTA_INPUT Source;
Source.Editable = TRUE;
Source.lpStart = pSourceBuffer;
Source.uSize = dwSourceBuferSize;
HANDLE hDeltaFile = CreateFileA(
"C:\\Windows\\WinSxS\\amd64_microsoft-windows-win32k_31bf3856ad364e35_10.0.22621.674_none_1aec2f5c63bcf4f9\\r\\win32k.sys",
FILE_GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (hDeltaFile == INVALID_HANDLE_VALUE)
{
std::cout << std::format("Cannot open file.") << std::endl;
return 0;
}
DWORD dwDeltaBuferSize = GetFileSize(hDeltaFile, NULL);
LPVOID pDeltaBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwDeltaBuferSize);
ReadFile(
hDeltaFile,
pDeltaBuffer,
dwDeltaBuferSize,
&dwNumRead,
NULL
);
if (dwNumRead != dwDeltaBuferSize)
{
std::cout << std::format("Cannot read file.") << std::endl;
return 0;
}
DELTA_INPUT Delta;
Delta.Editable = TRUE;
Delta.lpStart = pDeltaBuffer;
Delta.uSize = dwDeltaBuferSize;
DELTA_OUTPUT Output;
BOOL bResult = ApplyDeltaB(
DELTA_FLAG_NONE,
Source,
Delta,
&Output
);
if (!bResult)
{
std::cout << std::format("{0:#x}", GetLastError()) << std::endl;
}
return 0;
}
【问题讨论】:
-
请拨打
GetLastError立即地在您确定它将返回有意义的数据之后,绝对没有干预代码。 -
尽管这个问题可能与将垃圾值传递给
ApplyDeltaB一样平凡。值得注意的是,DELTA_OUTPUT Output包含不确定的值,可能应该被零初始化。