00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
#include "ntrtlp.h"
00027
00028 PIMAGE_NT_HEADERS
00029 RtlImageNtHeader (
00030 IN PVOID Base
00031 )
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 {
00050
#if defined (BLDR_KERNEL_RUNTIME) || defined(NTOS_KERNEL_RUNTIME)
00051
PIMAGE_NT_HEADERS NtHeaders =
NULL;
00052
00053
if (Base !=
NULL && Base != (PVOID)-1) {
00054
if (((PIMAGE_DOS_HEADER)Base)->e_magic == IMAGE_DOS_SIGNATURE) {
00055 NtHeaders = (PIMAGE_NT_HEADERS)((PCHAR)Base + ((PIMAGE_DOS_HEADER)Base)->e_lfanew);
00056
00057
#if defined(NTOS_KERNEL_RUNTIME)
00058
if (Base < MM_HIGHEST_USER_ADDRESS) {
00059
if ((PVOID)NtHeaders >= MM_HIGHEST_USER_ADDRESS) {
00060
return NULL;
00061 }
00062
if ((PVOID)((PCHAR)NtHeaders +
sizeof (IMAGE_NT_HEADERS)) >= MM_HIGHEST_USER_ADDRESS) {
00063
return NULL;
00064 }
00065 }
00066
#endif
00067
00068
if (NtHeaders->Signature != IMAGE_NT_SIGNATURE) {
00069 NtHeaders =
NULL;
00070 }
00071 }
00072 }
00073
00074
return NtHeaders;
00075
#else
00076
return RtlpImageNtHeader( Base );
00077
#endif
00078
}
00079
00080
00081 PIMAGE_SECTION_HEADER
00082 RtlSectionTableFromVirtualAddress (
00083 IN PIMAGE_NT_HEADERS NtHeaders,
00084 IN PVOID Base,
00085 IN ULONG Address
00086 )
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112 {
00113 ULONG i;
00114 PIMAGE_SECTION_HEADER NtSection;
00115
00116 NtSection = IMAGE_FIRST_SECTION( NtHeaders );
00117
for (i=0; i<NtHeaders->FileHeader.NumberOfSections; i++) {
00118
if ((ULONG)Address >= NtSection->VirtualAddress &&
00119 (ULONG)Address < NtSection->VirtualAddress + NtSection->SizeOfRawData
00120 ) {
00121
return NtSection;
00122 }
00123 ++NtSection;
00124 }
00125
00126
return NULL;
00127 }
00128
00129
00130 PVOID
00131 RtlAddressInSectionTable (
00132 IN PIMAGE_NT_HEADERS NtHeaders,
00133 IN PVOID Base,
00134 IN ULONG Address
00135 )
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 {
00162 PIMAGE_SECTION_HEADER NtSection;
00163
00164 NtSection =
RtlSectionTableFromVirtualAddress( NtHeaders,
00165 Base,
00166 Address
00167 );
00168
if (NtSection !=
NULL) {
00169
return( ((PCHAR)Base + ((ULONG_PTR)Address - NtSection->VirtualAddress) + NtSection->PointerToRawData) );
00170 }
00171
else {
00172
return(
NULL );
00173 }
00174 }
00175
00176
00177 PVOID
00178 RtlpImageDirectoryEntryToData32 (
00179 IN PVOID Base,
00180 IN BOOLEAN MappedAsImage,
00181 IN USHORT DirectoryEntry,
00182 OUT PULONG Size,
00183 PIMAGE_NT_HEADERS32 NtHeaders
00184 )
00185 {
00186 ULONG DirectoryAddress;
00187
00188
if (DirectoryEntry >= NtHeaders->OptionalHeader.NumberOfRvaAndSizes) {
00189
return(
NULL );
00190 }
00191
00192
if (!(DirectoryAddress = NtHeaders->OptionalHeader.DataDirectory[ DirectoryEntry ].VirtualAddress)) {
00193
return(
NULL );
00194 }
00195
00196
#if defined(NTOS_KERNEL_RUNTIME)
00197
if (Base < MM_HIGHEST_USER_ADDRESS) {
00198
if ((PVOID)((PCHAR)Base + DirectoryAddress) >= MM_HIGHEST_USER_ADDRESS) {
00199
return(
NULL );
00200 }
00201 }
00202
#endif
00203
00204 *
Size = NtHeaders->OptionalHeader.DataDirectory[ DirectoryEntry ].Size;
00205
if (MappedAsImage || DirectoryAddress < NtHeaders->OptionalHeader.SizeOfHeaders) {
00206
return( (PVOID)((PCHAR)Base + DirectoryAddress) );
00207 }
00208
00209
return(
RtlAddressInSectionTable((PIMAGE_NT_HEADERS)NtHeaders, Base, DirectoryAddress ));
00210 }
00211
00212
00213 PVOID
00214 RtlpImageDirectoryEntryToData64 (
00215 IN PVOID Base,
00216 IN BOOLEAN MappedAsImage,
00217 IN USHORT DirectoryEntry,
00218 OUT PULONG Size,
00219 PIMAGE_NT_HEADERS64 NtHeaders
00220 )
00221 {
00222 ULONG DirectoryAddress;
00223
00224
if (DirectoryEntry >= NtHeaders->OptionalHeader.NumberOfRvaAndSizes) {
00225
return(
NULL );
00226 }
00227
00228
if (!(DirectoryAddress = NtHeaders->OptionalHeader.DataDirectory[ DirectoryEntry ].VirtualAddress)) {
00229
return(
NULL );
00230 }
00231
00232
#if defined(NTOS_KERNEL_RUNTIME)
00233
if (Base < MM_HIGHEST_USER_ADDRESS) {
00234
if ((PVOID)((PCHAR)Base + DirectoryAddress) >= MM_HIGHEST_USER_ADDRESS) {
00235
return(
NULL );
00236 }
00237 }
00238
#endif
00239
00240 *
Size = NtHeaders->OptionalHeader.DataDirectory[ DirectoryEntry ].Size;
00241
if (MappedAsImage || DirectoryAddress < NtHeaders->OptionalHeader.SizeOfHeaders) {
00242
return( (PVOID)((PCHAR)Base + DirectoryAddress) );
00243 }
00244
00245
return(
RtlAddressInSectionTable((PIMAGE_NT_HEADERS)NtHeaders, Base, DirectoryAddress ));
00246 }
00247
00248
00249 PVOID
00250 RtlImageDirectoryEntryToData (
00251 IN PVOID Base,
00252 IN BOOLEAN MappedAsImage,
00253 IN USHORT DirectoryEntry,
00254 OUT PULONG Size
00255 )
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 {
00285 PIMAGE_NT_HEADERS NtHeaders;
00286
00287
if ((ULONG_PTR)Base & 0x00000001) {
00288 Base = (PVOID)((ULONG_PTR)Base & ~0x00000001);
00289 MappedAsImage =
FALSE;
00290 }
00291
00292 NtHeaders =
RtlImageNtHeader(Base);
00293
00294
if (!NtHeaders)
00295
return NULL;
00296
00297
if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
00298
return (
RtlpImageDirectoryEntryToData32(Base,
00299 MappedAsImage,
00300 DirectoryEntry,
00301
Size,
00302 (PIMAGE_NT_HEADERS32)NtHeaders));
00303 }
else if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
00304
return (
RtlpImageDirectoryEntryToData64(Base,
00305 MappedAsImage,
00306 DirectoryEntry,
00307
Size,
00308 (PIMAGE_NT_HEADERS64)NtHeaders));
00309 }
else {
00310
return (
NULL);
00311 }
00312 }
00313
00314
00315
#if !defined(NTOS_KERNEL_RUNTIME) && !defined(BLDR_KERNEL_RUNTIME)
00316
00317 PIMAGE_SECTION_HEADER
00318 RtlImageRvaToSection(
00319 IN PIMAGE_NT_HEADERS NtHeaders,
00320 IN PVOID Base,
00321 IN ULONG Rva
00322 )
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 {
00351 ULONG i;
00352 PIMAGE_SECTION_HEADER NtSection;
00353
00354 NtSection = IMAGE_FIRST_SECTION( NtHeaders );
00355
for (i=0; i<NtHeaders->FileHeader.NumberOfSections; i++) {
00356
if (Rva >= NtSection->VirtualAddress &&
00357 Rva < NtSection->VirtualAddress + NtSection->SizeOfRawData
00358 ) {
00359
return NtSection;
00360 }
00361 ++NtSection;
00362 }
00363
00364
return NULL;
00365 }
00366
00367
00368
00369 PVOID
00370 RtlImageRvaToVa(
00371 IN PIMAGE_NT_HEADERS NtHeaders,
00372 IN PVOID Base,
00373 IN ULONG Rva,
00374 IN OUT PIMAGE_SECTION_HEADER *LastRvaSection OPTIONAL
00375 )
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407 {
00408 PIMAGE_SECTION_HEADER NtSection;
00409
00410
if (!ARGUMENT_PRESENT( LastRvaSection ) ||
00411 (NtSection = *LastRvaSection) ==
NULL ||
00412 Rva < NtSection->VirtualAddress ||
00413 Rva >= NtSection->VirtualAddress + NtSection->SizeOfRawData
00414 ) {
00415 NtSection =
RtlImageRvaToSection( NtHeaders,
00416 Base,
00417 Rva
00418 );
00419 }
00420
00421
if (NtSection !=
NULL) {
00422
if (LastRvaSection !=
NULL) {
00423 *LastRvaSection = NtSection;
00424 }
00425
00426
return (PVOID)((PCHAR)Base +
00427 (Rva - NtSection->VirtualAddress) +
00428 NtSection->PointerToRawData
00429 );
00430 }
00431
else {
00432
return NULL;
00433 }
00434 }
00435
00436
#endif