Skip to content

Commit 03cd7c9

Browse files
committed
Fixed alignment of values/addresses on 64bit systems.
1 parent de5dbce commit 03cd7c9

File tree

3 files changed

+111
-8
lines changed

3 files changed

+111
-8
lines changed

MemoryModule.c

Lines changed: 84 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@
3939
#pragma warning(error: 4244)
4040
// C4267: conversion from 'size_t' to 'int', possible loss of data.
4141
#pragma warning(error: 4267)
42+
43+
#define inline __inline
4244
#endif
4345

4446
#ifndef IMAGE_SIZEOF_BASE_RELOCATION
@@ -78,8 +80,21 @@ typedef struct {
7880
} SECTIONFINALIZEDATA, *PSECTIONFINALIZEDATA;
7981

8082
#define GET_HEADER_DICTIONARY(module, idx) &(module)->headers->OptionalHeader.DataDirectory[idx]
81-
#define ALIGN_DOWN(address, alignment) (LPVOID)((uintptr_t)(address) & ~((alignment) - 1))
82-
#define ALIGN_VALUE_UP(value, alignment) (((value) + (alignment) - 1) & ~((alignment) - 1))
83+
84+
static inline uintptr_t
85+
AlignValueDown(uintptr_t value, uintptr_t alignment) {
86+
return value & ~(alignment - 1);
87+
}
88+
89+
static inline LPVOID
90+
AlignAddressDown(LPVOID address, uintptr_t alignment) {
91+
return (LPVOID) AlignValueDown((uintptr_t) address, alignment);
92+
}
93+
94+
static inline size_t
95+
AlignValueUp(size_t value, size_t alignment) {
96+
return (value + alignment - 1) & ~(alignment - 1);
97+
}
8398

8499
#ifdef DEBUG_OUTPUT
85100
static void
@@ -246,7 +261,7 @@ FinalizeSections(PMEMORYMODULE module)
246261
#endif
247262
SECTIONFINALIZEDATA sectionData;
248263
sectionData.address = (LPVOID)((uintptr_t)section->Misc.PhysicalAddress | imageOffset);
249-
sectionData.alignedAddress = ALIGN_DOWN(sectionData.address, module->pageSize);
264+
sectionData.alignedAddress = AlignAddressDown(sectionData.address, module->pageSize);
250265
sectionData.size = GetRealSectionSize(module, section);
251266
sectionData.characteristics = section->Characteristics;
252267
sectionData.last = FALSE;
@@ -255,7 +270,7 @@ FinalizeSections(PMEMORYMODULE module)
255270
// loop through all sections and change access flags
256271
for (i=1; i<module->headers->FileHeader.NumberOfSections; i++, section++) {
257272
LPVOID sectionAddress = (LPVOID)((uintptr_t)section->Misc.PhysicalAddress | imageOffset);
258-
LPVOID alignedAddress = ALIGN_DOWN(sectionAddress, module->pageSize);
273+
LPVOID alignedAddress = AlignAddressDown(sectionAddress, module->pageSize);
259274
DWORD sectionSize = GetRealSectionSize(module, section);
260275
// Combine access flags of all sections that share a page
261276
// TODO(fancycode): We currently share flags of a trailing large section
@@ -547,8 +562,8 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, size_t size,
547562
}
548563

549564
GetNativeSystemInfo(&sysInfo);
550-
alignedImageSize = ALIGN_VALUE_UP(old_header->OptionalHeader.SizeOfImage, sysInfo.dwPageSize);
551-
if (alignedImageSize != ALIGN_VALUE_UP(lastSectionEnd, sysInfo.dwPageSize)) {
565+
alignedImageSize = AlignValueUp(old_header->OptionalHeader.SizeOfImage, sysInfo.dwPageSize);
566+
if (alignedImageSize != AlignValueUp(lastSectionEnd, sysInfo.dwPageSize)) {
552567
SetLastError(ERROR_BAD_EXE_FORMAT);
553568
return NULL;
554569
}
@@ -998,3 +1013,66 @@ MemoryLoadStringEx(HMEMORYMODULE module, UINT id, LPTSTR buffer, int maxsize, WO
9981013
#endif
9991014
return size;
10001015
}
1016+
1017+
#ifdef TESTSUITE
1018+
#include <stdio.h>
1019+
#include <inttypes.h>
1020+
1021+
#ifndef PRIxPTR
1022+
#ifdef _WIN64
1023+
#define PRIxPTR "I64x"
1024+
#else
1025+
#define PRIxPTR "x"
1026+
#endif
1027+
#endif
1028+
1029+
static const uintptr_t AlignValueDownTests[][3] = {
1030+
{16, 16, 16},
1031+
{17, 16, 16},
1032+
{32, 16, 32},
1033+
{33, 16, 32},
1034+
#ifdef _WIN64
1035+
{0x12345678abcd1000, 0x1000, 0x12345678abcd1000},
1036+
{0x12345678abcd101f, 0x1000, 0x12345678abcd1000},
1037+
#endif
1038+
{0, 0, 0},
1039+
};
1040+
1041+
static const uintptr_t AlignValueUpTests[][3] = {
1042+
{16, 16, 16},
1043+
{17, 16, 32},
1044+
{32, 16, 32},
1045+
{33, 16, 48},
1046+
#ifdef _WIN64
1047+
{0x12345678abcd1000, 0x1000, 0x12345678abcd1000},
1048+
{0x12345678abcd101f, 0x1000, 0x12345678abcd2000},
1049+
#endif
1050+
{0, 0, 0},
1051+
};
1052+
1053+
BOOL MemoryModuleTestsuite() {
1054+
BOOL success = TRUE;
1055+
for (size_t idx = 0; AlignValueDownTests[idx][0]; ++idx) {
1056+
const uintptr_t* tests = AlignValueDownTests[idx];
1057+
uintptr_t value = AlignValueDown(tests[0], tests[1]);
1058+
if (value != tests[2]) {
1059+
printf("AlignValueDown failed for 0x%" PRIxPTR "/0x%" PRIxPTR ": expected 0x%" PRIxPTR ", got 0x%" PRIxPTR "\n",
1060+
tests[0], tests[1], tests[2], value);
1061+
success = FALSE;
1062+
}
1063+
}
1064+
for (size_t idx = 0; AlignValueDownTests[idx][0]; ++idx) {
1065+
const uintptr_t* tests = AlignValueUpTests[idx];
1066+
uintptr_t value = AlignValueUp(tests[0], tests[1]);
1067+
if (value != tests[2]) {
1068+
printf("AlignValueUp failed for 0x%" PRIxPTR "/0x%" PRIxPTR ": expected 0x%" PRIxPTR ", got 0x%" PRIxPTR "\n",
1069+
tests[0], tests[1], tests[2], value);
1070+
success = FALSE;
1071+
}
1072+
}
1073+
if (success) {
1074+
printf("OK\n");
1075+
}
1076+
return success;
1077+
}
1078+
#endif

tests/Makefile

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ RC = rc
1616
endif
1717

1818
RM = rm
19-
CFLAGS = -Wall -g
19+
CFLAGS = -Wall -g -DTESTSUITE
2020
LDFLAGS =
2121
RCFLAGS = -O coff
2222

@@ -49,13 +49,20 @@ TEST_DLLS = \
4949
test-relocate.dll \
5050

5151
LOADDLL_OBJ = LoadDll.o ../MemoryModule.o
52+
TESTSUITE_OBJ = TestSuite.o ../MemoryModule.o
5253
DLL_OBJ = SampleDLL.o SampleDLL.res
5354

54-
all: LoadDll.exe $(TEST_DLLS)
55+
all: prepare_testsuite LoadDll.exe TestSuite.exe $(TEST_DLLS)
56+
57+
prepare_testsuite:
58+
rm -f $(TESTSUITE_OBJ)
5559

5660
LoadDll.exe: $(LOADDLL_OBJ)
5761
$(CC) $(LDFLAGS_EXE) $(LDFLAGS) -Wl,--image-base -Wl,0x20000000 -o LoadDll.exe $(LOADDLL_OBJ)
5862

63+
TestSuite.exe: $(TESTSUITE_OBJ)
64+
$(CC) $(LDFLAGS_EXE) $(LDFLAGS) -o TestSuite.exe $(TESTSUITE_OBJ)
65+
5966
LoadDll.o: LoadDll.cpp
6067
$(CXX) $(CFLAGS) $(CFLAGS_EXE) -c $<
6168

@@ -78,4 +85,5 @@ clean:
7885
$(RM) -rf LoadDll.exe $(TEST_DLLS) $(LOADDLL_OBJ) $(DLL_OBJ)
7986

8087
test: all
88+
./TestSuite.exe
8189
./runtests.sh $(PLATFORM) "$(TEST_DLLS)"

tests/TestSuite.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#define WIN32_LEAN_AND_MEAN
2+
#ifndef _CRT_SECURE_NO_WARNINGS
3+
#define _CRT_SECURE_NO_WARNINGS
4+
#endif
5+
6+
#include <windows.h>
7+
8+
extern BOOL MemoryModuleTestsuite();
9+
10+
int main(int argc, char* argv[])
11+
{
12+
if (!MemoryModuleTestsuite()) {
13+
return 1;
14+
}
15+
16+
return 0;
17+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy