3535#if _MSC_VER
3636// Disable warning about data -> function pointer conversion
3737#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
3844#endif
3945
4046#ifndef IMAGE_SIZEOF_BASE_RELOCATION
@@ -68,14 +74,27 @@ typedef struct {
6874typedef struct {
6975 LPVOID address ;
7076 LPVOID alignedAddress ;
71- DWORD size ;
77+ SIZE_T size ;
7278 DWORD characteristics ;
7379 BOOL last ;
7480} SECTIONFINALIZEDATA , * PSECTIONFINALIZEDATA ;
7581
7682#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+ }
7998
8099#ifdef DEBUG_OUTPUT
81100static void
@@ -173,7 +192,7 @@ static int ProtectionFlags[2][2][2] = {
173192 },
174193};
175194
176- static DWORD
195+ static SIZE_T
177196GetRealSectionSize (PMEMORYMODULE module , PIMAGE_SECTION_HEADER section ) {
178197 DWORD size = section -> SizeOfRawData ;
179198 if (size == 0 ) {
@@ -183,7 +202,7 @@ GetRealSectionSize(PMEMORYMODULE module, PIMAGE_SECTION_HEADER section) {
183202 size = module -> headers -> OptionalHeader .SizeOfUninitializedData ;
184203 }
185204 }
186- return size ;
205+ return ( SIZE_T ) size ;
187206}
188207
189208static BOOL
@@ -242,7 +261,7 @@ FinalizeSections(PMEMORYMODULE module)
242261#endif
243262 SECTIONFINALIZEDATA sectionData ;
244263 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 );
246265 sectionData .size = GetRealSectionSize (module , section );
247266 sectionData .characteristics = section -> Characteristics ;
248267 sectionData .last = FALSE;
@@ -251,8 +270,8 @@ FinalizeSections(PMEMORYMODULE module)
251270 // loop through all sections and change access flags
252271 for (i = 1 ; i < module -> headers -> FileHeader .NumberOfSections ; i ++ , section ++ ) {
253272 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 );
256275 // Combine access flags of all sections that share a page
257276 // TODO(fancycode): We currently share flags of a trailing large section
258277 // with the page of a first small section. This should be optimized.
@@ -263,7 +282,7 @@ FinalizeSections(PMEMORYMODULE module)
263282 } else {
264283 sectionData .characteristics |= section -> Characteristics ;
265284 }
266- sectionData .size = (((uintptr_t )sectionAddress ) + sectionSize ) - (uintptr_t ) sectionData .address ;
285+ sectionData .size = (((uintptr_t )sectionAddress ) + (( uintptr_t ) sectionSize ) ) - (uintptr_t ) sectionData .address ;
267286 continue ;
268287 }
269288
@@ -543,8 +562,8 @@ HMEMORYMODULE MemoryLoadLibraryEx(const void *data, size_t size,
543562 }
544563
545564 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 )) {
548567 SetLastError (ERROR_BAD_EXE_FORMAT );
549568 return NULL ;
550569 }
@@ -849,7 +868,11 @@ static PIMAGE_RESOURCE_DIRECTORY_ENTRY _MemorySearchResourceEntry(
849868 cmp = _wcsnicmp (searchKey , resourceString -> NameString , resourceString -> Length );
850869 if (cmp == 0 ) {
851870 // 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+ }
853876 }
854877 if (cmp < 0 ) {
855878 end = (middle != end ? middle : middle - 1 );
@@ -994,3 +1017,66 @@ MemoryLoadStringEx(HMEMORYMODULE module, UINT id, LPTSTR buffer, int maxsize, WO
9941017#endif
9951018 return size ;
9961019}
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