From: ajkhoury aidankhoury@gmail.com
--- dlls/mspatcha/pa19.c | 179 +++++++++++++++++++++---------------------- 1 file changed, 88 insertions(+), 91 deletions(-)
diff --git a/dlls/mspatcha/pa19.c b/dlls/mspatcha/pa19.c index a8adc01cc7c..569df54408e 100644 --- a/dlls/mspatcha/pa19.c +++ b/dlls/mspatcha/pa19.c @@ -733,7 +733,7 @@ static BOOL rebase_image( &reloc_dir_size, mapped_image_base, mapped_image_size); if (!reloc_block || !reloc_dir_size - || ((PUCHAR)reloc_block > (mapped_image_end - sizeof(IMAGE_BASE_RELOCATION)))) { + || ((PUCHAR)reloc_block + sizeof(IMAGE_BASE_RELOCATION)) > mapped_image_end) { return result; }
@@ -741,51 +741,49 @@ static BOOL rebase_image( result = TRUE;
reloc_dir_remaining = (LONG)reloc_dir_size; - while (reloc_dir_remaining > 0) { + while (reloc_dir_remaining > 0 + && reloc_block->SizeOfBlock <= (ULONG)reloc_dir_remaining + && reloc_block->SizeOfBlock > sizeof(IMAGE_BASE_RELOCATION)) {
- if (reloc_block->SizeOfBlock <= (ULONG)reloc_dir_remaining - && reloc_block->SizeOfBlock > sizeof(IMAGE_BASE_RELOCATION)) + reloc_block_base = (IMAGE_BASE_RELOCATION UNALIGNED *)(mapped_image_base + + image_rva_to_file_offset(nt_headers, reloc_block->VirtualAddress, mapped_image_base, mapped_image_size)); + if (reloc_block_base) { - reloc_block_base = (IMAGE_BASE_RELOCATION UNALIGNED *)(mapped_image_base + - image_rva_to_file_offset(nt_headers, reloc_block->VirtualAddress, mapped_image_base, mapped_image_size)); - if (reloc_block_base) - { - reloc = (USHORT UNALIGNED *)((PUCHAR)reloc_block + sizeof(IMAGE_BASE_RELOCATION)); - reloc_count = (reloc_block->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT); - while (reloc_count--) { - if ((PUCHAR)reloc > mapped_image_end) { - break; - } + reloc = (USHORT UNALIGNED *)((PUCHAR)reloc_block + sizeof(IMAGE_BASE_RELOCATION)); + reloc_count = (reloc_block->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT); + while (reloc_count--) { + if ((PUCHAR)reloc > mapped_image_end) { + break; + }
- reloc_fixup = (PUCHAR)reloc_block_base + (*reloc & 0x0FFF); - if (reloc_fixup < mapped_image_end) + reloc_fixup = (PUCHAR)reloc_block_base + (*reloc & 0x0FFF); + if (reloc_fixup < mapped_image_end) + { + switch (*reloc >> 12) { - switch (*reloc >> 12) - { - case IMAGE_REL_BASED_HIGH: - *(USHORT UNALIGNED *)reloc_fixup = (USHORT)(((*(USHORT UNALIGNED *)reloc_fixup << 16) + delta) >> 16); - break; - case IMAGE_REL_BASED_LOW: - *(USHORT UNALIGNED *)reloc_fixup = (USHORT)(*(SHORT UNALIGNED *)reloc_fixup + delta); - break; - case IMAGE_REL_BASED_HIGHLOW: - if (reloc_fixup + sizeof(USHORT) <= mapped_image_end) { - *(LONG UNALIGNED *)reloc_fixup += delta; - } - break; - case IMAGE_REL_BASED_HIGHADJ: - ++reloc; - --reloc_count; - if ((PUCHAR)reloc <= (mapped_image_end - sizeof(USHORT))) - *(USHORT UNALIGNED *)reloc_fixup = (USHORT)(((*(USHORT UNALIGNED *)reloc_fixup << 16) + (SHORT)*reloc + delta + 0x8000) >> 16); - break; - default: - + case IMAGE_REL_BASED_HIGH: + *(USHORT UNALIGNED *)reloc_fixup = (USHORT)(((*(USHORT UNALIGNED *)reloc_fixup << 16) + delta) >> 16); + break; + case IMAGE_REL_BASED_LOW: + *(USHORT UNALIGNED *)reloc_fixup = (USHORT)(*(SHORT UNALIGNED *)reloc_fixup + delta); + break; + case IMAGE_REL_BASED_HIGHLOW: + if (reloc_fixup + sizeof(USHORT) <= mapped_image_end) { + *(LONG UNALIGNED *)reloc_fixup += delta; } - } + break; + case IMAGE_REL_BASED_HIGHADJ: + ++reloc; + --reloc_count; + if ((PUCHAR)reloc <= (mapped_image_end - sizeof(USHORT))) + *(USHORT UNALIGNED *)reloc_fixup = (USHORT)(((*(USHORT UNALIGNED *)reloc_fixup << 16) + (SHORT)*reloc + delta + 0x8000) >> 16); + break; + default:
- ++reloc; + } } + + ++reloc; } }
@@ -1221,77 +1219,76 @@ static void patch_transform_PE_relocations( reloc_entry_count = 0; reloc_block = (IMAGE_BASE_RELOCATION UNALIGNED *)&mapped_image[reloc_dir_offset]; reloc_dir_remaining = (LONG)reloc_dir_size; - while (reloc_dir_remaining > 0) { - if ((PUCHAR)reloc_block > (mapped_image_end - sizeof(IMAGE_BASE_RELOCATION))) { + while (reloc_dir_remaining > 0 + && reloc_block->SizeOfBlock <= (ULONG)reloc_dir_remaining + && reloc_block->SizeOfBlock > sizeof(IMAGE_BASE_RELOCATION)) + { + if (((PUCHAR)reloc_block + sizeof(IMAGE_BASE_RELOCATION)) > mapped_image_end) { throw_pe_fmt_exception(); }
- if ((reloc_block->SizeOfBlock <= (ULONG)reloc_dir_remaining) && - (reloc_block->SizeOfBlock > sizeof(IMAGE_BASE_RELOCATION))) { - - reloc_block_base = (IMAGE_BASE_RELOCATION UNALIGNED *)(mapped_image + - image_rva_to_file_offset(nt_headers, reloc_block->VirtualAddress, mapped_image, image_size)); - if (reloc_block_base) { + reloc_block_base = (IMAGE_BASE_RELOCATION UNALIGNED *)(mapped_image + + image_rva_to_file_offset(nt_headers, reloc_block->VirtualAddress, mapped_image, image_size)); + if (reloc_block_base) {
- reloc_block_base_va = reloc_block->VirtualAddress + image_base_va; - reloc = (PUSHORT)((ULONG_PTR)reloc_block + sizeof(IMAGE_BASE_RELOCATION)); - reloc_count = (reloc_block->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT); - while (reloc_count--) { - if ((PUCHAR)reloc > (mapped_image_end - sizeof(USHORT))) { - throw_pe_fmt_exception(); - } + reloc_block_base_va = reloc_block->VirtualAddress + image_base_va; + reloc = (PUSHORT)((ULONG_PTR)reloc_block + sizeof(IMAGE_BASE_RELOCATION)); + reloc_count = (reloc_block->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT); + while (reloc_count--) { + if ((PUCHAR)reloc > (mapped_image_end - sizeof(USHORT))) { + throw_pe_fmt_exception(); + }
- reloc_type_offset = *reloc; - reloc_type = (UCHAR)(reloc_type_offset >> 12); - if (reloc_type != IMAGE_REL_BASED_ABSOLUTE) { + reloc_type_offset = *reloc; + reloc_type = (UCHAR)(reloc_type_offset >> 12); + if (reloc_type != IMAGE_REL_BASED_ABSOLUTE) {
- reloc_offset = (USHORT)(reloc_type_offset & 0xFFF); - reloc_fixup = (PUCHAR)reloc_block_base + reloc_offset; - reloc_fixup_rva = reloc_block_base_va + reloc_offset - image_base_va; + reloc_offset = (USHORT)(reloc_type_offset & 0xFFF); + reloc_fixup = (PUCHAR)reloc_block_base + reloc_offset; + reloc_fixup_rva = reloc_block_base_va + reloc_offset - image_base_va;
- reloc_entries[reloc_entry_count].rva = get_new_rva_from_xfrm_table(xfrm_tbl, reloc_fixup_rva); - reloc_entries[reloc_entry_count].type = reloc_type; + reloc_entries[reloc_entry_count].rva = get_new_rva_from_xfrm_table(xfrm_tbl, reloc_fixup_rva); + reloc_entries[reloc_entry_count].type = reloc_type;
- switch (reloc_type) { + switch (reloc_type) {
- case IMAGE_REL_BASED_HIGH: - case IMAGE_REL_BASED_LOW: - if (reloc_fixup < mapped_image_end) { - *(USHORT UNALIGNED *)(hintmap + (reloc_fixup - mapped_image)) |= 0x0101; - } - break; + case IMAGE_REL_BASED_HIGH: + case IMAGE_REL_BASED_LOW: + if (reloc_fixup < mapped_image_end) { + *(USHORT UNALIGNED *)(hintmap + (reloc_fixup - mapped_image)) |= 0x0101; + } + break;
- case IMAGE_REL_BASED_HIGHLOW: - if (reloc_fixup < (mapped_image_end - sizeof(LONG))) { - *(ULONG UNALIGNED *)(hintmap + (reloc_fixup - mapped_image)) |= 0x01010101; + case IMAGE_REL_BASED_HIGHLOW: + if (reloc_fixup < (mapped_image_end - sizeof(LONG))) { + *(ULONG UNALIGNED *)(hintmap + (reloc_fixup - mapped_image)) |= 0x01010101;
- reloc_target_va = *(ULONG UNALIGNED *)reloc_fixup; - reloc_target_rva = reloc_target_va - image_base_va; + reloc_target_va = *(ULONG UNALIGNED *)reloc_fixup; + reloc_target_rva = reloc_target_va - image_base_va;
- new_rva = get_new_rva_from_xfrm_table(xfrm_tbl, reloc_target_rva); - if (new_rva != reloc_target_rva) { - *(ULONG UNALIGNED *)reloc_fixup = image_base_va + new_rva; - } + new_rva = get_new_rva_from_xfrm_table(xfrm_tbl, reloc_target_rva); + if (new_rva != reloc_target_rva) { + *(ULONG UNALIGNED *)reloc_fixup = image_base_va + new_rva; } - break; - - case IMAGE_REL_BASED_HIGHADJ: - if (reloc_fixup < mapped_image_end) { - *(USHORT UNALIGNED *)(hintmap + (reloc_fixup - mapped_image)) |= 0x0101; - } - - ++reloc; - --reloc_count; + } + break;
- reloc_entries[reloc_entry_count].hiadj = *reloc; - break; + case IMAGE_REL_BASED_HIGHADJ: + if (reloc_fixup < mapped_image_end) { + *(USHORT UNALIGNED *)(hintmap + (reloc_fixup - mapped_image)) |= 0x0101; }
- ++reloc_entry_count; + ++reloc; + --reloc_count; + + reloc_entries[reloc_entry_count].hiadj = *reloc; + break; }
- ++reloc; + ++reloc_entry_count; } + + ++reloc; } }