00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include "mi.h"
00023
#include "zwapi.h"
00024
00025
00026
VOID
00027
MiSuperSectionDelete (
00028 PVOID Object
00029 );
00030
00031 BOOLEAN
00032
MiSuperSectionInitialization (
00033 );
00034
00035
#ifdef ALLOC_PRAGMA
00036
#pragma alloc_text(INIT,MiSuperSectionInitialization)
00037
#endif
00038
00039 #define MM_MAX_SUPERSECTION_COUNT (32)
00040
00041 POBJECT_TYPE MmSuperSectionObjectType;
00042
00043 #define STATUS_TOO_MANY_SECTIONS ((NTSTATUS)0xC0033333)
00044 #define STATUS_INCOMPLETE_MAP ((NTSTATUS)0xC0033334)
00045
00046
00047 extern GENERIC_MAPPING
MiSectionMapping;
00048
00049 typedef struct _MMSUPER_SECTION {
00050 ULONG
NumberOfSections;
00051 PSECTION SectionPointers[1];
00052 }
MMSUPER_SECTION, *
PMMSUPER_SECTION;
00053
00054
00055
NTSTATUS
00056 NtCreateSuperSection (
00057 OUT PHANDLE SuperSectionHandle,
00058 IN ACCESS_MASK DesiredAccess,
00059 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
00060 IN ULONG Count,
00061 IN HANDLE SectionHandles[]
00062 )
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 {
00096
NTSTATUS Status;
00097
PSECTION Section;
00098
PCONTROL_AREA ControlArea;
00099 HANDLE CapturedHandle;
00100 HANDLE CapturedHandles[
MM_MAX_SUPERSECTION_COUNT];
00101
PMMSUPER_SECTION SuperSection;
00102
KPROCESSOR_MODE PreviousMode;
00103 ULONG
RefCount;
00104 ULONG i;
00105 KIRQL OldIrql;
00106
00107
if (
Count >
MM_MAX_SUPERSECTION_COUNT) {
00108
return STATUS_TOO_MANY_SECTIONS;
00109 }
00110
00111
try {
00112
00113
if (PreviousMode !=
KernelMode) {
00114
ProbeForWriteHandle (SuperSectionHandle);
00115 }
00116
00117 i= 0;
00118
do {
00119 CapturedHandles[i] = SectionHandles[i];
00120 i += 1;
00121 }
while (i <
Count);
00122
00123 } except (
ExSystemExceptionFilter()) {
00124
00125
00126
00127
00128
00129
00130
00131
return GetExceptionCode();
00132 }
00133
00134
Status =
ObCreateObject (PreviousMode,
00135
MmSuperSectionObjectType,
00136
ObjectAttributes,
00137 PreviousMode,
00138
NULL,
00139
sizeof(
MMSUPER_SECTION) +
00140 (
sizeof(
PSECTION) * (
Count - 1)),
00141
sizeof(
MMSUPER_SECTION) +
00142 (
sizeof(
PSECTION) * (
Count - 1)),
00143 0,
00144 (PVOID *)&SuperSection);
00145
00146
if (!
NT_SUCCESS(
Status)) {
00147
return Status;
00148 }
00149
00150 SuperSection->NumberOfSections =
Count;
00151
00152 i = 0;
00153
RefCount = 0;
00154
do {
00155
00156
00157
00158
00159
00160
00161
Status =
ObReferenceObjectByHandle(CapturedHandles[i],
00162 DesiredAccess,
00163
MmSectionObjectType,
00164 PreviousMode,
00165 (PVOID *)&Section,
00166
NULL);
00167
00168
if (
NT_SUCCESS(
Status) !=
FALSE) {
00169
if (Section->u.Flags.Image == 0) {
00170
00171
00172
00173
00174
00175
Status = STATUS_SECTION_NOT_IMAGE;
00176
goto ServiceFailed;
00177 }
00178
RefCount += 1;
00179 SuperSection->SectionPointers[i] = Section;
00180 }
else {
00181
goto ServiceFailed;
00182 }
00183
00184 i += 1;
00185 }
while (i <
Count);
00186
00187 i= 0;
00188
do {
00189
00190
00191
00192
00193
00194
00195 ControlArea = SuperSection->SectionPointers[i]->
Segment->
ControlArea;
00196
00197
LOCK_PFN (OldIrql);
00198 ControlArea->
NumberOfSectionReferences += 1;
00199 ControlArea->
NumberOfUserReferences += 1;
00200
UNLOCK_PFN (OldIrql);
00201 i++;
00202
00203 }
while (i <
Count);
00204
00205
00206
Status =
ObInsertObject (SuperSection,
00207
NULL,
00208 DesiredAccess,
00209 0,
00210 (PVOID *)
NULL,
00211 &CapturedHandle);
00212
00213
try {
00214 *SuperSectionHandle = CapturedHandle;
00215 } except (
EXCEPTION_EXECUTE_HANDLER) {
00216
return Status;
00217 }
00218
return Status;
00219
00220 ServiceFailed:
00221
while (
RefCount > 0) {
00222
RefCount -= 1;
00223
ObDereferenceObject(SuperSection->SectionPointers[
RefCount]);
00224 }
00225
00226
00227
00228
00229
00230
00231
ObDereferenceObject (SuperSection);
00232
return Status;
00233 }
00234
00235
00236
NTSTATUS
00237 NtOpenSuperSection (
00238 OUT PHANDLE SuperSectionHandle,
00239 IN ACCESS_MASK DesiredAccess,
00240 IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
00241 )
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268 {
00269 HANDLE
Handle;
00270
KPROCESSOR_MODE PreviousMode;
00271
NTSTATUS Status;
00272
00273
00274
00275
00276
00277 PreviousMode = KeGetPreviousMode();
00278
if (PreviousMode !=
KernelMode) {
00279
try {
00280
ProbeForWriteHandle(SuperSectionHandle);
00281 } except (
EXCEPTION_EXECUTE_HANDLER) {
00282
return GetExceptionCode();
00283 }
00284 }
00285
00286
00287
00288
00289
00290
00291
Status =
ObOpenObjectByName (
ObjectAttributes,
00292
MmSuperSectionObjectType,
00293 PreviousMode,
00294
NULL,
00295 DesiredAccess,
00296
NULL,
00297 &
Handle
00298 );
00299
00300
try {
00301 *SuperSectionHandle =
Handle;
00302 } except (
EXCEPTION_EXECUTE_HANDLER) {
00303
return Status;
00304 }
00305
00306
return Status;
00307 }
00308
00309
00310
NTSTATUS
00311 NtMapViewOfSuperSection (
00312 IN HANDLE SuperSectionHandle,
00313 IN HANDLE ProcessHandle,
00314 IN OUT PULONG Count,
00315 OUT PVOID BaseAddress[],
00316 OUT ULONG ViewSize[],
00317 IN SECTION_INHERIT InheritDisposition,
00318 )
00319
00320
00321
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
00352
00353
00354
00355 {
00356
NTSTATUS Status;
00357 PVOID CapturedBases[
MM_MAX_SUPERSECTION_COUNT];
00358 ULONG CapturedViews[
MM_MAX_SUPERSECTION_COUNT];
00359
PMMSUPER_SECTION SuperSection;
00360
KPROCESSOR_MODE PreviousMode;
00361 ULONG i;
00362 ULONG CapturedCount;
00363 ULONG NumberMapped;
00364
PEPROCESS Process;
00365 LARGE_INTEGER LargeZero = {0,0};
00366
00367
00368 PreviousMode = KeGetPreviousMode();
00369
00370
try {
00371
ProbeForWriteUlong (
Count);
00372 CapturedCount = *
Count;
00373
00374
if (PreviousMode !=
KernelMode) {
00375
ProbeForWrite (BaseAddress,
00376
sizeof(PVOID) * CapturedCount,
00377
sizeof(PVOID));
00378
ProbeForWrite (ViewSize,
00379
sizeof(ULONG) * CapturedCount,
00380
sizeof(ULONG));
00381 }
00382
00383 } except (
ExSystemExceptionFilter()) {
00384
00385
00386
00387
00388
00389
00390
00391
return GetExceptionCode();
00392 }
00393
00394
Status =
ObReferenceObjectByHandle ( ProcessHandle,
00395 PROCESS_VM_OPERATION,
00396
PsProcessType,
00397 PreviousMode,
00398 (PVOID *)&Process,
00399
NULL );
00400
if (!
NT_SUCCESS(
Status)) {
00401
return Status;
00402 }
00403
00404
00405
00406
00407
00408
Status =
ObReferenceObjectByHandle ( SuperSectionHandle,
00409 SECTION_MAP_EXECUTE,
00410
MmSuperSectionObjectType,
00411 PreviousMode,
00412 (PVOID *)&SuperSection,
00413
NULL );
00414
00415
if (!
NT_SUCCESS(
Status)) {
00416
ObDereferenceObject (Process);
00417
return Status;
00418 }
00419
00420
if (CapturedCount < SuperSection->NumberOfSections) {
00421
ObDereferenceObject (Process);
00422
ObDereferenceObject (SuperSection);
00423
return STATUS_BUFFER_TOO_SMALL;
00424 }
00425
00426 NumberMapped = 0;
00427
do {
00428
00429
00430
00431
00432
00433
00434
Status =
MmMapViewOfSection (SuperSection->SectionPointers[i],
00435 Process,
00436 &CapturedBases[i],
00437 0,
00438 0,
00439 &LargeZero,
00440 &CapturedViews[i],
00441 InheritDisposition,
00442 0,
00443 PAGE_EXECUTE);
00444
00445
if (
NT_SUCCESS (
Status) ==
FALSE) {
00446
Status =
STATUS_INCOMPLETE_MAP;
00447
break;
00448 }
00449 NumberMapped++;
00450 }
while (NumberMapped < SuperSection->NumberOfSections);
00451
00452
00453
00454
00455
00456
ObDereferenceObject (SuperSection);
00457
ObDereferenceObject (Process);
00458
00459
try {
00460 *
Count = NumberMapped;
00461 i = 0;
00462
00463
do {
00464
00465
00466
00467
00468
00469
00470 BaseAddress[i] = CapturedBases[i];
00471 ViewSize[i] = CapturedViews[i];
00472
00473 i++;
00474 }
while (i < NumberMapped);
00475
00476 } except (
ExSystemExceptionFilter()) {
00477 NOTHING;
00478 }
00479
00480
return(
Status);
00481 }
00482
00483
00484
00485
#if 0
00486
00487
NTSTATUS
00488 NtQuerySuperSection (
00489 IN HANDLE SuperSectionHandle,
00490 IN SUPERSECTION_INFORMATION_CLASS SectionInformationClass,
00491 OUT PVOID SuperSectionInformation,
00492 IN ULONG SuperSectionInformationLength,
00493 OUT PULONG ReturnLength OPTIONAL
00494 )
00495
00496 Routine
Description:
00497
00498 This function returns information about an opened supersection object.
00499 This function provides
the capability to determine
the basic section
00500 information about each section in
the supersection or
the image
00501 information about each section in
the supersection.
00502
00503 Arguments:
00504
00505 SuperSectionHandle - Supplies an open handle to a section object.
00506
00507 SectionInformationClass - The section information
class about
00508 which to retrieve information.
00509
00510 SuperSectionInformation -
A pointer to a buffer that receives
the
00511 specified information. The
format and content of
the buffer
00512 depend on
the specified section class.
00513
00514
00515 SuperSectionInformationLength - Specifies
the length in bytes of
the
00516 section information buffer.
00517
00518 ReturnLength - An optional pointer which, if specified, receives
00519
the number of bytes placed in
the section information buffer.
00520
00521
00522 Return Value:
00523
00524 Returns
the status
00525
00526 TBS
00527
00528
00529 --*/
00530
00531
00532 #endif
00533
00534
VOID
00535 MiSuperSectionDelete (
00536 PVOID Object
00537 )
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558 {
00559
PMMSUPER_SECTION SuperSection;
00560
PCONTROL_AREA ControlArea;
00561 KIRQL OldIrql;
00562 ULONG i = 0;
00563
00564 SuperSection = (
PMMSUPER_SECTION)Object;
00565
00566
do {
00567
00568
00569
00570
00571
00572
00573 ControlArea = SuperSection->
SectionPointers[i]->Segment->ControlArea;
00574
00575
LOCK_PFN (OldIrql);
00576 ControlArea->NumberOfSectionReferences -= 1;
00577 ControlArea->NumberOfUserReferences -= 1;
00578
UNLOCK_PFN (OldIrql);
00579
ObDereferenceObject (SuperSection->SectionPointers[i]);
00580 i++;
00581
00582 }
while (i < SuperSection->NumberOfSections);
00583
00584
return;
00585 }
00586
00587 BOOLEAN
00588 MiSuperSectionInitialization (
00589 )
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613 {
00614
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
00615 UNICODE_STRING TypeName;
00616
00617
00618
00619
00620
00621 RtlZeroMemory( &ObjectTypeInitializer,
sizeof( ObjectTypeInitializer ) );
00622 ObjectTypeInitializer.Length =
sizeof( ObjectTypeInitializer );
00623 ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
00624 ObjectTypeInitializer.GenericMapping =
MiSectionMapping;
00625 ObjectTypeInitializer.PoolType =
PagedPool;
00626
00627
00628
00629
00630
00631
RtlInitUnicodeString (&TypeName,
L"SuperSection");
00632
00633
00634
00635
00636
00637 ObjectTypeInitializer.ValidAccessMask = SECTION_ALL_ACCESS;
00638 ObjectTypeInitializer.DeleteProcedure =
MiSuperSectionDelete;
00639 ObjectTypeInitializer.GenericMapping =
MiSectionMapping;
00640 ObjectTypeInitializer.UseDefaultObject =
TRUE;
00641
if ( !
NT_SUCCESS(
ObCreateObjectType(&TypeName,
00642 &ObjectTypeInitializer,
00643 (PSECURITY_DESCRIPTOR)
NULL,
00644 &
MmSuperSectionObjectType
00645 )) ) {
00646
return FALSE;
00647 }
00648
00649
return TRUE;
00650
00651 }