├── docs ├── BadApp.png ├── favicon.ico ├── Gemfile ├── assets │ └── css │ │ └── style.scss ├── _config.yml ├── index.md └── _layouts │ └── default.html ├── BadApp ├── BadApp.ico ├── BadApp.rc ├── BadApp.rc2 ├── Github.ico ├── Resource.h ├── BadApp_32.ico ├── stdafx.c ├── targetver.h ├── version.h ├── stdafx.h ├── BadApp.h ├── Handles.c ├── Support.c ├── BadApp.vcxproj.filters ├── Crash.c ├── Heap.c ├── CriticalSection.c ├── BadApp.vcxproj ├── Diag.c └── BadApp.c ├── README.md ├── appveyor.yml ├── LICENSE ├── BadApp.sln ├── GenVersion.bat └── .gitignore /docs/BadApp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/learn-more/BadApp/HEAD/docs/BadApp.png -------------------------------------------------------------------------------- /BadApp/BadApp.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/learn-more/BadApp/HEAD/BadApp/BadApp.ico -------------------------------------------------------------------------------- /BadApp/BadApp.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/learn-more/BadApp/HEAD/BadApp/BadApp.rc -------------------------------------------------------------------------------- /BadApp/BadApp.rc2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/learn-more/BadApp/HEAD/BadApp/BadApp.rc2 -------------------------------------------------------------------------------- /BadApp/Github.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/learn-more/BadApp/HEAD/BadApp/Github.ico -------------------------------------------------------------------------------- /BadApp/Resource.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/learn-more/BadApp/HEAD/BadApp/Resource.h -------------------------------------------------------------------------------- /docs/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/learn-more/BadApp/HEAD/docs/favicon.ico -------------------------------------------------------------------------------- /BadApp/BadApp_32.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/learn-more/BadApp/HEAD/BadApp/BadApp_32.ico -------------------------------------------------------------------------------- /docs/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | gem 'github-pages', group: :jekyll_plugins 3 | -------------------------------------------------------------------------------- /docs/assets/css/style.scss: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | @import "{{ site.theme }}"; 5 | 6 | #downloads 7 | { 8 | width: 120px !important; 9 | } 10 | 11 | -------------------------------------------------------------------------------- /docs/_config.yml: -------------------------------------------------------------------------------- 1 | title: BadApp 2 | description: Test-application exposing bad behavior 3 | theme: jekyll-theme-slate 4 | show_downloads: "true" 5 | 6 | # To serve jekyll locally: 7 | repository: learn-more/BadApp 8 | -------------------------------------------------------------------------------- /BadApp/stdafx.c: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // BadApp.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /BadApp/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /BadApp/version.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../generated_git_version.h" 4 | 5 | #define xstr(s) str(s) 6 | #define str(s) #s 7 | 8 | #define GIT_VERSION_STR \ 9 | xstr(GIT_VERSION_MAJOR) "." \ 10 | xstr(GIT_VERSION_MINOR) "." \ 11 | xstr(GIT_VERSION_PATCH) "." \ 12 | xstr(GIT_VERSION_REV) \ 13 | GIT_VERSION_DIRTY 14 | 15 | -------------------------------------------------------------------------------- /BadApp/stdafx.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PROJECT: BadApp 3 | * LICENSE: MIT (https://spdx.org/licenses/MIT) 4 | * PURPOSE: Precompiled header 5 | * COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen@reactos.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "targetver.h" 11 | 12 | #define WIN32_LEAN_AND_MEAN 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #include "BadApp.h" 20 | 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BadApp 2 | 3 | [![Build status](https://ci.appveyor.com/api/projects/status/265by2qbx81xgc91/branch/master?svg=true)](https://ci.appveyor.com/project/learn-more/badapp/branch/master) 4 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://spdx.org/licenses/MIT) 5 | ![GitHub release (latest SemVer including pre-releases)](https://img.shields.io/github/v/release/learn-more/BadApp?include_prereleases&sort=semver) 6 | ![Works on Windows XP](https://img.shields.io/badge/Works%20on-Windows%20XP-blue) 7 | 8 | 9 | ## Test application exposing bad application behavior. 10 | 11 | See https://learn-more.github.io/BadApp/ for an overview of the features. 12 | 13 | 14 | ![Layout](docs/BadApp.png) 15 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | version: '#{build}-{branch}' 2 | image: Visual Studio 2015 3 | 4 | configuration: Release 5 | 6 | environment: 7 | matrix: 8 | - PlatformToolset: v140_xp 9 | 10 | platform: 11 | - x86 12 | - x64 13 | 14 | build: 15 | project: BadApp.sln 16 | parallel: true 17 | verbosity: minimal 18 | 19 | after_build: 20 | cmd: >- 21 | 7z a BadApp-%PLATFORM%.zip %APPVEYOR_BUILD_FOLDER%\bin\BadApp-%PLATFORM%.exe 22 | 23 | 7z a BadApp-%PLATFORM%.zip %APPVEYOR_BUILD_FOLDER%\bin\BadApp-%PLATFORM%.pdb 24 | 25 | test: off 26 | 27 | artifacts: 28 | - path: BadApp-$(platform).zip 29 | name: BadApp-$(platform) 30 | 31 | skip_commits: 32 | files: 33 | - docs/* 34 | - '**/*.html' 35 | 36 | deploy: 37 | - provider: GitHub 38 | auth_token: 39 | secure: K/oTY+JKhuE+bOORvKuQfrFLikCqE0evsloU/50wDrtrAfsweE4aa8viM1PTkEDm 40 | draft: true 41 | on: 42 | APPVEYOR_REPO_TAG: true 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Mark Jansen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /BadApp.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BadApp", "BadApp\BadApp.vcxproj", "{C42D2E62-1DBE-46AF-8D38-4CE43CB7E40A}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|x64 = Debug|x64 11 | Debug|x86 = Debug|x86 12 | Release|x64 = Release|x64 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {C42D2E62-1DBE-46AF-8D38-4CE43CB7E40A}.Debug|x64.ActiveCfg = Debug|x64 17 | {C42D2E62-1DBE-46AF-8D38-4CE43CB7E40A}.Debug|x64.Build.0 = Debug|x64 18 | {C42D2E62-1DBE-46AF-8D38-4CE43CB7E40A}.Debug|x86.ActiveCfg = Debug|Win32 19 | {C42D2E62-1DBE-46AF-8D38-4CE43CB7E40A}.Debug|x86.Build.0 = Debug|Win32 20 | {C42D2E62-1DBE-46AF-8D38-4CE43CB7E40A}.Release|x64.ActiveCfg = Release|x64 21 | {C42D2E62-1DBE-46AF-8D38-4CE43CB7E40A}.Release|x64.Build.0 = Release|x64 22 | {C42D2E62-1DBE-46AF-8D38-4CE43CB7E40A}.Release|x86.ActiveCfg = Release|Win32 23 | {C42D2E62-1DBE-46AF-8D38-4CE43CB7E40A}.Release|x86.Build.0 = Release|Win32 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /GenVersion.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | setlocal 4 | 5 | set HEADER_NAME="%~dp0generated_git_version.h" 6 | 7 | for /f %%i in ('git describe --tags --dirty --long') do set GIT_VERSION=%%i 8 | set FULL_STRING=#define GIT_VERSION_DESC "%GIT_VERSION%" 9 | if exist %HEADER_NAME% ( 10 | set /p CURRENT_STRING=<%HEADER_NAME% 11 | ) else ( 12 | set CURRENT_STRING=_does_not_exist_ 13 | ) 14 | if "!%FULL_STRING%!" == "!%CURRENT_STRING%!" goto DONE 15 | 16 | 17 | for /F "tokens=1,2,3,4,5,6 delims=.-" %%a in ("%GIT_VERSION%") do ( 18 | set GIT_MAJOR=%%a 19 | set GIT_MINOR=%%b 20 | set GIT_PATCH=%%c 21 | set GIT_REV=%%d 22 | set GIT_HASH=%%e 23 | if [%%f] == [] ( 24 | set GIT_DIRTY= 25 | set GIT_DIRTY_STR="" 26 | ) else ( 27 | set GIT_DIRTY=* 28 | set GIT_DIRTY_STR="*" 29 | ) 30 | ) 31 | 32 | (echo %FULL_STRING%)> %HEADER_NAME% 33 | (echo #define GIT_VERSION_MAJOR %GIT_MAJOR%)>> %HEADER_NAME% 34 | (echo #define GIT_VERSION_MINOR %GIT_MINOR%)>> %HEADER_NAME% 35 | (echo #define GIT_VERSION_PATCH %GIT_PATCH%)>> %HEADER_NAME% 36 | (echo #define GIT_VERSION_REV %GIT_REV%)>> %HEADER_NAME% 37 | (echo #define GIT_VERSION_DIRTY %GIT_DIRTY_STR%)>> %HEADER_NAME% 38 | (echo #define GIT_VERSION_HASH "%GIT_HASH%")>> %HEADER_NAME% 39 | 40 | echo Version: %GIT_MAJOR%.%GIT_MINOR%.%GIT_PATCH%.%GIT_REV%-%GIT_HASH%%GIT_DIRTY% 41 | 42 | :DONE 43 | 44 | endlocal 45 | -------------------------------------------------------------------------------- /BadApp/BadApp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * PROJECT: BadApp 3 | * LICENSE: MIT (https://spdx.org/licenses/MIT) 4 | * PURPOSE: Shared functions 5 | * COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen@reactos.org) 6 | */ 7 | 8 | #pragma once 9 | 10 | #include "resource.h" 11 | 12 | /* Export all symbols, to generate a nicer callstack without symbols */ 13 | #if 1 14 | #define BADAPP_EXPORT __declspec(dllexport) 15 | #else 16 | #define BADAPP_EXPORT 17 | #endif 18 | 19 | 20 | void BADAPP_EXPORT Gui_AddOutput(LPCWSTR Text); 21 | void BADAPP_EXPORT Output(wchar_t const* const _Format, ...); 22 | void BADAPP_EXPORT xwprintf(wchar_t *_Dest, size_t _Count, wchar_t const* const _Format, ...); 23 | unsigned long BADAPP_EXPORT wcstoul_(const wchar_t* str, wchar_t** endptr, int base); 24 | LPCWSTR BADAPP_EXPORT wcspbrk_(LPCWSTR Source, LPCWSTR Find); 25 | 26 | typedef void (*Action)(void); 27 | 28 | typedef enum _ACTION_ICON 29 | { 30 | NoIcon, 31 | ApplicationIcon, // IDI_APPLICATION 32 | BadIcon, // IDI_HAND 33 | InformationIcon, // IDI_ASTERISK 34 | OsIcon, // IDI_WINLOGO 35 | ShieldIcon, // IDI_SHIELD 36 | GithubIcon, // IDI_GITHUB 37 | MaxIcons 38 | } ACTION_ICON; 39 | 40 | typedef struct _BAD_ACTION 41 | { 42 | LPCWSTR Name; 43 | LPCWSTR Description; 44 | Action Execute; 45 | ACTION_ICON iIcon; 46 | } BAD_ACTION; 47 | 48 | 49 | BOOL BADAPP_EXPORT IsRunAsAdmin(void); 50 | void BADAPP_EXPORT Register_Category(BAD_ACTION* Name, BAD_ACTION* Actions); 51 | 52 | void BADAPP_EXPORT Crash_Init(void); 53 | void BADAPP_EXPORT CriticalSection_Init(void); 54 | void BADAPP_EXPORT Handles_Init(void); 55 | void BADAPP_EXPORT Heap_Init(void); 56 | void BADAPP_EXPORT Diag_Init(void); 57 | 58 | -------------------------------------------------------------------------------- /BadApp/Handles.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PROJECT: BadApp 3 | * LICENSE: MIT (https://spdx.org/licenses/MIT) 4 | * PURPOSE: Handle bugs 5 | * COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen@reactos.org) 6 | */ 7 | 8 | #include "stdafx.h" 9 | 10 | 11 | void BADAPP_EXPORT SetInvalidFN(void) 12 | { 13 | HANDLE hHandle = ((HANDLE)(LONG_PTR)-2); 14 | SetEvent(hHandle); 15 | } 16 | 17 | void BADAPP_EXPORT SetNullFN(void) 18 | { 19 | HANDLE hHandle = ((HANDLE)(LONG_PTR)0); 20 | SetEvent(hHandle); 21 | } 22 | 23 | void BADAPP_EXPORT WaitForMultipleObjectsFN(void) 24 | { 25 | DWORD nCount = 0; 26 | WaitForMultipleObjects(nCount, NULL, TRUE, 100); 27 | } 28 | 29 | void BADAPP_EXPORT WrongEventFN(void) 30 | { 31 | HANDLE hSemaphore = CreateSemaphoreW(NULL, 0, 10, NULL); 32 | SetEvent(hSemaphore); 33 | CloseHandle(hSemaphore); 34 | } 35 | 36 | 37 | static BAD_ACTION g_Actions[] = 38 | { 39 | { 40 | L"SetEvent on invalid", 41 | L"Call SetEvent with a handle value of -2.", 42 | SetInvalidFN, 43 | BadIcon 44 | }, 45 | { 46 | L"SetEvent NULL handle", 47 | L"Call SetEvent with a NULL handle.", 48 | SetNullFN, 49 | BadIcon 50 | }, 51 | { 52 | L"WaitForMultipleObjects", 53 | L"Pass WaitForMultipleObjects a NULL pointer as handle array", 54 | WaitForMultipleObjectsFN, 55 | BadIcon 56 | }, 57 | { 58 | L"WrongEvent", 59 | L"Create a semaphore (CreateSemaphoreW), and use this to call SetEvent", 60 | WrongEventFN, 61 | BadIcon 62 | }, 63 | { NULL }, 64 | }; 65 | 66 | static BAD_ACTION g_Category = 67 | { 68 | L"Handles", 69 | L"Trigger various bugs related to invalid handles", 70 | NULL, 71 | NoIcon 72 | }; 73 | 74 | void BADAPP_EXPORT Handles_Init(void) 75 | { 76 | Register_Category(&g_Category, g_Actions); 77 | } 78 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | title: BadApp 4 | --- 5 | 6 | # BadApp 7 | 8 | ![Example](BadApp.png) 9 | 10 | ## Why BadApp? 11 | When developing tooling to detect / fix bad application behavior, it can be hard to find applications exposing this bad behavior in a controlled way. 12 | 13 | Combining all kinds of common application bugs in a simple application ensures that testing the detections or fixes is as simple as pressing a button. 14 | 15 | ## Features 16 | 17 | 18 | * Crashes: 19 | * Crash by calling a nullptr 20 | * Crash by reading from a nullptr 21 | * Crash by writing to a nullptr 22 | * Crash by causing a stack overflow 23 | * Crash by simulating the 'Abort' button from an assertion 24 | * Critical sections: 25 | * Terminate a thread holding a critical section 26 | * Free the memory of a critical section without deleting the section 27 | * Initialize a critical section twice 28 | * Delete a locked critical section 29 | * Release a critical section multiple times 30 | * Use a critical section without initializing it 31 | * Call VirtualFree on an active critical section 32 | * Use a private critical section (ntdll!FastPebLock) 33 | * Handles: 34 | * Call SetEvent on an invalid handle 35 | * Call SetEvent on a NULL handle 36 | * WaitForMultipleObjects with no handles 37 | * Call SetEvent on a Semaphore 38 | * Heap bugs: 39 | * Modify memory after it has been freed (Use after free) 40 | * Free memory twice (Double free) 41 | * Free allocation from another heap as it was allocated from 42 | * Write more data than was allocated (Buffer overflow) 43 | * Diagnostics: 44 | * Relaunch BadApp as Admin 45 | * Reset global FTH ticket state 46 | * Enable WER for BadApp (Current user, and when possible, all users) 47 | * Disable WER for BadApp (Current user, and when possible, all users) 48 | * Check the github release page for the latest release 49 | * Control the context the bugs will use: 50 | * Called directly from WndProc (Respond to button click) 51 | * Called from a message posted to the WndProc 52 | * Called from a new Win32 thread (CreateThread) 53 | * Called from a new Native thread (RtlCreateUserThread) 54 | * Called from a dialog init message (WM_INITDIALOG) 55 | * Heuristics: 56 | * Detect some known applied mitigations (SHIMS) 57 | * Detect the current 'ticket' state for the FTH 58 | * Detect the application WER status (disabled for current user, for all users) 59 | * Detect ZoneID 60 | * Detect GlobalFlag being set in the registry 61 | -------------------------------------------------------------------------------- /BadApp/Support.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PROJECT: BadApp 3 | * LICENSE: MIT (https://spdx.org/licenses/MIT) 4 | * PURPOSE: Various support functions 5 | * COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen@reactos.org) 6 | */ 7 | 8 | #include "stdafx.h" 9 | 10 | #pragma comment(linker,"\"/manifestdependency:type='win32' \ 11 | name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \ 12 | processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") 13 | 14 | static int (__cdecl* p_vsnwprintf)(wchar_t *_Dest, size_t _Count, const wchar_t *_Format, va_list _Args); 15 | int BADAPP_EXPORT vsnwprintf_(wchar_t *_Dest, size_t _Count, const wchar_t *_Format, va_list _Args) 16 | { 17 | if (!p_vsnwprintf) 18 | { 19 | HMODULE mod = GetModuleHandleW(L"ntdll.dll"); 20 | p_vsnwprintf = (int (__cdecl*)(wchar_t *, size_t, const wchar_t *, va_list))GetProcAddress(mod, "_vsnwprintf"); 21 | } 22 | return p_vsnwprintf(_Dest, _Count, _Format, _Args); 23 | } 24 | 25 | void BADAPP_EXPORT Output(wchar_t const* const _Format, ...) 26 | { 27 | va_list _ArgList; 28 | va_start(_ArgList, _Format); 29 | 30 | wchar_t buf[1024]; 31 | vsnwprintf_(buf, _countof(buf), _Format, _ArgList); 32 | va_end(_ArgList); 33 | StringCchCatW(buf, _countof(buf), L"\r\n"); 34 | OutputDebugStringW(buf); 35 | 36 | Gui_AddOutput(buf); 37 | } 38 | 39 | void BADAPP_EXPORT xwprintf(wchar_t *_Dest, size_t _Count, wchar_t const* const _Format, ...) 40 | { 41 | va_list _ArgList; 42 | va_start(_ArgList, _Format); 43 | 44 | vsnwprintf_(_Dest, _Count, _Format, _ArgList); 45 | va_end(_ArgList); 46 | } 47 | 48 | void* memset(void *s, int c, size_t len) 49 | { 50 | unsigned char *dst = s; 51 | while (len > 0) { 52 | *dst = (unsigned char) c; 53 | dst++; 54 | len--; 55 | } 56 | return s; 57 | } 58 | 59 | unsigned long (__cdecl *p_wcstoul)(const wchar_t* str, wchar_t** endptr, int base); 60 | unsigned long BADAPP_EXPORT wcstoul_(const wchar_t* str, wchar_t** endptr, int base) 61 | { 62 | if (!p_wcstoul) 63 | p_wcstoul = (unsigned long (__cdecl *)(const wchar_t *,wchar_t **,int))GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "wcstoul"); 64 | 65 | return p_wcstoul(str, endptr, base); 66 | } 67 | 68 | LPCWSTR BADAPP_EXPORT wcspbrk_(LPCWSTR Source, LPCWSTR Find) 69 | { 70 | for (;*Source; ++Source) 71 | { 72 | LPCWSTR FindCur; 73 | for (FindCur = Find; *FindCur; ++FindCur) 74 | { 75 | if (*FindCur == *Source) 76 | return Source; 77 | } 78 | } 79 | return NULL; 80 | } 81 | 82 | -------------------------------------------------------------------------------- /BadApp/BadApp.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hh;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | 44 | 45 | Header Files 46 | 47 | 48 | Header Files 49 | 50 | 51 | Header Files 52 | 53 | 54 | Header Files 55 | 56 | 57 | Header Files 58 | 59 | 60 | 61 | 62 | Resource Files 63 | 64 | 65 | Resource Files 66 | 67 | 68 | Resource Files 69 | 70 | 71 | 72 | 73 | Resource Files 74 | 75 | 76 | 77 | 78 | Resource Files 79 | 80 | 81 | -------------------------------------------------------------------------------- /docs/_layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | {% seo %} 12 | 13 | 14 | 15 | 16 | 17 |
18 |
19 | {% if site.github.is_project_page %} 20 | View on GitHub 21 | {% endif %} 22 | 23 |

{{ site.title | default: site.github.repository_name }}

24 |

{{ site.description | default: site.github.project_tagline }}

25 | 26 | {% if site.show_downloads %} 27 |
28 | 29 | Go to the downloads 30 | 31 |
32 | {% endif %} 33 |
34 |
35 | 36 | 37 |
38 |
39 | {{ content }} 40 |
41 |
42 | 43 | 44 | 57 | 58 | {% if site.google_analytics %} 59 | 67 | {% endif %} 68 | 69 | 70 | -------------------------------------------------------------------------------- /BadApp/Crash.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PROJECT: BadApp 3 | * LICENSE: MIT (https://spdx.org/licenses/MIT) 4 | * PURPOSE: Crashing functions 5 | * COPYRIGHT: Copyright 2018-2020 Mark Jansen (mark.jansen@reactos.org) 6 | */ 7 | 8 | #include "stdafx.h" 9 | #include 10 | 11 | void BADAPP_EXPORT CallNullptrFN(void) 12 | { 13 | // Hide from the compiler that we are calling a nullptr 14 | Action Proc = (Action)GetProcAddress(0, "__this_function_does_not_exist_but_my_compiler_doesnt_know_that__"); 15 | 16 | Proc(); 17 | if (Proc == CallNullptrFN) 18 | Output(L"Done."); // Prevent tail call optimalization 19 | } 20 | 21 | void BADAPP_EXPORT ReadNullptrFN(void) 22 | { 23 | PDWORD DwordPtr = (PDWORD)NULL; 24 | DWORD Value = *DwordPtr; 25 | Output(L"Value: %u", Value); 26 | } 27 | 28 | void BADAPP_EXPORT WriteNullptrFN(void) 29 | { 30 | PDWORD DwordPtr = (PDWORD)NULL; 31 | *DwordPtr = 0x112233; 32 | } 33 | 34 | void BADAPP_EXPORT StackOverflowFN(void) 35 | { 36 | // Suppress warnings / hide from the compiler what we are doing here 37 | Action recurse = (Action)GetProcAddress(0, "StackOverflowFN"); 38 | if (recurse == NULL) 39 | recurse = StackOverflowFN; 40 | 41 | recurse(); 42 | if (recurse == CallNullptrFN) 43 | Output(L"Done."); // Prevent tail call optimalization 44 | } 45 | 46 | void BADAPP_EXPORT SimulateAssertionFN(void) 47 | { 48 | int (__cdecl* p_raise)(_In_ int _Signal); 49 | void (__cdecl* p__exit)(_In_ int _Code); 50 | 51 | HMODULE mod = GetModuleHandleW(L"msvcrt.dll"); 52 | assert(mod != 0); 53 | 54 | if (mod) 55 | { 56 | p_raise = (int (__cdecl *)(int))GetProcAddress(mod, "raise"); 57 | if (p_raise) 58 | { 59 | p__exit = (void (__cdecl *)(int))GetProcAddress(mod, "_exit"); 60 | if (p__exit) 61 | { 62 | p_raise(SIGABRT); 63 | p__exit(3); 64 | // Unreachable 65 | assert(0); 66 | } 67 | else 68 | { 69 | Output(L"Unable to resolve msvcrt!_exit"); 70 | } 71 | } 72 | else 73 | { 74 | Output(L"Unable to resolve msvcrt!raise"); 75 | } 76 | } 77 | else 78 | { 79 | Output(L"Unable to get a reference to msvcrt.dll"); 80 | } 81 | } 82 | 83 | static BAD_ACTION g_Actions[] = 84 | { 85 | { 86 | L"Call nullptr", 87 | L"Crash by calling a nullptr", 88 | CallNullptrFN, 89 | BadIcon 90 | }, 91 | { 92 | L"Read nullptr", 93 | L"Crash by reading from a nullptr", 94 | ReadNullptrFN, 95 | BadIcon 96 | }, 97 | { 98 | L"Write nullptr", 99 | L"Crash by writing to a nullptr", 100 | WriteNullptrFN, 101 | BadIcon 102 | }, 103 | { 104 | L"Stack overflow", 105 | L"Crash by causing a stack overflow", 106 | StackOverflowFN, 107 | BadIcon 108 | }, 109 | { 110 | L"AssertionAbort", 111 | L"Simulate the 'abort' button on an assertion dialog", 112 | SimulateAssertionFN, 113 | BadIcon 114 | }, 115 | { NULL, NULL }, 116 | }; 117 | 118 | static BAD_ACTION g_Category = 119 | { 120 | L"Crashes", 121 | L"Apply various techniques to crash BadApp.", 122 | NULL 123 | }; 124 | 125 | void BADAPP_EXPORT Crash_Init(void) 126 | { 127 | Register_Category(&g_Category, g_Actions); 128 | } 129 | -------------------------------------------------------------------------------- /BadApp/Heap.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PROJECT: BadApp 3 | * LICENSE: MIT (https://spdx.org/licenses/MIT) 4 | * PURPOSE: Heap bugs 5 | * COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen@reactos.org) 6 | */ 7 | 8 | #include "stdafx.h" 9 | 10 | static HANDLE g_Heap1; 11 | static HANDLE g_Heap2; 12 | 13 | #define ALLOCATION_SIZE 0x0d 14 | 15 | PVOID BADAPP_EXPORT DoAllocation(void) 16 | { 17 | PVOID Allocation = HeapAlloc(g_Heap1, 0, ALLOCATION_SIZE); 18 | Output(L"Alloc(Heap1, 0x%x)=%p", ALLOCATION_SIZE, Allocation); 19 | return Allocation; 20 | } 21 | 22 | void BADAPP_EXPORT NormalFree1FN(void) 23 | { 24 | PVOID Allocation = DoAllocation(); 25 | HeapFree(g_Heap1, 0, Allocation); 26 | } 27 | 28 | void BADAPP_EXPORT NormalFree2FN(void) 29 | { 30 | PVOID Allocation = HeapAlloc(g_Heap2, 0, ALLOCATION_SIZE); 31 | Output(L"Alloc(Heap2, 0x%x)=%p", ALLOCATION_SIZE, Allocation); 32 | HeapFree(g_Heap2, 0, Allocation); 33 | } 34 | 35 | void BADAPP_EXPORT UseAfterFreeFN(void) 36 | { 37 | PVOID Allocation = DoAllocation(); 38 | PBYTE ptr = (PBYTE)Allocation; 39 | HeapFree(g_Heap1, 0, Allocation); 40 | ptr[0] = 0x11; 41 | } 42 | 43 | void BADAPP_EXPORT DoubleFreeFN(void) 44 | { 45 | PVOID Allocation = DoAllocation(); 46 | HeapFree(g_Heap1, 0, Allocation); 47 | HeapFree(g_Heap1, 0, Allocation); 48 | } 49 | 50 | void BADAPP_EXPORT WrongHeapFN(void) 51 | { 52 | PVOID Allocation = DoAllocation(); 53 | HeapFree(g_Heap2, 0, Allocation); 54 | } 55 | 56 | void BADAPP_EXPORT OverflowFN(void) 57 | { 58 | PVOID Allocation = DoAllocation(); 59 | PBYTE ptr = (PBYTE)Allocation; 60 | ptr[ALLOCATION_SIZE] = 0x11; 61 | HeapFree(g_Heap1, 0, Allocation); 62 | } 63 | 64 | void BADAPP_EXPORT LeakFN(void) 65 | { 66 | DoAllocation(); 67 | } 68 | 69 | static BAD_ACTION g_Actions[] = 70 | { 71 | { 72 | L"Normal alloc Heap1", 73 | L"Allocate and free memory using HeapAlloc and HeapFree. This can be used to trigger checks in the heap functions. This function operates on Heap1.", 74 | NormalFree1FN, 75 | NoIcon 76 | }, 77 | { 78 | L"Normal alloc Heap2", 79 | L"Allocate and free memory using HeapAlloc and HeapFree. This can be used to trigger checks in the heap functions. This function operates on Heap1.", 80 | NormalFree2FN, 81 | NoIcon 82 | }, 83 | { 84 | L"Use after free", 85 | L"Free memory using HeapFree, and modify it afterwards.", 86 | UseAfterFreeFN, 87 | BadIcon 88 | }, 89 | { 90 | L"Double free", 91 | L"Free memory twice using HeapFree.", 92 | DoubleFreeFN, 93 | BadIcon 94 | }, 95 | { 96 | L"Free wrong heap", 97 | L"Allocate memory using HeapAlloc from Heap1, then free it using HeapFree from Heap2.", 98 | WrongHeapFN, 99 | BadIcon 100 | }, 101 | { 102 | L"Buffer overflow", 103 | L"Write 2 bytes past the allocated space, then free the memory using HeapFree.", 104 | OverflowFN, 105 | BadIcon 106 | }, 107 | { 108 | L"Leak allocation", 109 | L"Allocate memory, but never free it.", 110 | LeakFN, 111 | BadIcon 112 | }, 113 | { NULL }, 114 | }; 115 | 116 | static BAD_ACTION g_Category = 117 | { 118 | L"Heap", 119 | L"Trigger various heap bugs", 120 | NULL, 121 | NoIcon 122 | }; 123 | 124 | void BADAPP_EXPORT Heap_Init(void) 125 | { 126 | g_Heap1 = HeapCreate(0, 0, 0); 127 | g_Heap2 = HeapCreate(0, 0, 0); 128 | 129 | Register_Category(&g_Category, g_Actions); 130 | Output(L"Heap1: %p", g_Heap1); 131 | Output(L"Heap2: %p", g_Heap2); 132 | } 133 | 134 | 135 | -------------------------------------------------------------------------------- /BadApp/CriticalSection.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PROJECT: BadApp 3 | * LICENSE: MIT (https://spdx.org/licenses/MIT) 4 | * PURPOSE: CriticalSection bugs 5 | * COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen@reactos.org) 6 | */ 7 | 8 | #include "stdafx.h" 9 | 10 | HANDLE BADAPP_EXPORT CSHeap(void) 11 | { 12 | return GetProcessHeap(); 13 | } 14 | 15 | 16 | LPCRITICAL_SECTION BADAPP_EXPORT CreateAndInitializeSection(void) 17 | { 18 | HANDLE hHeap = CSHeap(); 19 | LPCRITICAL_SECTION lpSection = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(*lpSection)); 20 | 21 | InitializeCriticalSection(lpSection); 22 | return lpSection; 23 | } 24 | 25 | 26 | DWORD BADAPP_EXPORT WINAPI TerminateFN_ThreadProc(LPVOID pArg) 27 | { 28 | LPCRITICAL_SECTION lpSection = CreateAndInitializeSection(); 29 | UNREFERENCED_PARAMETER(pArg); 30 | 31 | EnterCriticalSection(lpSection); 32 | 33 | ExitThread(0); 34 | } 35 | 36 | void BADAPP_EXPORT TerminateFN(void) 37 | { 38 | HANDLE hThread; 39 | 40 | hThread = CreateThread(NULL, 0, TerminateFN_ThreadProc, NULL, 0, NULL); 41 | WaitForSingleObject(hThread, 2000); 42 | CloseHandle(hThread); 43 | } 44 | 45 | void BADAPP_EXPORT FreeFN(void) 46 | { 47 | LPCRITICAL_SECTION lpSection = CreateAndInitializeSection(); 48 | 49 | HeapFree(CSHeap(), 0, lpSection); 50 | } 51 | 52 | void BADAPP_EXPORT InitTwiceFN(void) 53 | { 54 | LPCRITICAL_SECTION lpSection = CreateAndInitializeSection(); 55 | 56 | /* Initialize for the second time */ 57 | InitializeCriticalSection(lpSection); 58 | 59 | DeleteCriticalSection(lpSection); 60 | 61 | HeapFree(CSHeap(), 0, lpSection); 62 | } 63 | 64 | 65 | typedef struct _EventData 66 | { 67 | LPCRITICAL_SECTION lpSection; 68 | HANDLE hLockHeld; 69 | HANDLE hExitThread; 70 | } EventData; 71 | 72 | DWORD BADAPP_EXPORT WINAPI DeleteHeldSectionFN_ThreadProc(LPVOID pArg) 73 | { 74 | DWORD dwWait; 75 | EventData Data = *(EventData*)pArg; 76 | 77 | EnterCriticalSection(Data.lpSection); 78 | SetEvent(Data.hLockHeld); 79 | dwWait = WaitForSingleObject(Data.hExitThread, 10 * 1000); 80 | 81 | if (dwWait != WAIT_OBJECT_0) 82 | Output(L"Failed to wait for the exit event (%u)", dwWait); 83 | 84 | return 0; 85 | } 86 | 87 | void BADAPP_EXPORT DeleteHeldSectionFN(void) 88 | { 89 | EventData Evt; 90 | HANDLE hThread; 91 | DWORD dwWait; 92 | 93 | Evt.lpSection = CreateAndInitializeSection(); 94 | Evt.hLockHeld = CreateEvent(NULL, TRUE, FALSE, NULL); 95 | Evt.hExitThread = CreateEvent(NULL, TRUE, FALSE, NULL); 96 | 97 | hThread = CreateThread(NULL, 0, DeleteHeldSectionFN_ThreadProc, (LPVOID)&Evt, 0, NULL); 98 | dwWait = WaitForSingleObject(Evt.hLockHeld, 2 * 1000); 99 | if (dwWait != WAIT_OBJECT_0) 100 | Output(L"Failed to wait for the section to be entered (%u)", dwWait); 101 | 102 | DeleteCriticalSection(Evt.lpSection); 103 | SetEvent(Evt.hExitThread); 104 | 105 | dwWait = WaitForSingleObject(hThread, 2 * 1000); 106 | if (dwWait != WAIT_OBJECT_0) 107 | Output(L"Failed to wait for the thread to be done (%u)", dwWait); 108 | 109 | CloseHandle(hThread); 110 | CloseHandle(Evt.hLockHeld); 111 | CloseHandle(Evt.hExitThread); 112 | 113 | HeapFree(CSHeap(), 0, Evt.lpSection); 114 | } 115 | 116 | void BADAPP_EXPORT ReleaseMultipleFN(void) 117 | { 118 | LPCRITICAL_SECTION lpSection = CreateAndInitializeSection(); 119 | 120 | EnterCriticalSection(lpSection); 121 | LeaveCriticalSection(lpSection); 122 | LeaveCriticalSection(lpSection); 123 | 124 | DeleteCriticalSection(lpSection); 125 | HeapFree(CSHeap(), 0, lpSection); 126 | } 127 | 128 | void BADAPP_EXPORT UseNoInitFN(void) 129 | { 130 | CRITICAL_SECTION Section = { NULL }; 131 | 132 | EnterCriticalSection(&Section); 133 | } 134 | 135 | void BADAPP_EXPORT VirtualFreeFN(void) 136 | { 137 | LPCRITICAL_SECTION lpSection = VirtualAlloc(NULL, sizeof(*lpSection), MEM_COMMIT, PAGE_READWRITE); 138 | 139 | InitializeCriticalSection(lpSection); 140 | 141 | VirtualFree(lpSection, 0, MEM_RELEASE); 142 | } 143 | 144 | typedef struct _DUM_PEB 145 | { 146 | INT_PTR Flags; 147 | PVOID Mutant; 148 | PVOID ImageBaseAddress; 149 | PVOID Ldr; 150 | PVOID ProcessParameters; 151 | PVOID SubSystemData; 152 | HANDLE ProcessHeap; 153 | RTL_CRITICAL_SECTION* FastPebLock; 154 | } DUM_PEB; 155 | 156 | #ifdef _WIN64 157 | C_ASSERT(offsetof(DUM_PEB, FastPebLock) == 0x38); 158 | #else 159 | C_ASSERT(offsetof(DUM_PEB, FastPebLock) == 0x1c); 160 | #endif 161 | 162 | void BADAPP_EXPORT PrivateSectionFN(void) 163 | { 164 | DUM_PEB* peb; 165 | 166 | #ifdef _WIN64 167 | peb = (DUM_PEB*)__readgsqword(0x60); 168 | #else 169 | peb = (DUM_PEB*)__readfsdword(0x30); 170 | #endif 171 | 172 | EnterCriticalSection(peb->FastPebLock); 173 | LeaveCriticalSection(peb->FastPebLock); 174 | } 175 | 176 | static BAD_ACTION g_Actions[] = 177 | { 178 | { 179 | L"Terminate thread", 180 | L"Terminate a thread holding a critical section", 181 | TerminateFN, 182 | BadIcon 183 | }, 184 | { 185 | L"Free without delete", 186 | L"Free an allocated critical section without deleting it.", 187 | FreeFN, 188 | BadIcon 189 | }, 190 | { 191 | L"Initialize twice", 192 | L"Initialize a critical section twice.", 193 | InitTwiceFN, 194 | BadIcon 195 | }, 196 | { 197 | L"Delete locked section", 198 | L"Delete a critical section while it is being held.", 199 | DeleteHeldSectionFN, 200 | BadIcon 201 | }, 202 | { 203 | L"Release multiple", 204 | L"Release a critical section multiple times.", 205 | ReleaseMultipleFN, 206 | BadIcon 207 | }, 208 | { 209 | L"Use without init", 210 | L"Use a critical section without initializing it.", 211 | UseNoInitFN, 212 | BadIcon 213 | }, 214 | { 215 | L"Call VirtualFree", 216 | L"Call VirtualFree on a critical section without releasing it.", 217 | VirtualFreeFN, 218 | BadIcon 219 | }, 220 | { 221 | L"Private section", 222 | L"Use an ntdll private section (ntdll!FastPebLock)", 223 | PrivateSectionFN, 224 | BadIcon 225 | }, 226 | 227 | { NULL }, 228 | }; 229 | 230 | static BAD_ACTION g_Category = 231 | { 232 | L"Critical Section", 233 | L"Trigger various bugs related to critical sections", 234 | NULL, 235 | NoIcon 236 | }; 237 | 238 | void BADAPP_EXPORT CriticalSection_Init(void) 239 | { 240 | Register_Category(&g_Category, g_Actions); 241 | } 242 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015/2017 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # Visual Studio 2017 auto generated files 33 | Generated\ Files/ 34 | 35 | # MSTest test Results 36 | [Tt]est[Rr]esult*/ 37 | [Bb]uild[Ll]og.* 38 | 39 | # NUNIT 40 | *.VisualState.xml 41 | TestResult.xml 42 | 43 | # Build Results of an ATL Project 44 | [Dd]ebugPS/ 45 | [Rr]eleasePS/ 46 | dlldata.c 47 | 48 | # Benchmark Results 49 | BenchmarkDotNet.Artifacts/ 50 | 51 | # .NET Core 52 | project.lock.json 53 | project.fragment.lock.json 54 | artifacts/ 55 | **/Properties/launchSettings.json 56 | 57 | # StyleCop 58 | StyleCopReport.xml 59 | 60 | # Files built by Visual Studio 61 | *_i.c 62 | *_p.c 63 | *_i.h 64 | *.ilk 65 | *.meta 66 | *.obj 67 | *.iobj 68 | *.pch 69 | *.pdb 70 | *.ipdb 71 | *.pgc 72 | *.pgd 73 | *.rsp 74 | *.sbr 75 | *.tlb 76 | *.tli 77 | *.tlh 78 | *.tmp 79 | *.tmp_proj 80 | *.log 81 | *.vspscc 82 | *.vssscc 83 | .builds 84 | *.pidb 85 | *.svclog 86 | *.scc 87 | 88 | # Chutzpah Test files 89 | _Chutzpah* 90 | 91 | # Visual C++ cache files 92 | ipch/ 93 | *.aps 94 | *.ncb 95 | *.opendb 96 | *.opensdf 97 | *.sdf 98 | *.cachefile 99 | *.VC.db 100 | *.VC.VC.opendb 101 | 102 | # Visual Studio profiler 103 | *.psess 104 | *.vsp 105 | *.vspx 106 | *.sap 107 | 108 | # Visual Studio Trace Files 109 | *.e2e 110 | 111 | # TFS 2012 Local Workspace 112 | $tf/ 113 | 114 | # Guidance Automation Toolkit 115 | *.gpState 116 | 117 | # ReSharper is a .NET coding add-in 118 | _ReSharper*/ 119 | *.[Rr]e[Ss]harper 120 | *.DotSettings.user 121 | 122 | # JustCode is a .NET coding add-in 123 | .JustCode 124 | 125 | # TeamCity is a build add-in 126 | _TeamCity* 127 | 128 | # DotCover is a Code Coverage Tool 129 | *.dotCover 130 | 131 | # AxoCover is a Code Coverage Tool 132 | .axoCover/* 133 | !.axoCover/settings.json 134 | 135 | # Visual Studio code coverage results 136 | *.coverage 137 | *.coveragexml 138 | 139 | # NCrunch 140 | _NCrunch_* 141 | .*crunch*.local.xml 142 | nCrunchTemp_* 143 | 144 | # MightyMoose 145 | *.mm.* 146 | AutoTest.Net/ 147 | 148 | # Web workbench (sass) 149 | .sass-cache/ 150 | 151 | # Installshield output folder 152 | [Ee]xpress/ 153 | 154 | # DocProject is a documentation generator add-in 155 | DocProject/buildhelp/ 156 | DocProject/Help/*.HxT 157 | DocProject/Help/*.HxC 158 | DocProject/Help/*.hhc 159 | DocProject/Help/*.hhk 160 | DocProject/Help/*.hhp 161 | DocProject/Help/Html2 162 | DocProject/Help/html 163 | 164 | # Click-Once directory 165 | publish/ 166 | 167 | # Publish Web Output 168 | *.[Pp]ublish.xml 169 | *.azurePubxml 170 | # Note: Comment the next line if you want to checkin your web deploy settings, 171 | # but database connection strings (with potential passwords) will be unencrypted 172 | *.pubxml 173 | *.publishproj 174 | 175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 176 | # checkin your Azure Web App publish settings, but sensitive information contained 177 | # in these scripts will be unencrypted 178 | PublishScripts/ 179 | 180 | # NuGet Packages 181 | *.nupkg 182 | # The packages folder can be ignored because of Package Restore 183 | **/[Pp]ackages/* 184 | # except build/, which is used as an MSBuild target. 185 | !**/[Pp]ackages/build/ 186 | # Uncomment if necessary however generally it will be regenerated when needed 187 | #!**/[Pp]ackages/repositories.config 188 | # NuGet v3's project.json files produces more ignorable files 189 | *.nuget.props 190 | *.nuget.targets 191 | 192 | # Microsoft Azure Build Output 193 | csx/ 194 | *.build.csdef 195 | 196 | # Microsoft Azure Emulator 197 | ecf/ 198 | rcf/ 199 | 200 | # Windows Store app package directories and files 201 | AppPackages/ 202 | BundleArtifacts/ 203 | Package.StoreAssociation.xml 204 | _pkginfo.txt 205 | *.appx 206 | 207 | # Visual Studio cache files 208 | # files ending in .cache can be ignored 209 | *.[Cc]ache 210 | # but keep track of directories ending in .cache 211 | !*.[Cc]ache/ 212 | 213 | # Others 214 | ClientBin/ 215 | ~$* 216 | *~ 217 | *.dbmdl 218 | *.dbproj.schemaview 219 | *.jfm 220 | *.pfx 221 | *.publishsettings 222 | orleans.codegen.cs 223 | 224 | # Including strong name files can present a security risk 225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 226 | #*.snk 227 | 228 | # Since there are multiple workflows, uncomment next line to ignore bower_components 229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 230 | #bower_components/ 231 | 232 | # RIA/Silverlight projects 233 | Generated_Code/ 234 | 235 | # Backup & report files from converting an old project file 236 | # to a newer Visual Studio version. Backup files are not needed, 237 | # because we have git ;-) 238 | _UpgradeReport_Files/ 239 | Backup*/ 240 | UpgradeLog*.XML 241 | UpgradeLog*.htm 242 | ServiceFabricBackup/ 243 | *.rptproj.bak 244 | 245 | # SQL Server files 246 | *.mdf 247 | *.ldf 248 | *.ndf 249 | 250 | # Business Intelligence projects 251 | *.rdl.data 252 | *.bim.layout 253 | *.bim_*.settings 254 | *.rptproj.rsuser 255 | 256 | # Microsoft Fakes 257 | FakesAssemblies/ 258 | 259 | # GhostDoc plugin setting file 260 | *.GhostDoc.xml 261 | 262 | # Node.js Tools for Visual Studio 263 | .ntvs_analysis.dat 264 | node_modules/ 265 | 266 | # Visual Studio 6 build log 267 | *.plg 268 | 269 | # Visual Studio 6 workspace options file 270 | *.opt 271 | 272 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 273 | *.vbw 274 | 275 | # Visual Studio LightSwitch build output 276 | **/*.HTMLClient/GeneratedArtifacts 277 | **/*.DesktopClient/GeneratedArtifacts 278 | **/*.DesktopClient/ModelManifest.xml 279 | **/*.Server/GeneratedArtifacts 280 | **/*.Server/ModelManifest.xml 281 | _Pvt_Extensions 282 | 283 | # Paket dependency manager 284 | .paket/paket.exe 285 | paket-files/ 286 | 287 | # FAKE - F# Make 288 | .fake/ 289 | 290 | # JetBrains Rider 291 | .idea/ 292 | *.sln.iml 293 | 294 | # CodeRush 295 | .cr/ 296 | 297 | # Python Tools for Visual Studio (PTVS) 298 | __pycache__/ 299 | *.pyc 300 | 301 | # Cake - Uncomment if you are using it 302 | # tools/** 303 | # !tools/packages.config 304 | 305 | # Tabs Studio 306 | *.tss 307 | 308 | # Telerik's JustMock configuration file 309 | *.jmconfig 310 | 311 | # BizTalk build output 312 | *.btp.cs 313 | *.btm.cs 314 | *.odx.cs 315 | *.xsd.cs 316 | 317 | # OpenCover UI analysis results 318 | OpenCover/ 319 | 320 | # Azure Stream Analytics local run output 321 | ASALocalRun/ 322 | 323 | # MSBuild Binary and Structured Log 324 | *.binlog 325 | 326 | # NVidia Nsight GPU debugger configuration file 327 | *.nvuser 328 | 329 | # MFractors (Xamarin productivity tool) working folder 330 | .mfractor/ 331 | generated_git_version.h 332 | -------------------------------------------------------------------------------- /BadApp/BadApp.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | Debug 14 | x64 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | Create 30 | Create 31 | Create 32 | Create 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | {C42D2E62-1DBE-46AF-8D38-4CE43CB7E40A} 56 | Win32Proj 57 | BadApp 58 | 5.1 59 | 60 | 61 | 62 | Application 63 | true 64 | v140_xp 65 | Unicode 66 | 67 | 68 | Application 69 | false 70 | v140_xp 71 | true 72 | Unicode 73 | 74 | 75 | Application 76 | true 77 | v140_xp 78 | Unicode 79 | 80 | 81 | Application 82 | false 83 | v140_xp 84 | true 85 | Unicode 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | true 107 | $(ProjectName)-$(PlatformTarget) 108 | 109 | 110 | true 111 | $(ProjectName)-$(PlatformTarget) 112 | 113 | 114 | false 115 | $(SolutionDir)bin\ 116 | $(ProjectName)-$(PlatformTarget) 117 | 118 | 119 | false 120 | $(SolutionDir)bin\ 121 | $(ProjectName)-$(PlatformTarget) 122 | 123 | 124 | 125 | Use 126 | Level3 127 | Disabled 128 | WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions) 129 | true 130 | false 131 | MultiThreadedDebug 132 | 133 | 134 | Windows 135 | true 136 | comctl32.lib;wininet.lib;version.lib;%(AdditionalDependencies) 137 | 138 | 139 | /IGNORE:4216 /EXPORT:wWinMain %(AdditionalOptions) 140 | shell32.dll;wininet.dll 141 | 142 | 143 | $(SolutionDir)GenVersion.bat 144 | 145 | 146 | Generating version header 147 | 148 | 149 | 150 | 151 | Use 152 | Level3 153 | Disabled 154 | _DEBUG;_WINDOWS;%(PreprocessorDefinitions) 155 | true 156 | false 157 | MultiThreadedDebug 158 | 159 | 160 | Windows 161 | true 162 | 5.01 163 | comctl32.lib;wininet.lib;version.lib;%(AdditionalDependencies) 164 | 165 | 166 | /IGNORE:4216 /EXPORT:wWinMain %(AdditionalOptions) 167 | shell32.dll;wininet.dll 168 | 169 | 170 | $(SolutionDir)GenVersion.bat 171 | 172 | 173 | Generating version header 174 | 175 | 176 | 177 | 178 | Level4 179 | Use 180 | Disabled 181 | true 182 | false 183 | WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 184 | true 185 | MultiThreaded 186 | false 187 | true 188 | false 189 | false 190 | OldStyle 191 | Disabled 192 | 193 | 194 | Windows 195 | true 196 | true 197 | true 198 | comctl32.lib;wininet.lib;version.lib;%(AdditionalDependencies) 199 | wWinMain 200 | Default 201 | /IGNORE:4216 /EXPORT:wWinMain %(AdditionalOptions) 202 | shell32.dll;wininet.dll 203 | 204 | 205 | $(SolutionDir)GenVersion.bat 206 | 207 | 208 | Generating version header 209 | 210 | 211 | 212 | 213 | Level4 214 | Use 215 | Disabled 216 | true 217 | false 218 | NDEBUG;_WINDOWS;%(PreprocessorDefinitions) 219 | true 220 | MultiThreaded 221 | false 222 | true 223 | false 224 | false 225 | OldStyle 226 | false 227 | Disabled 228 | 229 | 230 | Windows 231 | true 232 | true 233 | true 234 | comctl32.lib;wininet.lib;version.lib;%(AdditionalDependencies) 235 | wWinMain 236 | Default 237 | /IGNORE:4216 /EXPORT:wWinMain %(AdditionalOptions) 238 | shell32.dll;wininet.dll 239 | 240 | 241 | $(SolutionDir)GenVersion.bat 242 | 243 | 244 | Generating version header 245 | 246 | 247 | 248 | 249 | 250 | -------------------------------------------------------------------------------- /BadApp/Diag.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PROJECT: BadApp 3 | * LICENSE: MIT (https://spdx.org/licenses/MIT) 4 | * PURPOSE: Diagnostic / support functions 5 | * COPYRIGHT: Copyright 2018,2019 Mark Jansen (mark.jansen@reactos.org) 6 | */ 7 | 8 | #include "stdafx.h" 9 | #include "version.h" 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | PCWSTR BADAPP_EXPORT AppExecutable() 16 | { 17 | static WCHAR PathBuffer[MAX_PATH * 4] = { 0 }; 18 | 19 | if (!PathBuffer[0]) 20 | GetModuleFileNameW(NULL, PathBuffer, _countof(PathBuffer)); 21 | 22 | return PathBuffer; 23 | } 24 | 25 | 26 | #define FTH_STATE_KEY L"SOFTWARE\\Microsoft\\FTH\\State" 27 | 28 | #define MAX_LAYER_LENGTH 256 29 | #define GPLK_USER 1 30 | #define GPLK_MACHINE 2 31 | 32 | typedef BOOL(WINAPI *SdbGetPermLayerKeysProc)(PCWSTR wszPath, PWSTR pwszLayers, PDWORD pdwBytes, DWORD dwFlags); 33 | 34 | 35 | void BADAPP_EXPORT AnalyzeShims(LPCWSTR Executable) 36 | { 37 | WCHAR Buffer[MAX_LAYER_LENGTH]; 38 | DWORD dwBytes; 39 | HMODULE hModule = LoadLibraryW(L"apphelp.dll"); 40 | SdbGetPermLayerKeysProc GetPerm = (SdbGetPermLayerKeysProc)GetProcAddress(hModule, "SdbGetPermLayerKeys"); 41 | if (GetPerm) 42 | { 43 | dwBytes = sizeof(Buffer); 44 | memset(Buffer, 0, sizeof(Buffer)); 45 | if (GetPerm(Executable, Buffer, &dwBytes, GPLK_USER)) 46 | { 47 | Output(L"Shims(USER): %s", Buffer); 48 | } 49 | dwBytes = sizeof(Buffer); 50 | memset(Buffer, 0, sizeof(Buffer)); 51 | if (GetPerm(Executable, Buffer, &dwBytes, GPLK_MACHINE)) 52 | { 53 | Output(L"Shims(MACHINE): %s", Buffer); 54 | } 55 | } 56 | FreeLibrary(hModule); 57 | } 58 | 59 | BOOL BADAPP_EXPORT ShowChar(WCHAR ch) 60 | { 61 | if (ch >= 0x20 && ch <= 0x7e) 62 | { 63 | return TRUE; 64 | } 65 | return FALSE; 66 | } 67 | 68 | #define CHARS_PER_LINE 8 69 | 70 | void BADAPP_EXPORT AnalyzeFTHState(LPCWSTR Executable) 71 | { 72 | HKEY StateKey; 73 | LSTATUS Status; 74 | BYTE Data[0x80]; 75 | WCHAR Buffer[100], TextBuffer[CHARS_PER_LINE + 1], Tmp[40]; 76 | DWORD x, y, dwType, dwDataSize; 77 | 78 | Status = RegOpenKeyExW(HKEY_LOCAL_MACHINE, FTH_STATE_KEY, 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY | KEY_ENUMERATE_SUB_KEYS, &StateKey); 79 | if (Status == ERROR_SUCCESS) 80 | { 81 | dwDataSize = sizeof(Data); 82 | 83 | Status = RegQueryValueExW(StateKey, Executable, NULL, &dwType, Data, &dwDataSize); 84 | if (Status == ERROR_SUCCESS) 85 | { 86 | Output(L"HKLM\\%s\\", FTH_STATE_KEY); 87 | Output(L" [%s]=", Executable); 88 | for (y = 0; y < dwDataSize; y += CHARS_PER_LINE) 89 | { 90 | Buffer[0] = UNICODE_NULL; 91 | memset(TextBuffer, 0, sizeof(TextBuffer)); 92 | for (x = 0; x < CHARS_PER_LINE; ++x) 93 | { 94 | DWORD n = x + y; 95 | if (n < dwDataSize) 96 | { 97 | xwprintf(Tmp, _countof(Tmp), L" %02X", Data[n]); 98 | StringCchCatW(Buffer, _countof(Buffer), Tmp); 99 | TextBuffer[n % CHARS_PER_LINE] = ShowChar(Data[n]) ? Data[n] : '.'; 100 | } 101 | else 102 | { 103 | StringCchCatW(Buffer, _countof(Buffer), L" "); 104 | } 105 | if (x+1 == CHARS_PER_LINE / 2) 106 | { 107 | StringCchCatW(Buffer, _countof(Buffer), L" "); 108 | } 109 | } 110 | Output(L"0x%04X %s %s", y, Buffer, TextBuffer); 111 | } 112 | } 113 | 114 | CloseHandle(StateKey); 115 | } 116 | } 117 | 118 | BOOL BADAPP_EXPORT RelaunchAsAdmin() 119 | { 120 | BOOL bSuccess = TRUE; 121 | SHELLEXECUTEINFOW shExInfo = { sizeof(shExInfo) }; 122 | shExInfo.lpVerb = L"runas"; 123 | shExInfo.fMask = SEE_MASK_UNICODE | SEE_MASK_NOZONECHECKS | SEE_MASK_NOASYNC; 124 | shExInfo.lpFile = AppExecutable(); 125 | shExInfo.nShow = SW_SHOW; 126 | 127 | 128 | CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); 129 | if (!ShellExecuteExW(&shExInfo)) 130 | { 131 | Output(L"Unable to start task"); 132 | bSuccess = FALSE; 133 | } 134 | CoUninitialize(); 135 | return bSuccess; 136 | } 137 | 138 | static BOOL g_bAdmin = -1; 139 | BOOL BADAPP_EXPORT IsRunAsAdmin() 140 | { 141 | if (g_bAdmin == -1) 142 | { 143 | BOOL fIsRunAsAdmin = FALSE; 144 | PSID pAdministratorsGroup = NULL; 145 | 146 | // Allocate and initialize a SID of the administrators group. 147 | SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; 148 | if (AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 149 | 0, 0, 0, 0, 0, 0, &pAdministratorsGroup)) 150 | { 151 | if (!CheckTokenMembership(NULL, pAdministratorsGroup, &fIsRunAsAdmin)) 152 | fIsRunAsAdmin = FALSE; 153 | 154 | if (pAdministratorsGroup) 155 | FreeSid(pAdministratorsGroup); 156 | } 157 | g_bAdmin = fIsRunAsAdmin; 158 | } 159 | return g_bAdmin; 160 | } 161 | 162 | void BADAPP_EXPORT ResetFTHState(void) 163 | { 164 | SHELLEXECUTEINFOW shExInfo = { sizeof(shExInfo) }; 165 | shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS; 166 | shExInfo.lpVerb = L"runas"; 167 | shExInfo.fMask = SEE_MASK_UNICODE | SEE_MASK_NOZONECHECKS | SEE_MASK_NOASYNC; 168 | shExInfo.lpFile = L"rundll32"; 169 | shExInfo.lpParameters = L"fthsvc.dll,FthSysprepSpecialize"; 170 | shExInfo.nShow = SW_SHOW; 171 | 172 | CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); 173 | if (ShellExecuteExW(&shExInfo)) 174 | { 175 | DWORD dwExit; 176 | if (WaitForSingleObject(shExInfo.hProcess, 2000) == WAIT_OBJECT_0) 177 | { 178 | GetExitCodeProcess(shExInfo.hProcess, &dwExit); 179 | Output(L"Result: %u", dwExit); 180 | } 181 | else 182 | { 183 | Output(L"Timeout"); 184 | } 185 | CloseHandle(shExInfo.hProcess); 186 | } 187 | else 188 | { 189 | Output(L"Unable to start task"); 190 | } 191 | CoUninitialize(); 192 | } 193 | 194 | 195 | typedef HRESULT(__stdcall* WerAddExcludedApplicationProc)(PCWSTR pwzExeName, BOOL bAllUsers); 196 | typedef HRESULT(__stdcall* WerRemoveExcludedApplicationProc)(PCWSTR pwzExeName, BOOL bAllUsers); 197 | 198 | void BADAPP_EXPORT EnableWER(BOOL bAllUsers) 199 | { 200 | WCHAR PathBuffer[MAX_PATH * 4]; 201 | GetModuleFileNameW(NULL, PathBuffer, _countof(PathBuffer)); 202 | 203 | HMODULE mod = LoadLibraryW(L"wer.dll"); 204 | WerRemoveExcludedApplicationProc proc = (WerRemoveExcludedApplicationProc)GetProcAddress(mod, "WerRemoveExcludedApplication"); 205 | if (proc) 206 | { 207 | HRESULT hr = proc(AppExecutable(), bAllUsers); 208 | Output(L"WerRemoveExcludedApplication(bAllUsers=%d) = 0x%x", bAllUsers, hr); 209 | } 210 | else 211 | { 212 | Output(L"WerRemoveExcludedApplication not found"); 213 | } 214 | if (mod) 215 | FreeLibrary(mod); 216 | } 217 | 218 | void BADAPP_EXPORT DisableWER(BOOL bAllUsers) 219 | { 220 | HMODULE mod = LoadLibraryW(L"wer.dll"); 221 | WerAddExcludedApplicationProc proc = (WerAddExcludedApplicationProc)GetProcAddress(mod, "WerAddExcludedApplication"); 222 | if (proc) 223 | { 224 | HRESULT hr = proc(AppExecutable(), bAllUsers); 225 | Output(L"WerAddExcludedApplication(bAllUsers=%d) = 0x%x", bAllUsers, hr); 226 | } 227 | else 228 | { 229 | Output(L"WerAddExcludedApplication not found"); 230 | } 231 | if (mod) 232 | FreeLibrary(mod); 233 | } 234 | 235 | 236 | #define WER_EXCLUDED_KEY L"SOFTWARE\\Microsoft\\Windows\\Windows Error Reporting\\ExcludedApplications" 237 | 238 | 239 | BOOL BADAPP_EXPORT IsWerDisabled(LPCWSTR Executable, BOOL bAllUsers) 240 | { 241 | HKEY StateKey; 242 | LSTATUS Status; 243 | DWORD dwValue, dwType, dwSize; 244 | BOOL bDisabled = FALSE; 245 | 246 | Status = RegOpenKeyExW(bAllUsers ? HKEY_LOCAL_MACHINE : HKEY_CURRENT_USER, WER_EXCLUDED_KEY, 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &StateKey); 247 | if (Status == ERROR_SUCCESS) 248 | { 249 | dwSize = sizeof(dwValue); 250 | Status = RegQueryValueExW(StateKey, Executable, NULL, &dwType, (LPBYTE)&dwValue, &dwSize); 251 | if (Status == ERROR_SUCCESS && dwSize == sizeof(DWORD) && dwType == REG_DWORD) 252 | { 253 | bDisabled = dwValue != 0; 254 | } 255 | 256 | RegCloseKey(StateKey); 257 | } 258 | 259 | return bDisabled; 260 | } 261 | 262 | void BADAPP_EXPORT AnalyzeWER(LPCWSTR ExeOnly) 263 | { 264 | BOOL bCurrentUser, bAllUsers; 265 | 266 | bAllUsers = IsWerDisabled(ExeOnly, TRUE); 267 | bCurrentUser = IsWerDisabled(ExeOnly, FALSE); 268 | if (bAllUsers || bCurrentUser) 269 | { 270 | Output(L"WER disabled: %s%s%s", 271 | bAllUsers ? L"All Users" : L"", 272 | (bAllUsers && bCurrentUser) ? L", " : L"", 273 | bCurrentUser ? L"Current User" : L""); 274 | } 275 | } 276 | 277 | void BADAPP_EXPORT AnalyzeZoneID(LPCWSTR Executable) 278 | { 279 | IInternetSecurityManager* pism; 280 | HRESULT hr; 281 | 282 | CoInitialize(NULL); 283 | 284 | hr = CoCreateInstance(&CLSID_InternetSecurityManager, NULL, CLSCTX_ALL, &IID_IInternetSecurityManager, &pism); 285 | if (SUCCEEDED(hr)) 286 | { 287 | DWORD dwZone; 288 | hr = pism->lpVtbl->MapUrlToZone(pism, Executable, &dwZone, MUTZ_ISFILE | MUTZ_DONT_UNESCAPE); 289 | if (SUCCEEDED(hr) && dwZone != URLZONE_LOCAL_MACHINE) 290 | { 291 | PCWSTR wszZoneIds[6] = 292 | { 293 | L"URLZONE_LOCAL_MACHINE", 294 | L"URLZONE_INTRANET", 295 | L"URLZONE_TRUSTED", 296 | L"URLZONE_INTERNET", 297 | L"URLZONE_UNTRUSTED", 298 | L"" 299 | }; 300 | Output(L"ZoneID: %u [%s]\n", dwZone, wszZoneIds[min(dwZone, 5)]); 301 | } 302 | 303 | pism->lpVtbl->Release(pism); 304 | } 305 | 306 | CoUninitialize(); 307 | } 308 | 309 | #define IMAGEEXECOPTIONSSTRING L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options" 310 | 311 | void BADAPP_EXPORT AnalyzeGlobalFlags(LPCWSTR ExeOnly) 312 | { 313 | LONG Ret; 314 | HKEY HandleKey, HandleSubKey; 315 | WCHAR Buffer[20] = { 0 }; 316 | DWORD Type, Len = sizeof(Buffer) - sizeof(WCHAR); 317 | 318 | if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, IMAGEEXECOPTIONSSTRING, 0, KEY_READ, &HandleKey) != ERROR_SUCCESS) 319 | { 320 | Output(L"Unable to open HKLM\\%s", IMAGEEXECOPTIONSSTRING); 321 | return; 322 | } 323 | 324 | Ret = RegCreateKeyExW(HandleKey, ExeOnly, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_READ, NULL, &HandleSubKey, NULL); 325 | CloseHandle(HandleKey); 326 | 327 | if (Ret != ERROR_SUCCESS) 328 | return; 329 | 330 | if (RegQueryValueExW(HandleSubKey, L"GlobalFlag", NULL, &Type, (BYTE*)Buffer, &Len) == ERROR_SUCCESS) 331 | { 332 | DWORD Flags = 0; 333 | if (Type == REG_SZ) 334 | { 335 | Flags = wcstoul_(Buffer, NULL, 16); 336 | Output(L"GlobalFlag(sz): %08x", Flags); 337 | } 338 | else if (Type == REG_DWORD && Len == sizeof(DWORD)) 339 | { 340 | Flags = *(DWORD*)Buffer; 341 | Output(L"GlobalFlag(dw): %08x", Flags); 342 | } 343 | else 344 | { 345 | Output(L"Unknown type: %u", Type); 346 | } 347 | } 348 | 349 | CloseHandle(HandleSubKey); 350 | } 351 | 352 | 353 | void BADAPP_EXPORT RelaunchFN(void) 354 | { 355 | if (RelaunchAsAdmin()) 356 | PostQuitMessage(0); 357 | } 358 | 359 | void BADAPP_EXPORT EnableWerFN(void) 360 | { 361 | EnableWER(TRUE); 362 | EnableWER(FALSE); 363 | } 364 | 365 | void BADAPP_EXPORT DisableWerFN(void) 366 | { 367 | DisableWER(TRUE); 368 | DisableWER(FALSE); 369 | } 370 | 371 | void BADAPP_EXPORT CheckOsVersionFN(void) 372 | { 373 | DWORD dwVersion; 374 | DWORD dwMajorVersion, dwMinorVersion, dwBuildNumber = 0; 375 | OSVERSIONINFOEXW VersionInfo; 376 | void (__stdcall* pRtlGetVersion)(OSVERSIONINFOEXW*); 377 | 378 | dwVersion = GetVersion(); 379 | dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion))); 380 | dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion))); 381 | if (dwVersion < 0x80000000) 382 | dwBuildNumber = (DWORD)(HIWORD(dwVersion)); 383 | 384 | Output(L"GetVersion() = %d.%d (%d)", dwMajorVersion, dwMinorVersion, dwBuildNumber); 385 | 386 | ZeroMemory(&VersionInfo, sizeof(VersionInfo)); 387 | VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo); 388 | if (GetVersionExW((LPOSVERSIONINFOW)&VersionInfo)) 389 | { 390 | Output(L"GetVersionExW() = %d.%d (%d)", VersionInfo.dwMajorVersion, VersionInfo.dwMinorVersion, VersionInfo.dwBuildNumber); 391 | if (VersionInfo.wServicePackMajor || VersionInfo.wServicePackMinor || VersionInfo.szCSDVersion[0]) 392 | Output(L" Service Pack = %d.%d (%s)", (DWORD)VersionInfo.wServicePackMajor, (DWORD)VersionInfo.wServicePackMinor, VersionInfo.szCSDVersion); 393 | } 394 | else 395 | { 396 | Output(L"GetVersionExW() failed (%u)", GetLastError()); 397 | } 398 | 399 | pRtlGetVersion = (void (__stdcall*)(OSVERSIONINFOEXW*))GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlGetVersion"); 400 | if (pRtlGetVersion) 401 | { 402 | ZeroMemory(&VersionInfo, sizeof(VersionInfo)); 403 | VersionInfo.dwOSVersionInfoSize = sizeof(VersionInfo); 404 | pRtlGetVersion(&VersionInfo); 405 | Output(L"RtlGetVersion() = %d.%d (%d)", VersionInfo.dwMajorVersion, VersionInfo.dwMinorVersion, VersionInfo.dwBuildNumber); 406 | if (VersionInfo.wServicePackMajor || VersionInfo.wServicePackMinor || VersionInfo.szCSDVersion[0]) 407 | Output(L" Service Pack = %d.%d (%s)", (DWORD)VersionInfo.wServicePackMajor, (DWORD)VersionInfo.wServicePackMinor, VersionInfo.szCSDVersion); 408 | } 409 | else 410 | { 411 | Output(L"RtlGetVersion() not found (%u)", GetLastError()); 412 | } 413 | } 414 | 415 | void BADAPP_EXPORT PrintModule(MODULEENTRY32W* me) 416 | { 417 | DWORD dwInfoSize, dwDum; 418 | LPVOID lpInfo; 419 | 420 | Output(L"%s", me->szModule); 421 | Output(L" Address: %p", me->modBaseAddr); 422 | 423 | dwInfoSize = GetFileVersionInfoSizeW(me->szExePath, &dwDum); 424 | lpInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwInfoSize); 425 | if (lpInfo) 426 | { 427 | if (GetFileVersionInfoW(me->szExePath, 0, dwInfoSize, lpInfo)) 428 | { 429 | VS_FIXEDFILEINFO* versionInfo; 430 | UINT versionInfoSize; 431 | if (VerQueryValueW(lpInfo, L"\\", &versionInfo, &versionInfoSize)) 432 | { 433 | Output(L" Version: %d.%d.%d.%d", 434 | (versionInfo->dwFileVersionMS >> 16) & 0xffff, 435 | (versionInfo->dwFileVersionMS >> 0) & 0xffff, 436 | (versionInfo->dwFileVersionLS >> 16) & 0xffff, 437 | (versionInfo->dwFileVersionLS >> 0) & 0xffff); 438 | } 439 | } 440 | } 441 | } 442 | 443 | void BADAPP_EXPORT ListModulesFN(void) 444 | { 445 | HANDLE hSnap; 446 | DWORD dwErr; 447 | 448 | do { 449 | hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0); 450 | dwErr = GetLastError(); 451 | } while (hSnap == INVALID_HANDLE_VALUE && dwErr == ERROR_BAD_LENGTH); 452 | 453 | if (hSnap != INVALID_HANDLE_VALUE) 454 | { 455 | MODULEENTRY32W me = { sizeof(me) }; 456 | if (Module32FirstW(hSnap, &me)) 457 | { 458 | do { 459 | PrintModule(&me); 460 | } while (Module32NextW(hSnap, &me)); 461 | } 462 | CloseHandle(hSnap); 463 | } 464 | else 465 | { 466 | Output(L"CreateToolhelp32Snapshot() failed (%u)", dwErr); 467 | } 468 | } 469 | 470 | 471 | 472 | void BADAPP_EXPORT CheckVersionFN(void) 473 | { 474 | HINTERNET hInternet = InternetOpenA("BadApp/" GIT_VERSION_STR, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); 475 | if (hInternet) 476 | { 477 | HINTERNET hUrl = InternetOpenUrlW(hInternet, L"https://github.com/learn-more/BadApp/releases/latest", NULL, 0, 478 | INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_NO_UI | INTERNET_FLAG_NO_AUTO_REDIRECT, 0); 479 | if (hUrl) 480 | { 481 | WCHAR Buf[512] = {0}; 482 | DWORD dwBufSize = sizeof(Buf); 483 | DWORD dwIndex = 0; 484 | if (HttpQueryInfoW(hUrl, HTTP_QUERY_LOCATION, Buf, &dwBufSize, &dwIndex)) 485 | { 486 | Output(L"Latest release: %s", Buf); 487 | } 488 | else 489 | { 490 | Output(L"Error %u calling HttpQueryInfoA", GetLastError()); 491 | } 492 | InternetCloseHandle(hUrl); 493 | } 494 | else 495 | { 496 | Output(L"Error %u calling InternetOpenUrlA", GetLastError()); 497 | } 498 | 499 | InternetCloseHandle(hInternet); 500 | } 501 | else 502 | { 503 | Output(L"Error %u calling InternetOpenA", GetLastError()); 504 | } 505 | } 506 | 507 | static BAD_ACTION g_Actions[] = 508 | { 509 | { 510 | L"Relaunch as admin", 511 | L"Relaunch BadApp as administrator. This allows the modification of some properties in HKLM.", 512 | RelaunchFN, 513 | ShieldIcon 514 | }, 515 | { 516 | L"Reset FTH State", 517 | L"Reset the list of applications tracked by FTH. This also removes FTH from all applications, so certain applications might start to malfuction (again).", 518 | ResetFTHState, 519 | ShieldIcon 520 | }, 521 | { 522 | L"Enable WER", 523 | L"Enable Windows Error Reporting for BadApp. First try to set this for all users, then for the current user.", 524 | EnableWerFN, 525 | ApplicationIcon 526 | }, 527 | { 528 | L"Disable WER", 529 | L"Disable Windows Error Reporting for BadApp. First try to set this for all users, then for the current user.", 530 | DisableWerFN, 531 | ApplicationIcon 532 | }, 533 | { 534 | L"OS version", 535 | L"Query the OS version using various techniques.", 536 | CheckOsVersionFN, 537 | OsIcon 538 | }, 539 | { 540 | L"List modules", 541 | L"Show all loaded modules.", 542 | ListModulesFN, 543 | OsIcon 544 | }, 545 | { 546 | L"Check version", 547 | L"Check the github release page to see what the latest version is.", 548 | CheckVersionFN, 549 | GithubIcon 550 | }, 551 | { NULL } 552 | }; 553 | 554 | static BAD_ACTION g_Category = 555 | { 556 | L"Diagnostics", 557 | L"Elevate BadApp, reset FTH, disable WER, check version", 558 | NULL 559 | }; 560 | 561 | void BADAPP_EXPORT Diag_Init(void) 562 | { 563 | BOOL bAdmin; 564 | LPCWSTR ExeOnly, FullPath, Tmp; 565 | 566 | ExeOnly = FullPath = Tmp = AppExecutable(); 567 | 568 | while ((Tmp = wcspbrk_(ExeOnly, L"\\/")) != NULL) 569 | { 570 | ExeOnly = Tmp + 1; 571 | } 572 | 573 | AnalyzeShims(FullPath); 574 | AnalyzeWER(ExeOnly); 575 | AnalyzeFTHState(FullPath); 576 | AnalyzeZoneID(FullPath); 577 | AnalyzeGlobalFlags(ExeOnly); 578 | 579 | bAdmin = IsRunAsAdmin(); 580 | if (bAdmin) 581 | g_Actions[1].iIcon = ApplicationIcon; 582 | Register_Category(&g_Category, g_Actions + (bAdmin ? 1 : 0)); 583 | } 584 | 585 | -------------------------------------------------------------------------------- /BadApp/BadApp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * PROJECT: BadApp 3 | * LICENSE: MIT (https://spdx.org/licenses/MIT) 4 | * PURPOSE: Entrypoint / UI 5 | * COPYRIGHT: Copyright 2018 Mark Jansen (mark.jansen@reactos.org) 6 | */ 7 | 8 | #include "stdafx.h" 9 | #include "version.h" 10 | #include 11 | #include 12 | #include 13 | 14 | 15 | typedef struct _BAD_CATEGORY 16 | { 17 | BAD_ACTION Info; 18 | HTREEITEM hItem; 19 | BAD_ACTION* Actions; 20 | } BAD_CATEGORY; 21 | 22 | typedef enum _BAD_CALLCONTEXT 23 | { 24 | InvalidCC = CB_ERR, 25 | DirectCC = 0, 26 | PostMessageCC, 27 | CreateThreadCC, 28 | RtlCreateUserThreadCC, 29 | DialogBoxInitCC, 30 | } BAD_CALLCONTEXT; 31 | 32 | #define MAX_NUMBER_OF_CATEGORY 5 33 | static BAD_CATEGORY g_Category[MAX_NUMBER_OF_CATEGORY + 1] = {0}; 34 | static BAD_CALLCONTEXT g_CallContext = DirectCC; 35 | static ULONG g_ExecMessage; 36 | static HWND g_hTreeView; 37 | static HIMAGELIST g_hTreeViewImagelist; 38 | static HWND g_hDescriptionEdit; 39 | static HWND g_hOutputEdit; 40 | static HWND g_hGripper; 41 | static HWND g_hCombo; 42 | 43 | INT_PTR BADAPP_EXPORT CALLBACK AboutProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); 44 | 45 | #define POS_FIXED 1 46 | #define POS_PERCENT 2 47 | #define POS_FOLLOW_SM 3 48 | #define POS_FOLLOW_OBJH 4 49 | 50 | #define FIXED_AT(n) { .u.s.Value = n, .u.s.Max = 0, .Type = POS_FIXED } 51 | #define PERCENTAGE(n) { .u.s.Value = n, .u.s.Max = 0, .Type = POS_PERCENT } 52 | #define FOLLOW_SM(n,m) { .u.s.Value = n, .u.s.Max = m, .Type = POS_FOLLOW_SM } 53 | #define FOLLOW_OBJH(h) { .u.hOther = h, .Type = POS_FOLLOW_OBJH } 54 | 55 | typedef struct _RESIZE_COORD 56 | { 57 | union 58 | { 59 | struct 60 | { 61 | WORD Value; 62 | WORD Max; 63 | } s; 64 | HWND* hOther; 65 | } u; 66 | BYTE Type; 67 | } RESIZE_COORD; 68 | 69 | #define TV_WIDTH 200 70 | 71 | static 72 | const 73 | struct _RESIZE_STRUCT 74 | { 75 | HWND* hWindow; 76 | RESIZE_COORD Left; 77 | RESIZE_COORD Top; 78 | RESIZE_COORD Right; 79 | RESIZE_COORD Bottom; 80 | } g_Resize[] = 81 | { 82 | { &g_hTreeView, FIXED_AT(0), FIXED_AT(0), FIXED_AT(TV_WIDTH), PERCENTAGE(100) }, 83 | { &g_hDescriptionEdit, FIXED_AT(TV_WIDTH), FIXED_AT(0), PERCENTAGE(100), FIXED_AT(100) }, 84 | { &g_hCombo, FIXED_AT(TV_WIDTH), FOLLOW_OBJH(&g_hCombo), FOLLOW_SM(SM_CXVSCROLL,TV_WIDTH + 200), PERCENTAGE(100) }, 85 | { &g_hOutputEdit, FIXED_AT(TV_WIDTH), FIXED_AT(100), PERCENTAGE(100), FOLLOW_OBJH(&g_hCombo) }, 86 | { &g_hGripper, FOLLOW_SM(SM_CXVSCROLL,0), FOLLOW_SM(SM_CYVSCROLL,0), PERCENTAGE(100), PERCENTAGE(100) }, 87 | }; 88 | 89 | LONG BADAPP_EXPORT DoCoord(LONG MaxValue, const RESIZE_COORD* coord) 90 | { 91 | if (coord->Type == POS_FIXED) 92 | return coord->u.s.Value; 93 | if (coord->Type == POS_PERCENT) 94 | return coord->u.s.Value * MaxValue / 100; 95 | if (coord->Type == POS_FOLLOW_SM) 96 | { 97 | LONG Value = MaxValue - GetSystemMetrics(coord->u.s.Value); 98 | if (coord->u.s.Max && Value > coord->u.s.Max) 99 | return coord->u.s.Max; 100 | return Value; 101 | } 102 | if (coord->Type == POS_FOLLOW_OBJH) 103 | { 104 | RECT rc; 105 | GetWindowRect(*coord->u.hOther, &rc); 106 | return MaxValue - (rc.bottom - rc.top); 107 | } 108 | assert(0); 109 | return 0; 110 | } 111 | 112 | void BADAPP_EXPORT OnSize(HWND hWnd, WPARAM wParam) 113 | { 114 | HDWP hdwp; 115 | RECT rcClient; 116 | DWORD n, dwFlags = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOCOPYBITS; 117 | 118 | GetClientRect(hWnd, &rcClient); 119 | assert(rcClient.left == 0); 120 | assert(rcClient.top == 0); 121 | 122 | hdwp = BeginDeferWindowPos(_countof(g_Resize)); 123 | 124 | for (n = 0; n < _countof(g_Resize); ++n) 125 | { 126 | RECT rc; 127 | HWND hChild = *g_Resize[n].hWindow; 128 | 129 | rc.left = DoCoord(rcClient.right, &g_Resize[n].Left); 130 | rc.top = DoCoord(rcClient.bottom, &g_Resize[n].Top); 131 | rc.right = DoCoord(rcClient.right, &g_Resize[n].Right); 132 | rc.bottom = DoCoord(rcClient.bottom, &g_Resize[n].Bottom); 133 | 134 | if (hdwp) 135 | hdwp = DeferWindowPos(hdwp, hChild, NULL, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, dwFlags); 136 | } 137 | 138 | EndDeferWindowPos(hdwp); 139 | ShowWindow(g_hGripper, (wParam == SIZE_MAXIMIZED) ? SW_HIDE : SW_SHOW); 140 | } 141 | 142 | HTREEITEM BADAPP_EXPORT InsertTV(HWND hwndTV, BAD_ACTION* Item, HTREEITEM Parent, HTREEITEM InsertAfter) 143 | { 144 | TVINSERTSTRUCTW tvins = {0}; 145 | HTREEITEM hItem; 146 | tvins.item.mask = TVIF_TEXT | TVIF_PARAM | TVIF_STATE; 147 | tvins.item.pszText = (LPWSTR)Item->Name; 148 | tvins.item.lParam = (LPARAM)Item; 149 | tvins.hParent = Parent; 150 | tvins.hInsertAfter = InsertAfter; 151 | tvins.item.state = INDEXTOSTATEIMAGEMASK(Item->iIcon); 152 | tvins.item.stateMask = TVIS_STATEIMAGEMASK; 153 | 154 | hItem = (HTREEITEM)SendMessageW(hwndTV, TVM_INSERTITEMW, 0L, (LPARAM)&tvins); 155 | return hItem; 156 | } 157 | 158 | void BADAPP_EXPORT FillTV(void) 159 | { 160 | DWORD n, j; 161 | HTREEITEM hPrevCat = TVI_FIRST; 162 | LPWSTR Icons[MaxIcons] = { 163 | MAKEINTRESOURCE(IDI_ABOUT), // NoIcon, but the treeview state handles index '0' as not assigned.. 164 | IDI_APPLICATION, // ApplicationIcon 165 | IDI_HAND, // BadIcon 166 | IDI_ASTERISK, // InformationIcon 167 | IDI_WINLOGO, // OsIcon 168 | IDI_SHIELD, // ShieldIcon 169 | MAKEINTRESOURCE(IDI_GITHUB),// GithubIcon 170 | }; 171 | HICON hIcon = NULL, hBackup = NULL; 172 | HMODULE hMod[2] = { NULL, NULL }; 173 | hMod[0] = GetModuleHandle(NULL); 174 | 175 | g_hTreeViewImagelist = ImageList_Create(16, 16, ILC_COLOR32, 1, 1); 176 | for (n = 0; n < _countof(Icons); ++n) 177 | { 178 | for (j = 0; j < _countof(hMod); ++j) 179 | { 180 | hIcon = LoadImage(hMod[j], Icons[n], IMAGE_ICON, 16, 16, LR_SHARED | LR_CREATEDIBSECTION); 181 | if (hIcon) 182 | { 183 | ImageList_AddIcon(g_hTreeViewImagelist, hIcon); 184 | if (n == 0) 185 | hBackup = hIcon; 186 | break; 187 | } 188 | } 189 | if (!hIcon && hBackup) 190 | { 191 | ImageList_AddIcon(g_hTreeViewImagelist, hBackup); 192 | } 193 | } 194 | 195 | SendMessageW(g_hTreeView, TVM_SETIMAGELIST, TVSIL_STATE, (LPARAM)g_hTreeViewImagelist); 196 | for (n = 0; g_Category[n].Actions; ++n) 197 | { 198 | hPrevCat = InsertTV(g_hTreeView, &g_Category[n].Info, TVI_ROOT, hPrevCat); 199 | g_Category[n].hItem = hPrevCat; 200 | 201 | BAD_ACTION* Action = g_Category[n].Actions; 202 | HTREEITEM hPrevAction = TVI_FIRST; 203 | for (j = 0; Action[j].Name; ++j) 204 | { 205 | hPrevAction = InsertTV(g_hTreeView, &Action[j], hPrevCat, hPrevAction); 206 | } 207 | } 208 | } 209 | 210 | void BADAPP_EXPORT OnCreate(HWND hWnd) 211 | { 212 | DWORD dwTvStyle = TVS_HASLINES | TVS_HASBUTTONS | TVS_LINESATROOT | TVS_SHOWSELALWAYS | TVS_INFOTIP; 213 | HINSTANCE hInstance = GetModuleHandleW(NULL); 214 | LOGFONTW lf = {0}; 215 | HFONT hFont; 216 | 217 | /* Treeview for all actions */ 218 | g_hTreeView = CreateWindowExW(0, WC_TREEVIEW, L"Hello :)", WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP | dwTvStyle, 219 | 0, 0, 0, 0, hWnd, NULL, hInstance, NULL); 220 | SendMessageW(g_hTreeView, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)FALSE); 221 | 222 | /* Show description of the selected node */ 223 | g_hDescriptionEdit = CreateWindowExW(WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE, WC_EDITW, NULL, 224 | WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_READONLY, 225 | 0, 0, 0, 0, hWnd, NULL, hInstance, NULL); 226 | SendMessageW(g_hDescriptionEdit, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)FALSE); 227 | 228 | /* Show output */ 229 | g_hOutputEdit = CreateWindowExW(WS_EX_NOPARENTNOTIFY | WS_EX_CLIENTEDGE, WC_EDITW, NULL, 230 | WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_MULTILINE | ES_READONLY, 231 | 0, 0, 0, 0, hWnd, NULL, hInstance, NULL); 232 | lf.lfHeight = -11; 233 | lf.lfWeight = FW_NORMAL; 234 | StringCchCopyW(lf.lfFaceName, _countof(lf.lfFaceName), L"Courier New"); 235 | hFont = CreateFontIndirectW(&lf); 236 | SendMessageW(g_hOutputEdit, WM_SETFONT, (WPARAM)hFont, (LPARAM)FALSE); 237 | 238 | /* Resize gripper */ 239 | g_hGripper = CreateWindowExW(0, L"Scrollbar", L"size", WS_CHILD | WS_VISIBLE | SBS_SIZEGRIP, 240 | 0, 0, 0, 0, hWnd, NULL, hInstance, NULL); 241 | SendMessageW(g_hGripper, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)FALSE); 242 | SetWindowPos(g_hGripper, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_SHOWWINDOW); 243 | 244 | g_hCombo = CreateWindowExW(0, WC_COMBOBOXW, L"", CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_OVERLAPPED | WS_VISIBLE | WS_TABSTOP, 245 | 0, 0, 0, 200, hWnd, NULL, hInstance, NULL); 246 | SendMessageW(g_hCombo, WM_SETFONT, (WPARAM)GetStockObject(DEFAULT_GUI_FONT), (LPARAM)FALSE); 247 | 248 | SendMessageW(g_hCombo, CB_ADDSTRING, 0L, (LPARAM)L"Direct call"); // DirectCC 249 | SendMessageW(g_hCombo, CB_ADDSTRING, 0L, (LPARAM)L"PostMessage"); // WindowMessageCC 250 | SendMessageW(g_hCombo, CB_ADDSTRING, 0L, (LPARAM)L"CreateThread"); // NewThreadCC 251 | SendMessageW(g_hCombo, CB_ADDSTRING, 0L, (LPARAM)L"RtlCreateUserThread");// RtlCreateUserThreadCC 252 | SendMessageW(g_hCombo, CB_ADDSTRING, 0L, (LPARAM)L"DialogBoxInit"); // DialogBoxInitCC 253 | SendMessageW(g_hCombo, CB_SETCURSEL, (WPARAM)g_CallContext, 0L); 254 | 255 | /* Register all handlers */ 256 | Crash_Init(); 257 | CriticalSection_Init(); 258 | Handles_Init(); 259 | Heap_Init(); 260 | Diag_Init(); 261 | 262 | /* Dump handlers in treeview */ 263 | FillTV(); 264 | } 265 | 266 | /* This is only here to show up in the callstack */ 267 | void BADAPP_EXPORT OnDirectCall(BAD_ACTION* Action) 268 | { 269 | Action->Execute(); 270 | Output(L"'%s' done.", Action->Name); 271 | } 272 | 273 | DWORD BADAPP_EXPORT WINAPI ThreadProcK32(LPVOID pArg) 274 | { 275 | BAD_ACTION* Action = (BAD_ACTION*)pArg; 276 | Action->Execute(); 277 | Output(L"'%s' from ThreadProcK32 done.", Action->Name); 278 | return 0; 279 | } 280 | 281 | DWORD BADAPP_EXPORT WINAPI ThreadProcNt(LPVOID pArg) 282 | { 283 | BAD_ACTION* Action = (BAD_ACTION*)pArg; 284 | Action->Execute(); 285 | Output(L"'%s' from ThreadProcNt done.", Action->Name); 286 | return 0; 287 | } 288 | 289 | typedef ULONG (NTAPI *tRtlCreateUserThread)(HANDLE ProcessHandle, PSECURITY_DESCRIPTOR SecurityDescriptor, 290 | BOOLEAN CreateSuspended, ULONG StackZeroBits, SIZE_T StackReserve, 291 | SIZE_T StackCommit, PTHREAD_START_ROUTINE StartAddress, 292 | PVOID Parameter, PHANDLE ThreadHandle, PVOID ClientId); 293 | static tRtlCreateUserThread RtlCreateUserThread; 294 | 295 | 296 | void BADAPP_EXPORT OnExecute(HWND hWnd, BAD_ACTION* Action) 297 | { 298 | HANDLE hThread; 299 | 300 | switch (g_CallContext) 301 | { 302 | case DirectCC: 303 | Output(L"Calling '%s'", Action->Name); 304 | OnDirectCall(Action); 305 | break; 306 | case PostMessageCC: 307 | Output(L"Posting '%s'", Action->Name); 308 | PostMessageW(hWnd, g_ExecMessage, 0L, (LPARAM)Action); 309 | break; 310 | case CreateThreadCC: 311 | Output(L"CreateThread '%s'", Action->Name); 312 | hThread = CreateThread(NULL, 0, ThreadProcK32, Action, 0, NULL); 313 | if (hThread) 314 | CloseHandle(hThread); 315 | else 316 | Output(L"Failed to create thread"); 317 | break; 318 | case RtlCreateUserThreadCC: 319 | if (!RtlCreateUserThread) 320 | { 321 | RtlCreateUserThread = (tRtlCreateUserThread)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "RtlCreateUserThread"); 322 | } 323 | Output(L"RtlCreateUserThread '%s'", Action->Name); 324 | RtlCreateUserThread(((HANDLE)(LONG_PTR)-1), NULL, 0, 0, 0, 0, ThreadProcNt, Action, NULL, NULL); 325 | break; 326 | case DialogBoxInitCC: 327 | Output(L"DialogBoxInit '%s'", Action->Name); 328 | DialogBoxParamW(GetModuleHandle(NULL), MAKEINTRESOURCEW(IDD_ABOUTBOX), hWnd, AboutProc, (LPARAM)Action); 329 | break; 330 | default: 331 | assert(0); 332 | break; 333 | } 334 | } 335 | 336 | void BADAPP_EXPORT OnExecuteTVSelection(HWND hWnd) 337 | { 338 | TVITEMW tvi = {0}; 339 | BAD_ACTION* Action; 340 | 341 | tvi.mask = TVIF_PARAM; 342 | tvi.hItem = (HTREEITEM)SendMessageW(g_hTreeView, TVM_GETNEXTITEM, TVGN_CARET, 0L); 343 | if (tvi.hItem && SendMessageW(g_hTreeView, TVM_GETITEMW, 0L, (LPARAM)&tvi)) 344 | { 345 | Action = (BAD_ACTION*)tvi.lParam; 346 | if (Action->Execute) 347 | { 348 | OnExecute(hWnd, Action); 349 | } 350 | } 351 | } 352 | 353 | void BADAPP_EXPORT OnTreeviewNotify(HWND hWnd, LPNMTREEVIEWW lTreeview) 354 | { 355 | LPNMTVGETINFOTIPW pTip; 356 | LPNMTVKEYDOWN pKey; 357 | BAD_ACTION* Action; 358 | 359 | switch (lTreeview->hdr.code) 360 | { 361 | case TVN_SELCHANGEDW: 362 | if (!(lTreeview->itemNew.mask & TVIF_PARAM)) 363 | { 364 | Output(L"Got tvitem without PARAM!"); 365 | assert(0); 366 | return; 367 | } 368 | Action = (BAD_ACTION*)lTreeview->itemNew.lParam; 369 | if (Action->Description && Action->Description[0]) 370 | SetWindowTextW(g_hDescriptionEdit, Action->Description); 371 | else 372 | SetWindowTextW(g_hDescriptionEdit, L""); 373 | break; 374 | case TVN_GETINFOTIP: 375 | pTip = (LPNMTVGETINFOTIPW)lTreeview; 376 | Action = (BAD_ACTION*)pTip->lParam; 377 | if (Action->Description && Action->Description[0]) 378 | StringCchCopyW(pTip->pszText, pTip->cchTextMax, Action->Description); 379 | break; 380 | case TVN_KEYDOWN: 381 | pKey = (LPNMTVKEYDOWN)lTreeview; 382 | if (pKey->wVKey == VK_RETURN || pKey->wVKey == VK_EXECUTE) 383 | { 384 | OnExecuteTVSelection(hWnd); 385 | } 386 | else if (pKey->wVKey == VK_SPACE) 387 | { 388 | HTREEITEM hItem = (HTREEITEM)SendMessageW(g_hTreeView, TVM_GETNEXTITEM, TVGN_CARET, 0L); 389 | if (hItem) 390 | SendMessageW(g_hTreeView, TVM_EXPAND, TVE_TOGGLE, (LPARAM)hItem); 391 | } 392 | break; 393 | case NM_DBLCLK: 394 | OnExecuteTVSelection(hWnd); 395 | break; 396 | } 397 | } 398 | 399 | LRESULT BADAPP_EXPORT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) 400 | { 401 | if (g_ExecMessage == Msg) 402 | { 403 | BAD_ACTION* Action = (BAD_ACTION*)lParam; 404 | Action->Execute(); 405 | Output(L"'%s' done.", Action->Name); 406 | return 0L; 407 | } 408 | 409 | switch (Msg) 410 | { 411 | case WM_CREATE: 412 | OnCreate(hWnd); 413 | break; 414 | case WM_SIZE: 415 | OnSize(hWnd, wParam); 416 | break; 417 | case WM_GETMINMAXINFO: 418 | ((MINMAXINFO *)lParam)->ptMinTrackSize.x = 400; 419 | ((MINMAXINFO *)lParam)->ptMinTrackSize.y = 300; 420 | break; 421 | case WM_COMMAND: 422 | if (lParam == (LPARAM)g_hCombo && HIWORD(wParam) == CBN_SELCHANGE) 423 | { 424 | g_CallContext = (BAD_CALLCONTEXT)SendMessageW(g_hCombo, CB_GETCURSEL, 0L, 0L); 425 | if (g_CallContext == InvalidCC) 426 | g_CallContext = DirectCC; 427 | } 428 | break; 429 | case WM_DESTROY: 430 | PostQuitMessage(0); 431 | break; 432 | case WM_NOTIFY: 433 | if (((LPNMHDR)lParam)->hwndFrom == g_hTreeView) 434 | OnTreeviewNotify(hWnd, (LPNMTREEVIEWW)lParam); 435 | break; 436 | default: 437 | break; 438 | } 439 | return DefWindowProcW(hWnd, Msg, wParam, lParam); 440 | } 441 | 442 | BOOL BADAPP_EXPORT RegisterWndClass(HINSTANCE hInstance, LPCWSTR ClassName) 443 | { 444 | WCHAR Buffer[50]; 445 | WNDCLASSEX wc = {0}; 446 | 447 | wc.cbSize = sizeof(wc); 448 | wc.lpfnWndProc = WndProc; 449 | wc.hInstance = hInstance; 450 | wc.hIcon = LoadImageW(hInstance, MAKEINTRESOURCE(IDI_BADAPP), IMAGE_ICON, 0, 0, LR_DEFAULTSIZE); 451 | wc.hCursor = LoadCursor(NULL, IDC_ARROW); 452 | wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); 453 | wc.lpszClassName = ClassName; 454 | 455 | if (!RegisterClassExW(&wc)) 456 | { 457 | xwprintf(Buffer, _countof(Buffer), L"Window Registration Failed: %u", GetLastError()); 458 | MessageBoxW(NULL, Buffer, L"Error!", MB_ICONEXCLAMATION | MB_OK); 459 | return FALSE; 460 | } 461 | 462 | return TRUE; 463 | } 464 | 465 | HWND BADAPP_EXPORT CreateBadWindow(HINSTANCE hInstance, LPCWSTR ClassName) 466 | { 467 | HWND hWnd; 468 | WCHAR Buffer[50]; 469 | 470 | xwprintf(Buffer, _countof(Buffer), 471 | L"BadApp %S%s", 472 | GIT_VERSION_STR, 473 | IsRunAsAdmin() ? L" (Administrator)" : L""); 474 | 475 | hWnd = CreateWindowExW(WS_EX_CLIENTEDGE, ClassName, Buffer, WS_OVERLAPPEDWINDOW, 476 | CW_USEDEFAULT, CW_USEDEFAULT, 600, 400, NULL, NULL, hInstance, NULL); 477 | 478 | if (hWnd == NULL) 479 | { 480 | xwprintf(Buffer, _countof(Buffer), L"Window Creation Failed: %u", GetLastError()); 481 | MessageBoxW(NULL, Buffer, L"Error!", MB_ICONEXCLAMATION | MB_OK); 482 | } 483 | 484 | return hWnd; 485 | } 486 | 487 | void BADAPP_EXPORT Gui_AddOutput(LPCWSTR Text) 488 | { 489 | SendMessageW(g_hOutputEdit, EM_SETSEL, INT_MAX, INT_MAX); 490 | SendMessageW(g_hOutputEdit, EM_REPLACESEL, FALSE, (LPARAM)Text); 491 | SendMessageW(g_hOutputEdit, EM_SCROLLCARET, 0L, 0L); 492 | } 493 | 494 | void BADAPP_EXPORT Register_Category(BAD_ACTION* Name, BAD_ACTION* Actions) 495 | { 496 | DWORD n; 497 | 498 | assert(Name->Execute == NULL); 499 | for (n = 0; Actions[n].Name; ++n) 500 | { 501 | assert(Actions[n].Execute != NULL); 502 | } 503 | 504 | for (n = 0; n < MAX_NUMBER_OF_CATEGORY; ++n) 505 | { 506 | if (!g_Category[n].Actions) 507 | { 508 | g_Category[n].Info = *Name; 509 | g_Category[n].Actions = Actions; 510 | return; 511 | } 512 | } 513 | 514 | Output(L"Increase MAX_NUMBER_OF_CATEGORY"); 515 | assert(0); 516 | } 517 | 518 | void BADAPP_EXPORT OnInitAboutDlg(HWND hDlg) 519 | { 520 | HWND hWndParent; 521 | RECT rc; 522 | int w, h; 523 | 524 | hWndParent = GetParent(hDlg); 525 | GetWindowRect(hDlg, &rc); 526 | w = rc.right - rc.left; 527 | h = rc.bottom - rc.top; 528 | GetWindowRect(hWndParent, &rc); 529 | SetWindowPos(hDlg, HWND_TOP, 530 | rc.left + ((rc.right - rc.left) - w) / 2, 531 | rc.top + ((rc.bottom - rc.top) - h) / 2, 532 | 0, 0, SWP_NOSIZE); 533 | 534 | SetDlgItemTextA(hDlg, IDC_VERSION, "BadApp " GIT_VERSION_STR); 535 | } 536 | 537 | INT_PTR BADAPP_EXPORT CALLBACK AboutProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 538 | { 539 | 540 | switch (uMsg) 541 | { 542 | case WM_INITDIALOG: 543 | if (lParam) 544 | { 545 | BAD_ACTION* Action = (BAD_ACTION*)lParam; 546 | Action->Execute(); 547 | Output(L"'%s' done.", Action->Name); 548 | // Hide the dialog again 549 | EndDialog(hDlg, 0); 550 | } 551 | OnInitAboutDlg(hDlg); 552 | return TRUE; 553 | case WM_COMMAND: 554 | switch (LOWORD(wParam)) 555 | { 556 | case IDCANCEL: 557 | case IDOK: 558 | EndDialog(hDlg, 0); 559 | break; 560 | } 561 | break; 562 | case WM_NOTIFY: 563 | switch (((LPNMHDR)lParam)->code) 564 | { 565 | case NM_CLICK: 566 | case NM_RETURN: 567 | { 568 | PNMLINK pNMLink = (PNMLINK)lParam; 569 | if (pNMLink->hdr.idFrom == IDC_VERSION || pNMLink->hdr.idFrom == IDC_CREDITS) 570 | { 571 | SHELLEXECUTEINFOW shExInfo = { sizeof(shExInfo) }; 572 | shExInfo.lpVerb = L"open"; 573 | shExInfo.hwnd = hDlg; 574 | shExInfo.fMask = SEE_MASK_UNICODE | SEE_MASK_NOZONECHECKS | SEE_MASK_NOASYNC; 575 | shExInfo.lpFile = pNMLink->item.szUrl; 576 | shExInfo.nShow = SW_SHOW; 577 | 578 | CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); 579 | ShellExecuteExW(&shExInfo); 580 | CoUninitialize(); 581 | } 582 | } 583 | break; 584 | } 585 | default: 586 | break; 587 | } 588 | return FALSE; 589 | } 590 | 591 | 592 | int APIENTRY wWinMain(_In_ HINSTANCE hInstance, 593 | _In_opt_ HINSTANCE hPrevInstance, 594 | _In_ LPWSTR lpCmdLine, 595 | _In_ int nCmdShow) 596 | { 597 | HWND hWnd; 598 | MSG Msg; 599 | BOOL bRet; 600 | const LPCWSTR lpClassName = L"BadAppClass"; 601 | 602 | UNREFERENCED_PARAMETER(hPrevInstance); 603 | UNREFERENCED_PARAMETER(lpCmdLine); 604 | UNREFERENCED_PARAMETER(nCmdShow); 605 | 606 | hInstance = GetModuleHandleW(NULL); 607 | g_ExecMessage = RegisterWindowMessageW(L"BadAppExecLaterMSG"); 608 | InitCommonControls(); 609 | 610 | if (!RegisterWndClass(hInstance, lpClassName)) 611 | { 612 | ExitProcess(GetLastError()); 613 | } 614 | 615 | hWnd = CreateBadWindow(hInstance, lpClassName); 616 | if (!hWnd) 617 | { 618 | ExitProcess(GetLastError()); 619 | } 620 | 621 | ShowWindow(hWnd, SW_SHOW); 622 | UpdateWindow(hWnd); 623 | 624 | while((bRet = GetMessageW(&Msg, NULL, 0, 0)) != 0) 625 | { 626 | if (bRet == -1) 627 | { 628 | DestroyWindow(hWnd); 629 | ExitProcess(GetLastError()); 630 | } 631 | if (!IsDialogMessageW(hWnd, &Msg)) 632 | { 633 | TranslateMessage(&Msg); 634 | DispatchMessageW(&Msg); 635 | } 636 | 637 | /* Just spy for messages here. This way we also see it when a child control has focus */ 638 | if (Msg.message == WM_KEYUP && Msg.wParam == VK_F1) 639 | { 640 | DialogBoxParamW(hInstance, MAKEINTRESOURCEW(IDD_ABOUTBOX), hWnd, AboutProc, 0L); 641 | } 642 | } 643 | ExitProcess((UINT)Msg.wParam); 644 | } 645 | 646 | --------------------------------------------------------------------------------