Windows2003-3790/sdktools/avrf/avrf.cxx
2020-09-30 16:53:55 +02:00

1143 lines
28 KiB
C++

//
// Application verifier manager (command line version)
// Copyright (c) Microsoft Corporation, 2001
//
//
// module: avrf.cxx
// author: silviuc
// created: 02/14/2001
//
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <malloc.h>
#include <tchar.h>
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <common.ver>
LPTSTR HelpText =
TEXT("avrf - Base application verifier settings --") BUILD_MACHINE_TAG TEXT("\n")
VER_LEGALCOPYRIGHT_STR TEXT("\n")
TEXT(" \n")
TEXT("NOTE. In order to access all application verifier features please use \n")
TEXT("`appverif.exe'. The tool can be downloaded from `http://appverifier'. \n")
TEXT(" \n")
TEXT("avrf [OPTION ...] \n")
TEXT(" \n")
TEXT(" /enable PROGRAM Enable verifier with default settings. \n")
TEXT(" /disable PROGRAM Disable verifier. \n")
TEXT(" \n")
TEXT(" /pageheap Enable full page heap (default). \n")
TEXT(" /lightheap Enable light page heap. \n")
TEXT(" /locks Enable critical section verifier (default). \n")
TEXT(" /nolocks Disable critical section verifier. \n")
TEXT(" /handles Enable handle checking and tracking (default). \n")
TEXT(" /nohandles Disable handle checking. \n")
TEXT(" /stacks Stack overflow in low memory conditions checks.\n")
TEXT(" /nostacks Disable stack overflow checks (default). \n")
TEXT(" /tls Check thread local storage calls (default). \n")
TEXT(" /notls Do not check thread local storage calls. \n")
TEXT(" /rpc Enable RPC verifier. \n")
TEXT(" /norpc Disable RPC verifier (default). \n")
TEXT(" /locals Check for uninitialized local variables. \n")
TEXT(" /nolocals Do not check for uninitialized locals (default).\n")
TEXT(" /com Enable COM verifier. \n")
TEXT(" /nocom Disable COM verifier (default). \n")
TEXT(" /deadlock Enable deadlock verifier. \n")
TEXT(" /nodeadlock Disable deadlock verifier (default). \n")
TEXT(" /race Enable race checks (random delays). \n")
TEXT(" /norace Disable race checks (default). \n")
TEXT(" /badapis Detect calls to dangerous APIs (default). \n")
TEXT(" /nobadapis Do not detect calls to dangerous APIs. \n")
TEXT(" /vmem Check virtual memory calls (default). \n")
TEXT(" /novmem Do not check virtual memory calls. \n")
TEXT(" \n")
TEXT(" The following checks marked by (*) are experimental and should \n")
TEXT(" not be used on a large scale in labs. They are supported though \n")
TEXT(" and you will get assistance from `avrf' alias' for debugging. \n")
TEXT(" \n")
TEXT(" /misc (*) Miscellaneous checks (e.g. wrap tick count). \n")
TEXT(" /nomisc (*) No miscellaneous checks (default). \n")
TEXT(" /log (*) Log issues in a file instead of debugger. \n")
TEXT(" /nolog (*) Do not log in a file (default). \n")
TEXT(" /fastheap (*) Enable fast fill debug heap. \n")
TEXT(" /nofastheap (*) No fast fill heap (default). \n")
TEXT(" \n")
TEXT(" /debug Launch under debugger `ntsd -g -G -x'. \n")
TEXT(" /kdebug Launch under debugger `ntsd -g -G -d -x'. \n")
TEXT(" \n")
TEXT(" /verifier DLL ... Specify additional verifier providers. Verifier providers \n")
TEXT(" are special DLLs which extend verifier functionality. \n")
TEXT(" This option cannot be used to verify only one DLL in a process. \n")
TEXT(" \n")
TEXT(" \n")
TEXT("PROGRAM Name of the binary with extension (.exe or something else).\n")
TEXT("DLL Name of the binary with extension (.dll or something else).\n")
TEXT(" \n")
TEXT("If no option specified the program will print all verifier enabled \n")
TEXT("applications and their specific options. \n")
TEXT(" \n")
TEXT("The /verifier option is useful whenever additional verification layers \n")
TEXT("must run on top of the core verification layer. The dlls specified \n")
TEXT("must obey the format for a verifier provider dll. \n")
TEXT(" \n")
TEXT("The /badapis option detects calls to interfaces like TerminateThread. \n")
TEXT(" \n")
TEXT("Note. Enabling application verifier does not affect currently running \n")
TEXT("processes. If you need to use verifier for processes that are \n")
TEXT("already running and cannot be restarted (csrss.exe, winlogon.exe), \n")
TEXT("a reboot is needed after the verifier has been enabled for \n")
TEXT("that process. \n")
TEXT(" \n");
VOID
Help (
)
{
_fputts (HelpText, stdout);
exit(1);
}
VOID
PrintFlags (
DWORD Flags
)
{
if ((Flags & RTL_VRF_FLG_FULL_PAGE_HEAP)) {
printf("pageheap ");
}
else {
printf("lightheap ");
}
if ((Flags & RTL_VRF_FLG_LOCK_CHECKS)) {
printf("locks ");
}
if ((Flags & RTL_VRF_FLG_HANDLE_CHECKS)) {
printf("handles ");
}
if ((Flags & RTL_VRF_FLG_STACK_CHECKS)) {
printf("stacks ");
}
if ((Flags & RTL_VRF_FLG_TLS_CHECKS)) {
printf("tls ");
}
if ((Flags & RTL_VRF_FLG_RPC_CHECKS)) {
printf("rpc ");
}
if ((Flags & RTL_VRF_FLG_COM_CHECKS)) {
printf("com ");
}
if ((Flags & RTL_VRF_FLG_RACE_CHECKS)) {
printf("race ");
}
if ((Flags & RTL_VRF_FLG_DEADLOCK_CHECKS)) {
printf("deadlock ");
}
if ((Flags & RTL_VRF_FLG_DANGEROUS_APIS)) {
printf("badapis ");
}
if ((Flags & RTL_VRF_FLG_DIRTY_STACKS)) {
printf("uninit_locals ");
}
if ((Flags & RTL_VRF_FLG_VIRTUAL_MEM_CHECKS)) {
printf("vmem ");
}
if ((Flags & RTL_VRF_FLG_ENABLE_LOGGING)) {
printf("log ");
}
if ((Flags & RTL_VRF_FLG_FAST_FILL_HEAP)) {
printf("fastheap ");
}
if ((Flags & RTL_VRF_FLG_MISCELLANEOUS_CHECKS)) {
printf("misc ");
}
}
BOOL
EnableVerifier (
LPCTSTR Name,
LPTSTR DebugString,
char * * Args);
BOOL
DisableVerifier (
LPCTSTR Name);
BOOL
IsVerifierEnabled (
LPCTSTR Name);
BOOL
IsVerifierFlagsValueDefined (
LPCTSTR Name,
PDWORD Value);
BOOL
ReadGlobalFlagValue (
HKEY Key,
LPTSTR Buffer,
ULONG Length);
BOOL
WriteGlobalFlagValue (
HKEY Key,
LPTSTR Buffer,
ULONG Length);
BOOL
ReadVerifierValue (
HKEY Key,
LPTSTR Name,
PDWORD Value
);
BOOL
WriteVerifierValue (
HKEY Key,
LPTSTR Name,
DWORD Value
);
BOOL
DeleteVerifierFlagValue (
HKEY Key);
BOOL
WriteDebuggerValue (
HKEY Key,
LPTSTR Buffer,
ULONG Length);
BOOL
DeleteDebuggerValue (
HKEY Key);
HKEY
OpenImageKey (
LPCTSTR Name,
BOOL ShouldExist);
VOID
CloseImageKey (
HKEY Key);
VOID
CreateImageName (
LPCTSTR Source,
LPTSTR Name,
ULONG Length);
VOID
PrintVerifierEnabledApplications (
);
VOID
Help (
);
VOID
__cdecl
Error (
LPCTSTR Format,
...);
BOOL
IsWow64Active (
);
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
char * *
SearchOption (
char * Args[],
char * Option
)
{
while (*Args) {
if (_stricmp(*Args, Option) == 0) {
return Args;
}
Args++;
}
return NULL;
}
void _cdecl
main (int argc, char *argv[])
{
TCHAR ImageName [MAX_PATH];
char * * Option;
if (IsWow64Active()) {
_tprintf (TEXT ("Warning: avrf.exe is running inside WOW64. \n"
"This scenario can be used to test x86 binaries (running inside WOW64) \n"
"but not native (IA64) binaries. \n\n"));
}
if (argc == 2 && strstr (argv[1], TEXT("?")) != NULL) {
Help ();
}
else if ((Option = SearchOption(argv + 1, "/enable"))) {
PCHAR DebugString = NULL;
if (SearchOption (argv + 1, "/debug") != NULL) {
DebugString = "ntsd -g -G -x";
}
if (SearchOption (argv + 1, "/kdebug") != NULL) {
DebugString = "ntsd -g -G -d -x";
}
if (Option[1] && Option[1][0] != '/') {
CreateImageName (Option[1], ImageName, MAX_PATH);
EnableVerifier (ImageName, DebugString, argv);
}
else {
Help();
}
}
else if ((Option = SearchOption(argv + 1, "/disable"))) {
if (Option[1]) {
CreateImageName (Option[1], ImageName, MAX_PATH);
DisableVerifier (ImageName);
}
else {
Help();
}
}
else if (argc == 2) {
CreateImageName (argv[1], ImageName, MAX_PATH);
if (IsVerifierEnabled (ImageName) == FALSE) {
_tprintf (TEXT("%s: verifier is not enabled for this application \n"), argv[1]);
}
else {
DWORD Value;
if (IsVerifierFlagsValueDefined (ImageName, &Value)) {
_tprintf (TEXT("%s: verifier enabled with flags ("), argv[1]);
PrintFlags (Value);
_tprintf (TEXT(")\n"));
}
else {
_tprintf (TEXT("%s: verifier enabled with default flags \n"), argv[1]);
}
}
}
else {
PrintVerifierEnabledApplications ();
}
}
VOID
__cdecl
Error (
LPCTSTR Format,
...)
{
va_list Params;
va_start (Params, Format);
_tprintf (TEXT("Error: "));
_vtprintf (Format, Params);
_tprintf ( TEXT("\n "));
exit (1);
}
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
BOOL
IsVerifierEnabled (
LPCTSTR Name)
{
HKEY Key;
TCHAR Buffer [128];
DWORD Flags;
BOOL Success;
if ((Key = OpenImageKey (Name, TRUE)) == NULL) {
return FALSE;
}
Success = ReadGlobalFlagValue (Key, Buffer, sizeof Buffer);
CloseImageKey (Key);
if (Success == FALSE) {
return FALSE;
}
if (_stscanf (Buffer, TEXT("%x"), &Flags) == 0) {
return FALSE;
}
return (Flags & FLG_APPLICATION_VERIFIER) ? TRUE : FALSE;
}
BOOL
IsVerifierFlagsValueDefined (
LPCTSTR Name,
PDWORD Value)
{
HKEY Key;
DWORD VerifierFlags = 0;
if ((Key = OpenImageKey (Name, TRUE)) == NULL) {
return FALSE;
}
if (ReadVerifierValue (Key, TEXT("VerifierFlags"), &VerifierFlags) == FALSE) {
CloseImageKey (Key);
return FALSE;
}
CloseImageKey (Key);
*Value = VerifierFlags;
return TRUE;
}
BOOL
EnableVerifier (
LPCTSTR Name,
LPTSTR DebugString,
char * * Args
)
{
HKEY Key;
TCHAR Buffer [128];
DWORD Flags;
DWORD VerifierFlags;
char * * Option;
LONG Result;
int Scanned;
if ((Key = OpenImageKey (Name, FALSE)) == NULL) {
Error (TEXT("Cannot open image registry key for %s"), Name);
}
if (ReadGlobalFlagValue (Key, Buffer, sizeof Buffer) == FALSE) {
Flags = 0;
}
else {
Scanned = _stscanf (Buffer, TEXT("%x"), &Flags);
if (Scanned != 1) {
Error (TEXT("Cannot convert to a number the globals flags value %s \n"), Buffer);
}
}
Flags |= FLG_APPLICATION_VERIFIER;
_stprintf (Buffer, TEXT("0x%08X"), Flags);
if (WriteGlobalFlagValue (Key, Buffer, _tcslen(Buffer)) == FALSE) {
return FALSE;
}
//
// Write `Debugger' value if needed.
//
if (DebugString != NULL) {
if (WriteDebuggerValue (Key, DebugString, _tcslen(DebugString)) == FALSE) {
return FALSE;
}
}
//
// Fill out default verifier settings.
//
VerifierFlags = RTL_VRF_FLG_FULL_PAGE_HEAP
| RTL_VRF_FLG_LOCK_CHECKS
| RTL_VRF_FLG_HANDLE_CHECKS
| RTL_VRF_FLG_TLS_CHECKS
| RTL_VRF_FLG_DANGEROUS_APIS
| RTL_VRF_FLG_VIRTUAL_MEM_CHECKS;
//
// Check for explicit feature requests.
//
if ((Option = SearchOption (Args, "/pageheap")) != NULL) {
VerifierFlags |= RTL_VRF_FLG_FULL_PAGE_HEAP;
}
if ((Option = SearchOption (Args, "/lightheap")) != NULL) {
VerifierFlags &= ~RTL_VRF_FLG_FULL_PAGE_HEAP;
}
if ((Option = SearchOption (Args, "/locks")) != NULL) {
VerifierFlags |= RTL_VRF_FLG_LOCK_CHECKS;
}
if ((Option = SearchOption (Args, "/nolocks")) != NULL) {
VerifierFlags &= ~RTL_VRF_FLG_LOCK_CHECKS;
}
if ((Option = SearchOption (Args, "/handles")) != NULL) {
VerifierFlags |= RTL_VRF_FLG_HANDLE_CHECKS;
}
if ((Option = SearchOption (Args, "/nohandles")) != NULL) {
VerifierFlags &= ~RTL_VRF_FLG_HANDLE_CHECKS;
}
if ((Option = SearchOption (Args, "/stacks")) != NULL) {
VerifierFlags |= RTL_VRF_FLG_STACK_CHECKS;
}
if ((Option = SearchOption (Args, "/nostacks")) != NULL) {
VerifierFlags &= ~RTL_VRF_FLG_STACK_CHECKS;
}
if ((Option = SearchOption (Args, "/tls")) != NULL) {
VerifierFlags |= RTL_VRF_FLG_TLS_CHECKS;
}
if ((Option = SearchOption (Args, "/notls")) != NULL) {
VerifierFlags &= ~RTL_VRF_FLG_TLS_CHECKS;
}
if ((Option = SearchOption (Args, "/rpc")) != NULL) {
VerifierFlags |= RTL_VRF_FLG_RPC_CHECKS;
}
if ((Option = SearchOption (Args, "/norpc")) != NULL) {
VerifierFlags &= ~RTL_VRF_FLG_RPC_CHECKS;
}
if ((Option = SearchOption (Args, "/com")) != NULL) {
VerifierFlags |= RTL_VRF_FLG_COM_CHECKS;
}
if ((Option = SearchOption (Args, "/nocom")) != NULL) {
VerifierFlags &= ~RTL_VRF_FLG_COM_CHECKS;
}
if ((Option = SearchOption (Args, "/deadlock")) != NULL) {
VerifierFlags |= RTL_VRF_FLG_DEADLOCK_CHECKS;
}
if ((Option = SearchOption (Args, "/nodeadlock")) != NULL) {
VerifierFlags &= ~RTL_VRF_FLG_DEADLOCK_CHECKS;
}
if ((Option = SearchOption (Args, "/race")) != NULL) {
VerifierFlags |= RTL_VRF_FLG_RACE_CHECKS;
}
if ((Option = SearchOption (Args, "/norace")) != NULL) {
VerifierFlags &= ~RTL_VRF_FLG_RACE_CHECKS;
}
if ((Option = SearchOption (Args, "/badapis")) != NULL) {
VerifierFlags |= RTL_VRF_FLG_DANGEROUS_APIS;
}
if ((Option = SearchOption (Args, "/nobadapis")) != NULL) {
VerifierFlags &= ~RTL_VRF_FLG_DANGEROUS_APIS;
}
if ((Option = SearchOption (Args, "/locals")) != NULL) {
VerifierFlags |= RTL_VRF_FLG_DIRTY_STACKS;
}
if ((Option = SearchOption (Args, "/nolocals")) != NULL) {
VerifierFlags &= ~RTL_VRF_FLG_DIRTY_STACKS;
}
if ((Option = SearchOption (Args, "/vmem")) != NULL) {
VerifierFlags |= RTL_VRF_FLG_VIRTUAL_MEM_CHECKS;
}
if ((Option = SearchOption (Args, "/novmem")) != NULL) {
VerifierFlags &= ~RTL_VRF_FLG_VIRTUAL_MEM_CHECKS;
}
if ((Option = SearchOption (Args, "/log")) != NULL) {
VerifierFlags |= RTL_VRF_FLG_ENABLE_LOGGING;
}
if ((Option = SearchOption (Args, "/nolog")) != NULL) {
VerifierFlags &= ~RTL_VRF_FLG_ENABLE_LOGGING;
}
if ((Option = SearchOption (Args, "/fastheap")) != NULL) {
VerifierFlags |= RTL_VRF_FLG_FAST_FILL_HEAP;
}
if ((Option = SearchOption (Args, "/nofastheap")) != NULL) {
VerifierFlags &= ~RTL_VRF_FLG_FAST_FILL_HEAP;
}
if ((Option = SearchOption (Args, "/misc")) != NULL) {
VerifierFlags |= RTL_VRF_FLG_MISCELLANEOUS_CHECKS;
}
if ((Option = SearchOption (Args, "/nomisc")) != NULL) {
VerifierFlags &= ~RTL_VRF_FLG_MISCELLANEOUS_CHECKS;
}
if ((Option = SearchOption (Args, "/_debug")) != NULL) {
DWORD DebugFlags = 0;
if (Option[1] && Option[1][0] != '/') {
printf("Setting _debug to %s \n", Option[1]);
if (_stscanf (Option[1], TEXT("%x"), &DebugFlags) == 0) {
Error (TEXT("Failed to set internal debug flags."));
}
if (WriteVerifierValue (Key, TEXT("VerifierDebug"), DebugFlags) == FALSE) {
Error (TEXT("Failed to write verifier internal debug registry value."));
}
}
}
//
// Check /dlls option
//
Option = SearchOption (Args, "/verifier");
if (Option != NULL) {
TCHAR Dlls[512];
ULONG Index;
if (Option[1]) {
for (Index = 1, Dlls[0] = '\0';
Option[Index] && Option[Index][0] != '/';
Index++) {
_tcscat (Dlls, Option[Index]);
_tcscat (Dlls, " ");
//
// We do not allow more than 200 characters because the verifier
// support in loader (\nt\base\ntdll\verifier.c) does not handle
// more characters anyway.
//
if (_tcslen (Dlls) > 200) {
break;
}
}
//
// SilviuC: the call to _tcslen below is not correct if we
// ever will want to make this program Unicode.
//
Result = RegSetValueEx (
Key, TEXT ("VerifierDlls"), 0, REG_SZ,
(LPBYTE)(Dlls), _tcslen(Dlls) + 1);
if (Result) {
Error (TEXT("Failed to write VerifierDlls value: error %u"), Result);
}
}
}
//
// Finally write the verifier flags value.
//
if (WriteVerifierValue (Key, TEXT("VerifierFlags"), VerifierFlags) == FALSE) {
Error (TEXT("Failed to write VerifierFlags value."));
return FALSE;
}
CloseImageKey (Key);
return TRUE;
}
BOOL
DisableVerifier (
LPCTSTR Name)
{
HKEY Key;
TCHAR Buffer [128];
DWORD Flags;
if ((Key = OpenImageKey (Name, TRUE)) == NULL) {
//
// There is no key therefore nothing to disable.
//
return TRUE;
}
if (ReadGlobalFlagValue (Key, Buffer, sizeof Buffer) == FALSE) {
Flags = 0;
}
else {
if (_stscanf (Buffer, TEXT("%x"), &Flags) == 0) {
Flags = 0;;
}
}
Flags &= ~FLG_APPLICATION_VERIFIER;
_stprintf (Buffer, TEXT("0x%08X"), Flags);
//
// If by wiping the verifier bit from `GlobalFlags' we get a zero
// value we will wipe out the value altogether. This is important
// when we run the app under debugger. In this case it makes a
// difference if the value is not there or is all zeroes.
//
if (Flags != 0) {
if (WriteGlobalFlagValue (Key, Buffer, _tcslen(Buffer)) == FALSE) {
return FALSE;
}
}
else {
RegDeleteValue (Key, TEXT ("GlobalFlag"));
}
RegDeleteValue (Key, TEXT ("VerifierFlags"));
RegDeleteValue (Key, TEXT ("VerifierDebug"));
RegDeleteValue (Key, TEXT ("VerifierDlls"));
RegDeleteValue (Key, TEXT ("Debugger"));
CloseImageKey (Key);
return TRUE;
}
BOOL
ReadGlobalFlagValue (
HKEY Key,
LPTSTR Buffer,
ULONG Length)
{
LONG Result;
DWORD Type;
DWORD ReadLength = Length;
Result = RegQueryValueEx (
Key,
TEXT ("GlobalFlag"),
0,
&Type,
(LPBYTE)Buffer,
&ReadLength);
if (Result != ERROR_SUCCESS || Type != REG_SZ) {
return FALSE;
}
else {
return TRUE;
}
}
BOOL
WriteGlobalFlagValue (
HKEY Key,
LPTSTR Buffer,
ULONG Length)
{
LONG Result;
Result = RegSetValueEx (
Key,
TEXT ("GlobalFlag"),
0,
REG_SZ,
(LPBYTE)Buffer,
Length);
if (Result != ERROR_SUCCESS) {
return FALSE;
}
else {
return TRUE;
}
}
BOOL
ReadVerifierValue (
HKEY Key,
LPTSTR Name,
PDWORD Value
)
{
LONG Result;
DWORD Type;
DWORD ReadLength = sizeof *Value;
Result = RegQueryValueEx (Key,
Name,
0,
&Type,
(LPBYTE)Value,
&ReadLength);
if (Result != ERROR_SUCCESS || Type != REG_DWORD) {
return FALSE;
}
else {
return TRUE;
}
}
BOOL
WriteVerifierValue (
HKEY Key,
LPTSTR Name,
DWORD Value
)
{
LONG Result;
Result = RegSetValueEx (Key,
Name,
0,
REG_DWORD,
(LPBYTE)(&Value),
sizeof Value);
if (Result != ERROR_SUCCESS) {
return FALSE;
}
else {
return TRUE;
}
}
BOOL
WriteDebuggerValue (
HKEY Key,
LPTSTR Buffer,
ULONG Length)
{
LONG Result;
Result = RegSetValueEx (
Key,
TEXT ("Debugger"),
0,
REG_SZ,
(LPBYTE)Buffer,
Length);
if (Result != ERROR_SUCCESS) {
return FALSE;
}
else {
return TRUE;
}
}
BOOL
IsShutdownFlagsValueDefined (
LPCTSTR KeyName
)
{
HKEY Key;
LONG Result;
DWORD Value;
DWORD Type;
DWORD ReadLength = sizeof (DWORD);
if ((Key = OpenImageKey (KeyName, TRUE)) == NULL) {
return FALSE;
}
Result = RegQueryValueEx (
Key,
TEXT ("ShutdownFlags"),
0,
&Type,
(LPBYTE)(&Value),
&ReadLength);
CloseImageKey (Key);
if (Result == ERROR_SUCCESS && (Value & 0x03) == 0x03) {
return TRUE;
}
else {
return FALSE;
}
}
HKEY
OpenImageKey (
LPCTSTR Name,
BOOL ShouldExist)
{
HKEY Key;
LONG Result;
TCHAR Buffer [2 * MAX_PATH];
_stprintf (
Buffer,
TEXT ("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\%s"),
Name);
if (ShouldExist) {
Result = RegOpenKeyEx (
HKEY_LOCAL_MACHINE,
Buffer,
0,
KEY_ALL_ACCESS,
&Key);
}
else {
Result = RegCreateKeyEx (
HKEY_LOCAL_MACHINE,
Buffer,
0,
0,
0,
KEY_ALL_ACCESS,
NULL,
&Key,
NULL);
}
if (Result != ERROR_SUCCESS) {
return NULL;
}
else {
return Key;
}
}
VOID
CloseImageKey (
HKEY Key)
{
RegCloseKey (Key);
}
VOID
CreateImageName (
LPCTSTR Source,
LPTSTR Name,
ULONG Length)
{
SIZE_T ExtraSpace;
ExtraSpace = 1 + _tcslen (TEXT(".exe"));
if (Length <= ExtraSpace) {
return;
}
RtlZeroMemory (Name, Length);
_tcsncpy (Name, Source, Length - ExtraSpace);
Name[Length - 1] = 0;
_tcslwr (Name);
if (_tcsstr (Name, TEXT(".")) == 0) {
_tcscat (Name, TEXT(".exe"));
}
}
VOID
PrintVerifierEnabledApplications (
)
{
LPCTSTR ImageFileExecutionOptionsKeyName =
TEXT ("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options");
HKEY OptionsKey;
LONG Result;
TCHAR KeyName [MAX_PATH];
ULONG KeySize;
BOOL FoundOne = FALSE;
ULONG Index;
FILETIME FileTime;
Result = RegOpenKeyEx (
HKEY_LOCAL_MACHINE,
ImageFileExecutionOptionsKeyName,
0,
KEY_ALL_ACCESS,
&OptionsKey);
if (Result != ERROR_SUCCESS) {
Error (TEXT("Cannot open registry key %s: error %u"),
ImageFileExecutionOptionsKeyName,
Result);
}
for (Index = 0; TRUE; Index++) {
KeySize = MAX_PATH;
Result = RegEnumKeyEx (
OptionsKey,
Index,
KeyName,
&KeySize,
NULL,
NULL,
NULL,
&FileTime);
if (Result == ERROR_NO_MORE_ITEMS) {
break;
}
if (Result != ERROR_SUCCESS) {
Error (TEXT("Cannot enumerate registry key %s: error %u"),
ImageFileExecutionOptionsKeyName,
Result);
}
if (IsVerifierEnabled (KeyName)) {
DWORD Value;
FoundOne = TRUE;
if (IsVerifierFlagsValueDefined (KeyName, &Value)) {
_tprintf (TEXT("%s: verifier enabled with flags ("), KeyName);
PrintFlags (Value);
_tprintf (TEXT(")\n"));
}
else {
_tprintf (TEXT("%s: verifier enabled with default flags \n"), KeyName);
}
}
}
if (FoundOne == FALSE) {
_tprintf (TEXT("No application has verifier enabled.\n"));
}
}
BOOL
IsWow64Active (
)
{
ULONG_PTR ul;
NTSTATUS st;
//
// If this call succeeds then we are on Windows 2000 or later.
//
st = NtQueryInformationProcess(NtCurrentProcess(),
ProcessWow64Information,
&ul,
sizeof(ul),
NULL);
if (NT_SUCCESS(st) && (0 != ul)) {
// 32-bit code running on Win64
return TRUE;
}
else {
return FALSE;
}
}