Add project files.

Add .gitattributes, .gitignore, and README.md.

Removed potential IoC

Revert "Removed potential IoC"

This reverts commit 1cfe8e3362dbda546515109730a59907477c2e61.

Revert "Revert "Removed potential IoC""

This reverts commit 5cfa94f7f69d533e1d8bcc239488d7d6b3f83e93.
This commit is contained in:
ret2sleep
2022-07-08 19:29:07 +01:00
commit 59ef82a070
7 changed files with 1214 additions and 0 deletions
+63
View File
@@ -0,0 +1,63 @@
###############################################################################
# Set default behavior to automatically normalize line endings.
###############################################################################
* text=auto
###############################################################################
# Set default behavior for command prompt diff.
#
# This is need for earlier builds of msysgit that does not have it on by
# default for csharp files.
# Note: This is only used by command line
###############################################################################
#*.cs diff=csharp
###############################################################################
# Set the merge driver for project and solution files
#
# Merging from the command prompt will add diff markers to the files if there
# are conflicts (Merging from VS is not affected by the settings below, in VS
# the diff markers are never inserted). Diff markers may cause the following
# file extensions to fail to load in VS. An alternative would be to treat
# these files as binary and thus will always conflict and require user
# intervention with every merge. To do so, just uncomment the entries below
###############################################################################
#*.sln merge=binary
#*.csproj merge=binary
#*.vbproj merge=binary
#*.vcxproj merge=binary
#*.vcproj merge=binary
#*.dbproj merge=binary
#*.fsproj merge=binary
#*.lsproj merge=binary
#*.wixproj merge=binary
#*.modelproj merge=binary
#*.sqlproj merge=binary
#*.wwaproj merge=binary
###############################################################################
# behavior for image files
#
# image files are treated as binary by default.
###############################################################################
#*.jpg binary
#*.png binary
#*.gif binary
###############################################################################
# diff behavior for common document formats
#
# Convert binary document formats to text before diffing them. This feature
# is only available from the command line. Turn it on by uncommenting the
# entries below.
###############################################################################
#*.doc diff=astextplain
#*.DOC diff=astextplain
#*.docx diff=astextplain
#*.DOCX diff=astextplain
#*.dot diff=astextplain
#*.DOT diff=astextplain
#*.pdf diff=astextplain
#*.PDF diff=astextplain
#*.rtf diff=astextplain
#*.RTF diff=astextplain
+363
View File
@@ -0,0 +1,363 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Ww][Ii][Nn]32/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Oo]ut/
[Ll]og/
[Ll]ogs/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUnit
*.VisualState.xml
TestResult.xml
nunit-*.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# ASP.NET Scaffolding
ScaffoldingReadMe.txt
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Coverlet is a free, cross platform Code Coverage Tool
coverage*.json
coverage*.xml
coverage*.info
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/
# Fody - auto-generated XML schema
FodyWeavers.xsd
+1
View File
@@ -0,0 +1 @@
WTSRM
+31
View File
@@ -0,0 +1,31 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.1.32328.378
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WTSRM", "WTSRM\WTSRM.vcxproj", "{23D32FDD-F377-4725-8FE2-98002ADBACB7}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{23D32FDD-F377-4725-8FE2-98002ADBACB7}.Debug|x64.ActiveCfg = Debug|x64
{23D32FDD-F377-4725-8FE2-98002ADBACB7}.Debug|x64.Build.0 = Debug|x64
{23D32FDD-F377-4725-8FE2-98002ADBACB7}.Debug|x86.ActiveCfg = Debug|Win32
{23D32FDD-F377-4725-8FE2-98002ADBACB7}.Debug|x86.Build.0 = Debug|Win32
{23D32FDD-F377-4725-8FE2-98002ADBACB7}.Release|x64.ActiveCfg = Release|x64
{23D32FDD-F377-4725-8FE2-98002ADBACB7}.Release|x64.Build.0 = Release|x64
{23D32FDD-F377-4725-8FE2-98002ADBACB7}.Release|x86.ActiveCfg = Release|Win32
{23D32FDD-F377-4725-8FE2-98002ADBACB7}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8C450B93-3E5E-48EA-9949-DB28921B6C95}
EndGlobalSection
EndGlobal
+152
View File
@@ -0,0 +1,152 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{23d32fdd-f377-4725-8fe2-98002adbacb7}</ProjectGuid>
<RootNamespace>WTSRM</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>false</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<ExceptionHandling>false</ExceptionHandling>
<BufferSecurityCheck>false</BufferSecurityCheck>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<Optimization>MinSpace</Optimization>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>false</GenerateDebugInformation>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="entry.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
+22
View File
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="entry.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
+582
View File
@@ -0,0 +1,582 @@
#include <Windows.h>
#include <winternl.h>
#pragma comment(linker,"/ENTRY:entry")
#define DEBUG 0 // 0 disable, 1 enable
#define HASHALGO HashStringDjb2
constexpr auto CACHE = 10;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLRATIONS ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma region commonmacros
#define NtCurrentProcess() ( (HANDLE)(LONG_PTR) -1 )
#define RVA2VA(Type, Base, Rva) (Type)((ULONG_PTR) Base + Rva) // Credit to modexp
#define TOKENIZE( x ) #x
#define CONCAT( X, Y ) X##Y
#if DEBUG == 0
#define PRINT( STR, ... )
#else
#define PRINT( STR, ... ) \
if (1) { \
LPWSTR buf = (LPWSTR)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 1024 ); \
if ( buf != NULL ) { \
int len = wsprintfW( buf, STR, __VA_ARGS__ ); \
WriteConsoleW( GetStdHandle( STD_OUTPUT_HANDLE ), buf, len, NULL, NULL ); \
HeapFree( GetProcessHeap(), 0, buf ); \
} \
}
#endif
#pragma endregion
#pragma region helpers
wchar_t* _strcpy(wchar_t* dest, const wchar_t* src);
wchar_t* _strcat(wchar_t* dest, const wchar_t* src);
void _memcpy(void* dst, const void* src, SIZE_T count);
__forceinline char upper(char c);
#pragma endregion
#pragma region hashing
#pragma region HashStringDjb2
// https://github.com/vxunderground/VX-API/blob/main/VX-API/MalwareStrings.h
constexpr DWORD HashStringDjb2(const char* String)
{
ULONG Hash = 5381;
INT c = 0;
while ((c = *String++)) {
Hash = ((Hash << 5) + Hash) + c;
}
return Hash;
}
constexpr DWORD HashStringDjb2(const wchar_t* String)
{
ULONG Hash = 5381;
INT c = 0;
while ((c = *String++)) {
Hash = ((Hash << 5) + Hash) + c;
}
return Hash;
}
#pragma endregion
#pragma region HashStringFowlerNollVoVariant1a
constexpr ULONG HashStringFowlerNollVoVariant1a(const char* String)
{
ULONG Hash = 0x811c9dc5;
while (*String)
{
Hash ^= (UCHAR)*String++;
Hash *= 0x01000193;
}
return Hash;
}
constexpr ULONG HashStringFowlerNollVoVariant1a(const wchar_t* String)
{
ULONG Hash = 0x811c9dc5;
while (*String)
{
Hash ^= (UCHAR)*String++;
Hash *= 0x01000193;
}
return Hash;
}
#pragma endregion
inline void InitModules(void*);
void* GetProcAddrH(UINT moduleHash, UINT funcHash);
#pragma region macros
#define hash( VAL ) constexpr auto CONCAT( hash, VAL ) = HASHALGO( TOKENIZE( VAL ) );
#define dllhash(DLL, VAL ) constexpr auto CONCAT( hash, DLL ) = HASHALGO( VAL );
#define hashFunc( FUNCNAME , RETTYPE, ...) \
hash( FUNCNAME ) typedef RETTYPE( WINAPI* CONCAT( type, FUNCNAME ) )( __VA_ARGS__ );
#define API( DLL, FUNCNAME ) ( ( CONCAT( type, FUNCNAME ))GetProcAddrH( CONCAT( hash, DLL ) , \
CONCAT( hash,FUNCNAME ) ) )
dllhash(KERNEL32, L"KERNEL32.DLL")
dllhash(NTDLL, L"NTDLL.DLL")
hashFunc(NtUnmapViewOfSection, NTSTATUS, HANDLE, PVOID);
hashFunc(NtProtectVirtualMemory, NTSTATUS, HANDLE, PVOID*, PULONG, ULONG, PULONG);
hashFunc(NtOpenSection, NTSTATUS, HANDLE*, ACCESS_MASK, OBJECT_ATTRIBUTES*);
hashFunc(NtMapViewOfSection, NTSTATUS, HANDLE, HANDLE, PVOID, ULONG_PTR, SIZE_T, PLARGE_INTEGER, PSIZE_T, DWORD, ULONG, ULONG);
hashFunc(RtlInitUnicodeString, VOID, PUNICODE_STRING, PCWSTR);
#pragma endregion
#pragma endregion
#pragma region core
void CheckCommonlyHooked();
LPVOID RetrieveKnownDll(PWSTR name);
#pragma endregion
#pragma region random
constexpr int RandomSeed(void)
{
return '0' * -40271 + // offset accounting for digits' ANSI offsets
__TIME__[7] * 1 +
__TIME__[6] * 10 +
__TIME__[4] * 60 +
__TIME__[3] * 600 +
__TIME__[1] * 3600 +
__TIME__[0] * 36000;
};
constexpr auto KEY = RandomSeed() % 0xFF;
// https://github.com/Cih2001/String-Obfuscator
template <typename T, unsigned int N>
struct obfuscator {
T m_data[N] = { 0 };
constexpr obfuscator(const T* data) {
for (unsigned int i = 0; i < N; i++) {
m_data[i] = (data[i] ^ (i + KEY));
}
}
void deobfuscate(T* des) const {
int i = 0;
do {
des[i] = (m_data[i] ^ (i + KEY));
i++;
} while (des[i - 1]);
}
};
#define OBFW(str)\
[]() -> wchar_t* {\
constexpr auto size = sizeof(str)/sizeof(str[0]);\
constexpr auto obfuscated_str = obfuscator<wchar_t, size>(str);\
static wchar_t original_string[size];\
obfuscated_str.deobfuscate((wchar_t*)original_string);\
return original_string;\
}()
#define OBFA(str)\
[]() -> char* {\
constexpr auto size = sizeof(str)/sizeof(str[0]);\
constexpr auto obfuscated_str = obfuscator<char, size>(str);\
static char original_string[size];\
obfuscated_str.deobfuscate((char*)original_string);\
return original_string;\
}()
#pragma endregion
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// GLOBALS/STRUCTS ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
struct HashStruct
{
UINT Hash;
PVOID addr;
};
HashStruct ModuleHashes[] =
{
{ hashNTDLL , nullptr },
{ hashKERNEL32 , nullptr },
};
HashStruct HashCache[CACHE];
USHORT hashPointer;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// ENTRY ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
* entry() - entry point for this application as it's CRT-free
*
* Entropy is around 4 for entire PE
* * .text is 5.8
* Imports[0]:
* NO IMPORTS!
* Avoid PDB file names - Linker -> Debugging -> Generate Debug Info -> No
* Potential IOC - str in RetrieveKnownDll (XOR encrypted with a random key thanks to time)
* Context: Program entry point. Must not be called again.
*
* Return:
* * 0 - All cases
*/
int entry()
{
PPEB peb = NtCurrentTeb()->ProcessEnvironmentBlock;
LIST_ENTRY* head = &peb->Ldr->InMemoryOrderModuleList;
LIST_ENTRY* next = head->Flink;
// Calling as requested by InitModules contest
InitModules(head);
#if DEBUG == 1
CheckCommonlyHooked();
#endif
while (next != head)
{
LDR_DATA_TABLE_ENTRY* entry = (LDR_DATA_TABLE_ENTRY*)((PBYTE)next - offsetof(LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks));
UNICODE_STRING* fullname = &entry->FullDllName;
UNICODE_STRING* basename = (UNICODE_STRING*)((PBYTE)fullname + sizeof(UNICODE_STRING));
LPVOID addr = RetrieveKnownDll(basename->Buffer);
if (addr)
{
HMODULE module = (HMODULE)entry->DllBase;
PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)entry->DllBase;
PIMAGE_NT_HEADERS nt = RVA2VA(PIMAGE_NT_HEADERS, entry->DllBase, dos->e_lfanew);
// https://www.ired.team/offensive-security/defense-evasion/how-to-unhook-a-dll-using-c++
for (int i = 0; i < nt->FileHeader.NumberOfSections; i++) {
PIMAGE_SECTION_HEADER section =
(PIMAGE_SECTION_HEADER)((DWORD_PTR)IMAGE_FIRST_SECTION(nt) +
((DWORD_PTR)IMAGE_SIZEOF_SECTION_HEADER * i));
// strcmp will not inlined or optimized even with /O2
// thanks to modexp for the idea
if ((*(ULONG*)section->Name | 0x20202020) == 'xet.') {
ULONG dw;
PVOID base = RVA2VA(LPVOID, module, section->VirtualAddress);
ULONG size = section->Misc.VirtualSize;
// It's not a trivial task to make the DLL RW only especially in the case of NTDLL as we'll be using
// various NT functions. PAGE_EXECUTE_READWRITE is a potential IOC.
// I leave that as a task to the reader to get around this.
// It is also worth nothing NtProtectVirtualMemory could be hooked.
if (NT_SUCCESS(API(NTDLL,NtProtectVirtualMemory)(NtCurrentProcess(), &base, &size, PAGE_EXECUTE_READWRITE, &dw))) {
// Replacing all the DLLs with an unhooked version is a potential IOC if EDRs scan for unhooked DLLs
// Consider storing the hooked .text sections encrypted in an allocated buffer and restoring when
// you are done.
_memcpy(
RVA2VA(LPVOID, module, section->VirtualAddress),
RVA2VA(LPVOID, addr, section->VirtualAddress),
section->Misc.VirtualSize
);
// Restore original memory permissions
API(NTDLL,NtProtectVirtualMemory)(
NtCurrentProcess(),
&base,
&size,
dw,
&dw
);
PRINT(OBFW(L"[ ] Unhooked %s from \\KnownDlls\\%s \n"), basename->Buffer, basename->Buffer);
}
}
}
// Unmap pointer as required by RetrieveKnownDll
API(NTDLL,NtUnmapViewOfSection)(NtCurrentProcess(), addr);
}
next = next->Flink;
}
#if DEBUG == 1
CheckCommonlyHooked();
#endif
// Do whatever you want here
// Define API typedef with hashFunc macro and invoke using API(*)()
return 0;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#pragma region core
/**
* CheckCommonlyHooked() - Determines if 4 commonly hooked functions are hooked.
*
* Will check the opcodes of 4 commonly used functions exported by NTDLL in order to
* determine if they are hooked by compared against a previously known unhooked stub.
* 4C 8B D1 - mov r10, rcx
* B8 [SSN] - mov eax, 18 ; EDRs will always hook before or by this instruction
* Due to the nature of processors, this will be in reverse due to endianess
*
* Context: Any context.
* Return:
* * void
*/
void CheckCommonlyHooked()
{
HashStruct hashes[4] = {
{ hashNtProtectVirtualMemory, NULL },
{ hashNtProtectVirtualMemory, NULL },
{ hashNtMapViewOfSection, NULL },
{ hashNtOpenSection, NULL },
};
for (int i = 0; i < 4; i++) {
hashes[i].addr = GetProcAddrH(hashNTDLL, hashes[i].Hash);
if (*(ULONG*)hashes[i].addr != 0xb8d18b4c) {
PRINT(OBFW(L"[!] Hooked Function at 0x%p\n"), hashes[i].addr);
}
else {
PRINT(OBFW(L"[-] Function Not Hooked at 0x%p\n"), hashes[i].addr);
}
}
}
/**
* RetrieveKnownDlls() - Returns a pointer to a manually mapped KnownDll
*
* @name: Pointer to a unicode string
*
* Will attempt to open a section handle to \KnownDlls\@arg1 in order to map it.
* \KnownDlls\ is a directory of cached DLLs used to speed up loading of DLLs
* into a process at start time.
*
* Context: Any context. Expects to be unmapped once finished.
*
* Return:
* * LPVOID - to mapped \KnownDlls\@arg1
* * NULL - No valid \KnownDlls\ DLL was found
*/
LPVOID RetrieveKnownDll(PWSTR name)
{
BOOL success = FALSE;
PVOID addr = NULL;
ULONG_PTR size = NULL;
HANDLE section = INVALID_HANDLE_VALUE;
UNICODE_STRING uni;
OBJECT_ATTRIBUTES oa;
NTSTATUS status;
WCHAR buffer[MAX_PATH];
_strcpy(buffer, OBFW(L"\\KnownDlls\\")); // Potential IOC
_strcat(buffer, name);
API(NTDLL,RtlInitUnicodeString)(
&uni,
buffer
);
InitializeObjectAttributes(
&oa,
&uni,
OBJ_CASE_INSENSITIVE,
NULL,
NULL
);
if (!NT_SUCCESS(API(NTDLL,NtOpenSection)(&section, SECTION_MAP_READ, &oa)))
goto cleanup;
if (!NT_SUCCESS(API(NTDLL,NtMapViewOfSection)(section, NtCurrentProcess(), &addr, 0, 0, NULL, &size, 1, 0, PAGE_READONLY)))
goto cleanup;
cleanup:
return addr;
}
#pragma endregion
#pragma region helpers
wchar_t* _strcpy(wchar_t* dest, const wchar_t* src)
{
wchar_t* p;
if ((dest == NULL) || (src == NULL))
return dest;
if (dest == src)
return dest;
p = dest;
while (*src != 0) {
*p = *src;
p++;
src++;
}
*p = 0;
return dest;
}
wchar_t* _strcat(wchar_t* dest, const wchar_t* src)
{
if ((dest == NULL) || (src == NULL))
return dest;
while (*dest != 0)
dest++;
while (*src != 0) {
*dest = *src;
dest++;
src++;
}
*dest = 0;
return dest;
}
void _memcpy(void* dst, const void* src, SIZE_T count) {
for (volatile int i = 0; i < count; i++) {
((BYTE*)dst)[i] = ((BYTE*)src)[i];
}
}
__forceinline char upper(char c)
{
if (c >= 'a' && c <= 'z') {
return c - 'a' + 'A';
}
return c;
}
#pragma endregion
#pragma region hashing
/**
* GetProcAddrH() - Retrieve process address given the hash of a module and a corresponding function export hash
* @moduleHash: hash of module (hashMODULE)
* @funcHash: hash of the function (hashFUNCTION)
*
* Validates that the module hash is present in the ModuleHashes structure. If so it walks the export directory
* hashing all the names of the exports until it finds the corresponding function hash. The hash is then cached
* in the circular array HashCache which is indexed with hashPointer.
*
* Context: API(MODULE,FUNC) macro
* Determing whether an address is hooked or not.
* Return:
* * void* - pointer to exported function in specified module
* * NULL - in event of failure
*/
void* GetProcAddrH(UINT moduleHash, UINT funcHash)
{
void* base = nullptr;
for (auto i : ModuleHashes) {
if (i.Hash == moduleHash) {
base = i.addr;
}
}
if (base == NULL) {
return NULL;
}
for (DWORD i = 0; i < CACHE; i++)
{
if (funcHash == HashCache[i].Hash) {
return HashCache[i].addr;
}
}
PIMAGE_DOS_HEADER dos = (PIMAGE_DOS_HEADER)base;
PIMAGE_NT_HEADERS nt = RVA2VA(PIMAGE_NT_HEADERS, base, dos->e_lfanew);
PIMAGE_EXPORT_DIRECTORY exports = RVA2VA(PIMAGE_EXPORT_DIRECTORY, base, nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
if (exports->AddressOfNames != 0)
{
PWORD ordinals = RVA2VA(PWORD, base, exports->AddressOfNameOrdinals);
PDWORD names = RVA2VA(PDWORD, base, exports->AddressOfNames);
PDWORD functions = RVA2VA(PDWORD, base, exports->AddressOfFunctions);
for (DWORD i = 0; i < exports->NumberOfNames; i++) {
LPSTR name = RVA2VA(LPSTR, base, names[i]);
if (HASHALGO(name) == funcHash) {
PBYTE function = RVA2VA(PBYTE, base, functions[ordinals[i]]);
// Cache the result in a circular array
HashCache[hashPointer % CACHE].addr = function;
HashCache[hashPointer % CACHE].Hash = funcHash;
hashPointer = (hashPointer + 1) % CACHE;
return function;
}
}
}
return NULL;
}
/**
* InitModules() - Populate the ModuleHashes structure with the base addresses of the specified modules
* @headi1 - InMemoryOrderModuleList first entry
*
* Populates the ModuleHashes structure with the necessary DllBases required by checking against the
* respective module hash. Initializes the HashCache array and sets the hashPointer to 0 ready to be used.
*
* Context: Initialization. Before any hashed APIs are called.
*
*/
inline void InitModules(void* headi1)
{
LIST_ENTRY* head = (LIST_ENTRY*)headi1;
LIST_ENTRY* next = head->Flink;
while (next != head)
{
LDR_DATA_TABLE_ENTRY* entry = (LDR_DATA_TABLE_ENTRY*)((PBYTE)next - offsetof(LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks));
UNICODE_STRING* fullname = &entry->FullDllName;
UNICODE_STRING* basename = (UNICODE_STRING*)((PBYTE)fullname + sizeof(UNICODE_STRING));
char name[64];
if (basename->Length < sizeof(name) - 1)
{
int i = 0;
while (basename->Buffer[i] && i < sizeof(name) - 1)
{
name[i] = upper((char)basename->Buffer[i]); // can never be sure so uppercase
i++;
}
name[i] = 0;
UINT hash = HASHALGO(name);
for (auto& i : ModuleHashes) {
if (i.Hash == hash) {
i.addr = entry->DllBase;
}
}
}
next = next->Flink;
}
RtlSecureZeroMemory(HashCache, sizeof(HashCache));
hashPointer = 0;
}
#pragma endregion