recreate project as DLL

This commit is contained in:
2017-12-26 15:20:04 +01:00
parent 357d3178aa
commit 51118baca8
14 changed files with 103 additions and 61 deletions

37
test_cases/README.md Normal file
View File

@@ -0,0 +1,37 @@
Introduction
============
This project aims to give a simple overview on how good various x64 hooking
engines (on windows) are. I'll try to write various functions, that are hard to
patch and then see how each hooking engine does.
I'll test:
* [EasyHook](https://easyhook.github.io/)
* [PolyHook](https://github.com/stevemk14ebr/PolyHook)
* [MinHook](https://www.codeproject.com/Articles/44326/MinHook-The-Minimalistic-x-x-API-Hooking-Libra)
* [Mhook](http://codefromthe70s.org/mhook24.aspx)
(I'd like to test detours, but I'm not willing to pay for it. So that isn't
tested :( )
There are multiple things that make hooking difficult. Maybe you want to patch
while the application is running -- in that case you might get race conditions,
as the application is executing your half finished hook. Maybe the software has
some self protection features (or other software on the system provides that,
e.g. Trustee Rapport)
Evaluating how the hooking engines stack up against that is not the goal here.
Neither are non-functional criteria, like how fast it is or how much memory it
needs for each hook. This is just about the challenges the function to be
hooked itself poses.
Namely:
* Are jumps relocated?
* What about RIP adressing?
* If there's a loop at the beginning / if it's a tail recurisve function, does
the hooking engine handle it?
* How good is the dissassembler, how many instructions does it know?
* Can it hook already hooked functions?
Test cases
==========

View File

@@ -0,0 +1,17 @@
format ms64 coff
section '.text' code readable executable
use64
public _AVX
_AVX:
vbroadcastsd ymm0, xmm0 ; load @num into all slots
vsqrtpd ymm0, ymm0
vmovdqu [rdx], ymm0 ; store result in @res
ret
public _RDRAND
_RDRAND:
rdrand eax
ret

View File

@@ -0,0 +1,15 @@
#pragma once
extern "C" {
/**
* Gets the square root of num four times and writes it to @res
*
* @param num: the number of which the square root shall be taken
* @param res: where the 4 results shall be written
*/
void _declspec(dllexport) _AVX(float num, void* res);
/**
* Just a wrapper around RDRAND
*/
uint32_t _declspec(dllexport) _RDRAND(void);
}

7
test_cases/assemble.ps1 Normal file
View File

@@ -0,0 +1,7 @@
$fasm = "U:\fasm\fasm.exe"
$files = gci -r -File | where {$_.extension -eq ".asm"}
Foreach ($i in $files)
{
Write-Host $i.Name
& $fasm $i.Name
}

39
test_cases/backwards.asm Normal file
View File

@@ -0,0 +1,39 @@
format ms64 coff
section '.text' code readable executable
use64
public _loop
_loop:
xor eax, eax
inc eax
mov rbx, rdx ; RDX is overwritten by mul
@again:
cmp rbx, 0
je @loop_end
mul rcx
dec rbx
jmp @again
@loop_end:
ret
public _tail_recursion
_tail_recursion:
test ecx, ecx
je @is_0
mov eax, ecx
dec ecx
@loop:
test ecx, ecx
jz @tr_end
mul ecx
dec ecx
jnz @loop
jmp @tr_end
@is_0:
mov eax, 1
@tr_end:
ret

17
test_cases/backwards.h Normal file
View File

@@ -0,0 +1,17 @@
#pragma once
extern "C" {
/**
* Raises @num @cnt times
*
* @param num
* @param cnt
*/
uint32_t _declspec(dllexport) _loop(uint32_t num, uint32_t cnt);
/**
* Computes factorial
*
* @param x
*/
uint32_t _declspec(dllexport) _tail_recursion(uint32_t x);
}

12012
test_cases/catch.hpp Normal file

File diff suppressed because it is too large Load Diff

48
test_cases/main.cpp Normal file
View File

@@ -0,0 +1,48 @@
#include <stdint.h>
#include <iostream>
#define CATCH_CONFIG_RUNNER
#include "catch.hpp"
#include "test_cases.h"
/*#pragma comment(lib, "advanced_instructions.obj")
#pragma comment(lib, "simple_tests.obj")
#pragma comment(lib, "backwards.obj")*/
static Catch::Session session;
_declspec(dllexport) void SelfTest() {
session.run();
}
TEST_CASE("Simple functions work as expected, unhooked") {
REQUIRE(_small() == 0);
REQUIRE(_branch(1) == 0);
REQUIRE(_branch(0) == 0);
for (int i = 0; i < 1000; i++) {
REQUIRE(_rip_relative() == rand());
}
}
TEST_CASE("Advanced instruction functions work as expected, unhokked") {
double result[4];
_AVX(9., static_cast<void*>(result));
REQUIRE((result[0] - result[1]) < DBL_EPSILON);
REQUIRE((result[1] - result[2]) < DBL_EPSILON);
REQUIRE((result[2] - result[3]) < DBL_EPSILON);
REQUIRE((result[0] - 3.) < DBL_EPSILON);
}
TEST_CASE("Loops & tail recursion work as expected, unhook") {
REQUIRE(_loop(2, 3) == 8);
REQUIRE(_loop(5, 3) == 125);
REQUIRE(_loop(5, 0) == 1);
REQUIRE(_loop(5, 1) == 5);
REQUIRE(_tail_recursion(0) == 1);
REQUIRE(_tail_recursion(1) == 1);
REQUIRE(_tail_recursion(2) == 2);
REQUIRE(_tail_recursion(5) == 120);
}

View File

@@ -0,0 +1,54 @@
format ms64 coff
section '.text' code readable writeable executable
use64
public _small
_small:
xor eax, eax
ret
public _rip_relative
_rip_relative:
mov eax, [seed]
mov ecx, 214013
mul ecx
add eax, 2531011
mov [seed], eax
shr eax, 16
and eax, 0x7FFF
ret
seed dd 1
public _branch
_branch:
and rax, 1
jz @branch_ret
xor rax, rax
nop ; Just some padding, so the function can't be copied entirely into the
nop ; trampoline
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
@branch_ret:
ret

31
test_cases/simple_tests.h Normal file
View File

@@ -0,0 +1,31 @@
#pragma once
extern "C" {
/**
* A small function, that always returns 0
*/
uint64_t _declspec(dllexport) _small(void);
/**
* This function checks if the parameter is even or odd, and then
* always returns 0.
*
* The check is done with a branch, so the hooking engine has to take that
* into account.
*
* @param Number to be checked
*/
uint64_t _declspec(dllexport) _branch(uint64_t);
/**
* Replicates the MSVCRT rand().
*
* This function is used to check whether the hooking engine correctly fixes
* rip relative addressing.
*
* @internal:
* static seed = 1;
* return( ((seed = seed * 214013L
* + 2531011L) >> 16) & 0x7fff );
*/
uint64_t _declspec(dllexport) _rip_relative(void);
};

6
test_cases/test_cases.h Normal file
View File

@@ -0,0 +1,6 @@
#pragma once
#include "simple_tests.h"
#include "backwards.h"
#include "advanced_instructions.h"
_declspec(dllexport) void SelfTest();

View File

@@ -0,0 +1,180 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" 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">
<ProjectGuid>{8C444ABC-D25C-4B44-8F27-081B464D9AE4}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>test_cases</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v140</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)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;TEST_CASES_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>
</PrecompiledHeader>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;TEST_CASES_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;TEST_CASES_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<PrecompiledHeader>
</PrecompiledHeader>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;TEST_CASES_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>backwards.obj;simple_tests.obj;advanced_instructions.obj;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>$(MSBuildProjectDirectory)\assemble.ps</Command>
</PreBuildEvent>
<PreBuildEvent>
<Message>Assemble all .asm files using FASM</Message>
</PreBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="advanced_instructions.asm" />
<None Include="assemble.ps1" />
<None Include="backwards.asm" />
<None Include="README.md" />
<None Include="simple_tests.asm" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="advanced_instructions.h" />
<ClInclude Include="backwards.h" />
<ClInclude Include="catch.hpp" />
<ClInclude Include="simple_tests.h" />
<ClInclude Include="test_cases.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp" />
</ItemGroup>
<ItemGroup>
<Object Include="advanced_instructions.obj" />
<Object Include="backwards.obj" />
<Object Include="simple_tests.obj" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,59 @@
<?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;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>
<None Include="assemble.ps1">
<Filter>Source Files</Filter>
</None>
<None Include="advanced_instructions.asm">
<Filter>Source Files</Filter>
</None>
<None Include="backwards.asm">
<Filter>Source Files</Filter>
</None>
<None Include="simple_tests.asm">
<Filter>Source Files</Filter>
</None>
<None Include="README.md" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="advanced_instructions.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="backwards.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="catch.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="simple_tests.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="test_cases.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Object Include="advanced_instructions.obj" />
<Object Include="backwards.obj" />
<Object Include="simple_tests.obj" />
</ItemGroup>
</Project>