|
|
#include "precomp.h"
#pragma hdrstop
#include <ntexapi.dbg>
DECLARE_API( gflag )
/*++
Routine Description:
This function is called as an NTSD extension to dump or modify the contents of the NtGlobalFlag variable in NTDLL
Called as:
!gflag [value]
If a value is not given then displays the current bits set in NTDLL!NtGlobalFlag variable. Otherwise value can be one of the following:
-? - displays a list of valid flag abbreviations number - 32-bit number that becomes the new value stored into NtGlobalFlag +number - specifies one or more bits to set in NtGlobalFlag +abbrev - specifies a single bit to set in NtGlobalFlag -number - specifies one or more bits to clear in NtGlobalFlag -abbrev - specifies a single bit to clear in NtGlobalFlag
Return Value:
None.
--*/
{ ULONG gflagOffset; ULONG64 pebAddress; ULONG64 pNtGlobalFlag = 0; ULONG ValidBits = FLG_USERMODE_VALID_BITS; ULONG i; ULONG OldGlobalFlags; ULONG NewGlobalFlagsClear; ULONG NewGlobalFlagsSet; ULONG NewGlobalFlags; LPSTR s, Arg;
pNtGlobalFlag = GetExpression("nt!NtGlobalFlag"); ValidBits = FLG_VALID_BITS;
//
// If we could not get the global variable from the kernel, try from the
// PEB for user mode
//
if (!pNtGlobalFlag) { GetPebAddress(0, &pebAddress);
if (pebAddress) { if (GetFieldOffset("nt!_PEB", "NtGlobalFlag", &gflagOffset)) { dprintf("Could not find NtGlobalFlag in nt!_PEB\n"); return E_FAIL; } pNtGlobalFlag = gflagOffset + pebAddress; ValidBits = FLG_USERMODE_VALID_BITS; } }
if (!pNtGlobalFlag) { dprintf( "Unable to get address of NtGlobalFlag variable" ); return E_FAIL; }
if (!ReadMemory(pNtGlobalFlag, &OldGlobalFlags, sizeof(OldGlobalFlags), NULL)) { dprintf( "Unable to read contents of NtGlobalFlag variable at %p\n", pNtGlobalFlag ); return E_FAIL; }
OldGlobalFlags &= ValidBits;
s = (LPSTR)args; if (!s) { s = ""; }
NewGlobalFlagsClear = 0; NewGlobalFlagsSet = 0; while (*s) { while (*s && *s <= ' ') { s += 1; }
Arg = s; if (!*s) { break; }
while (*s && *s > ' ') { s += 1; }
if (*s) { *s++ = '\0'; }
if (!strcmp( Arg, "-?" )) { dprintf( "usage: !gflag [-? | flags]\n" ); dprintf( "Flags may either be a single hex number that specifies all\n" ); dprintf( "32-bits of the GlobalFlags value, or it can be one or more\n" ); dprintf( "arguments, each beginning with a + or -, where the + means\n" ); dprintf( "to set the corresponding bit(s) in the GlobalFlags and a -\n" ); dprintf( "means to clear the corresponding bit(s). After the + or -\n" ); dprintf( "may be either a hex number or a three letter abbreviation\n" ); dprintf( "for a GlobalFlag. Valid abbreviations are:\n" ); for (i=0; i<32; i++) { if ((GlobalFlagInfo[i].Flag & ValidBits) && GlobalFlagInfo[i].Abbreviation != NULL) { dprintf( " %s - %s\n", GlobalFlagInfo[i].Abbreviation, GlobalFlagInfo[i].Description ); } }
return E_FAIL; }
if (*Arg == '+' || *Arg == '-') { if (strlen(Arg+1) == 3) { for (i=0; i<32; i++) { if ((GlobalFlagInfo[i].Flag & ValidBits) && !_stricmp( GlobalFlagInfo[i].Abbreviation, Arg+1 )) { if (*Arg == '-') { NewGlobalFlagsClear |= GlobalFlagInfo[i].Flag; } else { NewGlobalFlagsSet |= GlobalFlagInfo[i].Flag; }
Arg += 4; break; } }
if (*Arg != '\0') { dprintf( "Invalid flag abbreviation - '%s'\n", Arg ); return E_FAIL; } }
if (*Arg != '\0') { if (*Arg++ == '-') { NewGlobalFlagsClear |= strtoul( Arg, &Arg, 16 ); } else { NewGlobalFlagsSet |= strtoul( Arg, &Arg, 16 ); } } } else { NewGlobalFlagsSet = strtoul( Arg, &Arg, 16 ); break; } }
NewGlobalFlags = (OldGlobalFlags & ~NewGlobalFlagsClear) | NewGlobalFlagsSet; NewGlobalFlags &= ValidBits; if (NewGlobalFlags != OldGlobalFlags) { if (!WriteMemory( pNtGlobalFlag, &NewGlobalFlags, sizeof( NewGlobalFlags ), NULL)) { dprintf( "Unable to store new global flag settings.\n" ); return E_FAIL; }
dprintf( "New NtGlobalFlag contents: 0x%08x\n", NewGlobalFlags ); OldGlobalFlags = NewGlobalFlags; } else { dprintf( "Current NtGlobalFlag contents: 0x%08x\n", OldGlobalFlags ); }
for (i=0; i<32; i++) { if (OldGlobalFlags & GlobalFlagInfo[i].Flag) { dprintf( " %s - %s\n", GlobalFlagInfo[i].Abbreviation, GlobalFlagInfo[i].Description ); } }
return S_OK; }
|