parent
b2a388dd58
commit
23bac4c28a
@ -0,0 +1,5 @@
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := shithook
|
||||
LOCAL_SRC_FILES := main.cpp shithook.hpp
|
||||
include $(BUILD_EXECUTABLE)
|
@ -0,0 +1,4 @@
|
||||
APP_PLATFORM := android-21
|
||||
APP_ABI := armeabi-v7a
|
||||
APP_BUILD_SCRIPT := android.mk
|
||||
APP_CPPFLAGS := -std=c++17
|
@ -1,170 +0,0 @@
|
||||
/*
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2020 xerox
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
#include <map>
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
|
||||
#if _M_IX86
|
||||
#define OFFSET_TO_ADDRESS 0x1
|
||||
#elif _M_X64
|
||||
#define OFFSET_TO_ADDRESS 0x2
|
||||
#endif
|
||||
|
||||
namespace hook
|
||||
{
|
||||
inline void write_to_readonly(void* addr, void* data, int size)
|
||||
{
|
||||
DWORD old_flags;
|
||||
if(!VirtualProtect(
|
||||
addr,
|
||||
size,
|
||||
PAGE_EXECUTE_READWRITE,
|
||||
&old_flags
|
||||
)) return;
|
||||
|
||||
memcpy(addr, data, size);
|
||||
|
||||
VirtualProtect(
|
||||
addr,
|
||||
size,
|
||||
old_flags,
|
||||
&old_flags
|
||||
);
|
||||
}
|
||||
|
||||
class detour
|
||||
{
|
||||
public:
|
||||
detour(void* addr_to_hook, void* jmp_to, bool enable = true)
|
||||
: hook_addr(addr_to_hook), detour_addr(jmp_to), hook_installed(false)
|
||||
{
|
||||
//setup hook
|
||||
memcpy(
|
||||
jmp_code + OFFSET_TO_ADDRESS,
|
||||
&jmp_to,
|
||||
sizeof(jmp_to)
|
||||
);
|
||||
//save bytes
|
||||
memcpy(
|
||||
org_bytes,
|
||||
hook_addr,
|
||||
sizeof(org_bytes)
|
||||
);
|
||||
if(enable)
|
||||
install();
|
||||
}
|
||||
|
||||
void install()
|
||||
{
|
||||
if (hook_installed.load())
|
||||
return;
|
||||
write_to_readonly(hook_addr, jmp_code, sizeof(jmp_code));
|
||||
hook_installed.exchange(true);
|
||||
}
|
||||
void uninstall()
|
||||
{
|
||||
if (!hook_installed.load())
|
||||
return;
|
||||
write_to_readonly(hook_addr, org_bytes, sizeof(org_bytes));
|
||||
hook_installed.exchange(false);
|
||||
}
|
||||
|
||||
~detour() { uninstall(); }
|
||||
bool installed() { return hook_installed; }
|
||||
void* hook_address() { return hook_addr; }
|
||||
void* detour_address() { return detour_addr; }
|
||||
private:
|
||||
std::atomic<bool> hook_installed;
|
||||
void *hook_addr, *detour_addr;
|
||||
|
||||
#if _M_IX86
|
||||
/*
|
||||
0: b8 ff ff ff ff mov eax, 0xffffffff
|
||||
5: ff e0 jmp eax
|
||||
*/
|
||||
unsigned char jmp_code[7] = {
|
||||
0xb8, 0x0, 0x0, 0x0, 0x0,
|
||||
0xFF, 0xE0
|
||||
};
|
||||
#elif _M_X64
|
||||
/*
|
||||
0: 48 c7 c0 ff ff ff ff mov rax,0xffffffffffffffff
|
||||
7: ff e0 jmp rax
|
||||
*/
|
||||
unsigned char jmp_code[12] = {
|
||||
0x48, 0xb8,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0x0,
|
||||
0xff, 0xe0
|
||||
};
|
||||
#endif
|
||||
std::uint8_t org_bytes[sizeof(jmp_code)];
|
||||
};
|
||||
|
||||
inline std::map<void*, std::unique_ptr<detour>> hooks{};
|
||||
|
||||
inline void make_hook(void* addr_to_hook, void* jmp_to_addr, bool enable = true)
|
||||
{
|
||||
if (!addr_to_hook)
|
||||
return;
|
||||
hooks.insert({
|
||||
addr_to_hook,
|
||||
std::make_unique<detour>(
|
||||
addr_to_hook,
|
||||
jmp_to_addr,
|
||||
enable
|
||||
)}
|
||||
);
|
||||
}
|
||||
|
||||
inline void enable(void* addr)
|
||||
{
|
||||
if (!addr)
|
||||
return;
|
||||
hooks.at(addr)->install();
|
||||
}
|
||||
|
||||
inline void disable(void* addr)
|
||||
{
|
||||
if (!addr)
|
||||
return;
|
||||
hooks.at(addr)->uninstall();
|
||||
}
|
||||
|
||||
inline void remove(void* addr)
|
||||
{
|
||||
if (!addr)
|
||||
return;
|
||||
hooks.erase(addr);
|
||||
}
|
||||
}
|
@ -0,0 +1,128 @@
|
||||
#pragma once
|
||||
#include <map>
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <string.h>
|
||||
|
||||
#define __arm__
|
||||
#include <unistd.h>
|
||||
#include "sys/mman.h"
|
||||
|
||||
#define ARM_JMP_CODE 0xE51FF004 // LDR PC, [PC, #-4]
|
||||
#define PAGE_START(ptr) reinterpret_cast<void*>(reinterpret_cast<std::uintptr_t>(ptr) >> 12 << 12)
|
||||
|
||||
namespace hook
|
||||
{
|
||||
class detour
|
||||
{
|
||||
public:
|
||||
detour(void* addr_to_hook, void* jmp_to, bool enable = true)
|
||||
:
|
||||
hook_addr(addr_to_hook),
|
||||
detour_addr(jmp_to),
|
||||
hook_installed(false)
|
||||
{
|
||||
reinterpret_cast<std::uint32_t*>(jmp_code)[0] = ARM_JMP_CODE;
|
||||
reinterpret_cast<void**>(jmp_code)[1] = jmp_to;
|
||||
memcpy(org_bytes, hook_addr, sizeof(org_bytes));
|
||||
|
||||
reinterpret_cast<std::uint32_t*>(landing_code)[2] = ARM_JMP_CODE;
|
||||
memcpy(landing_code, org_bytes, sizeof(org_bytes));
|
||||
reinterpret_cast<std::uint32_t*>(landing_code)[3] =
|
||||
reinterpret_cast<std::uintptr_t>(hook_addr) + 8;
|
||||
|
||||
mprotect(PAGE_START(landing_code), getpagesize(),
|
||||
PROT_EXEC | PROT_READ | PROT_WRITE);
|
||||
|
||||
cacheflush(reinterpret_cast<long>(PAGE_START(landing_code)),
|
||||
reinterpret_cast<long>(
|
||||
PAGE_START(landing_code)) + getpagesize(), NULL);
|
||||
|
||||
if (enable) install();
|
||||
}
|
||||
~detour() { uninstall(); }
|
||||
|
||||
void install()
|
||||
{
|
||||
if (hook_installed.load())
|
||||
return;
|
||||
|
||||
if (!mprotect(PAGE_START(hook_addr), getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC))
|
||||
{
|
||||
memcpy((void*)((long)hook_addr), jmp_code, sizeof(jmp_code));
|
||||
mprotect(PAGE_START(hook_addr), getpagesize(), PROT_READ | PROT_EXEC);
|
||||
cacheflush(reinterpret_cast<long>(hook_addr), reinterpret_cast<long>(hook_addr) + getpagesize(), NULL);
|
||||
hook_installed.exchange(true);
|
||||
}
|
||||
}
|
||||
|
||||
void uninstall()
|
||||
{
|
||||
if (!hook_installed.load())
|
||||
return;
|
||||
|
||||
if (!mprotect(PAGE_START(hook_addr), getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC))
|
||||
{
|
||||
memcpy(hook_addr, org_bytes, sizeof(jmp_code));
|
||||
mprotect(PAGE_START(hook_addr), getpagesize(), PROT_READ | PROT_EXEC);
|
||||
cacheflush(reinterpret_cast<long>(hook_addr), reinterpret_cast<long>(hook_addr) + getpagesize(), NULL);
|
||||
hook_installed.exchange(false);
|
||||
}
|
||||
}
|
||||
|
||||
bool installed() { return hook_installed; }
|
||||
void* hook_address() { return hook_addr; }
|
||||
void* detour_address(){ return detour_addr; }
|
||||
void* get_func() { return reinterpret_cast<void*>(landing_code); }
|
||||
private:
|
||||
std::atomic<bool> hook_installed;
|
||||
void* hook_addr, * detour_addr;
|
||||
unsigned char jmp_code[8];
|
||||
unsigned char landing_code[16];
|
||||
std::uint8_t org_bytes[sizeof(jmp_code)];
|
||||
};
|
||||
|
||||
inline std::map<void*, std::unique_ptr<detour>>* get_hooks()
|
||||
{
|
||||
static std::map<void*, std::unique_ptr<detour>> hooks{};
|
||||
return &hooks;
|
||||
}
|
||||
|
||||
template <class T, class U>
|
||||
inline void make_hook(T addr_to_hook, U jmp_to_addr, bool enable = true)
|
||||
{
|
||||
get_hooks()->insert({
|
||||
(void*)addr_to_hook,
|
||||
std::make_unique<detour>(
|
||||
(void*) addr_to_hook,
|
||||
(void*) jmp_to_addr,
|
||||
enable
|
||||
)}
|
||||
);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
inline void enable(T addr)
|
||||
{
|
||||
get_hooks()->at((void*)addr)->install();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T get_func(T addr)
|
||||
{
|
||||
return reinterpret_cast<T>(
|
||||
get_hooks()->at((void*)addr)->get_func());
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void disable(T addr)
|
||||
{
|
||||
get_hooks()->at((void*)addr)->uninstall();
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void remove(T addr)
|
||||
{
|
||||
get_hooks()->erase((void*)addr);
|
||||
}
|
||||
}
|
@ -1,170 +0,0 @@
|
||||
<?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>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="hook.hpp" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<ProjectGuid>{E5255EE2-A83E-4455-99E3-B5D236B76D36}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>shithook</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>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
<SpectreMitigation>false</SpectreMitigation>
|
||||
</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)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir>$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
@ -1,23 +0,0 @@
|
||||
<?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;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;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="hook.hpp">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
Loading…
Reference in new issue