35
35
#if _MSC_VER
36
36
// Disable warning about data -> function pointer conversion
37
37
#pragma warning(disable:4055)
38
+ // C4244: conversion from 'uintptr_t' to 'DWORD', possible loss of data.
39
+ #pragma warning(error: 4244)
40
+ // C4267: conversion from 'size_t' to 'int', possible loss of data.
41
+ #pragma warning(error: 4267)
42
+
43
+ #define inline __inline
38
44
#endif
39
45
40
46
#ifndef IMAGE_SIZEOF_BASE_RELOCATION
@@ -68,14 +74,27 @@ typedef struct {
68
74
typedef struct {
69
75
LPVOID address ;
70
76
LPVOID alignedAddress ;
71
- DWORD size ;
77
+ SIZE_T size ;
72
78
DWORD characteristics ;
73
79
BOOL last ;
74
80
} SECTIONFINALIZEDATA , * PSECTIONFINALIZEDATA ;
75
81
76
82
#define GET_HEADER_DICTIONARY (module , idx ) &(module)->headers->OptionalHeader.DataDirectory[idx]
77
- #define ALIGN_DOWN (address , alignment ) (LPVOID)((uintptr_t)(address) & ~((alignment) - 1))
78
- #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
+ }
79
98
80
99
#ifdef DEBUG_OUTPUT
81
100
static void
@@ -173,7 +192,7 @@ static int ProtectionFlags[2][2][2] = {
173
192
},
174
193
};
175
194
176
- static DWORD
195
+ static SIZE_T
177
196
GetRealSectionSize (PMEMORYMODULE module , PIMAGE_SECTION_HEADER section ) {
178
197
DWORD size = section -> SizeOfRawData ;
179
198
if (size == 0 ) {
@@ -183,7 +202,7 @@ GetRealSectionSize(PMEMORYMODULE module, PIMAGE_SECTION_HEADER section) {
183
202
size = module -> headers -> OptionalHeader .SizeOfUninitializedData ;
184
203
}
185
204
}
186
- return size ;
205
+ return ( SIZE_T ) size ;
187
206
}
188
207
189
208
static BOOL
@@ -242,7 +261,7 @@ FinalizeSections(PMEMORYMODULE module)
242
261
#endif
243
262
SECTIONFINALIZEDATA sectionData ;
244
263
sectionData .address = (LPVOID )((uintptr_t )section -> Misc .PhysicalAddress | imageOffset );
245
- sectionData .alignedAddress = ALIGN_DOWN (sectionData .address , module -> pageSize );
264
+ sectionData .alignedAddress = AlignAddressDown (sectionData .address , module -> pageSize );
246
265
sectionData .size = GetRealSectionSize (module , section );
247
266
sectionData .characteristics = section -> Characteristics ;
248
267
sectionData .last = FALSE;
@@ -251,8 +270,8 @@ FinalizeSections(PMEMORYMODULE module)
251
270
// loop through all sections and change access flags
252
271
for (i = 1 ; i < module -> headers -> FileHeader .NumberOfSections ; i ++ , section ++ ) {
253
272
LPVOID sectionAddress = (LPVOID )((uintptr_t )section -> Misc .PhysicalAddress | imageOffset );
254
- LPVOID alignedAddress = ALIGN_DOWN (sectionAddress , module -> pageSize );
255
- DWORD sectionSize = GetRealSectionSize (module , section );
273
+ LPVOID alignedAddress = AlignAddressDown (sectionAddress , module -> pageSize );
274
+ SIZE_T sectionSize = GetRealSectionSize (module , section );
256
275
// Combine access flags of all sections that share a page
257
276
// TODO(fancycode): We currently share flags of a trailing large section
258
277
// with the page of a first small section. This should be optimized.
@@ -263,7 +282,7 @@ FinalizeSections(PMEMORYMODULE module)
263
282
} else {
264
283
sectionData .characteristics |= section -> Characteristics ;
265
284
}
266
- sectionData .size = (((uintptr_t )sectionAddress ) + sectionSize ) - (uintptr_t ) sectionData .address ;
285
+ sectionData .size = (((uintptr_t )sectionAddress ) + (( uintptr_t ) sectionSize ) ) - (uintptr_t ) sectionData .address ;
267
286
continue ;
268
287
}
269
288
@@ -543,8 +562,8 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, size_t size,
543
562
}
544
563
545
564
GetNativeSystemInfo (& sysInfo );
546
- alignedImageSize = ALIGN_VALUE_UP (old_header -> OptionalHeader .SizeOfImage , sysInfo .dwPageSize );
547
- if (alignedImageSize != ALIGN_VALUE_UP (lastSectionEnd , sysInfo .dwPageSize )) {
565
+ alignedImageSize = AlignValueUp (old_header -> OptionalHeader .SizeOfImage , sysInfo .dwPageSize );
566
+ if (alignedImageSize != AlignValueUp (lastSectionEnd , sysInfo .dwPageSize )) {
548
567
SetLastError (ERROR_BAD_EXE_FORMAT );
549
568
return NULL ;
550
569
}
@@ -849,7 +868,11 @@ static PIMAGE_RESOURCE_DIRECTORY_ENTRY _MemorySearchResourceEntry(
849
868
cmp = _wcsnicmp (searchKey , resourceString -> NameString , resourceString -> Length );
850
869
if (cmp == 0 ) {
851
870
// Handle partial match
852
- cmp = searchKeyLen - resourceString -> Length ;
871
+ if (searchKeyLen > resourceString -> Length ) {
872
+ cmp = 1 ;
873
+ } else if (searchKeyLen < resourceString -> Length ) {
874
+ cmp = -1 ;
875
+ }
853
876
}
854
877
if (cmp < 0 ) {
855
878
end = (middle != end ? middle : middle - 1 );
@@ -994,3 +1017,66 @@ MemoryLoadStringEx(HMEMORYMODULE module, UINT id, LPTSTR buffer, int maxsize, WO
994
1017
#endif
995
1018
return size ;
996
1019
}
1020
+
1021
+ #ifdef TESTSUITE
1022
+ #include <stdio.h>
1023
+ #include <inttypes.h>
1024
+
1025
+ #ifndef PRIxPTR
1026
+ #ifdef _WIN64
1027
+ #define PRIxPTR "I64x"
1028
+ #else
1029
+ #define PRIxPTR "x"
1030
+ #endif
1031
+ #endif
1032
+
1033
+ static const uintptr_t AlignValueDownTests [][3 ] = {
1034
+ {16 , 16 , 16 },
1035
+ {17 , 16 , 16 },
1036
+ {32 , 16 , 32 },
1037
+ {33 , 16 , 32 },
1038
+ #ifdef _WIN64
1039
+ {0x12345678abcd1000 , 0x1000 , 0x12345678abcd1000 },
1040
+ {0x12345678abcd101f , 0x1000 , 0x12345678abcd1000 },
1041
+ #endif
1042
+ {0 , 0 , 0 },
1043
+ };
1044
+
1045
+ static const uintptr_t AlignValueUpTests [][3 ] = {
1046
+ {16 , 16 , 16 },
1047
+ {17 , 16 , 32 },
1048
+ {32 , 16 , 32 },
1049
+ {33 , 16 , 48 },
1050
+ #ifdef _WIN64
1051
+ {0x12345678abcd1000 , 0x1000 , 0x12345678abcd1000 },
1052
+ {0x12345678abcd101f , 0x1000 , 0x12345678abcd2000 },
1053
+ #endif
1054
+ {0 , 0 , 0 },
1055
+ };
1056
+
1057
+ BOOL MemoryModuleTestsuite () {
1058
+ BOOL success = TRUE;
1059
+ for (size_t idx = 0 ; AlignValueDownTests [idx ][0 ]; ++ idx ) {
1060
+ const uintptr_t * tests = AlignValueDownTests [idx ];
1061
+ uintptr_t value = AlignValueDown (tests [0 ], tests [1 ]);
1062
+ if (value != tests [2 ]) {
1063
+ printf ("AlignValueDown failed for 0x%" PRIxPTR "/0x%" PRIxPTR ": expected 0x%" PRIxPTR ", got 0x%" PRIxPTR "\n" ,
1064
+ tests [0 ], tests [1 ], tests [2 ], value );
1065
+ success = FALSE;
1066
+ }
1067
+ }
1068
+ for (size_t idx = 0 ; AlignValueDownTests [idx ][0 ]; ++ idx ) {
1069
+ const uintptr_t * tests = AlignValueUpTests [idx ];
1070
+ uintptr_t value = AlignValueUp (tests [0 ], tests [1 ]);
1071
+ if (value != tests [2 ]) {
1072
+ printf ("AlignValueUp failed for 0x%" PRIxPTR "/0x%" PRIxPTR ": expected 0x%" PRIxPTR ", got 0x%" PRIxPTR "\n" ,
1073
+ tests [0 ], tests [1 ], tests [2 ], value );
1074
+ success = FALSE;
1075
+ }
1076
+ }
1077
+ if (success ) {
1078
+ printf ("OK\n" );
1079
+ }
1080
+ return success ;
1081
+ }
1082
+ #endif
0 commit comments