ReactOS  0.4.15-dev-3207-ga415bd4
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 PCCH LoaderName, IN ULONG Success, IN ULONG Conflict, IN ULONG Invalid)
 
ULONG NTAPI LdrRelocateImageWithBias (IN PVOID BaseAddress, IN LONGLONG AdditionalBias, IN PCCH 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
unsigned int ULONG
Definition: retypes.h:1

◆ 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 {
398  SHORT Offset;
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 
431  case IMAGE_REL_BASED_LOW:
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 }
#define IMAGE_REL_BASED_DIR64
Definition: winnt_old.h:891
#define SWAPW(x)
Definition: bytesex.h:8
#define SWAPD(x)
Definition: bytesex.h:7
#define IMAGE_REL_BASED_HIGHLOW
Definition: winnt_old.h:886
#define IMAGE_REL_BASED_ABSOLUTE
Definition: winnt_old.h:883
short SHORT
Definition: pedump.c:59
#define IMAGE_REL_BASED_MIPS_JMPADDR
Definition: winnt_old.h:888
#define IMAGE_REL_BASED_LOW
Definition: winnt_old.h:885
#define MAKELONG(a, b)
Definition: typedefs.h:249
static WCHAR Address[46]
Definition: ping.c:68
#define IMAGE_REL_BASED_HIGHADJ
Definition: winnt_old.h:887
#define SWAPQ(x)
Definition: rtlp.h:26
int Count
Definition: noreturn.cpp:7
Type
Definition: Type.h:6
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define IMAGE_REL_BASED_HIGH
Definition: winnt_old.h:884
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
unsigned short USHORT
Definition: pedump.c:61
static ULONG Delta
Definition: xboxvideo.c:33
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
#define HIWORD(l)
Definition: typedefs.h:247
unsigned int ULONG
Definition: retypes.h:1
#define RVA(m, b)
Definition: image.c:20
#define LOWORD(l)
Definition: pedump.c:82
unsigned short * PUSHORT
Definition: retypes.h:2
unsigned __int64 * PUINT64
Definition: basetsd.h:189

Referenced by LdrRelocateImageWithBias().

◆ LdrRelocateImage()

ULONG NTAPI LdrRelocateImage ( IN PVOID  BaseAddress,
IN PCCH  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 }
ULONG NTAPI LdrRelocateImageWithBias(IN PVOID BaseAddress, IN LONGLONG AdditionalBias, IN PCCH LoaderName, IN ULONG Success, IN ULONG Conflict, IN ULONG Invalid)
Definition: image.c:474
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404

Referenced by ImgpLoadPEImage().

◆ LdrRelocateImageWithBias()

ULONG NTAPI LdrRelocateImageWithBias ( IN PVOID  BaseAddress,
IN LONGLONG  AdditionalBias,
IN PCCH  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;
488  LONGLONG Delta;
489 
490  NtHeaders = RtlImageNtHeader(BaseAddress);
491 
492  if (NtHeaders == NULL)
493  return Invalid;
494 
496  {
497  return Conflict;
498  }
499 
500  RelocationDDir = &NtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
501 
502  if (SWAPD(RelocationDDir->VirtualAddress) == 0 || SWAPD(RelocationDDir->Size) == 0)
503  {
504  return Success;
505  }
506 
507  Delta = (ULONG_PTR)BaseAddress - SWAPD(NtHeaders->OptionalHeader.ImageBase) + AdditionalBias;
508  RelocationDir = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)BaseAddress + SWAPD(RelocationDDir->VirtualAddress));
509  RelocationEnd = (PIMAGE_BASE_RELOCATION)((ULONG_PTR)RelocationDir + SWAPD(RelocationDDir->Size));
510 
511  while (RelocationDir < RelocationEnd &&
512  SWAPW(RelocationDir->SizeOfBlock) > 0)
513  {
514  Count = (SWAPW(RelocationDir->SizeOfBlock) - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(USHORT);
515  Address = (ULONG_PTR)RVA(BaseAddress, SWAPD(RelocationDir->VirtualAddress));
516  TypeOffset = (PUSHORT)(RelocationDir + 1);
517 
519  Count,
520  TypeOffset,
521  Delta);
522 
523  if (RelocationDir == NULL)
524  {
525  DPRINT1("Error during call to LdrProcessRelocationBlockLongLong()!\n");
526  return Invalid;
527  }
528  }
529 
530  return Success;
531 }
PIMAGE_BASE_RELOCATION NTAPI LdrProcessRelocationBlockLongLong(IN ULONG_PTR Address, IN ULONG Count, IN PUSHORT TypeOffset, IN LONGLONG Delta)
Definition: image.c:392
struct _IMAGE_BASE_RELOCATION * PIMAGE_BASE_RELOCATION
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntddk_ex.h:178
#define SWAPW(x)
Definition: bytesex.h:8
#define SWAPD(x)
Definition: bytesex.h:7
struct _IMAGE_BASE_RELOCATION IMAGE_BASE_RELOCATION
uint32_t ULONG_PTR
Definition: typedefs.h:65
static WCHAR Address[46]
Definition: ping.c:68
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
int64_t LONGLONG
Definition: typedefs.h:68
int Count
Definition: noreturn.cpp:7
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
PIMAGE_NT_HEADERS NTAPI RtlImageNtHeader(IN PVOID Base)
Definition: image.c:255
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
unsigned short USHORT
Definition: pedump.c:61
static ULONG Delta
Definition: xboxvideo.c:33
#define NULL
Definition: types.h:112
#define IMAGE_DIRECTORY_ENTRY_BASERELOC
Definition: pedump.c:264
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define IMAGE_FILE_RELOCS_STRIPPED
Definition: pedump.c:159
#define ULONG_PTR
Definition: config.h:101
#define RVA(m, b)
Definition: image.c:20
unsigned short * PUSHORT
Definition: retypes.h:2

Referenced by LdrRelocateImage().

◆ 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
52  PUSHORT Ptr;
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 }
_Out_ PNDIS_HANDLE _Out_ PUINT FileLength
Definition: ndis.h:3227
#define TRUE
Definition: types.h:120
unsigned char * PUCHAR
Definition: retypes.h:3
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
#define FALSE
Definition: types.h:117
Definition: Header.h:8
unsigned char BOOLEAN
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
PIMAGE_NT_HEADERS NTAPI RtlImageNtHeader(IN PVOID Base)
Definition: image.c:255
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
unsigned short USHORT
Definition: pedump.c:61
#define DPRINT1
Definition: precomp.h:8
#define HIWORD(l)
Definition: typedefs.h:247
unsigned int ULONG
Definition: retypes.h:1
#define LOWORD(l)
Definition: pedump.c:82
unsigned short * PUSHORT
Definition: retypes.h:2

◆ 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 }
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntddk_ex.h:178
#define SWAPD(x)
Definition: bytesex.h:7
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
PVOID NTAPI RtlImageRvaToVa(PIMAGE_NT_HEADERS NtHeader, PVOID BaseAddress, ULONG Rva, PIMAGE_SECTION_HEADER *SectionHeader)
Definition: image.c:362
if(dx==0 &&dy==0)
Definition: linetemp.h:174
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define FALSE
Definition: types.h:117
_In_ BOOLEAN MappedAsImage
Definition: rtlfuncs.h:3885
void * PVOID
Definition: retypes.h:9
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC
Definition: ntimage.h:377
PIMAGE_NT_HEADERS NTAPI RtlImageNtHeader(IN PVOID Base)
Definition: image.c:255
struct _IMAGE_OPTIONAL_HEADER * PIMAGE_OPTIONAL_HEADER32
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
#define NULL
Definition: types.h:112
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]
Definition: ntimage.h:370
struct _IMAGE_OPTIONAL_HEADER64 * PIMAGE_OPTIONAL_HEADER64
unsigned int ULONG
Definition: retypes.h:1
base for all directory entries
Definition: entries.h:138
#define ULONG_PTR
Definition: config.h:101

◆ 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 }
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2386
NTSTATUS NTAPI RtlImageNtHeaderEx(_In_ ULONG Flags, _In_ PVOID Base, _In_ ULONG64 Size, _Out_ PIMAGE_NT_HEADERS *OutHeaders)
Definition: libsupp.c:32
#define RTL_IMAGE_NT_HEADER_EX_FLAG_NO_RANGE_CHECK
Definition: rtltypes.h:356

Referenced by GetTimestampForLoadedLibrary(), LdrRelocateImageWithBias(), LdrVerifyMappedImageMatchesChecksum(), and RtlImageDirectoryEntryToData().

◆ 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 
343  Count = SWAPW(NtHeader->FileHeader.NumberOfSections);
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 SWAPW(x)
Definition: bytesex.h:8
#define SWAPD(x)
Definition: bytesex.h:7
#define IMAGE_FIRST_SECTION(NtHeader)
Definition: ntimage.h:427
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
int Count
Definition: noreturn.cpp:7
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1

Referenced by RtlImageRvaToVa().

◆ 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 SWAPD(x)
Definition: bytesex.h:7
DWORD PointerToRawData
Definition: pedump.c:290
uint32_t ULONG_PTR
Definition: typedefs.h:65
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
PIMAGE_SECTION_HEADER NTAPI RtlImageRvaToSection(PIMAGE_NT_HEADERS NtHeader, PVOID BaseAddress, ULONG Rva)
Definition: image.c:334
#define NULL
Definition: types.h:112
#define ULONG_PTR
Definition: config.h:101

Referenced by RtlImageDirectoryEntryToData().

◆ 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 */
176  WantsRangeCheck = !(Flags & RTL_IMAGE_NT_HEADER_EX_FLAG_NO_RANGE_CHECK);
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 */
227  if (Base <= MmHighestUserAddress)
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 }
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2386
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:361
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IMAGE_DOS_SIGNATURE
Definition: pedump.c:89
unsigned char BOOLEAN
#define IMAGE_NT_SIGNATURE
Definition: pedump.c:93
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:359
#define RTL_IMAGE_NT_HEADER_EX_FLAG_NO_RANGE_CHECK
Definition: rtltypes.h:356
#define RTL_SIZEOF_THROUGH_FIELD(type, field)
Definition: ntbasedef.h:672
#define NULL
Definition: types.h:112
PVOID MmHighestUserAddress
Definition: rtlcompat.c:29
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_SUCCESS
Definition: shellext.h:65
PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS
Definition: ntddk_ex.h:187

Referenced by RtlImageNtHeaderEx().