From: ajkhoury aidankhoury@gmail.com
--- dlls/mspatcha/Makefile.in | 3 +- dlls/mspatcha/pa19.c | 134 +++++++++++++++++++++++++++++++- dlls/mspatcha/pecoff.c | 155 -------------------------------------- dlls/mspatcha/pecoff.h | 44 ----------- 4 files changed, 134 insertions(+), 202 deletions(-) delete mode 100644 dlls/mspatcha/pecoff.c delete mode 100644 dlls/mspatcha/pecoff.h
diff --git a/dlls/mspatcha/Makefile.in b/dlls/mspatcha/Makefile.in index 081534f6b95..0e8663d2a2d 100644 --- a/dlls/mspatcha/Makefile.in +++ b/dlls/mspatcha/Makefile.in @@ -7,7 +7,6 @@ C_SRCS = \ lzxd_dec.c \ md5.c \ mspatcha_main.c \ - pa19.c \ - pecoff.c + pa19.c
RC_SRCS = version.rc diff --git a/dlls/mspatcha/pa19.c b/dlls/mspatcha/pa19.c index f4df066719d..233fa50b417 100644 --- a/dlls/mspatcha/pa19.c +++ b/dlls/mspatcha/pa19.c @@ -33,7 +33,6 @@ #include "patchapi.h"
#include "pa19.h" -#include "pecoff.h" #include "lzxd_dec.h"
WINE_DEFAULT_DEBUG_CHANNEL(mspatcha); @@ -708,6 +707,139 @@ static void apply_retained_ranges( } }
+static void DECLSPEC_NORETURN throw_pe_fmt_exception(void) +{ + RaiseException(0xE0000001, 0, 0, NULL); + for (;;) { /* silence compiler warning */ } +} + +static IMAGE_NT_HEADERS32 UNALIGNED *image_get_nt_headers(const void *image_base, size_t image_size) +{ + IMAGE_DOS_HEADER UNALIGNED *dos_hdr; + IMAGE_NT_HEADERS32 UNALIGNED *nt_headers; + const UCHAR *const image_end = (PUCHAR)image_base + image_size; + + if (image_size >= 0x200) { + dos_hdr = (IMAGE_DOS_HEADER *)image_base; + if (dos_hdr->e_magic == IMAGE_DOS_SIGNATURE && dos_hdr->e_lfanew < image_size) { + nt_headers = (IMAGE_NT_HEADERS32 *)((ULONG_PTR)dos_hdr + dos_hdr->e_lfanew); + if (((PUCHAR)nt_headers + sizeof(IMAGE_NT_HEADERS32)) <= image_end) { + if (nt_headers->Signature == IMAGE_NT_SIGNATURE + && nt_headers->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) { + return nt_headers; + } + } + } + } + + return NULL; +} + +static ULONG image_rva_to_file_offset( + IMAGE_NT_HEADERS32 UNALIGNED *nt_headers, ULONG rva, PUCHAR image_base, ULONG image_size) +{ + IMAGE_SECTION_HEADER UNALIGNED *section_table; + ULONG section_count; + ULONG i; + + if ( rva < nt_headers->OptionalHeader.SizeOfHeaders ) { + return rva; + } + + section_table = IMAGE_FIRST_SECTION(nt_headers); + section_count = nt_headers->FileHeader.NumberOfSections; + for (i = 0; i < section_count; i++) { + if ((PUCHAR)§ion_table[i] < image_base + || ((PUCHAR)§ion_table[i] + sizeof(IMAGE_SECTION_HEADER)) > &image_base[image_size]) { + throw_pe_fmt_exception(); + } + + if (rva >= section_table[i].VirtualAddress + && rva < (section_table[i].VirtualAddress + section_table[i].SizeOfRawData)) { + return (section_table[i].PointerToRawData + (rva - section_table[i].VirtualAddress)); + } + } + + return 0; +} + +static ULONG image_directory_rva_and_size( + IMAGE_NT_HEADERS32 UNALIGNED *nt_header, USHORT directory_entry, ULONG *directory_size, + PUCHAR image_base, ULONG image_size) +{ + IMAGE_DATA_DIRECTORY UNALIGNED *data_directory; + + if (directory_entry >= nt_header->OptionalHeader.NumberOfRvaAndSizes) { + return 0; + } + + data_directory = &nt_header->OptionalHeader.DataDirectory[directory_entry]; + if ((PUCHAR)data_directory < image_base + || ((PUCHAR)data_directory + sizeof(IMAGE_DATA_DIRECTORY)) > &image_base[image_size]) { + throw_pe_fmt_exception(); + } + + if (directory_size != NULL) { + *directory_size = data_directory->Size; + } + return data_directory->VirtualAddress; +} + +static ULONG image_directory_offset_and_size( + IMAGE_NT_HEADERS32 UNALIGNED *nt_header, USHORT directory_entry, ULONG *directory_size, + PUCHAR image_base, ULONG image_size) +{ + ULONG rva, offset = 0; + rva = image_directory_rva_and_size(nt_header, directory_entry, directory_size, image_base, image_size); + if (rva) { + offset = image_rva_to_file_offset(nt_header, rva, image_base, image_size); + } + return offset; +} + +static PVOID image_rva_to_mapped_address( + IMAGE_NT_HEADERS32 UNALIGNED *nt_headers, ULONG rva, PVOID image_base, ULONG image_size) +{ + const ULONG offset = image_rva_to_file_offset(nt_headers, rva, image_base, image_size); + if (offset && offset < image_size) { + return (PVOID)((PUCHAR)image_base + offset); + } + return NULL; +} + +static PVOID image_directory_mapped_address( + IMAGE_NT_HEADERS32 UNALIGNED *nt_headers, USHORT directory_entry, ULONG *directory_size, + PUCHAR image_base, ULONG image_size) +{ + ULONG dir_rva; + ULONG dir_size; + PVOID mapped_address; + + dir_rva = image_directory_rva_and_size(nt_headers, directory_entry, &dir_size, image_base, image_size); + if (!dir_rva) { + return NULL; + } + + mapped_address = image_rva_to_mapped_address(nt_headers, dir_rva, image_base, image_size); + if (!mapped_address) { + return NULL; + } + + if (((PUCHAR)mapped_address + dir_size) < (PUCHAR)mapped_address) { + throw_pe_fmt_exception(); + } + + if (((PUCHAR)mapped_address + dir_size) > &image_base[image_size]) { + return NULL; + } + + if (directory_size != NULL) { + *directory_size = dir_size; + } + + return mapped_address; +} + /* Fixup a given mapped image's relocation table for a new image base. */ static BOOL rebase_image( IMAGE_NT_HEADERS32 UNALIGNED *nt_headers, diff --git a/dlls/mspatcha/pecoff.c b/dlls/mspatcha/pecoff.c deleted file mode 100644 index 0bb240250a7..00000000000 --- a/dlls/mspatcha/pecoff.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * PatchAPI PE/COFF image helpers. - * - * Copyright 2023 Aidan Khoury - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "pecoff.h" -#include "winbase.h" - -void DECLSPEC_NORETURN throw_pe_fmt_exception(void) -{ - RaiseException(0xE0000001, 0, 0, NULL); - for (;;) { /* silence compiler warning */ } -} - -IMAGE_NT_HEADERS32 UNALIGNED *image_get_nt_headers(const void *image_base, size_t image_size) -{ - IMAGE_DOS_HEADER UNALIGNED *dos_hdr; - IMAGE_NT_HEADERS32 UNALIGNED *nt_headers; - const UCHAR *const image_end = (PUCHAR)image_base + image_size; - - if (image_size >= 0x200) { - dos_hdr = (IMAGE_DOS_HEADER *)image_base; - if (dos_hdr->e_magic == IMAGE_DOS_SIGNATURE && dos_hdr->e_lfanew < image_size) { - nt_headers = (IMAGE_NT_HEADERS32 *)((ULONG_PTR)dos_hdr + dos_hdr->e_lfanew); - if (((PUCHAR)nt_headers + sizeof(IMAGE_NT_HEADERS32)) <= image_end) { - if (nt_headers->Signature == IMAGE_NT_SIGNATURE - && nt_headers->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) { - return nt_headers; - } - } - } - } - - return NULL; -} - -ULONG image_rva_to_file_offset( - IMAGE_NT_HEADERS32 UNALIGNED *nt_headers, ULONG rva, PUCHAR image_base, ULONG image_size) -{ - IMAGE_SECTION_HEADER UNALIGNED *section_table; - ULONG section_count; - ULONG i; - - if ( rva < nt_headers->OptionalHeader.SizeOfHeaders ) { - return rva; - } - - section_table = IMAGE_FIRST_SECTION(nt_headers); - section_count = nt_headers->FileHeader.NumberOfSections; - for (i = 0; i < section_count; i++) { - if ((PUCHAR)§ion_table[i] < image_base - || ((PUCHAR)§ion_table[i] + sizeof(IMAGE_SECTION_HEADER)) > &image_base[image_size]) { - throw_pe_fmt_exception(); - } - - if (rva >= section_table[i].VirtualAddress - && rva < (section_table[i].VirtualAddress + section_table[i].SizeOfRawData)) { - return (section_table[i].PointerToRawData + (rva - section_table[i].VirtualAddress)); - } - } - - return 0; -} - -ULONG image_directory_rva_and_size( - IMAGE_NT_HEADERS32 UNALIGNED *nt_header, USHORT directory_entry, ULONG *directory_size, - PUCHAR image_base, ULONG image_size) -{ - IMAGE_DATA_DIRECTORY UNALIGNED *data_directory; - - if (directory_entry >= nt_header->OptionalHeader.NumberOfRvaAndSizes) { - return 0; - } - - data_directory = &nt_header->OptionalHeader.DataDirectory[directory_entry]; - if ((PUCHAR)data_directory < image_base - || ((PUCHAR)data_directory + sizeof(IMAGE_DATA_DIRECTORY)) > &image_base[image_size]) { - throw_pe_fmt_exception(); - } - - if (directory_size != NULL) { - *directory_size = data_directory->Size; - } - return data_directory->VirtualAddress; -} - -ULONG image_directory_offset_and_size( - IMAGE_NT_HEADERS32 UNALIGNED *nt_header, USHORT directory_entry, ULONG *directory_size, - PUCHAR image_base, ULONG image_size) -{ - ULONG rva, offset = 0; - rva = image_directory_rva_and_size(nt_header, directory_entry, directory_size, image_base, image_size); - if (rva) { - offset = image_rva_to_file_offset(nt_header, rva, image_base, image_size); - } - return offset; -} - -PVOID image_rva_to_mapped_address( - IMAGE_NT_HEADERS32 UNALIGNED *nt_headers, ULONG rva, PVOID image_base, ULONG image_size) -{ - const ULONG offset = image_rva_to_file_offset(nt_headers, rva, image_base, image_size); - if (offset && offset < image_size) { - return (PVOID)((PUCHAR)image_base + offset); - } - return NULL; -} - -PVOID image_directory_mapped_address( - IMAGE_NT_HEADERS32 UNALIGNED *nt_headers, USHORT directory_entry, ULONG *directory_size, - PUCHAR image_base, ULONG image_size) -{ - ULONG dir_rva; - ULONG dir_size; - PVOID mapped_address; - - dir_rva = image_directory_rva_and_size(nt_headers, directory_entry, &dir_size, image_base, image_size); - if (!dir_rva) { - return NULL; - } - - mapped_address = image_rva_to_mapped_address(nt_headers, dir_rva, image_base, image_size); - if (!mapped_address) { - return NULL; - } - - if (((PUCHAR)mapped_address + dir_size) < (PUCHAR)mapped_address) { - throw_pe_fmt_exception(); - } - - if (((PUCHAR)mapped_address + dir_size) > &image_base[image_size]) { - return NULL; - } - - if (directory_size != NULL) { - *directory_size = dir_size; - } - - return mapped_address; -} diff --git a/dlls/mspatcha/pecoff.h b/dlls/mspatcha/pecoff.h deleted file mode 100644 index 1664a2fe777..00000000000 --- a/dlls/mspatcha/pecoff.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * PatchAPI PE/COFF image helpers. - * - * Copyright 2023 Aidan Khoury - * - * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include <stdarg.h> -#include "windef.h" - -void DECLSPEC_NORETURN throw_pe_fmt_exception(void); - -IMAGE_NT_HEADERS32 UNALIGNED *image_get_nt_headers(const void *image_base, size_t image_size); - -ULONG image_rva_to_file_offset( - IMAGE_NT_HEADERS32 UNALIGNED *nt_headers, ULONG rva, PUCHAR image_base, ULONG image_size); - -ULONG image_directory_rva_and_size( - IMAGE_NT_HEADERS32 UNALIGNED *nt_header, USHORT directory_entry, ULONG *directory_size, - PUCHAR image_base, ULONG image_size); - -ULONG image_directory_offset_and_size( - IMAGE_NT_HEADERS32 UNALIGNED *nt_header, USHORT directory_entry, ULONG *directory_size, - PUCHAR image_base, ULONG image_size); - -PVOID image_rva_to_mapped_address( - IMAGE_NT_HEADERS32 UNALIGNED *nt_headers, ULONG rva, PVOID image_base, ULONG image_size); - -PVOID image_directory_mapped_address( - IMAGE_NT_HEADERS32 UNALIGNED *nt_headers, USHORT directory_entry, ULONG *directory_size, - PUCHAR image_base, ULONG image_size);