/* * Injectors - Function Calls Using Variadic Templates * * Copyright (C) 2014 LINK/2012 * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. If you use this software * in a product, an acknowledgment in the product documentation would be * appreciated but is not required. * * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * * 3. This notice may not be removed or altered from any source * distribution. * */ #pragma once #include "injector.hpp" #include #include #if __cplusplus >= 201103L || _MSC_VER >= 1800 // MSVC 2013 #else #error "This feature is not supported on this compiler" #endif namespace injector { template struct cstd; template struct cstd { // Call function at @p returning @Ret with args @Args static Ret call(memory_pointer_tr p, Args... a) { auto fn = (Ret(*)(Args...)) p.get(); return fn(std::forward(a)...); } template // Uses lazy pointer static Ret call(Args... a) { return call(lazy_pointer::get(), std::forward(a)...); } }; template struct stdcall; template struct stdcall { // Call function at @p returning @Ret with args @Args static Ret call(memory_pointer_tr p, Args... a) { auto fn = (Ret(__stdcall *)(Args...)) p.get(); return fn(std::forward(a)...); } template // Uses lazy pointer static Ret call(Args... a) { return call(lazy_pointer::get(), std::forward(a)...); } }; template struct fastcall; template struct fastcall { // Call function at @p returning @Ret with args @Args static Ret call(memory_pointer_tr p, Args... a) { auto fn = (Ret(__fastcall *)(Args...)) p.get();; return fn(std::forward(a)...); } template // Uses lazy pointer static Ret call(Args... a) { return call(lazy_pointer::get(), std::forward(a)...); } }; template struct thiscall; template struct thiscall { // Call function at @p returning @Ret with args @Args static Ret call(memory_pointer_tr p, Args... a) { auto fn = (Ret(__thiscall *)(Args...)) p.get(); return fn(std::forward(a)...); } // Call function at the index @i from the vtable of the object @a[0] template static Ret vtbl(Args... a) { auto obj = raw_ptr(std::get<0>(std::forward_as_tuple(a...))); auto p = raw_ptr( (*obj.template get()) [i] ); return call(p, std::forward(a)...); } template // Uses lazy pointer static Ret call(Args... a) { return call(lazy_pointer::get(), std::forward(a)...); } }; }