ReactOS 0.4.15-dev-7942-gd23573b
image.c File Reference
#include <rtl.h>
#include <debug.h>
Include dependency graph for image.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define RVA(m, b)   ((PVOID)((ULONG_PTR)(b) + (ULONG_PTR)(m)))
 

Functions

FORCEINLINE USHORT ChkSum (ULONG Sum, PUSHORT Src, ULONG Len)
 
BOOLEAN NTAPI LdrVerifyMappedImageMatchesChecksum (IN PVOID BaseAddress, IN SIZE_T ImageSize, IN ULONG FileLength)
 
NTSTATUS NTAPI RtlpImageNtHeaderEx (_In_ ULONG Flags, _In_ PVOID Base, _In_ ULONG64 Size, _Out_ PIMAGE_NT_HEADERS *OutHeaders)
 
PIMAGE_NT_HEADERS NTAPI RtlImageNtHeader (IN PVOID Base)
 
PVOID NTAPI RtlImageDirectoryEntryToData (PVOID BaseAddress, BOOLEAN MappedAsImage, USHORT Directory, PULONG Size)
 
PIMAGE_SECTION_HEADER NTAPI RtlImageRvaToSection (PIMAGE_NT_HEADERS NtHeader, PVOID BaseAddress, ULONG Rva)
 
PVOID NTAPI RtlImageRvaToVa (PIMAGE_NT_HEADERS NtHeader, PVOID BaseAddress, ULONG Rva, PIMAGE_SECTION_HEADER *SectionHeader)
 
PIMAGE_BASE_RELOCATION NTAPI LdrProcessRelocationBlockLongLong (IN ULONG_PTR Address, IN ULONG Count, IN PUSHORT TypeOffset, IN LONGLONG Delta)
 
ULONG NTAPI LdrRelocateImage (_In_ PVOID BaseAddress, _In_opt_ PCSTR LoaderName, _In_ ULONG Success, _In_ ULONG Conflict, _In_ ULONG Invalid)
 
ULONG NTAPI LdrRelocateImageWithBias (_In_ PVOID BaseAddress, _In_ LONGLONG AdditionalBias, _In_opt_ PCSTR LoaderName, _In_ ULONG Success, _In_ ULONG Conflict, _In_ ULONG Invalid)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 17 of file image.c.

◆ RVA

#define RVA (   m,
  b 
)    ((PVOID)((ULONG_PTR)(b) + (ULONG_PTR)(m)))

Definition at line 20 of file image.c.

Function Documentation

◆ ChkSum()

FORCEINLINE USHORT ChkSum ( ULONG  Sum,
PUSHORT  Src,
ULONG  Len 
)

Definition at line 26 of file image.c.

27{
28 ULONG i;
29
30 for (i=0; i<Len; i++)
31 {
32 /* Sum up the current word */
33 Sum += Src[i];
34
35 /* Sum up everything above the low word as a carry */
36 Sum = (Sum & 0xFFFF) + (Sum >> 16);
37 }
38
39 /* Apply carry one more time and clamp to the USHORT */
40 return (Sum + (Sum >> 16)) & 0xFFFF;
41}
#define Len
Definition: deflate.h:82
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
uint32_t ULONG
Definition: typedefs.h:59

◆ LdrProcessRelocationBlockLongLong()

PIMAGE_BASE_RELOCATION NTAPI LdrProcessRelocationBlockLongLong ( IN ULONG_PTR  Address,
IN ULONG  Count,
IN PUSHORT  TypeOffset,
IN LONGLONG  Delta 
)

Definition at line 392 of file image.c.

397{
399 USHORT Type;
400 ULONG i;
401 PUSHORT ShortPtr;
402 PULONG LongPtr;
403 PULONGLONG LongLongPtr;
404
405 for (i = 0; i < Count; i++)
406 {
407 Offset = SWAPW(*TypeOffset) & 0xFFF;
408 Type = SWAPW(*TypeOffset) >> 12;
409 ShortPtr = (PUSHORT)(RVA(Address, Offset));
410 /*
411 * Don't relocate within the relocation section itself.
412 * GCC/LD generates sometimes relocation records for the relocation section.
413 * This is a bug in GCC/LD.
414 * Fix for it disabled, since it was only in ntoskrnl and not in ntdll
415 */
416 /*
417 if ((ULONG_PTR)ShortPtr < (ULONG_PTR)RelocationDir ||
418 (ULONG_PTR)ShortPtr >= (ULONG_PTR)RelocationEnd)
419 {*/
420 switch (Type)
421 {
422 /* case IMAGE_REL_BASED_SECTION : */
423 /* case IMAGE_REL_BASED_REL32 : */
425 break;
426
428 *ShortPtr = HIWORD(MAKELONG(0, *ShortPtr) + (Delta & 0xFFFFFFFF));
429 break;
430
432 *ShortPtr = SWAPW(*ShortPtr) + LOWORD(Delta & 0xFFFF);
433 break;
434
436 LongPtr = (PULONG)RVA(Address, Offset);
437 *LongPtr = SWAPD(*LongPtr) + (Delta & 0xFFFFFFFF);
438 break;
439
441 LongLongPtr = (PUINT64)RVA(Address, Offset);
442 *LongLongPtr = SWAPQ(*LongLongPtr) + Delta;
443 break;
444
447 default:
448 DPRINT1("Unknown/unsupported fixup type %hu.\n", Type);
449 DPRINT1("Address %p, Current %u, Count %u, *TypeOffset %x\n",
450 (PVOID)Address, i, Count, SWAPW(*TypeOffset));
452 }
453
454 TypeOffset++;
455 }
456
457 return (PIMAGE_BASE_RELOCATION)TypeOffset;
458}
Type
Definition: Type.h:7
#define DPRINT1
Definition: precomp.h:8
unsigned __int64 * PUINT64
Definition: basetsd.h:187
#define SWAPD(x)
Definition: bytesex.h:7
#define SWAPW(x)
Definition: bytesex.h:8
#define NULL
Definition: types.h:112
int Count
Definition: noreturn.cpp:7
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define LOWORD(l)
Definition: pedump.c:82
short SHORT
Definition: pedump.c:59
unsigned short USHORT
Definition: pedump.c:61
static WCHAR Address[46]
Definition: ping.c:68
#define SWAPQ(x)
Definition: rtlp.h:26
#define RVA(m, b)
Definition: image.c:20
uint32_t * PULONG
Definition: typedefs.h:59
uint16_t * PUSHORT
Definition: typedefs.h:56
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define HIWORD(l)
Definition: typedefs.h:247
#define IMAGE_REL_BASED_HIGHLOW
Definition: winnt_old.h:852
#define IMAGE_REL_BASED_DIR64
Definition: winnt_old.h:857
#define IMAGE_REL_BASED_HIGH
Definition: winnt_old.h:850
#define IMAGE_REL_BASED_MIPS_JMPADDR
Definition: winnt_old.h:854
#define IMAGE_REL_BASED_HIGHADJ
Definition: winnt_old.h:853
#define IMAGE_REL_BASED_ABSOLUTE
Definition: winnt_old.h:849
#define IMAGE_REL_BASED_LOW
Definition: winnt_old.h:851
static ULONG Delta
Definition: xboxvideo.c:33

Referenced by LdrRelocateImageWithBias().

◆ LdrRelocateImage()

ULONG NTAPI LdrRelocateImage ( _In_ PVOID  BaseAddress,
_In_opt_ PCSTR  LoaderName,
_In_ ULONG  Success,
_In_ ULONG  Conflict,
_In_ ULONG  Invalid 
)

Definition at line 462 of file image.c.

468{
469 return LdrRelocateImageWithBias(BaseAddress, 0, LoaderName, Success, Conflict, Invalid);
470}
@ Invalid
Definition: asmpp.cpp:30
@ Success
Definition: eventcreate.c:712
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
ULONG NTAPI LdrRelocateImageWithBias(_In_ PVOID BaseAddress, _In_ LONGLONG AdditionalBias, _In_opt_ PCSTR LoaderName, _In_ ULONG Success, _In_ ULONG Conflict, _In_ ULONG Invalid)
Definition: image.c:474

Referenced by ImgpLoadPEImage().

◆ LdrRelocateImageWithBias()

ULONG NTAPI LdrRelocateImageWithBias ( _In_ PVOID  BaseAddress,
_In_ LONGLONG  AdditionalBias,
_In_opt_ PCSTR  LoaderName,
_In_ ULONG  Success,
_In_ ULONG  Conflict,
_In_ ULONG  Invalid 
)

Definition at line 474 of file image.c.

481{
482 PIMAGE_NT_HEADERS NtHeaders;
483 PIMAGE_DATA_DIRECTORY RelocationDDir;
484 PIMAGE_BASE_RELOCATION RelocationDir, RelocationEnd;
485 ULONG Count;
487 PUSHORT TypeOffset;
489
490 UNREFERENCED_PARAMETER(LoaderName);
491
492 NtHeaders = RtlImageNtHeader(BaseAddress);
493
494 if (NtHeaders == NULL)
495 return Invalid;
496
498 {
499 return Conflict;
500 }
501
503
504 if (SWAPD(RelocationDDir->VirtualAddress) == 0 || SWAPD(RelocationDDir->Size) == 0)
505 {
506 return Success;
507 }
508
509 Delta = (ULONG_PTR)BaseAddress - SWAPD(NtHeaders->OptionalHeader.ImageBase) + AdditionalBias;
510 RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)BaseAddress + SWAPD(RelocationDDir->VirtualAddress));
511 RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + SWAPD(RelocationDDir->Size));
512
513 while (RelocationDir < RelocationEnd &&
514 SWAPW(RelocationDir->SizeOfBlock) > 0)
515 {
516 Count = (SWAPW(RelocationDir->SizeOfBlock) - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
518 TypeOffset = (PUSHORT)(RelocationDir + 1);
519
521 Count,
522 TypeOffset,
523 Delta);
524
525 if (RelocationDir == NULL)
526 {
527 DPRINT1("Error during call to LdrProcessRelocationBlockLongLong()!\n");
528 return Invalid;
529 }
530 }
531
532 return Success;
533}
#define RtlImageNtHeader
Definition: compat.h:806
#define ULONG_PTR
Definition: config.h:101
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
struct _IMAGE_BASE_RELOCATION * PIMAGE_BASE_RELOCATION
struct _IMAGE_BASE_RELOCATION IMAGE_BASE_RELOCATION
#define IMAGE_DIRECTORY_ENTRY_BASERELOC
Definition: pedump.c:264
#define IMAGE_FILE_RELOCS_STRIPPED
Definition: pedump.c:159
PIMAGE_BASE_RELOCATION NTAPI LdrProcessRelocationBlockLongLong(IN ULONG_PTR Address, IN ULONG Count, IN PUSHORT TypeOffset, IN LONGLONG Delta)
Definition: image.c:392
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntddk_ex.h:178
int64_t LONGLONG
Definition: typedefs.h:68
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by LdrpInitializeProcess(), LdrpMapDll(), LdrRelocateImage(), LoadBootDeviceDriver(), MiReloadBootLoadedDrivers(), MmLoadSystemImage(), and PeLdrLoadImage().

◆ LdrVerifyMappedImageMatchesChecksum()

BOOLEAN NTAPI LdrVerifyMappedImageMatchesChecksum ( IN PVOID  BaseAddress,
IN SIZE_T  ImageSize,
IN ULONG  FileLength 
)

Definition at line 45 of file image.c.

49{
50#if 0
53 ULONG Sum;
54 ULONG CalcSum;
55 ULONG HeaderSum;
56 ULONG i;
57
58 // HACK: Ignore calls with ImageSize=0. Should be fixed by new MM.
59 if (ImageSize == 0) return TRUE;
60
61 /* Get NT header to check if it's an image at all */
63 if (!Header) return FALSE;
64
65 /* Get checksum to match */
66 HeaderSum = Header->OptionalHeader.CheckSum;
67
68 /* Zero checksum seems to be accepted */
69 if (HeaderSum == 0) return TRUE;
70
71 /* Calculate the checksum */
72 Sum = 0;
74 for (i = 0; i < ImageSize / sizeof (USHORT); i++)
75 {
76 Sum += (ULONG)*Ptr;
77 if (HIWORD(Sum) != 0)
78 {
79 Sum = LOWORD(Sum) + HIWORD(Sum);
80 }
81 Ptr++;
82 }
83
84 if (ImageSize & 1)
85 {
86 Sum += (ULONG)*((PUCHAR)Ptr);
87 if (HIWORD(Sum) != 0)
88 {
89 Sum = LOWORD(Sum) + HIWORD(Sum);
90 }
91 }
92
93 CalcSum = (USHORT)(LOWORD(Sum) + HIWORD(Sum));
94
95 /* Subtract image checksum from calculated checksum. */
96 /* fix low word of checksum */
97 if (LOWORD(CalcSum) >= LOWORD(HeaderSum))
98 {
99 CalcSum -= LOWORD(HeaderSum);
100 }
101 else
102 {
103 CalcSum = ((LOWORD(CalcSum) - LOWORD(HeaderSum)) & 0xFFFF) - 1;
104 }
105
106 /* Fix high word of checksum */
107 if (LOWORD(CalcSum) >= HIWORD(HeaderSum))
108 {
109 CalcSum -= HIWORD(HeaderSum);
110 }
111 else
112 {
113 CalcSum = ((LOWORD(CalcSum) - HIWORD(HeaderSum)) & 0xFFFF) - 1;
114 }
115
116 /* Add file length */
117 CalcSum += ImageSize;
118
119 if (CalcSum != HeaderSum)
120 DPRINT1("Image %p checksum mismatches! 0x%x != 0x%x, ImageSize %x, FileLen %x\n", BaseAddress, CalcSum, HeaderSum, ImageSize, FileLength);
121
122 return (BOOLEAN)(CalcSum == HeaderSum);
123#else
124 /*
125 * FIXME: Warning, this violates the PE standard and makes ReactOS drivers
126 * and other system code when normally on Windows they would not, since
127 * we do not write the checksum in them.
128 * Our compilers should be made to write out the checksum and this function
129 * should be enabled as to reject badly checksummed code.
130 */
131 return TRUE;
132#endif
133}
unsigned char BOOLEAN
Definition: Header.h:9
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
_Out_ PNDIS_HANDLE _Out_ PUINT FileLength
Definition: ndis.h:3228
unsigned char * PUCHAR
Definition: typedefs.h:53

◆ RtlImageDirectoryEntryToData()

PVOID NTAPI RtlImageDirectoryEntryToData ( PVOID  BaseAddress,
BOOLEAN  MappedAsImage,
USHORT  Directory,
PULONG  Size 
)

Definition at line 272 of file image.c.

277{
278 PIMAGE_NT_HEADERS NtHeader;
279 ULONG Va;
280
281 /* Magic flag for non-mapped images. */
282 if ((ULONG_PTR)BaseAddress & 1)
283 {
286 }
287
288 NtHeader = RtlImageNtHeader(BaseAddress);
289 if (NtHeader == NULL)
290 return NULL;
291
293 {
295
296 if (Directory >= SWAPD(OptionalHeader->NumberOfRvaAndSizes))
297 return NULL;
298
299 Va = SWAPD(OptionalHeader->DataDirectory[Directory].VirtualAddress);
300 if (Va == 0)
301 return NULL;
302
303 *Size = SWAPD(OptionalHeader->DataDirectory[Directory].Size);
304
305 if (MappedAsImage || Va < SWAPD(OptionalHeader->SizeOfHeaders))
306 return (PVOID)((ULONG_PTR)BaseAddress + Va);
307 }
308 else
309 {
311
312 if (Directory >= SWAPD(OptionalHeader->NumberOfRvaAndSizes))
313 return NULL;
314
315 Va = SWAPD(OptionalHeader->DataDirectory[Directory].VirtualAddress);
316 if (Va == 0)
317 return NULL;
318
319 *Size = SWAPD(OptionalHeader->DataDirectory[Directory].Size);
320
321 if (MappedAsImage || Va < SWAPD(OptionalHeader->SizeOfHeaders))
322 return (PVOID)((ULONG_PTR)BaseAddress + Va);
323 }
324
325 /* Image mapped as ordinary file, we must find raw pointer */
326 return RtlImageRvaToVa(NtHeader, BaseAddress, Va, NULL);
327}
#define RtlImageRvaToVa
Definition: compat.h:807
struct _IMAGE_OPTIONAL_HEADER * PIMAGE_OPTIONAL_HEADER32
if(dx< 0)
Definition: linetemp.h:194
_In_ BOOLEAN MappedAsImage
Definition: rtlfuncs.h:3938
struct _IMAGE_OPTIONAL_HEADER64 * PIMAGE_OPTIONAL_HEADER64
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC
Definition: ntimage.h:377
base for all directory entries
Definition: entries.h:138
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntimage.h:370
void * PVOID
Definition: typedefs.h:50
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533

◆ RtlImageNtHeader()

PIMAGE_NT_HEADERS NTAPI RtlImageNtHeader ( IN PVOID  Base)

Definition at line 255 of file image.c.

256{
257 PIMAGE_NT_HEADERS NtHeader;
258
259 /* Call the new API */
261 Base,
262 0,
263 &NtHeader);
264 return NtHeader;
265}
NTSTATUS NTAPI RtlImageNtHeaderEx(_In_ ULONG Flags, _In_ PVOID Base, _In_ ULONG64 Size, _Out_ PIMAGE_NT_HEADERS *OutHeaders)
Definition: libsupp.c:32
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2439
#define RTL_IMAGE_NT_HEADER_EX_FLAG_NO_RANGE_CHECK
Definition: rtltypes.h:358

◆ RtlImageRvaToSection()

PIMAGE_SECTION_HEADER NTAPI RtlImageRvaToSection ( PIMAGE_NT_HEADERS  NtHeader,
PVOID  BaseAddress,
ULONG  Rva 
)

Definition at line 334 of file image.c.

338{
339 PIMAGE_SECTION_HEADER Section;
340 ULONG Va;
341 ULONG Count;
342
344 Section = IMAGE_FIRST_SECTION(NtHeader);
345
346 while (Count--)
347 {
348 Va = SWAPD(Section->VirtualAddress);
349 if ((Va <= Rva) && (Rva < Va + SWAPD(Section->SizeOfRawData)))
350 return Section;
351 Section++;
352 }
353
354 return NULL;
355}
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427

◆ RtlImageRvaToVa()

PVOID NTAPI RtlImageRvaToVa ( PIMAGE_NT_HEADERS  NtHeader,
PVOID  BaseAddress,
ULONG  Rva,
PIMAGE_SECTION_HEADER SectionHeader 
)

Definition at line 362 of file image.c.

367{
368 PIMAGE_SECTION_HEADER Section = NULL;
369
370 if (SectionHeader)
371 Section = *SectionHeader;
372
373 if ((Section == NULL) ||
374 (Rva < SWAPD(Section->VirtualAddress)) ||
375 (Rva >= SWAPD(Section->VirtualAddress) + SWAPD(Section->SizeOfRawData)))
376 {
377 Section = RtlImageRvaToSection(NtHeader, BaseAddress, Rva);
378 if (Section == NULL)
379 return NULL;
380
381 if (SectionHeader)
382 *SectionHeader = Section;
383 }
384
385 return (PVOID)((ULONG_PTR)BaseAddress + Rva +
386 (ULONG_PTR)SWAPD(Section->PointerToRawData) -
387 (ULONG_PTR)SWAPD(Section->VirtualAddress));
388}
#define RtlImageRvaToSection
Definition: compat.h:808
DWORD PointerToRawData
Definition: pedump.c:290

◆ RtlpImageNtHeaderEx()

NTSTATUS NTAPI RtlpImageNtHeaderEx ( _In_ ULONG  Flags,
_In_ PVOID  Base,
_In_ ULONG64  Size,
_Out_ PIMAGE_NT_HEADERS OutHeaders 
)

Definition at line 140 of file image.c.

145{
146 PIMAGE_NT_HEADERS NtHeaders;
147 PIMAGE_DOS_HEADER DosHeader;
148 BOOLEAN WantsRangeCheck;
149 ULONG NtHeaderOffset;
150
151 /* You must want NT Headers, no? */
152 if (OutHeaders == NULL)
153 {
154 DPRINT1("OutHeaders is NULL\n");
156 }
157
158 /* Assume failure */
159 *OutHeaders = NULL;
160
161 /* Validate Flags */
163 {
164 DPRINT1("Invalid flags: 0x%lx\n", Flags);
166 }
167
168 /* Validate base */
169 if ((Base == NULL) || (Base == (PVOID)-1))
170 {
171 DPRINT1("Invalid base address: %p\n", Base);
173 }
174
175 /* Check if the caller wants range checks */
177 if (WantsRangeCheck)
178 {
179 /* Make sure the image size is at least big enough for the DOS header */
180 if (Size < sizeof(IMAGE_DOS_HEADER))
181 {
182 DPRINT1("Size too small\n");
184 }
185 }
186
187 /* Check if the DOS Signature matches */
188 DosHeader = Base;
189 if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE)
190 {
191 /* Not a valid COFF */
192 DPRINT1("Invalid image DOS signature!\n");
194 }
195
196 /* Get the offset to the NT headers (and copy from LONG to ULONG) */
197 NtHeaderOffset = DosHeader->e_lfanew;
198
199 /* The offset must not be larger than 256MB, as a hard-coded check.
200 In Windows this check is only done in user mode, not in kernel mode,
201 but it shouldn't harm to have it anyway. Note that without this check,
202 other overflow checks would become necessary! */
203 if (NtHeaderOffset >= (256 * 1024 * 1024))
204 {
205 /* Fail */
206 DPRINT1("NT headers offset is larger than 256MB!\n");
208 }
209
210 /* Check if the caller wants validation */
211 if (WantsRangeCheck)
212 {
213 /* Make sure the file header fits into the size */
214 if ((NtHeaderOffset +
216 {
217 /* Fail */
218 DPRINT1("NT headers beyond image size!\n");
220 }
221 }
222
223 /* Now get a pointer to the NT Headers */
224 NtHeaders = (PIMAGE_NT_HEADERS)((ULONG_PTR)Base + NtHeaderOffset);
225
226 /* Check if the mapping is in user space */
228 {
229 /* Make sure we don't overflow into kernel space */
230 if ((PVOID)(NtHeaders + 1) > MmHighestUserAddress)
231 {
232 DPRINT1("Image overflows from user space into kernel space!\n");
234 }
235 }
236
237 /* Verify the PE Signature */
238 if (NtHeaders->Signature != IMAGE_NT_SIGNATURE)
239 {
240 /* Fail */
241 DPRINT1("Invalid image NT signature!\n");
243 }
244
245 /* Now return success and the NT header */
246 *OutHeaders = NtHeaders;
247 return STATUS_SUCCESS;
248}
PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS
Definition: ntddk_ex.h:187
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:672
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
#define IMAGE_NT_SIGNATURE
Definition: pedump.c:93
#define IMAGE_DOS_SIGNATURE
Definition: pedump.c:89
PVOID MmHighestUserAddress
Definition: rtlcompat.c:29
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by RtlImageNtHeaderEx().