initial push
This commit is contained in:
		
							
								
								
									
										17
									
								
								.clang-format
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								.clang-format
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| IndentWidth: 4 | ||||
| ConstructorInitializerIndentWidth: 4 | ||||
| ContinuationIndentWidth: 4 | ||||
| UseTab: Never | ||||
| ColumnLimit: 0 | ||||
| SpaceAfterCStyleCast: true | ||||
| PointerAlignment: Right | ||||
| NamespaceIndentation: All | ||||
| AlwaysBreakTemplateDeclarations: Yes | ||||
| AllowShortBlocksOnASingleLine: Never | ||||
| AllowShortCaseLabelsOnASingleLine: true | ||||
| AllowShortEnumsOnASingleLine: true | ||||
| AllowShortFunctionsOnASingleLine: None | ||||
| AllowShortIfStatementsOnASingleLine: Never | ||||
| AllowShortLambdasOnASingleLine: None | ||||
| AllowShortLoopsOnASingleLine: false | ||||
| IndentPPDirectives: AfterHash | ||||
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| .vs | ||||
| .temp | ||||
|  | ||||
| build | ||||
							
								
								
									
										6
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| # osu-auth-reader | ||||
| Read portions of the raw token from osu's anticheat. | ||||
|  | ||||
| That's all really! | ||||
|  | ||||
|  | ||||
							
								
								
									
										25
									
								
								ac_checker.sln
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								ac_checker.sln
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
|  | ||||
| Microsoft Visual Studio Solution File, Format Version 12.00 | ||||
| # Visual Studio Version 17 | ||||
| VisualStudioVersion = 17.2.32505.173 | ||||
| MinimumVisualStudioVersion = 10.0.40219.1 | ||||
| Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ac_checker", "ac_checker\ac_checker.vcxproj", "{4FA0ACF4-DC50-4201-82BD-3A11664286AC}" | ||||
| EndProject | ||||
| Global | ||||
| 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||
| 		Debug|x86 = Debug|x86 | ||||
| 		Release|x86 = Release|x86 | ||||
| 	EndGlobalSection | ||||
| 	GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||||
| 		{4FA0ACF4-DC50-4201-82BD-3A11664286AC}.Debug|x86.ActiveCfg = Debug|Win32 | ||||
| 		{4FA0ACF4-DC50-4201-82BD-3A11664286AC}.Debug|x86.Build.0 = Debug|Win32 | ||||
| 		{4FA0ACF4-DC50-4201-82BD-3A11664286AC}.Release|x86.ActiveCfg = Release|Win32 | ||||
| 		{4FA0ACF4-DC50-4201-82BD-3A11664286AC}.Release|x86.Build.0 = Release|Win32 | ||||
| 	EndGlobalSection | ||||
| 	GlobalSection(SolutionProperties) = preSolution | ||||
| 		HideSolutionNode = FALSE | ||||
| 	EndGlobalSection | ||||
| 	GlobalSection(ExtensibilityGlobals) = postSolution | ||||
| 		SolutionGuid = {43EE6F3D-E5C7-4D8E-868F-4EF339262E61} | ||||
| 	EndGlobalSection | ||||
| EndGlobal | ||||
							
								
								
									
										103
									
								
								ac_checker/ac_checker.vcxproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								ac_checker/ac_checker.vcxproj
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,103 @@ | ||||
| <?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> | ||||
|   </ItemGroup> | ||||
|   <PropertyGroup Label="Globals"> | ||||
|     <VCProjectVersion>16.0</VCProjectVersion> | ||||
|     <Keyword>Win32Proj</Keyword> | ||||
|     <ProjectGuid>{4fa0acf4-dc50-4201-82bd-3a11664286ac}</ProjectGuid> | ||||
|     <RootNamespace>acchecker</RootNamespace> | ||||
|     <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> | ||||
|   </PropertyGroup> | ||||
|   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | ||||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | ||||
|     <ConfigurationType>DynamicLibrary</ConfigurationType> | ||||
|     <UseDebugLibraries>true</UseDebugLibraries> | ||||
|     <PlatformToolset>v143</PlatformToolset> | ||||
|     <CharacterSet>Unicode</CharacterSet> | ||||
|   </PropertyGroup> | ||||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> | ||||
|     <ConfigurationType>DynamicLibrary</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> | ||||
|   <PropertyGroup Label="UserMacros" /> | ||||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||||
|     <OutDir>$(SolutionDir)\build\$(Configuration)\</OutDir> | ||||
|     <IntDir>$(SolutionDir)\.temp\$(Configuration)\</IntDir> | ||||
|     <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\include;</IncludePath> | ||||
|   </PropertyGroup> | ||||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | ||||
|     <OutDir>$(SolutionDir)\build\$(Configuration)\</OutDir> | ||||
|     <IntDir>$(SolutionDir)\.temp\$(Configuration)\</IntDir> | ||||
|     <IncludePath>$(VC_IncludePath);$(WindowsSDK_IncludePath);$(ProjectDir)\include;</IncludePath> | ||||
|   </PropertyGroup> | ||||
|   <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | ||||
|     <ClCompile> | ||||
|       <WarningLevel>Level3</WarningLevel> | ||||
|       <SDLCheck>true</SDLCheck> | ||||
|       <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions> | ||||
|       <ConformanceMode>true</ConformanceMode> | ||||
|       <LanguageStandard>stdcpplatest</LanguageStandard> | ||||
|     </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> | ||||
|       <LanguageStandard>stdcpplatest</LanguageStandard> | ||||
|     </ClCompile> | ||||
|     <Link> | ||||
|       <SubSystem>Console</SubSystem> | ||||
|       <EnableCOMDATFolding>true</EnableCOMDATFolding> | ||||
|       <OptimizeReferences>true</OptimizeReferences> | ||||
|       <GenerateDebugInformation>true</GenerateDebugInformation> | ||||
|     </Link> | ||||
|   </ItemDefinitionGroup> | ||||
|   <ItemGroup> | ||||
|     <ClCompile Include="main.cpp" /> | ||||
|     <ClCompile Include="source\util\hooklib.cpp" /> | ||||
|     <ClCompile Include="source\util\memory.cpp" /> | ||||
|     <ClCompile Include="source\util\pe.cpp" /> | ||||
|     <ClCompile Include="source\vendor\hde.cpp" /> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClInclude Include="include\util\hooklib.hpp" /> | ||||
|     <ClInclude Include="include\util\memory.hpp" /> | ||||
|     <ClInclude Include="include\util\pe.hpp" /> | ||||
|     <ClInclude Include="include\vendor\hde.hpp" /> | ||||
|     <ClInclude Include="include\vendor\small_vector.hpp" /> | ||||
|   </ItemGroup> | ||||
|   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | ||||
|   <ImportGroup Label="ExtensionTargets"> | ||||
|   </ImportGroup> | ||||
| </Project> | ||||
							
								
								
									
										51
									
								
								ac_checker/ac_checker.vcxproj.filters
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								ac_checker/ac_checker.vcxproj.filters
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| <?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="main.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="source\util\memory.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="source\util\hooklib.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="source\vendor\hde.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|     <ClCompile Include="source\util\pe.cpp"> | ||||
|       <Filter>Source Files</Filter> | ||||
|     </ClCompile> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <ClInclude Include="include\vendor\small_vector.hpp"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="include\util\memory.hpp"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="include\util\hooklib.hpp"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="include\vendor\hde.hpp"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|     <ClInclude Include="include\util\pe.hpp"> | ||||
|       <Filter>Header Files</Filter> | ||||
|     </ClInclude> | ||||
|   </ItemGroup> | ||||
| </Project> | ||||
							
								
								
									
										6
									
								
								ac_checker/ac_checker.vcxproj.user
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								ac_checker/ac_checker.vcxproj.user
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||
|   <PropertyGroup> | ||||
|     <ShowAllFiles>true</ShowAllFiles> | ||||
|   </PropertyGroup> | ||||
| </Project> | ||||
							
								
								
									
										31
									
								
								ac_checker/include/util/hooklib.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								ac_checker/include/util/hooklib.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| #pragma once | ||||
| #include <cstdint> | ||||
| #include <type_traits> | ||||
|  | ||||
| namespace util { | ||||
|  | ||||
|     struct Hook { | ||||
|         uintptr_t _bytes = 0; | ||||
|         uintptr_t _target = 0; | ||||
|         uintptr_t _detour = 0; | ||||
|         uintptr_t _tramp = 0; | ||||
|  | ||||
|         bool enable(uintptr_t target, uintptr_t detour); | ||||
|         void disable(); | ||||
|  | ||||
|         template <typename Target, typename Detour> | ||||
|         inline bool enable(Target target, Detour detour) { | ||||
|             return enable((uintptr_t) target, (uintptr_t) detour); | ||||
|         } | ||||
|  | ||||
|         template <typename Func, typename... Args> | ||||
|         inline auto invoke(Args &&...args) const { | ||||
|             return ((Func) _tramp)(std::forward<Args>(args)...); | ||||
|         } | ||||
|     }; | ||||
|  | ||||
| } // namespace util | ||||
|  | ||||
| #define define_hook(name, ret, call_conv, ...) \ | ||||
|     inline util::Hook name;                    \ | ||||
|     ret call_conv name##_hook(__VA_ARGS__); | ||||
							
								
								
									
										16
									
								
								ac_checker/include/util/memory.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								ac_checker/include/util/memory.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| #pragma once | ||||
| #include <cstdint> | ||||
| #include <string> | ||||
|  | ||||
| namespace signatures { | ||||
|  | ||||
|     constexpr static auto s_token_log_ref = "558BEC83EC08C645FC01C745"; | ||||
|  | ||||
| } | ||||
|  | ||||
| namespace util { | ||||
|  | ||||
|     uint8_t *find_pattern(std::string_view pattern, uint8_t *begin, size_t size, ptrdiff_t offset = 0x0); | ||||
|     uint8_t *scan_module(std::string_view module_name, std::string_view pattern, ptrdiff_t offset = 0x0); | ||||
|      | ||||
| } // namespace util | ||||
							
								
								
									
										17
									
								
								ac_checker/include/util/pe.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								ac_checker/include/util/pe.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| #pragma once | ||||
| #include <cstdint> | ||||
| #include <string_view> | ||||
|  | ||||
| // <3 mr polish man | ||||
|  | ||||
| namespace util { | ||||
|  | ||||
|     struct ModuleInfo { | ||||
|         uintptr_t base; | ||||
|         size_t size; | ||||
|     }; | ||||
|  | ||||
|     ModuleInfo get_module(std::string_view module_name); | ||||
|     uintptr_t get_export(std::string_view module_name, std::string_view export_name); | ||||
|  | ||||
| } // namespace util | ||||
							
								
								
									
										104
									
								
								ac_checker/include/vendor/hde.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								ac_checker/include/vendor/hde.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,104 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <stdint.h> | ||||
|  | ||||
| #define C_NONE 0x00 | ||||
| #define C_MODRM 0x01 | ||||
| #define C_IMM8 0x02 | ||||
| #define C_IMM16 0x04 | ||||
| #define C_IMM_P66 0x10 | ||||
| #define C_REL8 0x20 | ||||
| #define C_REL32 0x40 | ||||
| #define C_GROUP 0x80 | ||||
| #define C_ERROR 0xff | ||||
|  | ||||
| #define PRE_ANY 0x00 | ||||
| #define PRE_NONE 0x01 | ||||
| #define PRE_F2 0x02 | ||||
| #define PRE_F3 0x04 | ||||
| #define PRE_66 0x08 | ||||
| #define PRE_67 0x10 | ||||
| #define PRE_LOCK 0x20 | ||||
| #define PRE_SEG 0x40 | ||||
| #define PRE_ALL 0xff | ||||
|  | ||||
| #define DELTA_OPCODES 0x4a | ||||
| #define DELTA_FPU_REG 0xf1 | ||||
| #define DELTA_FPU_MODRM 0xf8 | ||||
| #define DELTA_PREFIXES 0x130 | ||||
| #define DELTA_OP_LOCK_OK 0x1a1 | ||||
| #define DELTA_OP2_LOCK_OK 0x1b9 | ||||
| #define DELTA_OP_ONLY_MEM 0x1cb | ||||
| #define DELTA_OP2_ONLY_MEM 0x1da | ||||
|  | ||||
| #define F_MODRM 0x00000001 | ||||
| #define F_SIB 0x00000002 | ||||
| #define F_IMM8 0x00000004 | ||||
| #define F_IMM16 0x00000008 | ||||
| #define F_IMM32 0x00000010 | ||||
| #define F_DISP8 0x00000020 | ||||
| #define F_DISP16 0x00000040 | ||||
| #define F_DISP32 0x00000080 | ||||
| #define F_RELATIVE 0x00000100 | ||||
| #define F_2IMM16 0x00000800 | ||||
| #define F_ERROR 0x00001000 | ||||
| #define F_ERROR_OPCODE 0x00002000 | ||||
| #define F_ERROR_LENGTH 0x00004000 | ||||
| #define F_ERROR_LOCK 0x00008000 | ||||
| #define F_ERROR_OPERAND 0x00010000 | ||||
| #define F_PREFIX_REPNZ 0x01000000 | ||||
| #define F_PREFIX_REPX 0x02000000 | ||||
| #define F_PREFIX_REP 0x03000000 | ||||
| #define F_PREFIX_66 0x04000000 | ||||
| #define F_PREFIX_67 0x08000000 | ||||
| #define F_PREFIX_LOCK 0x10000000 | ||||
| #define F_PREFIX_SEG 0x20000000 | ||||
| #define F_PREFIX_ANY 0x3f000000 | ||||
|  | ||||
| #define PREFIX_SEGMENT_CS 0x2e | ||||
| #define PREFIX_SEGMENT_SS 0x36 | ||||
| #define PREFIX_SEGMENT_DS 0x3e | ||||
| #define PREFIX_SEGMENT_ES 0x26 | ||||
| #define PREFIX_SEGMENT_FS 0x64 | ||||
| #define PREFIX_SEGMENT_GS 0x65 | ||||
| #define PREFIX_LOCK 0xf0 | ||||
| #define PREFIX_REPNZ 0xf2 | ||||
| #define PREFIX_REPX 0xf3 | ||||
| #define PREFIX_OPERAND_SIZE 0x66 | ||||
| #define PREFIX_ADDRESS_SIZE 0x67 | ||||
|  | ||||
| #pragma pack(push, 1) | ||||
|  | ||||
| typedef struct { | ||||
|     uint8_t len; | ||||
|     uint8_t p_rep; | ||||
|     uint8_t p_lock; | ||||
|     uint8_t p_seg; | ||||
|     uint8_t p_66; | ||||
|     uint8_t p_67; | ||||
|     uint8_t opcode; | ||||
|     uint8_t opcode2; | ||||
|     uint8_t modrm; | ||||
|     uint8_t modrm_mod; | ||||
|     uint8_t modrm_reg; | ||||
|     uint8_t modrm_rm; | ||||
|     uint8_t sib; | ||||
|     uint8_t sib_scale; | ||||
|     uint8_t sib_index; | ||||
|     uint8_t sib_base; | ||||
|     union { | ||||
|         uint8_t imm8; | ||||
|         uint16_t imm16; | ||||
|         uint32_t imm32; | ||||
|     } imm; | ||||
|     union { | ||||
|         uint8_t disp8; | ||||
|         uint16_t disp16; | ||||
|         uint32_t disp32; | ||||
|     } disp; | ||||
|     uint32_t flags; | ||||
| } hde32s; | ||||
|  | ||||
| #pragma pack(pop) | ||||
|  | ||||
| unsigned int hde32_disasm(const void *code, hde32s *hs); | ||||
							
								
								
									
										371
									
								
								ac_checker/include/vendor/small_vector.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										371
									
								
								ac_checker/include/vendor/small_vector.hpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,371 @@ | ||||
| #pragma once | ||||
| #include <array> | ||||
| #include <iostream> | ||||
| #include <vector> | ||||
|  | ||||
| namespace vendor { | ||||
|  | ||||
|     template <class T, std::size_t N, class Allocator = std::allocator<T>> | ||||
|     class small_vector { | ||||
|         std::array<T, N> stack_; | ||||
|         std::vector<T, Allocator> heap_; | ||||
|         std::size_t size_{0}; | ||||
|  | ||||
|       public: | ||||
|         typedef T value_type; | ||||
|         typedef std::size_t size_type; | ||||
|         typedef value_type &reference; | ||||
|         typedef const value_type &const_reference; | ||||
|         typedef Allocator allocator_type; | ||||
|         typedef T *pointer; | ||||
|         typedef const T *const_pointer; | ||||
|  | ||||
|         small_vector() = default; | ||||
|  | ||||
|         explicit small_vector(size_type count, const T &value = T(), const Allocator &alloc = Allocator()) { | ||||
|             if (count == N) { | ||||
|                 stack_.fill(value); | ||||
|             } else if (count < N) { | ||||
|                 for (size_t i = 0; i < count; i++) { | ||||
|                     stack_[i] = value; | ||||
|                 } | ||||
|             } else { | ||||
|                 // use heap | ||||
|                 heap_ = std::move(std::vector<T>(count, value, alloc)); | ||||
|             } | ||||
|             size_ = count; | ||||
|         } | ||||
|  | ||||
|         small_vector(const small_vector &other, const Allocator &alloc = Allocator()) | ||||
|             : stack_(other.stack_), heap_(other.heap_, alloc), size_(other.size_) { | ||||
|         } | ||||
|  | ||||
|         small_vector(small_vector &&other, const Allocator &alloc = Allocator()) | ||||
|             : stack_(std::move(other.stack_)), heap_(std::move(other.heap_), alloc), size_(std::move(other.size_)) { | ||||
|         } | ||||
|  | ||||
|         small_vector(std::initializer_list<T> initlist, const Allocator &alloc = Allocator()) { | ||||
|             const auto input_size = initlist.size(); | ||||
|             if (input_size <= N) { | ||||
|                 std::copy(initlist.begin(), initlist.end(), stack_.begin()); | ||||
|             } else { | ||||
|                 heap_ = std::move(std::vector<T>(initlist, alloc)); | ||||
|             } | ||||
|             size_ = input_size; | ||||
|         } | ||||
|  | ||||
|         small_vector &operator=(const small_vector &rhs) { | ||||
|             stack_ = rhs.stack_; | ||||
|             heap_ = rhs.heap_; | ||||
|             size_ = rhs.size_; | ||||
|             return *this; | ||||
|         } | ||||
|  | ||||
|         small_vector &operator=(small_vector &&rhs) { | ||||
|             stack_ = std::move(rhs.stack_); | ||||
|             heap_ = std::move(rhs.heap_); | ||||
|             size_ = rhs.size_; | ||||
|             rhs.size_ = 0; | ||||
|             return *this; | ||||
|         } | ||||
|  | ||||
|         small_vector &operator=(std::initializer_list<value_type> rhs) { | ||||
|             if (rhs.size() <= N) { | ||||
|                 stack_ = rhs; | ||||
|             } else { | ||||
|                 heap_ = rhs; | ||||
|             } | ||||
|             size_ = rhs.size(); | ||||
|         } | ||||
|  | ||||
|         allocator_type get_allocator() const noexcept { | ||||
|             return heap_.get_allocator(); | ||||
|         } | ||||
|  | ||||
|         reference at(size_type pos) { | ||||
|             if (size_ < N) { | ||||
|                 return stack_.at(pos); | ||||
|             } else { | ||||
|                 return heap_.at(pos); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         const_reference at(size_type pos) const { | ||||
|             if (size_ < N) { | ||||
|                 return stack_.at(pos); | ||||
|             } else { | ||||
|                 return heap_.at(pos); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         reference operator[](size_type pos) { | ||||
|             if (size_ < N) { | ||||
|                 return stack_[pos]; | ||||
|             } else { | ||||
|                 return heap_[pos]; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         const_reference operator[](size_type pos) const { | ||||
|             if (size_ < N) { | ||||
|                 return stack_[pos]; | ||||
|             } else { | ||||
|                 return heap_[pos]; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         reference front() { | ||||
|             if (size_ < N) { | ||||
|                 return stack_.front(); | ||||
|             } else { | ||||
|                 return heap_.front(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         const_reference front() const { | ||||
|             if (size_ < N) { | ||||
|                 return stack_.front(); | ||||
|             } else { | ||||
|                 return heap_.front(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         reference back() { | ||||
|             if (size_ < N) { | ||||
|                 return stack_[size_ - 1]; | ||||
|             } else { | ||||
|                 return heap_[size_ - 1]; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         const_reference back() const { | ||||
|             if (size_ < N) { | ||||
|                 return stack_[size_ - 1]; | ||||
|             } else { | ||||
|                 return heap_[size_ - 1]; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         pointer data() noexcept { | ||||
|             if (size_ < N) { | ||||
|                 return stack_.data(); | ||||
|             } else { | ||||
|                 return heap_.data(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         const_pointer data() const noexcept { | ||||
|             if (size_ < N) { | ||||
|                 return stack_.data(); | ||||
|             } else { | ||||
|                 return heap_.data(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         bool empty() const { | ||||
|             return size_ == 0; | ||||
|         } | ||||
|  | ||||
|         size_type size() const { | ||||
|             return size_; | ||||
|         } | ||||
|  | ||||
|         void shrink_to_fit() { | ||||
|             if (size_ >= N) { | ||||
|                 heap_.shrink_to_fit(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         void push_back(const T &value) { | ||||
|             if (size_ < N) { | ||||
|                 stack_[size_] = value; | ||||
|             } else { | ||||
|                 if (size_ == N) { | ||||
|                     // move everything to heap | ||||
|                     std::move(stack_.begin(), stack_.end(), std::back_inserter(heap_)); | ||||
|                 } | ||||
|                 heap_.push_back(value); | ||||
|             } | ||||
|             size_ += 1; | ||||
|         } | ||||
|  | ||||
|         void push_back(T &&value) { | ||||
|             if (size_ < N) { | ||||
|                 stack_[size_] = std::move(value); | ||||
|             } else { | ||||
|                 if (size_ == N) { | ||||
|                     // move everything to heap | ||||
|                     std::move(stack_.begin(), stack_.end(), std::back_inserter(heap_)); | ||||
|                 } | ||||
|                 heap_.push_back(std::move(value)); | ||||
|             } | ||||
|             size_ += 1; | ||||
|         } | ||||
|  | ||||
|         void pop_back() { | ||||
|             if (size_ == 0) { | ||||
|                 // do nothing | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             if (size_ < N) { | ||||
|                 size_ -= 1; | ||||
|             } else { | ||||
|                 // currently using heap | ||||
|                 heap_.pop_back(); | ||||
|                 size_ -= 1; | ||||
|  | ||||
|                 // now check if all data can fit on stack | ||||
|                 // if so, move back to stack | ||||
|                 if (size_ < N) { | ||||
|                     std::move(heap_.begin(), heap_.end(), stack_.begin()); | ||||
|                     heap_.clear(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Resizes the container to contain count elements. | ||||
|         void resize(size_type count, T value = T()) { | ||||
|             if (count <= N) { | ||||
|                 // new `count` of elements completely fit on stack | ||||
|                 if (size_ >= N) { | ||||
|                     // currently, all data on heap | ||||
|                     // move back to stack | ||||
|                     std::move(heap_.begin(), heap_.end(), stack_.begin()); | ||||
|                 } else { | ||||
|                     // all data already on stack | ||||
|                     // just update size | ||||
|                 } | ||||
|             } else { | ||||
|                 // new `count` of data is going to be on the heap | ||||
|                 // check if data is currently on the stack | ||||
|                 if (size_ < N) { | ||||
|                     // move to heap | ||||
|                     std::move(stack_.begin(), stack_.end(), std::back_inserter(heap_)); | ||||
|                 } | ||||
|                 heap_.resize(count, value); | ||||
|             } | ||||
|             size_ = count; | ||||
|         } | ||||
|  | ||||
|         void swap(small_vector &other) noexcept { | ||||
|             std::swap(stack_, other.stack_); | ||||
|             std::swap(heap_, other.heap_); | ||||
|             std::swap(size_, other.size_); | ||||
|         }; | ||||
|  | ||||
|         // Assigns the given value value to all elements in the container | ||||
|         void fill(const_reference value) { | ||||
|             if (size_ < N) { | ||||
|                 stack_.fill(value); | ||||
|             } else { | ||||
|                 std::fill(heap_.begin(), heap_.end(), value); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         class iterator { | ||||
|             pointer ptr_; | ||||
|  | ||||
|           public: | ||||
|             typedef iterator self_type; | ||||
|             typedef T value_type; | ||||
|             typedef T &reference; | ||||
|             typedef T *pointer; | ||||
|             typedef std::forward_iterator_tag iterator_category; | ||||
|             typedef int difference_type; | ||||
|             iterator(pointer ptr) | ||||
|                 : ptr_(ptr) { | ||||
|             } | ||||
|             self_type operator++() { | ||||
|                 ptr_++; | ||||
|                 return *this; | ||||
|             } | ||||
|             self_type operator++(int) { | ||||
|                 self_type i = *this; | ||||
|                 ptr_++; | ||||
|                 return i; | ||||
|             } | ||||
|             reference operator*() { | ||||
|                 return *ptr_; | ||||
|             } | ||||
|             pointer operator->() { | ||||
|                 return ptr_; | ||||
|             } | ||||
|             bool operator==(const self_type &rhs) { | ||||
|                 return ptr_ == rhs.ptr_; | ||||
|             } | ||||
|             bool operator!=(const self_type &rhs) { | ||||
|                 return ptr_ != rhs.ptr_; | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         class const_iterator { | ||||
|             pointer ptr_; | ||||
|  | ||||
|           public: | ||||
|             typedef const_iterator self_type; | ||||
|             typedef T value_type; | ||||
|             typedef T &reference; | ||||
|             typedef T *pointer; | ||||
|             typedef int difference_type; | ||||
|             typedef std::forward_iterator_tag iterator_category; | ||||
|             const_iterator(pointer ptr) | ||||
|                 : ptr_(ptr) { | ||||
|             } | ||||
|             self_type operator++() { | ||||
|                 ptr_++; | ||||
|                 return *this; | ||||
|             } | ||||
|             self_type operator++(int) { | ||||
|                 self_type i = *this; | ||||
|                 ptr_++; | ||||
|                 return i; | ||||
|             } | ||||
|             const value_type &operator*() { | ||||
|                 return *ptr_; | ||||
|             } | ||||
|             const pointer operator->() { | ||||
|                 return ptr_; | ||||
|             } | ||||
|             bool operator==(const self_type &rhs) { | ||||
|                 return ptr_ == rhs.ptr_; | ||||
|             } | ||||
|             bool operator!=(const self_type &rhs) { | ||||
|                 return ptr_ != rhs.ptr_; | ||||
|             } | ||||
|         }; | ||||
|  | ||||
|         iterator begin() { | ||||
|             if (size_ < N) { | ||||
|                 return iterator(stack_.data()); | ||||
|             } else { | ||||
|                 return iterator(heap_.data()); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         iterator end() { | ||||
|             if (size_ < N) { | ||||
|                 return iterator(stack_.data() + size_); | ||||
|             } else { | ||||
|                 return iterator(heap_.data() + size_); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         const_iterator begin() const { | ||||
|             if (size_ < N) { | ||||
|                 return const_iterator(stack_.data()); | ||||
|             } else { | ||||
|                 return const_iterator(heap_.data()); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         const_iterator end() const { | ||||
|             if (size_ < N) { | ||||
|                 return const_iterator(stack_.data() + size_); | ||||
|             } else { | ||||
|                 return const_iterator(heap_.data() + size_); | ||||
|             } | ||||
|         } | ||||
|     }; | ||||
|  | ||||
| } // namespace vendor | ||||
							
								
								
									
										49
									
								
								ac_checker/main.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								ac_checker/main.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,49 @@ | ||||
| #include <Windows.h> | ||||
| #include <cstdint> | ||||
| #include <cstdio> | ||||
| #include <thread> | ||||
|  | ||||
| #include <util/hooklib.hpp> | ||||
| #include <util/memory.hpp> | ||||
|  | ||||
| define_hook(log_token, int, __fastcall, uintptr_t, uintptr_t, char *, size_t); | ||||
|  | ||||
| template <typename T> | ||||
| constexpr auto x86_abs_addr(T source, ptrdiff_t disp, size_t length) { | ||||
|     return (uintptr_t) (source + disp + length); | ||||
| } | ||||
|  | ||||
| static int __fastcall log_token_hook(uintptr_t ecx, uintptr_t edx, char *text, size_t size) { | ||||
|     if (size == 4 /*A trash value representing a flag has been pushed; do not print it.*/) { | ||||
|         fprintf(stdout, "[!] flag detected!\n"); | ||||
|     } else { | ||||
|         fprintf(stdout, "[~] %s\n", text); | ||||
|     } | ||||
|  | ||||
|     return log_token.invoke<decltype(&log_token_hook)>(ecx, edx, text, size); | ||||
| } | ||||
|  | ||||
| bool __stdcall DllMain(uintptr_t instance, uint32_t reason, uintptr_t reserved) { | ||||
|     if (reason == 1) { | ||||
|         std::thread([]() { | ||||
|             AllocConsole(); | ||||
|             SetConsoleTitleA("1337 h4x0r ac checker"); | ||||
|             freopen_s((FILE **) stdout, "CONOUT$", "w", stdout); | ||||
|  | ||||
|             fprintf(stdout, "iroha // pushfq\n"); | ||||
|  | ||||
|             if (auto addr = util::scan_module("osu!auth.dll", signatures::s_token_log_ref, 0x1A)) { | ||||
|                 log_token.enable(x86_abs_addr(addr, *(ptrdiff_t *) (addr + 0x1), 0x5), log_token_hook); | ||||
|             } | ||||
|             // The user is likely using a targeted build. (TODO: perhaps add support for this where possible?) | ||||
|             else { | ||||
|                 MessageBoxA(nullptr, "Unsupported target.", "osu!", MB_OK | MB_TOPMOST); | ||||
|                 exit(0); | ||||
|             } | ||||
|  | ||||
|             fprintf(stdout, "initialized.\n"); | ||||
|         }).detach(); | ||||
|     } | ||||
|  | ||||
|     return true; | ||||
| } | ||||
							
								
								
									
										76
									
								
								ac_checker/source/util/hooklib.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								ac_checker/source/util/hooklib.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,76 @@ | ||||
| #include <Windows.h> | ||||
| #include <util/hooklib.hpp> | ||||
| #include <vendor/hde.hpp> | ||||
|  | ||||
| namespace util { | ||||
|  | ||||
|     constexpr uint8_t target_shellcode[] = { | ||||
|         0x8D, 0x64, 0x24, 0xFC,                   // lea esp, [esp-0x4] | ||||
|         0xC7, 0x04, 0x24, 0xFF, 0xFF, 0xFF, 0xFF, // mov DWORD PTR [esp], ADDRESS | ||||
|         0xC3                                      // ret | ||||
|     }; | ||||
|  | ||||
|     constexpr uint8_t tramp_shellcode[] = { | ||||
|         0x68, 0xFF, 0xFF, 0xFF, 0xFF, // push imm32 | ||||
|         0xC3,                         // ret | ||||
|     }; | ||||
|  | ||||
|     bool Hook::enable(uintptr_t target, uintptr_t detour) { | ||||
|         hde32s hde_state; | ||||
|          | ||||
|         while (_bytes < sizeof(target_shellcode)) { | ||||
|             _bytes += hde32_disasm((const void *) (target + _bytes), &hde_state); | ||||
|  | ||||
|             if (hde_state.opcode == 0xC3) { | ||||
|                 _bytes = 0; | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         auto tramp = VirtualAlloc(nullptr, _bytes + sizeof(tramp_shellcode), MEM_COMMIT, PAGE_EXECUTE_READWRITE); | ||||
|  | ||||
|         if (!tramp) { | ||||
|             _bytes = 0; | ||||
|             return false; | ||||
|         } | ||||
|  | ||||
|         unsigned long old_prot; | ||||
|  | ||||
|         VirtualProtect((void *) target, _bytes, PAGE_EXECUTE_READWRITE, &old_prot); | ||||
|  | ||||
|         _target = target; | ||||
|         _detour = detour; | ||||
|         _tramp = (uintptr_t) tramp; | ||||
|  | ||||
|         memcpy((uint8_t *) _tramp, (const uint8_t *) _target, _bytes); | ||||
|         memcpy((uint8_t *) _tramp + _bytes, tramp_shellcode, sizeof(tramp_shellcode)); | ||||
|         memcpy((uint8_t *) _target, target_shellcode, sizeof(target_shellcode)); | ||||
|  | ||||
|         *(uintptr_t *) (_target + 7) = _detour; | ||||
|         *(uintptr_t *) (_tramp + _bytes + 1) = _target + _bytes; | ||||
|  | ||||
|         VirtualProtect((void *) target, _bytes, old_prot, &old_prot); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     void Hook::disable() { | ||||
|         if (!_bytes) | ||||
|             return; | ||||
|  | ||||
|         unsigned long old_prot; | ||||
|  | ||||
|         VirtualProtect((void *) _target, _bytes, PAGE_EXECUTE_READWRITE, &old_prot); | ||||
|  | ||||
|         memcpy((uint8_t *) _target, (const uint8_t *) _tramp + _bytes, _bytes); | ||||
|  | ||||
|         VirtualFree((void *) _tramp, 0, MEM_RELEASE); | ||||
|         VirtualProtect((void *) _target, _bytes, old_prot, &old_prot); | ||||
|  | ||||
|         _bytes = 0; | ||||
|         _target = 0; | ||||
|         _detour = 0; | ||||
|         _tramp = 0; | ||||
|     } | ||||
|  | ||||
| } // namespace util | ||||
							
								
								
									
										64
									
								
								ac_checker/source/util/memory.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								ac_checker/source/util/memory.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | ||||
| #include <util/memory.hpp> | ||||
| #include <util/pe.hpp> | ||||
| #include <vendor/small_vector.hpp> | ||||
|  | ||||
| namespace util { | ||||
|  | ||||
|     constexpr uint8_t hex_to_byte(char ch) { | ||||
|         if (ch >= '0' && ch <= '9') { | ||||
|             return ch - '0'; | ||||
|         } else if (ch >= 'a' && ch <= 'f') { | ||||
|             return ch - 'a' + 10; | ||||
|         } else if (ch >= 'A' && ch <= 'F') { | ||||
|             return ch - 'A' + 10; | ||||
|         } | ||||
|  | ||||
|         // >.< | ||||
|         std::unreachable(); | ||||
|     } | ||||
|  | ||||
|     constexpr uint8_t stich_byte(char x, char y) { | ||||
|         return hex_to_byte(x) << 4 | hex_to_byte(y); | ||||
|     } | ||||
|  | ||||
|     uint8_t *find_pattern(std::string_view pattern, uint8_t *begin, size_t size, ptrdiff_t offset) { | ||||
|         vendor::small_vector<uint8_t, 0x20> vec; | ||||
|  | ||||
|         for (auto i = 0u; i < pattern.size(); i++) { | ||||
|             auto &ch = pattern[i]; | ||||
|  | ||||
|             if (ch == '?') { | ||||
|                 vec.push_back(0xCC); | ||||
|             } else if (std::isxdigit(ch)) { | ||||
|                 vec.push_back(stich_byte(ch, pattern[++i])); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         for (auto mem = begin; mem < begin + size; mem++) { | ||||
|             bool is_found = true; | ||||
|  | ||||
|             for (auto i = 0u; i < vec.size(); i++) { | ||||
|                 if (vec[i] != 0xCC && vec[i] != mem[i]) { | ||||
|                     is_found = false; | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (is_found) { | ||||
|                 return mem + offset; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return nullptr; | ||||
|     } | ||||
|  | ||||
|     uint8_t *scan_module(std::string_view module_name, std::string_view pattern, ptrdiff_t offset) { | ||||
|         auto module_info = util::get_module(module_name); | ||||
|  | ||||
|         if (!module_info.base) | ||||
|             return nullptr; | ||||
|  | ||||
|         return util::find_pattern(pattern, (uint8_t *) module_info.base, module_info.size, offset); | ||||
|     } | ||||
|  | ||||
| } // namespace util | ||||
							
								
								
									
										70
									
								
								ac_checker/source/util/pe.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								ac_checker/source/util/pe.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | ||||
| #include <Windows.h> | ||||
| #include <Winternl.h> | ||||
| #include <cstdint> | ||||
| #include <cstdlib> | ||||
|  | ||||
| #include <util/pe.hpp> | ||||
|  | ||||
| struct LdrEntry { | ||||
|     LIST_ENTRY InLoadOrderLinks; | ||||
|     LIST_ENTRY InMemoryOrderLinks; | ||||
|     LIST_ENTRY InInitializationOrderLinks; | ||||
|     uintptr_t DllBase; | ||||
|     uintptr_t EntryPoint; | ||||
|     uint32_t SizeOfImage; | ||||
|     UNICODE_STRING FullDllName; | ||||
|     UNICODE_STRING BaseDllName; | ||||
| }; | ||||
|  | ||||
| namespace util { | ||||
|  | ||||
|     ModuleInfo get_module(std::string_view module_name) { | ||||
|         auto peb = ((_TEB *) __readfsdword(0x18))->ProcessEnvironmentBlock; | ||||
|         auto list = &peb->Ldr->InMemoryOrderModuleList; | ||||
|  | ||||
|         size_t wide_name_length = 0; | ||||
|         wchar_t wide_name[256] = {0}; | ||||
|  | ||||
|         mbstowcs_s(&wide_name_length, wide_name, 256, module_name.data(), module_name.size()); | ||||
|  | ||||
|         for (auto iter = list->Flink; iter != list; iter = iter->Flink) { | ||||
|             auto entry = CONTAINING_RECORD(iter, LdrEntry, InMemoryOrderLinks); | ||||
|  | ||||
|             if (entry->BaseDllName.Buffer && _wcsnicmp(entry->BaseDllName.Buffer, wide_name, wide_name_length) == 0) { | ||||
|                 return { | ||||
|                     .base = entry->DllBase, | ||||
|                     .size = entry->SizeOfImage, | ||||
|                 }; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return {}; | ||||
|     } | ||||
|  | ||||
|     uintptr_t get_export(std::string_view module_name, std::string_view export_name) { | ||||
|         auto module_info = get_module(module_name); | ||||
|         auto module_base = module_info.base; | ||||
|  | ||||
|         if (!module_base) | ||||
|             return 0u; | ||||
|  | ||||
|         auto dos_hdr = (IMAGE_DOS_HEADER *) module_base; | ||||
|         auto nt_hdrs = (IMAGE_NT_HEADERS *) (module_base + dos_hdr->e_lfanew); | ||||
|  | ||||
|         auto exports_va = nt_hdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; | ||||
|         auto exports_size = nt_hdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; | ||||
|         auto exports = (IMAGE_EXPORT_DIRECTORY *) (module_base + exports_va); | ||||
|  | ||||
|         auto names = (uintptr_t *) (module_base + exports->AddressOfNames); | ||||
|         auto functions = (uintptr_t *) (module_base + exports->AddressOfFunctions); | ||||
|         auto name_ordinals = (uint16_t *) (module_base + exports->AddressOfNameOrdinals); | ||||
|  | ||||
|         for (auto i = 0u; i < exports->NumberOfNames; i++) { | ||||
|             if (export_name.compare((const char *) (module_base + names[i])) == 0) | ||||
|                 return module_base + functions[name_ordinals[i]]; | ||||
|         } | ||||
|  | ||||
|         return 0u; | ||||
|     } | ||||
|  | ||||
| } // namespace util | ||||
							
								
								
									
										340
									
								
								ac_checker/source/vendor/hde.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										340
									
								
								ac_checker/source/vendor/hde.cpp
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,340 @@ | ||||
| #include <string.h> | ||||
| #include <vendor/hde.hpp> | ||||
|  | ||||
| static unsigned char hde32_table[] = { | ||||
|     0xa3, 0xa8, 0xa3, 0xa8, 0xa3, 0xa8, 0xa3, 0xa8, 0xa3, 0xa8, 0xa3, 0xa8, 0xa3, 0xa8, 0xa3, 0xa8, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, | ||||
|     0xaa, 0xaa, 0xac, 0xaa, 0xb2, 0xaa, 0x9f, 0x9f, 0x9f, 0x9f, 0xb5, 0xa3, 0xa3, 0xa4, 0xaa, 0xaa, 0xba, 0xaa, 0x96, 0xaa, 0xa8, 0xaa, | ||||
|     0xc3, 0xc3, 0x96, 0x96, 0xb7, 0xae, 0xd6, 0xbd, 0xa3, 0xc5, 0xa3, 0xa3, 0x9f, 0xc3, 0x9c, 0xaa, 0xaa, 0xac, 0xaa, 0xbf, 0x03, 0x7f, | ||||
|     0x11, 0x7f, 0x01, 0x7f, 0x01, 0x3f, 0x01, 0x01, 0x90, 0x82, 0x7d, 0x97, 0x59, 0x59, 0x59, 0x59, 0x59, 0x7f, 0x59, 0x59, 0x60, 0x7d, | ||||
|     0x7f, 0x7f, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x9a, 0x88, 0x7d, 0x59, 0x50, 0x50, 0x50, 0x50, | ||||
|     0x59, 0x59, 0x59, 0x59, 0x61, 0x94, 0x61, 0x9e, 0x59, 0x59, 0x85, 0x59, 0x92, 0xa3, 0x60, 0x60, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, | ||||
|     0x59, 0x59, 0x59, 0x59, 0x59, 0x9f, 0x01, 0x03, 0x01, 0x04, 0x03, 0xd5, 0x03, 0xcc, 0x01, 0xbc, 0x03, 0xf0, 0x10, 0x10, 0x10, 0x10, | ||||
|     0x50, 0x50, 0x50, 0x50, 0x14, 0x20, 0x20, 0x20, 0x20, 0x01, 0x01, 0x01, 0x01, 0xc4, 0x02, 0x10, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, | ||||
|     0xc0, 0xc2, 0x10, 0x11, 0x02, 0x03, 0x11, 0x03, 0x03, 0x04, 0x00, 0x00, 0x14, 0x00, 0x02, 0x00, 0x00, 0xc6, 0xc8, 0x02, 0x02, 0x02, | ||||
|     0x02, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xca, 0x01, 0x01, 0x01, 0x00, 0x06, 0x00, 0x04, 0x00, 0xc0, 0xc2, | ||||
|     0x01, 0x01, 0x03, 0x01, 0xff, 0xff, 0x01, 0x00, 0x03, 0xc4, 0xc4, 0xc6, 0x03, 0x01, 0x01, 0x01, 0xff, 0x03, 0x03, 0x03, 0xc8, 0x40, | ||||
|     0x00, 0x0a, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x33, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xbf, 0xff, 0xff, | ||||
|     0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||||
|     0xff, 0xff, 0x00, 0x00, 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0xff, 0x4a, 0x4a, 0x4a, 0x4a, | ||||
|     0x4b, 0x52, 0x4a, 0x4a, 0x4a, 0x4a, 0x4f, 0x4c, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x55, 0x45, 0x40, 0x4a, 0x4a, 0x4a, | ||||
|     0x45, 0x59, 0x4d, 0x46, 0x4a, 0x5d, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x61, 0x63, | ||||
|     0x67, 0x4e, 0x4a, 0x4a, 0x6b, 0x6d, 0x4a, 0x4a, 0x45, 0x6d, 0x4a, 0x4a, 0x44, 0x45, 0x4a, 0x4a, 0x00, 0x00, 0x00, 0x02, 0x0d, 0x06, | ||||
|     0x06, 0x06, 0x06, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x00, 0x06, 0x06, 0x02, 0x06, 0x00, 0x0a, 0x0a, 0x07, 0x07, 0x06, | ||||
|     0x02, 0x05, 0x05, 0x02, 0x02, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x0e, 0x05, 0x06, 0x06, 0x06, 0x01, 0x06, 0x00, | ||||
|     0x00, 0x08, 0x00, 0x10, 0x00, 0x18, 0x00, 0x20, 0x00, 0x28, 0x00, 0x30, 0x00, 0x80, 0x01, 0x82, 0x01, 0x86, 0x00, 0xf6, 0xcf, 0xfe, | ||||
|     0x3f, 0xab, 0x00, 0xb0, 0x00, 0xb1, 0x00, 0xb3, 0x00, 0xba, 0xf8, 0xbb, 0x00, 0xc0, 0x00, 0xc1, 0x00, 0xc7, 0xbf, 0x62, 0xff, 0x00, | ||||
|     0x8d, 0xff, 0x00, 0xc4, 0xff, 0x00, 0xc5, 0xff, 0x00, 0xff, 0xff, 0xeb, 0x01, 0xff, 0x0e, 0x12, 0x08, 0x00, 0x13, 0x09, 0x00, 0x16, | ||||
|     0x08, 0x00, 0x17, 0x09, 0x00, 0x2b, 0x09, 0x00, 0xae, 0xff, 0x07, 0xb2, 0xff, 0x00, 0xb4, 0xff, 0x00, 0xb5, 0xff, 0x00, 0xc3, 0x01, | ||||
|     0x00, 0xc7, 0xff, 0xbf, 0xe7, 0x08, 0x00, 0xf0, 0x02, 0x00 // | ||||
| }; | ||||
|  | ||||
| unsigned int hde32_disasm(const void *code, hde32s *hs) { | ||||
|     uint8_t x, c, *p = (uint8_t *) code, cflags, opcode, pref = 0; | ||||
|     uint8_t *ht = hde32_table, m_mod, m_reg, m_rm, disp_size = 0; | ||||
|  | ||||
|     memset(hs, 0, sizeof(hde32s)); | ||||
|  | ||||
|     for (x = 16; x; x--) | ||||
|         switch (c = *p++) { | ||||
|         case 0xf3: | ||||
|             hs->p_rep = c; | ||||
|             pref |= PRE_F3; | ||||
|             break; | ||||
|         case 0xf2: | ||||
|             hs->p_rep = c; | ||||
|             pref |= PRE_F2; | ||||
|             break; | ||||
|         case 0xf0: | ||||
|             hs->p_lock = c; | ||||
|             pref |= PRE_LOCK; | ||||
|             break; | ||||
|         case 0x26: | ||||
|         case 0x2e: | ||||
|         case 0x36: | ||||
|         case 0x3e: | ||||
|         case 0x64: | ||||
|         case 0x65: | ||||
|             hs->p_seg = c; | ||||
|             pref |= PRE_SEG; | ||||
|             break; | ||||
|         case 0x66: | ||||
|             hs->p_66 = c; | ||||
|             pref |= PRE_66; | ||||
|             break; | ||||
|         case 0x67: | ||||
|             hs->p_67 = c; | ||||
|             pref |= PRE_67; | ||||
|             break; | ||||
|         default: goto pref_done; | ||||
|         } | ||||
| pref_done: | ||||
|  | ||||
|     hs->flags = (uint32_t) pref << 23; | ||||
|  | ||||
|     if (!pref) | ||||
|         pref |= PRE_NONE; | ||||
|  | ||||
|     if ((hs->opcode = c) == 0x0f) { | ||||
|         hs->opcode2 = c = *p++; | ||||
|         ht += DELTA_OPCODES; | ||||
|     } else if (c >= 0xa0 && c <= 0xa3) { | ||||
|         if (pref & PRE_67) | ||||
|             pref |= PRE_66; | ||||
|         else | ||||
|             pref &= ~PRE_66; | ||||
|     } | ||||
|  | ||||
|     opcode = c; | ||||
|     cflags = ht[ht[opcode / 4] + (opcode % 4)]; | ||||
|  | ||||
|     if (cflags == C_ERROR) { | ||||
|         hs->flags |= F_ERROR | F_ERROR_OPCODE; | ||||
|         cflags = 0; | ||||
|         if ((opcode & -3) == 0x24) | ||||
|             cflags++; | ||||
|     } | ||||
|  | ||||
|     x = 0; | ||||
|     if (cflags & C_GROUP) { | ||||
|         uint16_t t; | ||||
|         t = *(uint16_t *) (ht + (cflags & 0x7f)); | ||||
|         cflags = (uint8_t) t; | ||||
|         x = (uint8_t) (t >> 8); | ||||
|     } | ||||
|  | ||||
|     if (hs->opcode2) { | ||||
|         ht = hde32_table + DELTA_PREFIXES; | ||||
|         if (ht[ht[opcode / 4] + (opcode % 4)] & pref) | ||||
|             hs->flags |= F_ERROR | F_ERROR_OPCODE; | ||||
|     } | ||||
|  | ||||
|     if (cflags & C_MODRM) { | ||||
|         hs->flags |= F_MODRM; | ||||
|         hs->modrm = c = *p++; | ||||
|         hs->modrm_mod = m_mod = c >> 6; | ||||
|         hs->modrm_rm = m_rm = c & 7; | ||||
|         hs->modrm_reg = m_reg = (c & 0x3f) >> 3; | ||||
|  | ||||
|         if (x && ((x << m_reg) & 0x80)) | ||||
|             hs->flags |= F_ERROR | F_ERROR_OPCODE; | ||||
|  | ||||
|         if (!hs->opcode2 && opcode >= 0xd9 && opcode <= 0xdf) { | ||||
|             uint8_t t = opcode - 0xd9; | ||||
|             if (m_mod == 3) { | ||||
|                 ht = hde32_table + DELTA_FPU_MODRM + t * 8; | ||||
|                 t = ht[m_reg] << m_rm; | ||||
|             } else { | ||||
|                 ht = hde32_table + DELTA_FPU_REG; | ||||
|                 t = ht[t] << m_reg; | ||||
|             } | ||||
|             if (t & 0x80) | ||||
|                 hs->flags |= F_ERROR | F_ERROR_OPCODE; | ||||
|         } | ||||
|  | ||||
|         if (pref & PRE_LOCK) { | ||||
|             if (m_mod == 3) { | ||||
|                 hs->flags |= F_ERROR | F_ERROR_LOCK; | ||||
|             } else { | ||||
|                 uint8_t *table_end, op = opcode; | ||||
|                 if (hs->opcode2) { | ||||
|                     ht = hde32_table + DELTA_OP2_LOCK_OK; | ||||
|                     table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK; | ||||
|                 } else { | ||||
|                     ht = hde32_table + DELTA_OP_LOCK_OK; | ||||
|                     table_end = ht + DELTA_OP2_LOCK_OK - DELTA_OP_LOCK_OK; | ||||
|                     op &= -2; | ||||
|                 } | ||||
|                 for (; ht != table_end; ht++) | ||||
|                     if (*ht++ == op) { | ||||
|                         if (!((*ht << m_reg) & 0x80)) | ||||
|                             goto no_lock_error; | ||||
|                         else | ||||
|                             break; | ||||
|                     } | ||||
|                 hs->flags |= F_ERROR | F_ERROR_LOCK; | ||||
|             no_lock_error:; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (hs->opcode2) { | ||||
|             switch (opcode) { | ||||
|             case 0x20: | ||||
|             case 0x22: | ||||
|                 m_mod = 3; | ||||
|                 if (m_reg > 4 || m_reg == 1) | ||||
|                     goto error_operand; | ||||
|                 else | ||||
|                     goto no_error_operand; | ||||
|             case 0x21: | ||||
|             case 0x23: | ||||
|                 m_mod = 3; | ||||
|                 if (m_reg == 4 || m_reg == 5) | ||||
|                     goto error_operand; | ||||
|                 else | ||||
|                     goto no_error_operand; | ||||
|             } | ||||
|         } else { | ||||
|             switch (opcode) { | ||||
|             case 0x8c: | ||||
|                 if (m_reg > 5) | ||||
|                     goto error_operand; | ||||
|                 else | ||||
|                     goto no_error_operand; | ||||
|             case 0x8e: | ||||
|                 if (m_reg == 1 || m_reg > 5) | ||||
|                     goto error_operand; | ||||
|                 else | ||||
|                     goto no_error_operand; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (m_mod == 3) { | ||||
|             uint8_t *table_end; | ||||
|             if (hs->opcode2) { | ||||
|                 ht = hde32_table + DELTA_OP2_ONLY_MEM; | ||||
|                 table_end = ht + sizeof(hde32_table) - DELTA_OP2_ONLY_MEM; | ||||
|             } else { | ||||
|                 ht = hde32_table + DELTA_OP_ONLY_MEM; | ||||
|                 table_end = ht + DELTA_OP2_ONLY_MEM - DELTA_OP_ONLY_MEM; | ||||
|             } | ||||
|             for (; ht != table_end; ht += 2) | ||||
|                 if (*ht++ == opcode) { | ||||
|                     if ((*ht++ & pref) && !((*ht << m_reg) & 0x80)) | ||||
|                         goto error_operand; | ||||
|                     else | ||||
|                         break; | ||||
|                 } | ||||
|             goto no_error_operand; | ||||
|         } else if (hs->opcode2) { | ||||
|             switch (opcode) { | ||||
|             case 0x50: | ||||
|             case 0xd7: | ||||
|             case 0xf7: | ||||
|                 if (pref & (PRE_NONE | PRE_66)) | ||||
|                     goto error_operand; | ||||
|                 break; | ||||
|             case 0xd6: | ||||
|                 if (pref & (PRE_F2 | PRE_F3)) | ||||
|                     goto error_operand; | ||||
|                 break; | ||||
|             case 0xc5: goto error_operand; | ||||
|             } | ||||
|             goto no_error_operand; | ||||
|         } else | ||||
|             goto no_error_operand; | ||||
|  | ||||
|     error_operand: | ||||
|         hs->flags |= F_ERROR | F_ERROR_OPERAND; | ||||
|     no_error_operand: | ||||
|  | ||||
|         c = *p++; | ||||
|         if (m_reg <= 1) { | ||||
|             if (opcode == 0xf6) | ||||
|                 cflags |= C_IMM8; | ||||
|             else if (opcode == 0xf7) | ||||
|                 cflags |= C_IMM_P66; | ||||
|         } | ||||
|  | ||||
|         switch (m_mod) { | ||||
|         case 0: | ||||
|             if (pref & PRE_67) { | ||||
|                 if (m_rm == 6) | ||||
|                     disp_size = 2; | ||||
|             } else if (m_rm == 5) | ||||
|                 disp_size = 4; | ||||
|             break; | ||||
|         case 1: disp_size = 1; break; | ||||
|         case 2: | ||||
|             disp_size = 2; | ||||
|             if (!(pref & PRE_67)) | ||||
|                 disp_size <<= 1; | ||||
|             break; | ||||
|         } | ||||
|  | ||||
|         if (m_mod != 3 && m_rm == 4 && !(pref & PRE_67)) { | ||||
|             hs->flags |= F_SIB; | ||||
|             p++; | ||||
|             hs->sib = c; | ||||
|             hs->sib_scale = c >> 6; | ||||
|             hs->sib_index = (c & 0x3f) >> 3; | ||||
|             if ((hs->sib_base = c & 7) == 5 && !(m_mod & 1)) | ||||
|                 disp_size = 4; | ||||
|         } | ||||
|  | ||||
|         p--; | ||||
|         switch (disp_size) { | ||||
|         case 1: | ||||
|             hs->flags |= F_DISP8; | ||||
|             hs->disp.disp8 = *p; | ||||
|             break; | ||||
|         case 2: | ||||
|             hs->flags |= F_DISP16; | ||||
|             hs->disp.disp16 = *(uint16_t *) p; | ||||
|             break; | ||||
|         case 4: | ||||
|             hs->flags |= F_DISP32; | ||||
|             hs->disp.disp32 = *(uint32_t *) p; | ||||
|             break; | ||||
|         } | ||||
|         p += disp_size; | ||||
|     } else if (pref & PRE_LOCK) | ||||
|         hs->flags |= F_ERROR | F_ERROR_LOCK; | ||||
|  | ||||
|     if (cflags & C_IMM_P66) { | ||||
|         if (cflags & C_REL32) { | ||||
|             if (pref & PRE_66) { | ||||
|                 hs->flags |= F_IMM16 | F_RELATIVE; | ||||
|                 hs->imm.imm16 = *(uint16_t *) p; | ||||
|                 p += 2; | ||||
|                 goto disasm_done; | ||||
|             } | ||||
|             goto rel32_ok; | ||||
|         } | ||||
|         if (pref & PRE_66) { | ||||
|             hs->flags |= F_IMM16; | ||||
|             hs->imm.imm16 = *(uint16_t *) p; | ||||
|             p += 2; | ||||
|         } else { | ||||
|             hs->flags |= F_IMM32; | ||||
|             hs->imm.imm32 = *(uint32_t *) p; | ||||
|             p += 4; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (cflags & C_IMM16) { | ||||
|         if (hs->flags & F_IMM32) { | ||||
|             hs->flags |= F_IMM16; | ||||
|             hs->disp.disp16 = *(uint16_t *) p; | ||||
|         } else if (hs->flags & F_IMM16) { | ||||
|             hs->flags |= F_2IMM16; | ||||
|             hs->disp.disp16 = *(uint16_t *) p; | ||||
|         } else { | ||||
|             hs->flags |= F_IMM16; | ||||
|             hs->imm.imm16 = *(uint16_t *) p; | ||||
|         } | ||||
|         p += 2; | ||||
|     } | ||||
|     if (cflags & C_IMM8) { | ||||
|         hs->flags |= F_IMM8; | ||||
|         hs->imm.imm8 = *p++; | ||||
|     } | ||||
|  | ||||
|     if (cflags & C_REL32) { | ||||
|     rel32_ok: | ||||
|         hs->flags |= F_IMM32 | F_RELATIVE; | ||||
|         hs->imm.imm32 = *(uint32_t *) p; | ||||
|         p += 4; | ||||
|     } else if (cflags & C_REL8) { | ||||
|         hs->flags |= F_IMM8 | F_RELATIVE; | ||||
|         hs->imm.imm8 = *p++; | ||||
|     } | ||||
|  | ||||
| disasm_done: | ||||
|  | ||||
|     if ((hs->len = (uint8_t) (p - (uint8_t *) code)) > 15) { | ||||
|         hs->flags |= F_ERROR | F_ERROR_LENGTH; | ||||
|         hs->len = 15; | ||||
|     } | ||||
|  | ||||
|     return (unsigned int) hs->len; | ||||
| } | ||||
		Reference in New Issue
	
	Block a user