mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[misc] add an address resolver for internal DLL function calls
* Not sure if we'll use this to hook into FfuCaptureImage()/FfuApplyImage()/FfuMountImage() directly. But at least, if we ever need it, it's there...
This commit is contained in:
parent
ef345bf106
commit
0363bfe503
8 changed files with 160 additions and 20 deletions
|
@ -606,6 +606,9 @@ t MSG_341 "a Windows Recovery Screen (BSOD) with '%s'"
|
||||||
t MSG_342 "Compressed VHDX Image"
|
t MSG_342 "Compressed VHDX Image"
|
||||||
t MSG_343 "Uncompressed VHD Image"
|
t MSG_343 "Uncompressed VHD Image"
|
||||||
t MSG_344 "Full Flash Update Image"
|
t MSG_344 "Full Flash Update Image"
|
||||||
|
t MSG_345 "Some additional data must be downloaded from Microsoft to use this functionality:\n"
|
||||||
|
"- Select 'Yes' to connect to the Internet and download it\n"
|
||||||
|
"- Select 'No' to cancel the operation"
|
||||||
# The following messages are for the Windows Store listing only and are not used by the application
|
# The following messages are for the Windows Store listing only and are not used by the application
|
||||||
t MSG_900 "Rufus is a utility that helps format and create bootable USB flash drives, such as USB keys/pendrives, memory sticks, etc."
|
t MSG_900 "Rufus is a utility that helps format and create bootable USB flash drives, such as USB keys/pendrives, memory sticks, etc."
|
||||||
t MSG_901 "Official site: %s"
|
t MSG_901 "Official site: %s"
|
||||||
|
|
10
src/drive.c
10
src/drive.c
|
@ -1541,7 +1541,7 @@ static BOOL StoreEspInfo(GUID* guid)
|
||||||
static_sprintf(key_name[0], "ToggleEsp%02u", j);
|
static_sprintf(key_name[0], "ToggleEsp%02u", j);
|
||||||
str = ReadSettingStr(key_name[0]);
|
str = ReadSettingStr(key_name[0]);
|
||||||
if ((str == NULL) || (str[0] == 0))
|
if ((str == NULL) || (str[0] == 0))
|
||||||
return WriteSettingStr(key_name[0], GuidToString(guid));
|
return WriteSettingStr(key_name[0], GuidToString(guid, TRUE));
|
||||||
}
|
}
|
||||||
// All slots are used => Move every key down and add to last slot
|
// All slots are used => Move every key down and add to last slot
|
||||||
// NB: No, we don't care that the slot we remove may not be the oldest.
|
// NB: No, we don't care that the slot we remove may not be the oldest.
|
||||||
|
@ -1550,7 +1550,7 @@ static BOOL StoreEspInfo(GUID* guid)
|
||||||
static_sprintf(key_name[1], "ToggleEsp%02u", j + 1);
|
static_sprintf(key_name[1], "ToggleEsp%02u", j + 1);
|
||||||
WriteSettingStr(key_name[0], ReadSettingStr(key_name[1]));
|
WriteSettingStr(key_name[0], ReadSettingStr(key_name[1]));
|
||||||
}
|
}
|
||||||
return WriteSettingStr(key_name[1], GuidToString(guid));
|
return WriteSettingStr(key_name[1], GuidToString(guid, TRUE));
|
||||||
}
|
}
|
||||||
|
|
||||||
static GUID* GetEspGuid(uint8_t index)
|
static GUID* GetEspGuid(uint8_t index)
|
||||||
|
@ -1990,7 +1990,7 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys
|
||||||
case PARTITION_STYLE_GPT:
|
case PARTITION_STYLE_GPT:
|
||||||
SelectedDrive.PartitionStyle = PARTITION_STYLE_GPT;
|
SelectedDrive.PartitionStyle = PARTITION_STYLE_GPT;
|
||||||
suprintf("Partition type: GPT, NB Partitions: %d", DriveLayout->PartitionCount);
|
suprintf("Partition type: GPT, NB Partitions: %d", DriveLayout->PartitionCount);
|
||||||
suprintf("Disk GUID: %s", GuidToString(&DriveLayout->Gpt.DiskId));
|
suprintf("Disk GUID: %s", GuidToString(&DriveLayout->Gpt.DiskId, TRUE));
|
||||||
suprintf("Max parts: %d, Start Offset: %" PRIi64 ", Usable = %" PRIi64 " bytes",
|
suprintf("Max parts: %d, Start Offset: %" PRIi64 ", Usable = %" PRIi64 " bytes",
|
||||||
DriveLayout->Gpt.MaxPartitionCount, DriveLayout->Gpt.StartingUsableOffset.QuadPart, DriveLayout->Gpt.UsableLength.QuadPart);
|
DriveLayout->Gpt.MaxPartitionCount, DriveLayout->Gpt.StartingUsableOffset.QuadPart, DriveLayout->Gpt.UsableLength.QuadPart);
|
||||||
for (i = 0; i < DriveLayout->PartitionCount; i++) {
|
for (i = 0; i < DriveLayout->PartitionCount; i++) {
|
||||||
|
@ -2006,7 +2006,7 @@ BOOL GetDrivePartitionData(DWORD DriveIndex, char* FileSystemName, DWORD FileSys
|
||||||
suprintf(" Name: '%S'", DriveLayout->PartitionEntry[i].Gpt.Name);
|
suprintf(" Name: '%S'", DriveLayout->PartitionEntry[i].Gpt.Name);
|
||||||
suprintf(" Detected File System: %s", GetFsName(hPhysical, DriveLayout->PartitionEntry[i].StartingOffset));
|
suprintf(" Detected File System: %s", GetFsName(hPhysical, DriveLayout->PartitionEntry[i].StartingOffset));
|
||||||
suprintf(" ID: %s\r\n Size: %s (%" PRIi64 " bytes)\r\n Start Sector: %" PRIi64 ", Attributes: 0x%016" PRIX64,
|
suprintf(" ID: %s\r\n Size: %s (%" PRIi64 " bytes)\r\n Start Sector: %" PRIi64 ", Attributes: 0x%016" PRIX64,
|
||||||
GuidToString(&DriveLayout->PartitionEntry[i].Gpt.PartitionId),
|
GuidToString(&DriveLayout->PartitionEntry[i].Gpt.PartitionId, TRUE),
|
||||||
SizeToHumanReadable(DriveLayout->PartitionEntry[i].PartitionLength.QuadPart, TRUE, FALSE),
|
SizeToHumanReadable(DriveLayout->PartitionEntry[i].PartitionLength.QuadPart, TRUE, FALSE),
|
||||||
DriveLayout->PartitionEntry[i].PartitionLength,
|
DriveLayout->PartitionEntry[i].PartitionLength,
|
||||||
DriveLayout->PartitionEntry[i].StartingOffset.QuadPart / SelectedDrive.SectorSize,
|
DriveLayout->PartitionEntry[i].StartingOffset.QuadPart / SelectedDrive.SectorSize,
|
||||||
|
@ -2646,5 +2646,5 @@ const char* GetGPTPartitionType(const GUID* guid)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; (i < ARRAYSIZE(gpt_type)) && !CompareGUID(guid, gpt_type[i].guid); i++);
|
for (i = 0; (i < ARRAYSIZE(gpt_type)) && !CompareGUID(guid, gpt_type[i].guid); i++);
|
||||||
return (i < ARRAYSIZE(gpt_type)) ? gpt_type[i].name : GuidToString(guid);
|
return (i < ARRAYSIZE(gpt_type)) ? gpt_type[i].name : GuidToString(guid, TRUE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -915,7 +915,7 @@ static DWORD WINAPI DownloadISOThread(LPVOID param)
|
||||||
// thinking that Rufus is doing something malicious...
|
// thinking that Rufus is doing something malicious...
|
||||||
IGNORE_RETVAL(CoCreateGuid(&guid));
|
IGNORE_RETVAL(CoCreateGuid(&guid));
|
||||||
// coverity[fixed_size_dest]
|
// coverity[fixed_size_dest]
|
||||||
strcpy(&pipe[9], GuidToString(&guid));
|
strcpy(&pipe[9], GuidToString(&guid, TRUE));
|
||||||
static_sprintf(icon_path, "%s%s.ico", temp_dir, APPLICATION_NAME);
|
static_sprintf(icon_path, "%s%s.ico", temp_dir, APPLICATION_NAME);
|
||||||
ExtractAppIcon(icon_path, TRUE);
|
ExtractAppIcon(icon_path, TRUE);
|
||||||
|
|
||||||
|
@ -973,7 +973,7 @@ static DWORD WINAPI DownloadISOThread(LPVOID param)
|
||||||
|
|
||||||
assert((fido_script != NULL) && (fido_len != 0));
|
assert((fido_script != NULL) && (fido_len != 0));
|
||||||
|
|
||||||
static_sprintf(script_path, "%s%s.ps1", temp_dir, GuidToString(&guid));
|
static_sprintf(script_path, "%s%s.ps1", temp_dir, GuidToString(&guid, TRUE));
|
||||||
hFile = CreateFileU(script_path, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_READONLY, NULL);
|
hFile = CreateFileU(script_path, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_READONLY, NULL);
|
||||||
if (hFile == INVALID_HANDLE_VALUE) {
|
if (hFile == INVALID_HANDLE_VALUE) {
|
||||||
uprintf("Unable to create download script '%s': %s", script_path, WindowsErrorString());
|
uprintf("Unable to create download script '%s': %s", script_path, WindowsErrorString());
|
||||||
|
|
|
@ -860,7 +860,7 @@ BOOL ParseSKUSiPolicy(void)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (!CompareGUID(&Header->PolicyTypeGUID, &SKU_CODE_INTEGRITY_POLICY)) {
|
if (!CompareGUID(&Header->PolicyTypeGUID, &SKU_CODE_INTEGRITY_POLICY)) {
|
||||||
uprintf("ParseSKUSiPolicy: Unexpected Policy Type GUID %s", GuidToString(&Header->PolicyTypeGUID));
|
uprintf("ParseSKUSiPolicy: Unexpected Policy Type GUID %s", GuidToString(&Header->PolicyTypeGUID, TRUE));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
15
src/rufus.c
15
src/rufus.c
|
@ -1861,7 +1861,7 @@ static DWORD WINAPI BootCheckThread(LPVOID param)
|
||||||
IGNORE_RETVAL(_chdirU(app_data_dir));
|
IGNORE_RETVAL(_chdirU(app_data_dir));
|
||||||
IGNORE_RETVAL(_mkdir(FILES_DIR));
|
IGNORE_RETVAL(_mkdir(FILES_DIR));
|
||||||
IGNORE_RETVAL(_chdir(FILES_DIR));
|
IGNORE_RETVAL(_chdir(FILES_DIR));
|
||||||
if (DownloadToFileOrBufferEx(DISKCOPY_URL, tmp, DISKCOPY_USER_AGENT, NULL, hMainDialog, FALSE) != DISKCOPY_SIZE) {
|
if (DownloadToFileOrBufferEx(DISKCOPY_URL, tmp, SYMBOL_SERVER_USER_AGENT, NULL, hMainDialog, FALSE) != DISKCOPY_SIZE) {
|
||||||
ret = BOOTCHECK_DOWNLOAD_ERROR;
|
ret = BOOTCHECK_DOWNLOAD_ERROR;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
@ -3787,7 +3787,18 @@ extern int TestHashes(void);
|
||||||
// Ctrl-T => Alternate Test mode that doesn't require a full rebuild
|
// Ctrl-T => Alternate Test mode that doesn't require a full rebuild
|
||||||
if ((ctrl_without_focus || ((GetKeyState(VK_CONTROL) & 0x8000) && (msg.message == WM_KEYDOWN)))
|
if ((ctrl_without_focus || ((GetKeyState(VK_CONTROL) & 0x8000) && (msg.message == WM_KEYDOWN)))
|
||||||
&& (msg.wParam == 'T')) {
|
&& (msg.wParam == 'T')) {
|
||||||
TestHashes();
|
// TestHashes();
|
||||||
|
dll_resolver_t resolver = { 0 };
|
||||||
|
resolver.path = "C:\\Windows\\System32\\Dism\\FfuProvider.dll";
|
||||||
|
resolver.count = 3;
|
||||||
|
resolver.name = calloc(resolver.count, sizeof(char*));
|
||||||
|
resolver.address = calloc(resolver.count, sizeof(uint32_t));
|
||||||
|
resolver.name[0] = "FfuCaptureImage";
|
||||||
|
resolver.name[1] = "FfuApplyImage";
|
||||||
|
resolver.name[2] = "FfuMountImage";
|
||||||
|
uprintf("Got %d resolved addresses", ResolveDllAddress(&resolver));
|
||||||
|
free(resolver.name);
|
||||||
|
free(resolver.address);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
13
src/rufus.h
13
src/rufus.h
|
@ -121,10 +121,10 @@
|
||||||
#define SEVENZIP_URL "https://7-zip.org/"
|
#define SEVENZIP_URL "https://7-zip.org/"
|
||||||
// Generated by following https://randomascii.wordpress.com/2013/03/09/symbols-the-microsoft-way/
|
// Generated by following https://randomascii.wordpress.com/2013/03/09/symbols-the-microsoft-way/
|
||||||
#define DISKCOPY_URL "https://msdl.microsoft.com/download/symbols/diskcopy.dll/54505118173000/diskcopy.dll"
|
#define DISKCOPY_URL "https://msdl.microsoft.com/download/symbols/diskcopy.dll/54505118173000/diskcopy.dll"
|
||||||
#define DISKCOPY_USER_AGENT "Microsoft-Symbol-Server/10.0.22621.755"
|
|
||||||
#define DISKCOPY_SIZE 0x16ee00
|
#define DISKCOPY_SIZE 0x16ee00
|
||||||
#define DISKCOPY_IMAGE_OFFSET 0x66d8
|
#define DISKCOPY_IMAGE_OFFSET 0x66d8
|
||||||
#define DISKCOPY_IMAGE_SIZE 0x168000
|
#define DISKCOPY_IMAGE_SIZE 0x168000
|
||||||
|
#define SYMBOL_SERVER_USER_AGENT "Microsoft-Symbol-Server/10.0.22621.755"
|
||||||
#define DEFAULT_ESP_MOUNT_POINT "S:\\"
|
#define DEFAULT_ESP_MOUNT_POINT "S:\\"
|
||||||
#define IS_POWER_OF_2(x) ((x != 0) && (((x) & ((x) - 1)) == 0))
|
#define IS_POWER_OF_2(x) ((x != 0) && (((x) & ((x) - 1)) == 0))
|
||||||
#define IGNORE_RETVAL(expr) do { (void)(expr); } while(0)
|
#define IGNORE_RETVAL(expr) do { (void)(expr); } while(0)
|
||||||
|
@ -472,6 +472,14 @@ typedef struct ext_t {
|
||||||
const char** description;
|
const char** description;
|
||||||
} ext_t;
|
} ext_t;
|
||||||
|
|
||||||
|
/* DLL address resolver */
|
||||||
|
typedef struct {
|
||||||
|
char* path;
|
||||||
|
uint32_t count;
|
||||||
|
char** name;
|
||||||
|
uint32_t* address; // 32-bit will do, as we're not dealing with >4GB DLLs...
|
||||||
|
} dll_resolver_t;
|
||||||
|
|
||||||
#ifndef __VA_GROUP__
|
#ifndef __VA_GROUP__
|
||||||
#define __VA_GROUP__(...) __VA_ARGS__
|
#define __VA_GROUP__(...) __VA_ARGS__
|
||||||
#endif
|
#endif
|
||||||
|
@ -613,7 +621,7 @@ extern void _UpdateProgressWithInfo(int op, int msg, uint64_t processed, uint64_
|
||||||
#define UpdateProgressWithInfoForce(op, msg, processed, total) _UpdateProgressWithInfo(op, msg, processed, total, TRUE)
|
#define UpdateProgressWithInfoForce(op, msg, processed, total) _UpdateProgressWithInfo(op, msg, processed, total, TRUE)
|
||||||
#define UpdateProgressWithInfoInit(hProgressDialog, bNoAltMode) UpdateProgressWithInfo(OP_INIT, (int)bNoAltMode, (uint64_t)(uintptr_t)hProgressDialog, 0);
|
#define UpdateProgressWithInfoInit(hProgressDialog, bNoAltMode) UpdateProgressWithInfo(OP_INIT, (int)bNoAltMode, (uint64_t)(uintptr_t)hProgressDialog, 0);
|
||||||
extern const char* StrError(DWORD error_code, BOOL use_default_locale);
|
extern const char* StrError(DWORD error_code, BOOL use_default_locale);
|
||||||
extern char* GuidToString(const GUID* guid);
|
extern char* GuidToString(const GUID* guid, BOOL bDecorated);
|
||||||
extern GUID* StringToGuid(const char* str);
|
extern GUID* StringToGuid(const char* str);
|
||||||
extern char* SizeToHumanReadable(uint64_t size, BOOL copy_to_log, BOOL fake_units);
|
extern char* SizeToHumanReadable(uint64_t size, BOOL copy_to_log, BOOL fake_units);
|
||||||
extern char* TimestampToHumanReadable(uint64_t ts);
|
extern char* TimestampToHumanReadable(uint64_t ts);
|
||||||
|
@ -723,6 +731,7 @@ extern HICON CreateMirroredIcon(HICON hiconOrg);
|
||||||
extern HANDLE CreatePreallocatedFile(const char* lpFileName, DWORD dwDesiredAccess,
|
extern HANDLE CreatePreallocatedFile(const char* lpFileName, DWORD dwDesiredAccess,
|
||||||
DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
|
DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
|
||||||
DWORD dwFlagsAndAttributes, LONGLONG fileSize);
|
DWORD dwFlagsAndAttributes, LONGLONG fileSize);
|
||||||
|
extern uint32_t ResolveDllAddress(dll_resolver_t* resolver);
|
||||||
#define GetTextWidth(hDlg, id) GetTextSize(GetDlgItem(hDlg, id), NULL).cx
|
#define GetTextWidth(hDlg, id) GetTextSize(GetDlgItem(hDlg, id), NULL).cx
|
||||||
|
|
||||||
DWORD WINAPI HashThread(void* param);
|
DWORD WINAPI HashThread(void* param);
|
||||||
|
|
10
src/rufus.rc
10
src/rufus.rc
|
@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||||
IDD_DIALOG DIALOGEX 12, 12, 232, 326
|
IDD_DIALOG DIALOGEX 12, 12, 232, 326
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
EXSTYLE WS_EX_ACCEPTFILES
|
EXSTYLE WS_EX_ACCEPTFILES
|
||||||
CAPTION "Rufus 4.2.2065"
|
CAPTION "Rufus 4.2.2066"
|
||||||
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
|
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
|
||||||
BEGIN
|
BEGIN
|
||||||
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
|
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
|
||||||
|
@ -392,8 +392,8 @@ END
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 4,2,2065,0
|
FILEVERSION 4,2,2066,0
|
||||||
PRODUCTVERSION 4,2,2065,0
|
PRODUCTVERSION 4,2,2066,0
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -411,13 +411,13 @@ BEGIN
|
||||||
VALUE "Comments", "https://rufus.ie"
|
VALUE "Comments", "https://rufus.ie"
|
||||||
VALUE "CompanyName", "Akeo Consulting"
|
VALUE "CompanyName", "Akeo Consulting"
|
||||||
VALUE "FileDescription", "Rufus"
|
VALUE "FileDescription", "Rufus"
|
||||||
VALUE "FileVersion", "4.2.2065"
|
VALUE "FileVersion", "4.2.2066"
|
||||||
VALUE "InternalName", "Rufus"
|
VALUE "InternalName", "Rufus"
|
||||||
VALUE "LegalCopyright", "© 2011-2023 Pete Batard (GPL v3)"
|
VALUE "LegalCopyright", "© 2011-2023 Pete Batard (GPL v3)"
|
||||||
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
|
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
|
||||||
VALUE "OriginalFilename", "rufus-4.2.exe"
|
VALUE "OriginalFilename", "rufus-4.2.exe"
|
||||||
VALUE "ProductName", "Rufus"
|
VALUE "ProductName", "Rufus"
|
||||||
VALUE "ProductVersion", "4.2.2065"
|
VALUE "ProductVersion", "4.2.2066"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
121
src/stdio.c
121
src/stdio.c
|
@ -28,20 +28,25 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <winternl.h>
|
#include <winternl.h>
|
||||||
|
#include <dbghelp.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "rufus.h"
|
#include "rufus.h"
|
||||||
|
#include "missing.h"
|
||||||
|
#include "settings.h"
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "msapi_utf8.h"
|
#include "msapi_utf8.h"
|
||||||
#include "localization.h"
|
#include "localization.h"
|
||||||
|
|
||||||
#define FACILITY_WIM 322
|
#define FACILITY_WIM 322
|
||||||
|
#define DEFAULT_BASE_ADDRESS 0x100000000ULL
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Globals
|
* Globals
|
||||||
*/
|
*/
|
||||||
|
const HANDLE hRufus = (HANDLE)0x0000005275667573ULL; // "\0\0\0Rufus"
|
||||||
HWND hStatus;
|
HWND hStatus;
|
||||||
size_t ubuffer_pos = 0;
|
size_t ubuffer_pos = 0;
|
||||||
char ubuffer[UBUFFER_SIZE]; // Buffer for ubpushf() messages we don't log right away
|
char ubuffer[UBUFFER_SIZE]; // Buffer for ubpushf() messages we don't log right away
|
||||||
|
@ -683,12 +688,13 @@ const char *WindowsErrorString(void)
|
||||||
return err_string;
|
return err_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* GuidToString(const GUID* guid)
|
char* GuidToString(const GUID* guid, BOOL bDecorated)
|
||||||
{
|
{
|
||||||
static char guid_string[MAX_GUID_STRING_LENGTH];
|
static char guid_string[MAX_GUID_STRING_LENGTH];
|
||||||
|
|
||||||
if (guid == NULL) return NULL;
|
if (guid == NULL) return NULL;
|
||||||
sprintf(guid_string, "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}",
|
sprintf(guid_string, bDecorated ? "{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}" :
|
||||||
|
"%08X%04X%04X%02X%02X%02X%02X%02X%02X%02X%02X",
|
||||||
(uint32_t)guid->Data1, guid->Data2, guid->Data3,
|
(uint32_t)guid->Data1, guid->Data2, guid->Data3,
|
||||||
guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
|
guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
|
||||||
guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
|
guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
|
||||||
|
@ -1143,3 +1149,114 @@ HANDLE CreatePreallocatedFile(const char* lpFileName, DWORD dwDesiredAccess,
|
||||||
|
|
||||||
return fileHandle;
|
return fileHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The following calls are used to resolve the addresses of DLL function calls
|
||||||
|
// that are not publicly exposed by Microsoft. This is accomplished by downloading
|
||||||
|
// the relevant .pdb and looking up the relevant address there. Once an address is
|
||||||
|
// found, it is stored in the Rufus settings so that it can be reused.
|
||||||
|
|
||||||
|
PF_TYPE_DECL(WINAPI, BOOL, SymInitialize, (HANDLE, PCSTR, BOOL));
|
||||||
|
PF_TYPE_DECL(WINAPI, DWORD64, SymLoadModuleEx, (HANDLE, HANDLE, PCSTR, PCSTR, DWORD64, DWORD, PMODLOAD_DATA, DWORD));
|
||||||
|
PF_TYPE_DECL(WINAPI, BOOL, SymGetModuleInfo64, (HANDLE, DWORD64, PIMAGEHLP_MODULE64));
|
||||||
|
PF_TYPE_DECL(WINAPI, BOOL, SymUnloadModule64, (HANDLE, DWORD64));
|
||||||
|
PF_TYPE_DECL(WINAPI, BOOL, SymEnumSymbols, (HANDLE, ULONG64, PCSTR, PSYM_ENUMERATESYMBOLS_CALLBACK, PVOID));
|
||||||
|
PF_TYPE_DECL(WINAPI, BOOL, SymCleanup, (HANDLE));
|
||||||
|
|
||||||
|
BOOL CALLBACK EnumSymProc(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID UserContext)
|
||||||
|
{
|
||||||
|
dll_resolver_t* resolver = (dll_resolver_t*)UserContext;
|
||||||
|
uint32_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < resolver->count; i++) {
|
||||||
|
if (safe_strcmp(pSymInfo->Name, resolver->name[i]) == 0) {
|
||||||
|
resolver->address[i] = (uint32_t)pSymInfo->Address;
|
||||||
|
#if defined(_DEBUG)
|
||||||
|
uprintf("%08x: %s", resolver->address[i], resolver->name[i]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t ResolveDllAddress(dll_resolver_t* resolver)
|
||||||
|
{
|
||||||
|
uint32_t r = 0;
|
||||||
|
uint32_t i;
|
||||||
|
char url[MAX_PATH], saved_id[MAX_PATH], path[MAX_PATH];
|
||||||
|
DWORD64 base_address;
|
||||||
|
IMAGEHLP_MODULE64 info = { sizeof(IMAGEHLP_MODULE64) };
|
||||||
|
|
||||||
|
PF_INIT(SymInitialize, DbgHelp);
|
||||||
|
PF_INIT(SymLoadModuleEx, DbgHelp);
|
||||||
|
PF_INIT(SymGetModuleInfo64, DbgHelp);
|
||||||
|
PF_INIT(SymUnloadModule64, DbgHelp);
|
||||||
|
PF_INIT(SymEnumSymbols, DbgHelp);
|
||||||
|
PF_INIT(SymCleanup, DbgHelp);
|
||||||
|
|
||||||
|
if (pfSymInitialize == NULL || pfSymLoadModuleEx == NULL || pfSymGetModuleInfo64 == NULL ||
|
||||||
|
pfSymUnloadModule64 == NULL || pfSymEnumSymbols == NULL || pfSymCleanup == NULL ||
|
||||||
|
resolver->count == 0 || resolver->path == NULL || resolver->name == NULL || resolver->address == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!pfSymInitialize(hRufus, NULL, FALSE)) {
|
||||||
|
uprintf("Could not initialize DLL symbol handler");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the PDB unique address from the DLL
|
||||||
|
base_address = pfSymLoadModuleEx(hRufus, NULL, resolver->path, NULL, DEFAULT_BASE_ADDRESS, 0, NULL, 0);
|
||||||
|
if (base_address == 0ULL || !pfSymGetModuleInfo64(hRufus, base_address, &info)) {
|
||||||
|
uprintf("Could not obtain DLL symbol info");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
assert(base_address == DEFAULT_BASE_ADDRESS);
|
||||||
|
pfSymUnloadModule64(hRufus, base_address);
|
||||||
|
|
||||||
|
// Check settings to see if we have existing data for these DLL calls.
|
||||||
|
for (i = 0; i < resolver->count; i++) {
|
||||||
|
static_sprintf(saved_id, "%s@%s%x:%s", _filenameU(resolver->path),
|
||||||
|
GuidToString(&info.PdbSig70, FALSE), (int)info.PdbAge, resolver->name[i]);
|
||||||
|
resolver->address[i] = ReadSetting32(saved_id);
|
||||||
|
if (resolver->address[i] == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == resolver->count) {
|
||||||
|
// No need to download the PDB
|
||||||
|
r = resolver->count;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Download the PDB from Microsoft's symbol servers
|
||||||
|
if (MessageBoxExU(hMainDialog, lmprintf(MSG_345), lmprintf(MSG_115),
|
||||||
|
MB_YESNO | MB_ICONWARNING | MB_IS_RTL, selected_langid) != IDYES)
|
||||||
|
goto out;
|
||||||
|
static_sprintf(path, "%s\\%s.pdb", temp_dir, info.ModuleName);
|
||||||
|
static_sprintf(url, "http://msdl.microsoft.com/download/symbols/%s.pdb/%s%x/%s.pdb",
|
||||||
|
info.ModuleName, GuidToString(&info.PdbSig70, FALSE), (int)info.PdbAge, info.ModuleName);
|
||||||
|
if (DownloadToFileOrBufferEx(url, path, SYMBOL_SERVER_USER_AGENT, NULL, hMainDialog, FALSE) < 200 * KB)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
// NB: SymLoadModuleEx() does not load a PDB unless the file has an explicit '.pdb' extension
|
||||||
|
base_address = pfSymLoadModuleEx(hRufus, NULL, path, NULL, DEFAULT_BASE_ADDRESS, 0, NULL, 0);
|
||||||
|
assert(base_address == DEFAULT_BASE_ADDRESS);
|
||||||
|
pfSymEnumSymbols(hRufus, base_address, "*!*", EnumSymProc, resolver);
|
||||||
|
DeleteFileU(path);
|
||||||
|
|
||||||
|
// Store the addresses
|
||||||
|
r = 0;
|
||||||
|
for (i = 0; i < resolver->count; i++) {
|
||||||
|
static_sprintf(saved_id, "%s@%s%x:%s", _filenameU(resolver->path),
|
||||||
|
GuidToString(&info.PdbSig70, FALSE), (int)info.PdbAge, resolver->name[i]);
|
||||||
|
if (resolver->address[i] != 0) {
|
||||||
|
WriteSetting32(saved_id, resolver->address[i]);
|
||||||
|
r++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
pfSymUnloadModule64(hRufus, base_address);
|
||||||
|
pfSymCleanup(hRufus);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue