Skip to content

Commit 2f0bb27

Browse files
committed
added support for 64bit DLLs
1 parent 285b108 commit 2f0bb27

1 file changed

Lines changed: 35 additions & 16 deletions

File tree

MemoryModule.c

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,16 @@
2424
*
2525
*/
2626

27+
#ifndef __GNUC__
2728
// disable warnings about pointer <-> DWORD conversions
2829
#pragma warning( disable : 4311 4312 )
30+
#endif
31+
32+
#ifdef _WIN64
33+
#define POINTER_TYPE ULONGLONG
34+
#else
35+
#define POINTER_TYPE DWORD
36+
#endif
2937

3038
#include <Windows.h>
3139
#include <winnt.h>
@@ -46,7 +54,7 @@ typedef struct {
4654
typedef BOOL (WINAPI *DllEntryProc)(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);
4755

4856
#define GET_HEADER_DICTIONARY(module, idx) &(module)->headers->OptionalHeader.DataDirectory[idx]
49-
#define CALCULATE_ADDRESS(base, offset) (((DWORD)(base)) + (offset))
57+
#define CALCULATE_ADDRESS(base, offset) (((unsigned char *)(base)) + (offset))
5058

5159
#ifdef DEBUG_OUTPUT
5260
static void
@@ -85,7 +93,7 @@ CopySections(const unsigned char *data, PIMAGE_NT_HEADERS old_headers, PMEMORYMO
8593
MEM_COMMIT,
8694
PAGE_READWRITE);
8795

88-
section->Misc.PhysicalAddress = (DWORD)dest;
96+
section->Misc.PhysicalAddress = (POINTER_TYPE)dest;
8997
memset(dest, 0, size);
9098
}
9199

@@ -99,7 +107,7 @@ CopySections(const unsigned char *data, PIMAGE_NT_HEADERS old_headers, PMEMORYMO
99107
MEM_COMMIT,
100108
PAGE_READWRITE);
101109
memcpy(dest, (unsigned char *)CALCULATE_ADDRESS(data, section->PointerToRawData), section->SizeOfRawData);
102-
section->Misc.PhysicalAddress = (DWORD)dest;
110+
section->Misc.PhysicalAddress = (POINTER_TYPE)dest;
103111
}
104112
}
105113

@@ -133,7 +141,7 @@ FinalizeSections(PMEMORYMODULE module)
133141
if (section->Characteristics & IMAGE_SCN_MEM_DISCARDABLE)
134142
{
135143
// section is not needed any more and can safely be freed
136-
VirtualFree((LPVOID)section->Misc.PhysicalAddress, section->SizeOfRawData, MEM_DECOMMIT);
144+
VirtualFree((LPVOID)(POINTER_TYPE)section->Misc.PhysicalAddress, section->SizeOfRawData, MEM_DECOMMIT);
137145
continue;
138146
}
139147

@@ -155,7 +163,7 @@ FinalizeSections(PMEMORYMODULE module)
155163
if (size > 0)
156164
{
157165
// change memory access flags
158-
if (VirtualProtect((LPVOID)section->Misc.PhysicalAddress, section->SizeOfRawData, protect, &oldProtect) == 0)
166+
if (VirtualProtect((LPVOID)(POINTER_TYPE)section->Misc.PhysicalAddress, section->SizeOfRawData, protect, &oldProtect) == 0)
159167
#ifdef DEBUG_OUTPUT
160168
OutputLastError("Error protecting memory page")
161169
#endif
@@ -165,7 +173,7 @@ FinalizeSections(PMEMORYMODULE module)
165173
}
166174

167175
static void
168-
PerformBaseRelocation(PMEMORYMODULE module, DWORD delta)
176+
PerformBaseRelocation(PMEMORYMODULE module, SIZE_T delta)
169177
{
170178
DWORD i;
171179
unsigned char *codeBase = module->codeBase;
@@ -181,6 +189,9 @@ PerformBaseRelocation(PMEMORYMODULE module, DWORD delta)
181189
for (i=0; i<((relocation->SizeOfBlock-IMAGE_SIZEOF_BASE_RELOCATION) / 2); i++, relInfo++)
182190
{
183191
DWORD *patchAddrHL;
192+
#ifdef _WIN64
193+
ULONGLONG *patchAddr64;
194+
#endif
184195
int type, offset;
185196

186197
// the upper 4 bits define the type of relocation
@@ -199,6 +210,13 @@ PerformBaseRelocation(PMEMORYMODULE module, DWORD delta)
199210
patchAddrHL = (DWORD *)CALCULATE_ADDRESS(dest, offset);
200211
*patchAddrHL += delta;
201212
break;
213+
214+
#ifdef _WIN64
215+
case IMAGE_REL_BASED_DIR64:
216+
patchAddr64 = (ULONGLONG *)CALCULATE_ADDRESS(dest, offset);
217+
*patchAddr64 += delta;
218+
break;
219+
#endif
202220

203221
default:
204222
//printf("Unknown relocation: %d\n", type);
@@ -224,7 +242,8 @@ BuildImportTable(PMEMORYMODULE module)
224242
PIMAGE_IMPORT_DESCRIPTOR importDesc = (PIMAGE_IMPORT_DESCRIPTOR)CALCULATE_ADDRESS(codeBase, directory->VirtualAddress);
225243
for (; !IsBadReadPtr(importDesc, sizeof(IMAGE_IMPORT_DESCRIPTOR)) && importDesc->Name; importDesc++)
226244
{
227-
DWORD *thunkRef, *funcRef;
245+
POINTER_TYPE *thunkRef;
246+
FARPROC *funcRef;
228247
HMODULE handle = LoadLibrary((LPCSTR)CALCULATE_ADDRESS(codeBase, importDesc->Name));
229248
if (handle == INVALID_HANDLE_VALUE)
230249
{
@@ -245,20 +264,20 @@ BuildImportTable(PMEMORYMODULE module)
245264
module->modules[module->numModules++] = handle;
246265
if (importDesc->OriginalFirstThunk)
247266
{
248-
thunkRef = (DWORD *)CALCULATE_ADDRESS(codeBase, importDesc->OriginalFirstThunk);
249-
funcRef = (DWORD *)CALCULATE_ADDRESS(codeBase, importDesc->FirstThunk);
267+
thunkRef = (POINTER_TYPE *)CALCULATE_ADDRESS(codeBase, importDesc->OriginalFirstThunk);
268+
funcRef = (FARPROC *)CALCULATE_ADDRESS(codeBase, importDesc->FirstThunk);
250269
} else {
251270
// no hint table
252-
thunkRef = (DWORD *)CALCULATE_ADDRESS(codeBase, importDesc->FirstThunk);
253-
funcRef = (DWORD *)CALCULATE_ADDRESS(codeBase, importDesc->FirstThunk);
271+
thunkRef = (POINTER_TYPE *)CALCULATE_ADDRESS(codeBase, importDesc->FirstThunk);
272+
funcRef = (FARPROC *)CALCULATE_ADDRESS(codeBase, importDesc->FirstThunk);
254273
}
255274
for (; *thunkRef; thunkRef++, funcRef++)
256275
{
257276
if IMAGE_SNAP_BY_ORDINAL(*thunkRef)
258-
*funcRef = (DWORD)GetProcAddress(handle, (LPCSTR)IMAGE_ORDINAL(*thunkRef));
277+
*funcRef = (FARPROC)GetProcAddress(handle, (LPCSTR)IMAGE_ORDINAL(*thunkRef));
259278
else {
260279
PIMAGE_IMPORT_BY_NAME thunkData = (PIMAGE_IMPORT_BY_NAME)CALCULATE_ADDRESS(codeBase, *thunkRef);
261-
*funcRef = (DWORD)GetProcAddress(handle, (LPCSTR)&thunkData->Name);
280+
*funcRef = (FARPROC)GetProcAddress(handle, (LPCSTR)&thunkData->Name);
262281
}
263282
if (*funcRef == 0)
264283
{
@@ -281,7 +300,7 @@ HMEMORYMODULE MemoryLoadLibrary(const void *data)
281300
PIMAGE_DOS_HEADER dos_header;
282301
PIMAGE_NT_HEADERS old_header;
283302
unsigned char *code, *headers;
284-
DWORD locationDelta;
303+
SIZE_T locationDelta;
285304
DllEntryProc DllEntry;
286305
BOOL successfull;
287306

@@ -348,13 +367,13 @@ HMEMORYMODULE MemoryLoadLibrary(const void *data)
348367
result->headers = (PIMAGE_NT_HEADERS)&((const unsigned char *)(headers))[dos_header->e_lfanew];
349368

350369
// update position
351-
result->headers->OptionalHeader.ImageBase = (DWORD)code;
370+
result->headers->OptionalHeader.ImageBase = (POINTER_TYPE)code;
352371

353372
// copy sections from DLL file block to new memory location
354373
CopySections(data, old_header, result);
355374

356375
// adjust base address of imported data
357-
locationDelta = (DWORD)(code - old_header->OptionalHeader.ImageBase);
376+
locationDelta = (SIZE_T)(code - old_header->OptionalHeader.ImageBase);
358377
if (locationDelta != 0)
359378
PerformBaseRelocation(result, locationDelta);
360379

0 commit comments

Comments
 (0)