Skip to content

Commit

Permalink
Add new address finding functions
Browse files Browse the repository at this point in the history
  • Loading branch information
crashfort committed Aug 27, 2017
1 parent 68c448a commit 87b1172
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 196 deletions.
84 changes: 69 additions & 15 deletions Source/HammerPatch/Application/Application.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "PrecompiledHeader.hpp"
#include "Application.hpp"
#include <cctype>

namespace
{
Expand Down Expand Up @@ -40,35 +41,44 @@ namespace

Application MainApplication;

/*
From Yalter's SPT
*/
namespace Memory
{
inline bool DataCompare(const uint8_t* data, const uint8_t* pattern, const char* mask)
/*
Not accessing the STL iterators in debug mode makes this run >10x faster, less sitting around waiting for nothing.
*/
inline bool DataCompare(const uint8_t* data, const HAP::BytePattern::Entry* pattern, size_t patternlength)
{
for (; *mask != 0; ++data, ++pattern, ++mask)
int index = 0;

for (size_t i = 0; i < patternlength; i++)
{
if (*mask == 'x' && *data != *pattern)
auto byte = *pattern;

if (!byte.Unknown && *data != byte.Value)
{
return false;
}

++data;
++pattern;
++index;
}

return (*mask == 0);
return index == patternlength;
}

void* FindPattern(const void* start, size_t length, const uint8_t* pattern, const char* mask)
void* FindPattern(void* start, size_t searchlength, const HAP::BytePattern& pattern)
{
auto masklength = strlen(mask);
auto patternstart = pattern.Bytes.data();
auto length = pattern.Bytes.size();

for (size_t i = 0; i <= length - masklength; ++i)
for (size_t i = 0; i <= searchlength - length; ++i)
{
auto addr = reinterpret_cast<const uint8_t*>(start) + i;
auto addr = (const uint8_t*)(start) + i;

if (DataCompare(addr, pattern, mask))
if (DataCompare(addr, patternstart, length))
{
return const_cast<void*>(reinterpret_cast<const void*>(addr));
return (void*)(addr);
}
}

Expand Down Expand Up @@ -191,12 +201,56 @@ void HAP::CallStartupFunctions()
}
}

HAP::BytePattern HAP::GetPatternFromString(const char* input)
{
BytePattern ret;

while (*input)
{
if (std::isspace(*input))
{
++input;
}

BytePattern::Entry entry;

if (std::isxdigit(*input))
{
entry.Unknown = false;
entry.Value = std::strtol(input, nullptr, 16);

input += 2;
}

else
{
entry.Unknown = true;
input += 2;
}

ret.Bytes.emplace_back(entry);
}

return ret;
}

void* HAP::GetAddressFromPattern(const ModuleInformation& library, const BytePattern& pattern)
{
return Memory::FindPattern(library.MemoryBase, library.MemorySize, pattern);
}

void HAP::AddModule(HookModuleBase* module)
{
MainApplication.Modules.emplace_back(module);
}

void* HAP::GetAddressFromPattern(const ModuleInformation& library, const uint8_t* pattern, const char* mask)
bool HAP::IsGame(const wchar_t* test)
{
return Memory::FindPattern(library.MemoryBase, library.MemorySize, pattern, mask);
wchar_t directory[4096];
GetCurrentDirectoryW(sizeof(directory), directory);
PathRemoveFileSpecW(directory);

auto name = PathFindFileNameW(directory);

return _wcsicmp(name, test) == 0;
}
201 changes: 20 additions & 181 deletions Source/HammerPatch/Application/Application.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,6 @@ namespace HAP

void CallStartupFunctions();

constexpr auto MemoryPattern(const char* input)
{
return reinterpret_cast<const uint8_t*>(input);
}

struct ModuleInformation
{
ModuleInformation(const char* name) : Name(name)
Expand All @@ -104,6 +99,20 @@ namespace HAP
size_t MemorySize;
};

struct BytePattern
{
struct Entry
{
uint8_t Value;
bool Unknown;
};

std::vector<Entry> Bytes;
};

BytePattern GetPatternFromString(const char* input);
void* GetAddressFromPattern(const ModuleInformation& library, const BytePattern& pattern);

struct HookModuleBase
{
HookModuleBase(const char* module, const char* name, void* newfunc) :
Expand All @@ -126,16 +135,13 @@ namespace HAP

void AddModule(HookModuleBase* module);

void* GetAddressFromPattern(const ModuleInformation& library, const uint8_t* pattern, const char* mask);

template <typename FuncSignature>
class HookModuleMask final : public HookModuleBase
{
public:
HookModuleMask(const char* module, const char* name, FuncSignature newfunction, const uint8_t* pattern, const char* mask) :
HookModuleMask(const char* module, const char* name, FuncSignature newfunction, const char* pattern) :
HookModuleBase(module, name, newfunction),
Pattern(pattern),
Mask(mask)
Pattern(GetPatternFromString(pattern))
{
AddModule(this);
}
Expand All @@ -148,183 +154,14 @@ namespace HAP
virtual MH_STATUS Create() override
{
ModuleInformation info(Module);
TargetFunction = GetAddressFromPattern(info, Pattern, Mask);

auto res = MH_CreateHookEx
(
TargetFunction,
NewFunction,
&OriginalFunction
);

return res;
}

private:
const uint8_t* Pattern;
const char* Mask;
};

/*
For use with unmodified addresses straight from IDA
*/
template <typename FuncSignature>
class HookModuleStaticAddressTest final : public HookModuleBase
{
public:
HookModuleStaticAddressTest(const char* module, const char* name, FuncSignature newfunction, uintptr_t address) :
HookModuleBase(module, name, newfunction),
Address(address)
{
AddModule(this);
}

inline auto GetOriginal() const
{
return static_cast<FuncSignature>(OriginalFunction);
}

virtual MH_STATUS Create() override
{
/*
IDA starts addresses at this value
*/
Address -= 0x10000000;

ModuleInformation info(Module);
Address += (uintptr_t)info.MemoryBase;

TargetFunction = (void*)Address;
TargetFunction = GetAddressFromPattern(info, Pattern);

auto res = MH_CreateHookEx(TargetFunction, NewFunction, &OriginalFunction);
return res;
}

private:
uintptr_t Address;
};

/*
For use where the correct address is found
through another method
*/
template <typename FuncSignature>
class HookModuleStaticAddress final : public HookModuleBase
{
public:
HookModuleStaticAddress(const char* module, const char* name, FuncSignature newfunction, void* address) :
HookModuleBase(module, name, newfunction),
Address(address)
{
AddModule(this);
}

inline auto GetOriginal() const
{
return static_cast<FuncSignature>(OriginalFunction);
}

virtual MH_STATUS Create() override
{
TargetFunction = Address;

auto res = MH_CreateHookEx(TargetFunction, NewFunction, &OriginalFunction);
return res;
}

private:
void* Address;
};

template <typename FuncSignature>
class HookModuleAPI final : public HookModuleBase
{
public:
HookModuleAPI(const char* module, const char* name, const char* exportname, FuncSignature newfunction) :
HookModuleBase(module, name, newfunction),
ExportName(exportname)
{
AddModule(this);
}

inline auto GetOriginal() const
{
return static_cast<FuncSignature>(OriginalFunction);
}

virtual MH_STATUS Create() override
{
wchar_t module[64];
swprintf_s(module, L"%S", Module);

auto res = MH_CreateHookApiEx(module, ExportName, NewFunction, &OriginalFunction, &TargetFunction);
return res;
}

private:
const char* ExportName;
};

struct AddressFinder
{
AddressFinder(const char* module, const uint8_t* pattern, const char* mask, int offset = 0)
{
auto addr = GetAddressFromPattern(module, pattern, mask);

auto addrmod = static_cast<uint8_t*>(addr);

/*
Increment for any extra instructions
*/
addrmod += offset;

Address = addrmod;
}

void* Get() const
{
return Address;
}

void* Address;
};

/*
First byte at target address should be E8
*/
struct RelativeJumpFunctionFinder
{
RelativeJumpFunctionFinder(AddressFinder address)
{
auto addrmod = static_cast<uint8_t*>(address.Get());

/*
Skip the E8 byte
*/
addrmod += sizeof(uint8_t);

auto offset = *reinterpret_cast<ptrdiff_t*>(addrmod);

/*
E8 jumps count relative distance from the next instruction,
in 32 bit the distance will be measued in 4 bytes.
*/
addrmod += sizeof(uintptr_t);

/*
Do the jump, address will now be the target function
*/
addrmod += offset;

Address = addrmod;
}

void* Get() const
{
return Address;
}

void* Address;
BytePattern Pattern;
};

struct StructureWalker
Expand Down Expand Up @@ -359,4 +196,6 @@ namespace HAP
uint8_t* Address;
uint8_t* Start;
};

bool IsGame(const wchar_t* test);
}

0 comments on commit 87b1172

Please sign in to comment.