feat: original commit of the files
This commit is contained in:
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
.vs
|
||||
.git
|
||||
x64
|
||||
todo.txt
|
||||
DevourClient/x64
|
||||
25
DevourClient.sln
Normal file
25
DevourClient.sln
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.1.32407.343
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DevourClient", "DevourClient\DevourClient.vcxproj", "{C7CBEBBD-CEF6-40C5-B6F5-2098545BB8A5}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{C7CBEBBD-CEF6-40C5-B6F5-2098545BB8A5}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{C7CBEBBD-CEF6-40C5-B6F5-2098545BB8A5}.Debug|x64.Build.0 = Debug|x64
|
||||
{C7CBEBBD-CEF6-40C5-B6F5-2098545BB8A5}.Release|x64.ActiveCfg = Release|x64
|
||||
{C7CBEBBD-CEF6-40C5-B6F5-2098545BB8A5}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {654219AA-AB13-4E5C-926A-7F2F21E4310B}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
12
DevourClient/Callbacks/OnUpdate.cpp
Normal file
12
DevourClient/Callbacks/OnUpdate.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#include "OnUpdate.hpp"
|
||||
|
||||
#include "../Utils/Settings/Settings.hpp"
|
||||
#include "../Dependencies/IL2CPP_Resolver/il2cpp_resolver.hpp"
|
||||
#include "../Utils/Players/Players.hpp"
|
||||
#include <iostream>
|
||||
|
||||
void OnUpdate() {
|
||||
if (settings::big_flashlight) {
|
||||
|
||||
}
|
||||
}
|
||||
2
DevourClient/Callbacks/OnUpdate.hpp
Normal file
2
DevourClient/Callbacks/OnUpdate.hpp
Normal file
@@ -0,0 +1,2 @@
|
||||
#pragma once
|
||||
void OnUpdate();
|
||||
2
DevourClient/Dependencies/IL2CPP_Resolver/.gitattributes
vendored
Normal file
2
DevourClient/Dependencies/IL2CPP_Resolver/.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
74
DevourClient/Dependencies/IL2CPP_Resolver/Cache.cpp
Normal file
74
DevourClient/Dependencies/IL2CPP_Resolver/Cache.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
#include "Includes.hpp"
|
||||
|
||||
namespace IL2CPP
|
||||
{
|
||||
namespace SystemTypeCache
|
||||
{
|
||||
class CCache
|
||||
{
|
||||
public:
|
||||
unsigned int m_uHash = 0U;
|
||||
Unity::il2cppObject* m_pSystemType = nullptr;
|
||||
|
||||
CCache() { }
|
||||
CCache(unsigned int m_uKey, Unity::il2cppObject* m_pValue)
|
||||
{
|
||||
m_uHash = m_uKey;
|
||||
m_pSystemType = m_pValue;
|
||||
}
|
||||
};
|
||||
std::vector<CCache> m_vCache;
|
||||
|
||||
void Add(unsigned int m_uHash, Unity::il2cppObject* m_pSystemType)
|
||||
{
|
||||
if (!m_pSystemType)
|
||||
return;
|
||||
|
||||
m_vCache.emplace_back(CCache(m_uHash, m_pSystemType));
|
||||
}
|
||||
|
||||
void Add(const char* m_pName, Unity::il2cppObject* m_pSystemType)
|
||||
{
|
||||
if (!m_pName)
|
||||
return;
|
||||
|
||||
Add(Utils::JOAAT(m_pName), m_pSystemType);
|
||||
}
|
||||
|
||||
Unity::il2cppObject* Find(unsigned int m_uHash)
|
||||
{
|
||||
size_t m_sSize = m_vCache.size();
|
||||
if (m_sSize > 0)
|
||||
{
|
||||
CCache* m_pData = m_vCache.data();
|
||||
for (size_t i = 0; m_sSize > i; ++i)
|
||||
{
|
||||
if (m_pData[i].m_uHash == m_uHash)
|
||||
return m_pData[i].m_pSystemType;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Unity::il2cppObject* Find(const char* m_pName)
|
||||
{
|
||||
return Find(Utils::JOAAT(m_pName));
|
||||
}
|
||||
|
||||
namespace Initializer
|
||||
{
|
||||
std::vector<const char*> m_vList;
|
||||
|
||||
void Add(const char* m_pName) { m_vList.emplace_back(m_pName); }
|
||||
|
||||
void PreCache()
|
||||
{
|
||||
for (const char* m_pName : m_vList)
|
||||
SystemTypeCache::Add(m_pName, IL2CPP::Class::GetSystemType(m_pName));
|
||||
|
||||
m_vList.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
27
DevourClient/Dependencies/IL2CPP_Resolver/Cache.hpp
Normal file
27
DevourClient/Dependencies/IL2CPP_Resolver/Cache.hpp
Normal file
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
namespace IL2CPP
|
||||
{
|
||||
namespace SystemTypeCache
|
||||
{
|
||||
void Add(unsigned int m_uHash, Unity::il2cppObject* m_pSystemType);
|
||||
|
||||
void Add(const char* m_pName, Unity::il2cppObject* m_pSystemType);
|
||||
|
||||
Unity::il2cppObject* Find(unsigned int m_uHash);
|
||||
|
||||
Unity::il2cppObject* Find(const char* m_pName);
|
||||
|
||||
namespace Initializer
|
||||
{
|
||||
extern std::vector<const char*> m_vList;
|
||||
|
||||
/*
|
||||
* (WARNING) this needs to be called before actual IL2CPP Resolver Init, otherwise use function Add outside Initializer namespace!
|
||||
*/
|
||||
void Add(const char* m_pName);
|
||||
|
||||
void PreCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
3
DevourClient/Dependencies/IL2CPP_Resolver/Data.cpp
Normal file
3
DevourClient/Dependencies/IL2CPP_Resolver/Data.cpp
Normal file
@@ -0,0 +1,3 @@
|
||||
#include "Includes.hpp"
|
||||
|
||||
namespace IL2CPP { SData Data; }
|
||||
32
DevourClient/Dependencies/IL2CPP_Resolver/Data.hpp
Normal file
32
DevourClient/Dependencies/IL2CPP_Resolver/Data.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
namespace IL2CPP
|
||||
{
|
||||
struct SData
|
||||
{
|
||||
HMODULE m_hGameAseembly = 0;
|
||||
|
||||
struct SFunctions
|
||||
{
|
||||
void* m_pClassFromName = nullptr;
|
||||
void* m_pClassGetFields = nullptr;
|
||||
void* m_pClassGetFieldFromName = nullptr;
|
||||
void* m_pClassGetMethods = nullptr;
|
||||
void* m_pClassGetMethodFromName = nullptr;
|
||||
void* m_pClassGetPropertyFromName = nullptr;
|
||||
void* m_pClassGetType = nullptr;
|
||||
void* m_pDomainGet = nullptr;
|
||||
void* m_pDomainGetAssemblies = nullptr;
|
||||
void* m_pFree = nullptr;
|
||||
void* m_pImageGetClass = nullptr;
|
||||
void* m_pImageGetClassCount = nullptr;
|
||||
void* m_pResolveFunction = nullptr;
|
||||
void* m_pStringNew = nullptr;
|
||||
void* m_pThreadAttach = nullptr;
|
||||
void* m_pThreadDetach = nullptr;
|
||||
void* m_pTypeGetObject = nullptr;
|
||||
};
|
||||
SFunctions Functions;
|
||||
};
|
||||
extern SData Data;
|
||||
}
|
||||
32
DevourClient/Dependencies/IL2CPP_Resolver/Defines.hpp
Normal file
32
DevourClient/Dependencies/IL2CPP_Resolver/Defines.hpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
// Disable Asserts
|
||||
//#define IL2CPP_ASSERT(x) assert(0)
|
||||
#ifndef IL2CPP_ASSERT
|
||||
#define IL2CPP_ASSERT(x) assert(x)
|
||||
#endif
|
||||
|
||||
#ifndef IL2CPP_MAIN_MODULE
|
||||
#define IL2CPP_MAIN_MODULE "GameAssembly.dll"
|
||||
#endif
|
||||
|
||||
#define IL2CPP_INIT_EXPORT "il2cpp_init"
|
||||
#define IL2CPP_CLASS_FROM_NAME_EXPORT "il2cpp_class_from_name"
|
||||
#define IL2CPP_CLASS_GET_FIELDS "il2cpp_class_get_fields"
|
||||
#define IL2CPP_CLASS_GET_FIELD_FROM_NAME_EXPORT "il2cpp_class_get_field_from_name"
|
||||
#define IL2CPP_CLASS_GET_METHODS "il2cpp_class_get_methods"
|
||||
#define IL2CPP_CLASS_GET_METHOD_FROM_NAME_EXPORT "il2cpp_class_get_method_from_name"
|
||||
#define IL2CPP_CLASS_GET_PROPERTY_FROM_NAME_EXPORT "il2cpp_class_get_property_from_name"
|
||||
#define IL2CPP_CLASS_GET_TYPE_EXPORT "il2cpp_class_get_type"
|
||||
#define IL2CPP_DOMAIN_GET_EXPORT "il2cpp_domain_get"
|
||||
#define IL2CPP_DOMAIN_GET_ASSEMBLIES_EXPORT "il2cpp_domain_get_assemblies"
|
||||
#define IL2CPP_FREE_EXPORT "il2cpp_free"
|
||||
#define IL2CPP_IMAGE_GET_CLASS_EXPORT "il2cpp_image_get_class"
|
||||
#define IL2CPP_IMAGE_GET_CLASS_COUNT_EXPORT "il2cpp_image_get_class_count"
|
||||
#define IL2CPP_RESOLVE_FUNC_EXPORT "il2cpp_resolve_icall"
|
||||
#define IL2CPP_STRING_NEW_EXPORT "il2cpp_string_new"
|
||||
#define IL2CPP_THREAD_ATTACH_EXPORT "il2cpp_thread_attach"
|
||||
#define IL2CPP_THREAD_DETACH_EXPORT "il2cpp_thread_detach"
|
||||
#define IL2CPP_TYPE_GET_OBJECT_EXPORT "il2cpp_type_get_object"
|
||||
|
||||
// Calling Convention
|
||||
#define IL2CPP_CALLING_CONVENTION __fastcall*
|
||||
@@ -0,0 +1,86 @@
|
||||
#include "../Includes.hpp"
|
||||
|
||||
namespace IL2CPP
|
||||
{
|
||||
namespace Callback
|
||||
{
|
||||
struct _VFuncCallback
|
||||
{
|
||||
std::vector<void*> m_vFunctions;
|
||||
|
||||
void** m_pVTable = nullptr;
|
||||
void* m_pOriginal = nullptr;
|
||||
};
|
||||
|
||||
namespace OnUpdate
|
||||
{
|
||||
_VFuncCallback Data;
|
||||
|
||||
void Add(void* m_pFunction) { Data.m_vFunctions.emplace_back(m_pFunction); }
|
||||
|
||||
void __fastcall Caller(void* rcx)
|
||||
{
|
||||
for (void* m_pFunction : Data.m_vFunctions)
|
||||
reinterpret_cast<void(*)()>(m_pFunction)();
|
||||
|
||||
reinterpret_cast<void(__fastcall*)(void*)>(Data.m_pOriginal)(rcx);
|
||||
}
|
||||
}
|
||||
|
||||
namespace OnLateUpdate
|
||||
{
|
||||
_VFuncCallback Data;
|
||||
|
||||
void Add(void* m_pFunction) { Data.m_vFunctions.emplace_back(m_pFunction); }
|
||||
|
||||
void __fastcall Caller(void* rcx)
|
||||
{
|
||||
for (void* m_pFunction : Data.m_vFunctions)
|
||||
reinterpret_cast<void(*)()>(m_pFunction)();
|
||||
|
||||
reinterpret_cast<void(__fastcall*)(void*)>(Data.m_pOriginal)(rcx);
|
||||
}
|
||||
}
|
||||
|
||||
void Replace_VFunc(void** m_pVTableFunc, void* m_pCaller, void** m_pCallbackOriginal)
|
||||
{
|
||||
DWORD m_dOldProtection = 0x0;
|
||||
if (m_pVTableFunc && VirtualProtect(m_pVTableFunc, sizeof(void*), PAGE_READWRITE, &m_dOldProtection))
|
||||
{
|
||||
if (m_pCallbackOriginal) *m_pCallbackOriginal = *m_pVTableFunc;
|
||||
*m_pVTableFunc = m_pCaller;
|
||||
|
||||
VirtualProtect(m_pVTableFunc, sizeof(void*), m_dOldProtection, &m_dOldProtection);
|
||||
}
|
||||
}
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
void* m_pThread = IL2CPP::Thread::Attach(IL2CPP::Domain::Get());
|
||||
|
||||
// Fetch
|
||||
{
|
||||
void** m_pMonoBehaviourVTable = *reinterpret_cast<void***>(IL2CPP::Helper::GetMonoBehaviour()->m_CachedPtr);
|
||||
if (m_pMonoBehaviourVTable) // x86: darkness my old friend
|
||||
{
|
||||
OnUpdate::Data.m_pVTable = VFunc::Find_ASM(m_pMonoBehaviourVTable, 99, { 0x33, 0xD2, 0xE9 }); // xor edx, edx | jmp
|
||||
OnLateUpdate::Data.m_pVTable = VFunc::Find_ASM(m_pMonoBehaviourVTable, 99, { 0xBA, 0x01, 0x00, 0x00, 0x00, 0xE9 }); // mov edx, 1 | jmp
|
||||
}
|
||||
}
|
||||
|
||||
IL2CPP::Thread::Detach(m_pThread);
|
||||
|
||||
// Replace
|
||||
{
|
||||
Replace_VFunc(OnUpdate::Data.m_pVTable, OnUpdate::Caller, &OnUpdate::Data.m_pOriginal);
|
||||
Replace_VFunc(OnLateUpdate::Data.m_pVTable, OnLateUpdate::Caller, &OnLateUpdate::Data.m_pOriginal);
|
||||
}
|
||||
}
|
||||
|
||||
void Uninitialize()
|
||||
{
|
||||
Replace_VFunc(OnUpdate::Data.m_pVTable, OnUpdate::Data.m_pOriginal, nullptr);
|
||||
Replace_VFunc(OnLateUpdate::Data.m_pVTable, OnLateUpdate::Data.m_pOriginal, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
namespace IL2CPP
|
||||
{
|
||||
namespace Callback
|
||||
{
|
||||
namespace OnUpdate
|
||||
{
|
||||
void Add(void* m_pFunction);
|
||||
}
|
||||
|
||||
namespace OnLateUpdate
|
||||
{
|
||||
void Add(void* m_pFunction);
|
||||
}
|
||||
|
||||
void Initialize();
|
||||
|
||||
void Uninitialize();
|
||||
}
|
||||
}
|
||||
289
DevourClient/Dependencies/IL2CPP_Resolver/Functions/Class.cpp
Normal file
289
DevourClient/Dependencies/IL2CPP_Resolver/Functions/Class.cpp
Normal file
@@ -0,0 +1,289 @@
|
||||
#include "../Includes.hpp"
|
||||
|
||||
namespace IL2CPP
|
||||
{
|
||||
namespace Class
|
||||
{
|
||||
Unity::il2cppFieldInfo* GetFields(Unity::il2cppClass* m_pClass, void** m_pIterator)
|
||||
{
|
||||
return reinterpret_cast<Unity::il2cppFieldInfo*(IL2CPP_CALLING_CONVENTION)(void*, void**)>(Data.Functions.m_pClassGetFields)(m_pClass, m_pIterator);
|
||||
}
|
||||
|
||||
void FetchFields(Unity::il2cppClass* m_pClass, std::vector<Unity::il2cppFieldInfo*>* m_pVector, void* m_pFieldIterator)
|
||||
{
|
||||
m_pVector->clear();
|
||||
|
||||
while (1)
|
||||
{
|
||||
Unity::il2cppFieldInfo* m_pField = GetFields(m_pClass, &m_pFieldIterator);
|
||||
if (!m_pField)
|
||||
break;
|
||||
|
||||
m_pVector->emplace_back(m_pField);
|
||||
}
|
||||
}
|
||||
|
||||
Unity::il2cppMethodInfo* GetMethods(Unity::il2cppClass* m_pClass, void** m_pIterator)
|
||||
{
|
||||
return reinterpret_cast<Unity::il2cppMethodInfo*(IL2CPP_CALLING_CONVENTION)(void*, void**)>(Data.Functions.m_pClassGetMethods)(m_pClass, m_pIterator);
|
||||
}
|
||||
|
||||
void FetchMethods(Unity::il2cppClass* m_pClass, std::vector<Unity::il2cppMethodInfo*>* m_pVector, void* m_pMethodIterator)
|
||||
{
|
||||
m_pVector->clear();
|
||||
|
||||
while (1)
|
||||
{
|
||||
Unity::il2cppMethodInfo* m_pMethod = GetMethods(m_pClass, &m_pMethodIterator);
|
||||
if (!m_pMethod)
|
||||
break;
|
||||
|
||||
m_pVector->emplace_back(m_pMethod);
|
||||
}
|
||||
}
|
||||
|
||||
Unity::il2cppType* GetType(Unity::il2cppClass* m_pClass)
|
||||
{
|
||||
return reinterpret_cast<Unity::il2cppType*(IL2CPP_CALLING_CONVENTION)(void*)>(Data.Functions.m_pClassGetType)(m_pClass);
|
||||
}
|
||||
|
||||
Unity::il2cppObject* GetSystemType(Unity::il2cppClass* m_pClass)
|
||||
{
|
||||
return reinterpret_cast<Unity::il2cppObject*(IL2CPP_CALLING_CONVENTION)(void*)>(Data.Functions.m_pTypeGetObject)(GetType(m_pClass));
|
||||
}
|
||||
|
||||
Unity::il2cppObject* GetSystemType(const char* m_pClassName)
|
||||
{
|
||||
Unity::il2cppClass* m_pClass = Find(m_pClassName);
|
||||
if (!m_pClass)
|
||||
return nullptr;
|
||||
|
||||
return GetSystemType(m_pClass);
|
||||
}
|
||||
|
||||
Unity::il2cppClass* GetFromName(Unity::il2cppImage* m_pImage, const char* m_pNamespace, const char* m_pName)
|
||||
{
|
||||
return reinterpret_cast<Unity::il2cppClass*(IL2CPP_CALLING_CONVENTION)(void*, const char*, const char*)>(Data.Functions.m_pClassFromName)(m_pImage, m_pNamespace, m_pName);
|
||||
}
|
||||
|
||||
Unity::il2cppClass* Find(const char* m_pName)
|
||||
{
|
||||
size_t m_sAssembliesCount = 0U;
|
||||
Unity::il2cppAssembly** m_pAssemblies = Domain::GetAssemblies(&m_sAssembliesCount);
|
||||
if (!m_pAssemblies || 0U >= m_sAssembliesCount) return nullptr;
|
||||
|
||||
const char* m_pNameSpaceEnd = strrchr(m_pName, '.');
|
||||
char* m_pNameSpace = nullptr;
|
||||
if (m_pNameSpaceEnd)
|
||||
{
|
||||
uintptr_t m_uNamespaceSize = static_cast<uintptr_t>(m_pNameSpaceEnd - m_pName);
|
||||
m_pNameSpace = new char[m_uNamespaceSize + 1];
|
||||
memcpy(m_pNameSpace, m_pName, m_uNamespaceSize);
|
||||
m_pNameSpace[m_uNamespaceSize] = '\0';
|
||||
|
||||
m_pName = m_pNameSpaceEnd + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_pNameSpace = new char[2];
|
||||
memset(m_pNameSpace, 0, 2);
|
||||
}
|
||||
|
||||
Unity::il2cppClass* m_pClassReturn = nullptr;
|
||||
for (size_t i = 0U; m_sAssembliesCount > i; ++i)
|
||||
{
|
||||
Unity::il2cppAssembly* m_pAssembly = m_pAssemblies[i];
|
||||
if (!m_pAssembly || !m_pAssembly->m_pImage) continue;
|
||||
|
||||
m_pClassReturn = GetFromName(m_pAssembly->m_pImage, m_pNameSpace, m_pName);
|
||||
if (m_pClassReturn) break;
|
||||
}
|
||||
|
||||
delete[] m_pNameSpace;
|
||||
return m_pClassReturn;
|
||||
}
|
||||
|
||||
void FetchClasses(std::vector<Unity::il2cppClass*>* m_pVector, const char* m_pModuleName, const char* m_pNamespace)
|
||||
{
|
||||
m_pVector->clear();
|
||||
|
||||
size_t m_sAssembliesCount = 0U;
|
||||
Unity::il2cppAssembly** m_pAssemblies = Domain::GetAssemblies(&m_sAssembliesCount);
|
||||
if (!m_pAssemblies || 0U >= m_sAssembliesCount) return;
|
||||
|
||||
Unity::il2cppImage* m_pImage = nullptr;
|
||||
for (size_t i = 0U; m_sAssembliesCount > i; ++i)
|
||||
{
|
||||
Unity::il2cppAssembly* m_pAssembly = m_pAssemblies[i];
|
||||
if (!m_pAssembly || !m_pAssembly->m_pImage || strcmp(m_pAssembly->m_pImage->m_pNameNoExt, m_pModuleName) != 0)
|
||||
continue;
|
||||
|
||||
m_pImage = m_pAssembly->m_pImage;
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_pImage)
|
||||
{
|
||||
size_t m_sClassesCount = reinterpret_cast<size_t(IL2CPP_CALLING_CONVENTION)(void*)>(Data.Functions.m_pImageGetClassCount)(m_pImage);
|
||||
for (size_t i = 0U; m_sClassesCount > i; ++i)
|
||||
{
|
||||
Unity::il2cppClass* m_pClass = reinterpret_cast<Unity::il2cppClass*(IL2CPP_CALLING_CONVENTION)(void*, size_t)>(Data.Functions.m_pImageGetClass)(m_pImage, i);
|
||||
if (m_pNamespace)
|
||||
{
|
||||
if (m_pNamespace[0] == '\0')
|
||||
{
|
||||
if (m_pClass->m_pNamespace[0] != '\0')
|
||||
continue;
|
||||
}
|
||||
else if (strcmp(m_pClass->m_pNamespace, m_pNamespace) != 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
m_pVector->emplace_back(m_pClass);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
int GetFieldOffset(Unity::il2cppClass* m_pClass, const char* m_pName)
|
||||
{
|
||||
void* m_pFieldIterator = nullptr;
|
||||
while (1)
|
||||
{
|
||||
Unity::il2cppFieldInfo* m_pField = GetFields(m_pClass, &m_pFieldIterator);
|
||||
if (!m_pField)
|
||||
break;
|
||||
|
||||
if (strcmp(m_pField->m_pName, m_pName) == 0)
|
||||
return m_pField->m_iOffset;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int GetFieldOffset(const char* m_pClassName, const char* m_pName)
|
||||
{
|
||||
Unity::il2cppClass* m_pClass = Find(m_pClassName);
|
||||
if (m_pClass)
|
||||
return GetFieldOffset(m_pClass, m_pName);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void* GetMethodPointer(Unity::il2cppClass* m_pClass, const char* m_pMethodName, int m_iArgs)
|
||||
{
|
||||
Unity::il2cppMethodInfo* pMethod = reinterpret_cast<Unity::il2cppMethodInfo*(IL2CPP_CALLING_CONVENTION)(void*, const char*, int)>(Data.Functions.m_pClassGetMethodFromName)(m_pClass, m_pMethodName, m_iArgs);
|
||||
if (!pMethod) return nullptr;
|
||||
|
||||
return pMethod->m_pMethodPointer;
|
||||
}
|
||||
|
||||
void* GetMethodPointer(const char* m_pClassName, const char* m_pMethodName, int m_iArgs)
|
||||
{
|
||||
Unity::il2cppClass* m_pClass = Find(m_pClassName);
|
||||
if (m_pClass)
|
||||
return GetMethodPointer(m_pClass, m_pMethodName, m_iArgs);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void* GetMethodPointer(const char* m_pClassName, const char* m_pMethodName, std::initializer_list<const char*> m_vNames)
|
||||
{
|
||||
Unity::il2cppClass* m_pClass = Find(m_pClassName);
|
||||
if (!m_pClass)
|
||||
return nullptr;
|
||||
|
||||
int m_iNamesCount = static_cast<int>(m_vNames.size());
|
||||
const char** m_pNames = const_cast<const char**>(m_vNames.begin());
|
||||
|
||||
void* m_pMethodIterator = nullptr;
|
||||
while (1)
|
||||
{
|
||||
Unity::il2cppMethodInfo* m_pMethod = GetMethods(m_pClass, &m_pMethodIterator);
|
||||
if (!m_pMethod)
|
||||
break;
|
||||
|
||||
if (strcmp(m_pMethod->m_pName, m_pMethodName) != 0)
|
||||
continue;
|
||||
|
||||
Unity::il2cppParameterInfo* m_pCurrentParameters = m_pMethod->m_pParameters;
|
||||
for (int i = 0; m_iNamesCount > i; ++i)
|
||||
{
|
||||
if (strcmp(m_pCurrentParameters->m_pName, m_pNames[i]) != 0)
|
||||
break;
|
||||
|
||||
m_pCurrentParameters++; // m_pCurrentParameters += sizeof(Unity::il2cppParameterInfo);
|
||||
if ((i + 1) == m_iNamesCount)
|
||||
return m_pMethod->m_pMethodPointer;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Unity::il2cppClass* FilterClass(std::vector<Unity::il2cppClass*>* m_pClasses, std::initializer_list<const char*> m_vNames, int m_iFoundCount)
|
||||
{
|
||||
int m_iNamesCount = static_cast<int>(m_vNames.size());
|
||||
const char** m_pNames = const_cast<const char**>(m_vNames.begin());
|
||||
|
||||
if (0 >= m_iFoundCount || m_iFoundCount > m_iNamesCount)
|
||||
m_iFoundCount = m_iNamesCount;
|
||||
|
||||
Unity::il2cppClass* m_pReturn = nullptr;
|
||||
for (size_t c = 0; m_pClasses->size() > c; ++c)
|
||||
{
|
||||
int m_iFoundCountNow = 0;
|
||||
|
||||
Unity::il2cppClass* m_pClass = m_pClasses->operator[](c);
|
||||
if (!m_pClass)
|
||||
continue;
|
||||
|
||||
for (int i = 0; m_iNamesCount > i; ++i)
|
||||
{
|
||||
const char* m_pNameToFind = m_pNames[i];
|
||||
|
||||
bool m_bFoundInClass = false;
|
||||
if (m_pNameToFind[0] == '~') // Field
|
||||
m_bFoundInClass = GetFieldOffset(m_pClass, &m_pNameToFind[1]) >= 0;
|
||||
else if (m_pNameToFind[0] == '-') // Method
|
||||
m_bFoundInClass = GetMethodPointer(m_pClass, &m_pNameToFind[1]) != nullptr;
|
||||
else // Both
|
||||
{
|
||||
m_bFoundInClass = GetFieldOffset(m_pClass, m_pNameToFind) >= 0;
|
||||
if (!m_bFoundInClass)
|
||||
m_bFoundInClass = GetMethodPointer(m_pClass, m_pNameToFind) != nullptr;
|
||||
}
|
||||
|
||||
if (m_bFoundInClass)
|
||||
++m_iFoundCountNow;
|
||||
}
|
||||
|
||||
if (m_iFoundCount == m_iFoundCountNow)
|
||||
{
|
||||
m_pReturn = m_pClass;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return m_pReturn;
|
||||
}
|
||||
|
||||
void* FilterClassToMethodPointer(std::vector<Unity::il2cppClass*>* m_pClasses, const char* m_pMethodName, int m_iArgs)
|
||||
{
|
||||
void* m_pMethodPointer = nullptr;
|
||||
for (size_t c = 0; m_pClasses->size() > c; ++c)
|
||||
{
|
||||
Unity::il2cppClass* m_pClass = m_pClasses->operator[](c);
|
||||
if (!m_pClass)
|
||||
continue;
|
||||
|
||||
m_pMethodPointer = GetMethodPointer(m_pClass, m_pMethodName, m_iArgs);
|
||||
if (m_pMethodPointer)
|
||||
break;
|
||||
}
|
||||
|
||||
return m_pMethodPointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
317
DevourClient/Dependencies/IL2CPP_Resolver/Functions/Class.hpp
Normal file
317
DevourClient/Dependencies/IL2CPP_Resolver/Functions/Class.hpp
Normal file
@@ -0,0 +1,317 @@
|
||||
#pragma once
|
||||
|
||||
namespace IL2CPP
|
||||
{
|
||||
namespace Class
|
||||
{
|
||||
Unity::il2cppFieldInfo* GetFields(Unity::il2cppClass* m_pClass, void** m_pIterator);
|
||||
|
||||
void FetchFields(Unity::il2cppClass* m_pClass, std::vector<Unity::il2cppFieldInfo*>* m_pVector, void* m_pFieldIterator = nullptr);
|
||||
|
||||
Unity::il2cppMethodInfo* GetMethods(Unity::il2cppClass* m_pClass, void** m_pIterator);
|
||||
|
||||
void FetchMethods(Unity::il2cppClass* m_pClass, std::vector<Unity::il2cppMethodInfo*>* m_pVector, void* m_pMethodIterator = nullptr);
|
||||
|
||||
Unity::il2cppType* GetType(Unity::il2cppClass* m_pClass);
|
||||
|
||||
Unity::il2cppObject* GetSystemType(Unity::il2cppClass* m_pClass);
|
||||
|
||||
Unity::il2cppObject* GetSystemType(const char* m_pClassName);
|
||||
|
||||
Unity::il2cppClass* GetFromName(Unity::il2cppImage* m_pImage, const char* m_pNamespace, const char* m_pName);
|
||||
|
||||
Unity::il2cppClass* Find(const char* m_pName);
|
||||
|
||||
/*
|
||||
* If you wanna fetch modules with custom classes use modulename: Assembly-CSharp
|
||||
* Nullptr namespace == pass any namespace
|
||||
*/
|
||||
void FetchClasses(std::vector<Unity::il2cppClass*>* m_pVector, const char* m_pModuleName, const char* m_pNamespace);
|
||||
|
||||
namespace Utils
|
||||
{
|
||||
int GetFieldOffset(Unity::il2cppClass* m_pClass, const char* m_pName);
|
||||
|
||||
int GetFieldOffset(const char* m_pClassName, const char* m_pName);
|
||||
|
||||
void* GetMethodPointer(Unity::il2cppClass* m_pClass, const char* m_pMethodName, int m_iArgs = -1);
|
||||
|
||||
void* GetMethodPointer(const char* m_pClassName, const char* m_pMethodName, int m_iArgs = -1);
|
||||
|
||||
/*
|
||||
* Usage:
|
||||
* m_vNames = { "arg1" , "arg2" , ... }
|
||||
*/
|
||||
void* GetMethodPointer(const char* m_pClassName, const char* m_pMethodName, std::initializer_list<const char*> m_vNames);
|
||||
|
||||
|
||||
/*
|
||||
* Name Prefixes
|
||||
* (Field) ~
|
||||
* (Method) -
|
||||
*/
|
||||
Unity::il2cppClass* FilterClass(std::vector<Unity::il2cppClass*>* m_pClasses, std::initializer_list<const char*> m_vNames, int m_iFoundCount = -1);
|
||||
|
||||
void* FilterClassToMethodPointer(std::vector<Unity::il2cppClass*>* m_pClasses, const char* m_pMethodName, int m_iArgs = -1);
|
||||
}
|
||||
}
|
||||
|
||||
enum class m_eClassPropType : int
|
||||
{
|
||||
Unknown = 0,
|
||||
Field, // Member of class that can be accessed directly by RVA
|
||||
Property, // Member of class that can be accessed by calling function
|
||||
Method, // Function of class
|
||||
};
|
||||
|
||||
class CClass
|
||||
{
|
||||
public:
|
||||
Unity::il2cppObject m_Object = { 0 };
|
||||
void* m_CachedPtr = nullptr;
|
||||
|
||||
// Wrappers for namespace, ah...
|
||||
Unity::il2cppFieldInfo* GetFields(void** m_pIterator)
|
||||
{
|
||||
return Class::GetFields(m_Object.m_pClass, m_pIterator);
|
||||
}
|
||||
|
||||
void FetchFields(std::vector<Unity::il2cppFieldInfo*>* m_pVector, void* m_pFieldIterator = nullptr)
|
||||
{
|
||||
Class::FetchFields(m_Object.m_pClass, m_pVector, m_pFieldIterator);
|
||||
}
|
||||
|
||||
Unity::il2cppMethodInfo* GetMethods(void** m_pIterator)
|
||||
{
|
||||
return Class::GetMethods(m_Object.m_pClass, m_pIterator);
|
||||
}
|
||||
|
||||
void FetchMethods(std::vector<Unity::il2cppMethodInfo*>* m_pVector, void* m_pMethodIterator = nullptr)
|
||||
{
|
||||
Class::FetchMethods(m_Object.m_pClass, m_pVector, m_pMethodIterator);
|
||||
}
|
||||
|
||||
void* GetMethodPointer(const char* m_pMethodName, int m_iArgs = -1)
|
||||
{
|
||||
return Class::Utils::GetMethodPointer(m_Object.m_pClass, m_pMethodName, m_iArgs);
|
||||
}
|
||||
|
||||
m_eClassPropType GetPropType(const char* m_pPropType)
|
||||
{
|
||||
Unity::il2cppFieldInfo* pField = reinterpret_cast<Unity::il2cppFieldInfo*(IL2CPP_CALLING_CONVENTION)(void*, const char*)>(Data.Functions.m_pClassGetFieldFromName)(m_Object.m_pClass, m_pPropType);
|
||||
if (pField)
|
||||
return m_eClassPropType::Field;
|
||||
|
||||
Unity::il2cppPropertyInfo* pProperty = reinterpret_cast<Unity::il2cppPropertyInfo*(IL2CPP_CALLING_CONVENTION)(void*, const char*)>(Data.Functions.m_pClassGetPropertyFromName)(m_Object.m_pClass, m_pPropType);
|
||||
if (pProperty)
|
||||
return m_eClassPropType::Property;
|
||||
|
||||
Unity::il2cppMethodInfo* pMethod = reinterpret_cast<Unity::il2cppMethodInfo*(IL2CPP_CALLING_CONVENTION)(void*, const char*, int)>(Data.Functions.m_pClassGetMethodFromName)(m_Object.m_pClass, m_pPropType, -1);
|
||||
if (pMethod)
|
||||
return m_eClassPropType::Method;
|
||||
|
||||
return m_eClassPropType::Unknown;
|
||||
}
|
||||
|
||||
// Call Method
|
||||
template<typename TReturn, typename... TArgs>
|
||||
TReturn CallMethod(void* m_pMethod, TArgs... tArgs) { return reinterpret_cast<TReturn(UNITY_CALLING_CONVENTION)(void*, TArgs...)>(m_pMethod)(this, tArgs...); }
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
TReturn CallMethod(const char* m_pMethodName, TArgs... tArgs) { return CallMethod<TReturn>(GetMethodPointer(m_pMethodName), tArgs...); }
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
TReturn CallMethodSafe(void* m_pMethod, TArgs... tArgs)
|
||||
{
|
||||
if (!m_pMethod)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
__debugbreak(); // remove it when you wanna step through your code and be like why the fuck it doesn't do anything.
|
||||
#endif
|
||||
|
||||
TReturn m_tDefault = {}; // void goes like illegal use of type. (use void* and fuck them)
|
||||
return m_tDefault;
|
||||
}
|
||||
|
||||
return CallMethod<TReturn>(m_pMethod, tArgs...);
|
||||
}
|
||||
|
||||
template<typename TReturn, typename... TArgs>
|
||||
TReturn CallMethodSafe(const char* m_pMethodName, TArgs... tArgs) { return CallMethodSafe<TReturn>(GetMethodPointer(m_pMethodName), tArgs...); }
|
||||
|
||||
// Properties/Fields
|
||||
|
||||
template<typename T>
|
||||
T GetPropertyValue(const char* m_pPropertyName)
|
||||
{
|
||||
Unity::il2cppPropertyInfo* pProperty = reinterpret_cast<Unity::il2cppPropertyInfo*(IL2CPP_CALLING_CONVENTION)(void*, const char*)>(Data.Functions.m_pClassGetPropertyFromName)(m_Object.m_pClass, m_pPropertyName);
|
||||
if (pProperty && pProperty->m_pGet)
|
||||
return reinterpret_cast<T(UNITY_CALLING_CONVENTION)(void*)>(pProperty->m_pGet->m_pMethodPointer)(this);
|
||||
|
||||
T tDefault = {};
|
||||
return tDefault;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SetPropertyValue(const char* m_pPropertyName, T m_tValue)
|
||||
{
|
||||
Unity::il2cppPropertyInfo* pProperty = reinterpret_cast<Unity::il2cppPropertyInfo*(IL2CPP_CALLING_CONVENTION)(void*, const char*)>(Data.Functions.m_pClassGetPropertyFromName)(m_Object.m_pClass, m_pPropertyName);
|
||||
if (pProperty && pProperty->m_pSet)
|
||||
return reinterpret_cast<void(UNITY_CALLING_CONVENTION)(void*, T)>(pProperty->m_pSet->m_pMethodPointer)(this, m_tValue);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
__inline T GetMemberValue(int m_iOffset)
|
||||
{
|
||||
return *reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(this) + m_iOffset);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
__inline void SetMemberValue(int m_iOffset, T m_tValue)
|
||||
{
|
||||
*reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(this) + m_iOffset) = m_tValue;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
__inline T GetMemberValue(Unity::il2cppFieldInfo* m_pField)
|
||||
{
|
||||
if (!m_pField || 0 > m_pField->m_iOffset)
|
||||
{
|
||||
T m_tDefault = {};
|
||||
return m_tDefault;
|
||||
}
|
||||
|
||||
return GetMemberValue<T>(m_pField->m_iOffset);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
__inline void SetMemberValue(Unity::il2cppFieldInfo* m_pField, T m_tValue)
|
||||
{
|
||||
if (!m_pField || 0 > m_pField->m_iOffset)
|
||||
return;
|
||||
|
||||
SetMemberValue<T>(m_pField->m_iOffset, m_tValue);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T GetMemberValue(const char* m_pMemberName)
|
||||
{
|
||||
Unity::il2cppFieldInfo* pField = reinterpret_cast<Unity::il2cppFieldInfo*(IL2CPP_CALLING_CONVENTION)(void*, const char*)>(Data.Functions.m_pClassGetFieldFromName)(m_Object.m_pClass, m_pMemberName);
|
||||
if (pField)
|
||||
{
|
||||
if (pField->m_iOffset >= 0) return *reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(this) + pField->m_iOffset);
|
||||
}
|
||||
else
|
||||
return GetPropertyValue<T>(m_pMemberName);
|
||||
|
||||
T tDefault = {};
|
||||
return tDefault;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SetMemberValue(const char* m_pMemberName, T m_tValue)
|
||||
{
|
||||
Unity::il2cppFieldInfo* pField = reinterpret_cast<Unity::il2cppFieldInfo*(IL2CPP_CALLING_CONVENTION)(void*, const char*)>(Data.Functions.m_pClassGetFieldFromName)(m_Object.m_pClass, m_pMemberName);
|
||||
if (pField)
|
||||
{
|
||||
if (pField->m_iOffset >= 0) *reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(this) + pField->m_iOffset) = m_tValue;
|
||||
return;
|
||||
}
|
||||
|
||||
SetPropertyValue<T>(m_pMemberName, m_tValue);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
__inline T GetObscuredViaOffset(int m_iOffset)
|
||||
{
|
||||
if (m_iOffset >= 0)
|
||||
{
|
||||
switch (sizeof(T))
|
||||
{
|
||||
case sizeof(double):
|
||||
{
|
||||
long long m_lKey = *reinterpret_cast<long long*>(reinterpret_cast<uintptr_t>(this) + m_iOffset);
|
||||
long long m_lValue = *reinterpret_cast<long long*>(reinterpret_cast<uintptr_t>(this) + m_iOffset + sizeof(m_lKey));
|
||||
|
||||
m_lValue ^= m_lKey;
|
||||
return *reinterpret_cast<T*>(&m_lValue);
|
||||
}
|
||||
break;
|
||||
case sizeof(int):
|
||||
{
|
||||
int m_iKey = *reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(this) + m_iOffset);
|
||||
int m_iValue = *reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(this) + m_iOffset + sizeof(m_iKey));
|
||||
|
||||
m_iValue ^= m_iKey;
|
||||
return *reinterpret_cast<T*>(&m_iValue);
|
||||
}
|
||||
break;
|
||||
case sizeof(bool):
|
||||
{
|
||||
unsigned char m_uKey = *reinterpret_cast<unsigned char*>(reinterpret_cast<uintptr_t>(this) + m_iOffset);
|
||||
int m_iValue = *reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(this) + m_iOffset + sizeof(m_uKey));
|
||||
|
||||
m_iValue ^= m_uKey;
|
||||
return *reinterpret_cast<T*>(&m_iValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
T m_tDefault = { 0 };
|
||||
return m_tDefault;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T GetObscuredValue(const char* m_pMemberName)
|
||||
{
|
||||
Unity::il2cppFieldInfo* m_pField = reinterpret_cast<Unity::il2cppFieldInfo*(IL2CPP_CALLING_CONVENTION)(void*, const char*)>(Data.Functions.m_pClassGetFieldFromName)(m_Object.m_pClass, m_pMemberName);
|
||||
return GetObscuredViaOffset<T>(m_pField ? m_pField->m_iOffset : -1);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
__inline void SetObscuredViaOffset(int m_iOffset, T m_tValue)
|
||||
{
|
||||
if (0 > m_iOffset)
|
||||
return;
|
||||
|
||||
switch (sizeof(T))
|
||||
{
|
||||
case sizeof(double):
|
||||
{
|
||||
long long m_lKey = *reinterpret_cast<long long*>(reinterpret_cast<uintptr_t>(this) + m_iOffset);
|
||||
long long* m_pValue = reinterpret_cast<long long*>(reinterpret_cast<uintptr_t>(this) + m_iOffset + sizeof(m_lKey));
|
||||
|
||||
*m_pValue = *reinterpret_cast<long long*>(&m_tValue) ^ m_lKey;
|
||||
}
|
||||
break;
|
||||
case sizeof(int):
|
||||
{
|
||||
int m_iKey = *reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(this) + m_iOffset);
|
||||
int* m_pValue = reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(this) + m_iOffset + sizeof(m_iKey));
|
||||
|
||||
*m_pValue = *reinterpret_cast<int*>(&m_tValue) ^ m_iKey;
|
||||
}
|
||||
break;
|
||||
case sizeof(bool):
|
||||
{
|
||||
unsigned char m_uKey = *reinterpret_cast<unsigned char*>(reinterpret_cast<uintptr_t>(this) + m_iOffset);
|
||||
int* m_pValue = reinterpret_cast<int*>(reinterpret_cast<uintptr_t>(this) + m_iOffset + sizeof(m_uKey));
|
||||
|
||||
*m_pValue = *reinterpret_cast<int*>(&m_tValue) ^ m_uKey;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void SetObscuredValue(const char* m_pMemberName, T m_tValue)
|
||||
{
|
||||
Unity::il2cppFieldInfo* m_pField = reinterpret_cast<Unity::il2cppFieldInfo*(IL2CPP_CALLING_CONVENTION)(void*, const char*)>(Data.Functions.m_pClassGetFieldFromName)(m_Object.m_pClass, m_pMemberName);
|
||||
if (!m_pField)
|
||||
return;
|
||||
|
||||
SetObscuredViaOffset<T>(m_pField->m_iOffset, m_tValue);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
namespace IL2CPP
|
||||
{
|
||||
namespace Domain
|
||||
{
|
||||
static void* Get()
|
||||
{
|
||||
return reinterpret_cast<void*(IL2CPP_CALLING_CONVENTION)()>(Data.Functions.m_pDomainGet)();
|
||||
}
|
||||
|
||||
static Unity::il2cppAssembly** GetAssemblies(size_t* m_pSize)
|
||||
{
|
||||
return reinterpret_cast<Unity::il2cppAssembly**(IL2CPP_CALLING_CONVENTION)(void*, size_t*)>(Data.Functions.m_pDomainGetAssemblies)(Get(), m_pSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
namespace IL2CPP
|
||||
{
|
||||
// Without this function, you're pretty much fucked up.
|
||||
static void* ResolveCall(const char* m_pName)
|
||||
{
|
||||
return reinterpret_cast<void*(IL2CPP_CALLING_CONVENTION)(const char*)>(Data.Functions.m_pResolveFunction)(m_pName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
#include "../Includes.hpp"
|
||||
|
||||
namespace IL2CPP
|
||||
{
|
||||
namespace String
|
||||
{
|
||||
Unity::System_String* New(const char* m_pString)
|
||||
{
|
||||
return reinterpret_cast<Unity::System_String*(IL2CPP_CALLING_CONVENTION)(const char*)>(Data.Functions.m_pStringNew)(m_pString);
|
||||
}
|
||||
|
||||
Unity::System_String* New(std::string m_sString) { return New(&m_sString[0]); }
|
||||
|
||||
namespace NoGC
|
||||
{
|
||||
Unity::System_String* New(const char* m_pString)
|
||||
{
|
||||
Unity::System_String* m_pNew = new Unity::System_String;
|
||||
m_pNew->m_pClass = IL2CPP::Class::Find("System.String");
|
||||
m_pNew->m_iLength = swprintf_s(m_pNew->m_wString, (sizeof(Unity::System_String::m_wString) / 4), L"%hs", m_pString);
|
||||
|
||||
return m_pNew;
|
||||
}
|
||||
|
||||
Unity::System_String* New(std::string m_sString) { return New(&m_sString[0]); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
namespace IL2CPP
|
||||
{
|
||||
namespace String
|
||||
{
|
||||
Unity::System_String* New(const char* m_pString);
|
||||
|
||||
Unity::System_String* New(std::string m_sString);
|
||||
|
||||
// Make sure to delete it after you done using it.
|
||||
namespace NoGC
|
||||
{
|
||||
Unity::System_String* New(const char* m_pString);
|
||||
|
||||
Unity::System_String* New(std::string m_sString);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
#include "../Includes.hpp"
|
||||
|
||||
namespace IL2CPP
|
||||
{
|
||||
DWORD __stdcall ThreadHandler(void* pReserved)
|
||||
{
|
||||
void* m_pIL2CPPThread = Thread::Attach(Domain::Get());
|
||||
|
||||
CThread* m_pThread = reinterpret_cast<CThread*>(pReserved);
|
||||
void* m_pThreadStart = m_pThread->m_pThreadOnStart;
|
||||
void* m_pThreadEnd = m_pThread->m_pThreadOnEnd;
|
||||
delete m_pThread;
|
||||
|
||||
reinterpret_cast<void(*)()>(m_pThreadStart)();
|
||||
if (m_pThreadEnd)
|
||||
reinterpret_cast<void(*)()>(m_pThreadEnd)();
|
||||
|
||||
Thread::Detach(m_pIL2CPPThread);
|
||||
return 0x0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
namespace IL2CPP
|
||||
{
|
||||
DWORD __stdcall ThreadHandler(void* pReserved);
|
||||
|
||||
class CThread
|
||||
{
|
||||
public:
|
||||
void* m_pThreadOnStart = nullptr;
|
||||
void* m_pThreadOnEnd = nullptr;
|
||||
|
||||
CThread() { /* Why would you even do this? */ }
|
||||
CThread(void* m_pOnStart, void* m_pOnEnd)
|
||||
{
|
||||
m_pThreadOnStart = m_pOnStart;
|
||||
m_pThreadOnEnd = m_pOnEnd;
|
||||
|
||||
if (!m_pThreadOnStart)
|
||||
{
|
||||
IL2CPP_ASSERT("IL2CPP::CThread - m_pThreadOnStart is nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
CreateThread(0, 0, ThreadHandler, this, 0, 0);
|
||||
}
|
||||
};
|
||||
|
||||
namespace Thread
|
||||
{
|
||||
static void Create(void* m_pOnStart, void* m_pOnEnd = nullptr)
|
||||
{
|
||||
CThread* pThread = new CThread(m_pOnStart, m_pOnEnd);
|
||||
IL2CPP_ASSERT(pThread && "IL2CPP::Thread::Create - Failed!");
|
||||
}
|
||||
|
||||
static void* Attach(void* m_pDomain)
|
||||
{
|
||||
return reinterpret_cast<void*(IL2CPP_CALLING_CONVENTION)(void*)>(IL2CPP::Data.Functions.m_pThreadAttach)(m_pDomain);
|
||||
}
|
||||
|
||||
static void Detach(void* m_pThread)
|
||||
{
|
||||
reinterpret_cast<void(IL2CPP_CALLING_CONVENTION)(void*)>(IL2CPP::Data.Functions.m_pThreadDetach)(m_pThread);
|
||||
}
|
||||
}
|
||||
}
|
||||
42
DevourClient/Dependencies/IL2CPP_Resolver/Includes.hpp
Normal file
42
DevourClient/Dependencies/IL2CPP_Resolver/Includes.hpp
Normal file
@@ -0,0 +1,42 @@
|
||||
#pragma once
|
||||
// Disable Asserts
|
||||
// #define IL2CPP_ASSERT(x) ((void)(x))
|
||||
#include "Defines.hpp"
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
#include <math.h>
|
||||
#include <assert.h>
|
||||
#include <unordered_map>
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include <string>
|
||||
|
||||
// Unity
|
||||
#include "Unity/Includes.hpp"
|
||||
|
||||
// IL2CPP API
|
||||
#include "Data.hpp" // Pointers, Variables, etc...
|
||||
#include "Cache.hpp"
|
||||
|
||||
// IL2CPP
|
||||
#include "Functions/Callback.hpp"
|
||||
#include "Functions/Class.hpp"
|
||||
#include "Functions/Domain.hpp"
|
||||
#include "Functions/ResolveCall.hpp"
|
||||
#include "Functions/String.hpp"
|
||||
#include "Functions/Thread.hpp"
|
||||
|
||||
// Unity API - Include here so we have access to some cute IL2CPP Features
|
||||
#include "Unity/API/_TEMPLATE_API.hpp"
|
||||
#include "Unity/API/Object.hpp"
|
||||
#include "Unity/API/Component.hpp"
|
||||
#include "Unity/API/GameObject.hpp"
|
||||
#include "Unity/API/Camera.hpp"
|
||||
#include "Unity/API/LayerMask.hpp"
|
||||
#include "Unity/API/Rigidbody.hpp"
|
||||
#include "Unity/API/Transform.hpp"
|
||||
|
||||
// Utils
|
||||
#include "Utils/Helper.hpp"
|
||||
#include "Utils/Joaat.hpp"
|
||||
#include "Utils/VFunc.hpp"
|
||||
24
DevourClient/Dependencies/IL2CPP_Resolver/LICENSE
Normal file
24
DevourClient/Dependencies/IL2CPP_Resolver/LICENSE
Normal file
@@ -0,0 +1,24 @@
|
||||
This is free and unencumbered software released into the public domain.
|
||||
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
distribute this software, either in source code form or as a compiled
|
||||
binary, for any purpose, commercial or non-commercial, and by any
|
||||
means.
|
||||
|
||||
In jurisdictions that recognize copyright laws, the author or authors
|
||||
of this software dedicate any and all copyright interest in the
|
||||
software to the public domain. We make this dedication for the benefit
|
||||
of the public at large and to the detriment of our heirs and
|
||||
successors. We intend this dedication to be an overt act of
|
||||
relinquishment in perpetuity of all present and future rights to this
|
||||
software under copyright law.
|
||||
|
||||
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 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.
|
||||
|
||||
For more information, please refer to <https://unlicense.org>
|
||||
36
DevourClient/Dependencies/IL2CPP_Resolver/README.md
Normal file
36
DevourClient/Dependencies/IL2CPP_Resolver/README.md
Normal file
@@ -0,0 +1,36 @@
|
||||
## IL2CPP Resolver
|
||||
A run-time API resolver for IL2CPP Unity.
|
||||
|
||||
[](https://www.paypal.com/donate/?hosted_button_id=F86FFE644E55E)
|
||||
|
||||
### Quick Example
|
||||
```cpp
|
||||
#include "Main.hpp"
|
||||
|
||||
void SomeFunction()
|
||||
{
|
||||
IL2CPP::Initialize(); // This needs to be called once!
|
||||
|
||||
Unity::CGameObject* pLocal = Unity::GameObject::Find("LocalPlayer");
|
||||
Unity::CComponent* pLocalData = pLocal->GetComponent("PlayerData");
|
||||
pLocalData->SetMemberValue<bool>("CanFly", true);
|
||||
}
|
||||
```
|
||||
|
||||
### Registering OnUpdate Callback
|
||||
```cpp
|
||||
void OurUpdateFunction()
|
||||
{
|
||||
// Your special code...
|
||||
}
|
||||
|
||||
void OnLoad()
|
||||
{
|
||||
IL2CPP::Initialize();
|
||||
|
||||
IL2CPP::Callback::Initialize();
|
||||
IL2CPP::Callback::OnUpdate::Add(OurUpdateFunction);
|
||||
}
|
||||
```
|
||||
|
||||
More: https://sneakyevil.gitbook.io/il2cpp-resolver/
|
||||
@@ -0,0 +1,32 @@
|
||||
#include "../../Includes.hpp"
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
SCameraFunctions CameraFunctions;
|
||||
|
||||
namespace Camera
|
||||
{
|
||||
void Initialize()
|
||||
{
|
||||
IL2CPP::SystemTypeCache::Initializer::Add(UNITY_CAMERA_CLASS);
|
||||
|
||||
CameraFunctions.m_pGetCurrent = IL2CPP::ResolveCall(UNITY_CAMERA_GETCURRENT);
|
||||
CameraFunctions.m_pGetMain = IL2CPP::ResolveCall(UNITY_CAMERA_GETMAIN);
|
||||
CameraFunctions.m_pGetDepth = IL2CPP::ResolveCall(UNITY_CAMERA_GETDEPTH);
|
||||
CameraFunctions.m_pSetDepth = IL2CPP::ResolveCall(UNITY_CAMERA_SETDEPTH);
|
||||
CameraFunctions.m_pGetFieldOfView = IL2CPP::ResolveCall(UNITY_CAMERA_GETFIELDOFVIEW);
|
||||
CameraFunctions.m_pSetFieldOfView = IL2CPP::ResolveCall(UNITY_CAMERA_SETFIELDOFVIEW);
|
||||
CameraFunctions.m_pWorldToScreen = IL2CPP::ResolveCall(UNITY_CAMERA_WORLDTOSCREEN);
|
||||
}
|
||||
|
||||
CCamera* GetCurrent()
|
||||
{
|
||||
return reinterpret_cast<CCamera*(UNITY_CALLING_CONVENTION)()>(CameraFunctions.m_pGetCurrent)();
|
||||
}
|
||||
|
||||
CCamera* GetMain()
|
||||
{
|
||||
return reinterpret_cast<CCamera*(UNITY_CALLING_CONVENTION)()>(CameraFunctions.m_pGetMain)();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
struct SCameraFunctions
|
||||
{
|
||||
void* m_pGetCurrent = nullptr;
|
||||
void* m_pGetMain = nullptr;
|
||||
void* m_pGetDepth = nullptr;
|
||||
void* m_pSetDepth = nullptr;
|
||||
void* m_pGetFieldOfView = nullptr;
|
||||
void* m_pSetFieldOfView = nullptr;
|
||||
void* m_pWorldToScreen = nullptr;
|
||||
};
|
||||
extern SCameraFunctions CameraFunctions;
|
||||
|
||||
class CCamera : public CGameObject
|
||||
{
|
||||
public:
|
||||
float GetDepth()
|
||||
{
|
||||
return reinterpret_cast<float(UNITY_CALLING_CONVENTION)(void*)>(CameraFunctions.m_pGetDepth)(this);
|
||||
}
|
||||
|
||||
void SetDepth(float m_fValue)
|
||||
{
|
||||
reinterpret_cast<void(UNITY_CALLING_CONVENTION)(void*, float)>(CameraFunctions.m_pSetDepth)(this, m_fValue);
|
||||
}
|
||||
|
||||
float GetFieldOfView()
|
||||
{
|
||||
return reinterpret_cast<float(UNITY_CALLING_CONVENTION)(void*)>(CameraFunctions.m_pGetFieldOfView)(this);
|
||||
}
|
||||
|
||||
void SetFieldOfView(float m_fValue)
|
||||
{
|
||||
reinterpret_cast<void(UNITY_CALLING_CONVENTION)(void*, float)>(CameraFunctions.m_pSetFieldOfView)(this, m_fValue);
|
||||
}
|
||||
|
||||
void WorldToScreen(Vector3& m_vWorld, Vector3& m_vScreen, int m_iEye = 2)
|
||||
{
|
||||
reinterpret_cast<void(UNITY_CALLING_CONVENTION)(void*, Vector3&, int, Vector3&)>(CameraFunctions.m_pWorldToScreen)(this, m_vWorld, m_iEye, m_vScreen);
|
||||
}
|
||||
};
|
||||
|
||||
namespace Camera
|
||||
{
|
||||
void Initialize();
|
||||
|
||||
CCamera* GetCurrent();
|
||||
|
||||
CCamera* GetMain();
|
||||
}
|
||||
|
||||
enum m_eCameraType : int
|
||||
{
|
||||
m_eCameraType_Game = 1,
|
||||
m_eCameraType_SceneView = 2,
|
||||
m_eCameraType_Preview = 4,
|
||||
m_eCameraType_VR = 8,
|
||||
m_eCameraType_Reflection = 16,
|
||||
};
|
||||
|
||||
enum m_eCameraEye : int
|
||||
{
|
||||
m_eCameraEye_Left = 0,
|
||||
m_eCameraEye_Right = 1,
|
||||
m_eCameraEye_Center = 2,
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#include "../../Includes.hpp"
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
SComponentFunctions ComponentFunctions;
|
||||
|
||||
namespace Component
|
||||
{
|
||||
void Initialize()
|
||||
{
|
||||
IL2CPP::SystemTypeCache::Initializer::Add(UNITY_COMPONENT_CLASS);
|
||||
|
||||
ComponentFunctions.m_pGetGameObject = IL2CPP::ResolveCall(UNITY_COMPONENT_GETGAMEOBJECT);
|
||||
ComponentFunctions.m_pGetTransform = IL2CPP::ResolveCall(UNITY_COMPONENT_GETTRANSFORM);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
struct SComponentFunctions
|
||||
{
|
||||
void* m_pGetGameObject = nullptr;
|
||||
void* m_pGetTransform = nullptr;
|
||||
};
|
||||
extern SComponentFunctions ComponentFunctions;
|
||||
|
||||
class CComponent : public CObject
|
||||
{
|
||||
public:
|
||||
CGameObject* GetGameObject()
|
||||
{
|
||||
return reinterpret_cast<CGameObject*(UNITY_CALLING_CONVENTION)(void*)>(ComponentFunctions.m_pGetGameObject)(this);
|
||||
}
|
||||
|
||||
CTransform* GetTransform()
|
||||
{
|
||||
return reinterpret_cast<CTransform*(UNITY_CALLING_CONVENTION)(void*)>(ComponentFunctions.m_pGetTransform)(this);
|
||||
}
|
||||
};
|
||||
|
||||
namespace Component
|
||||
{
|
||||
void Initialize();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#include "../../Includes.hpp"
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
SGameObjectFunctions GameObjectFunctions;
|
||||
|
||||
namespace GameObject
|
||||
{
|
||||
void Initialize()
|
||||
{
|
||||
IL2CPP::SystemTypeCache::Initializer::Add(UNITY_GAMEOBJECT_CLASS);
|
||||
|
||||
GameObjectFunctions.m_pAddComponent = IL2CPP::ResolveCall(UNITY_GAMEOBJECT_ADDCOMPONENT);
|
||||
GameObjectFunctions.m_pCreatePrimitive = IL2CPP::ResolveCall(UNITY_GAMEOBJECT_CREATEPRIMITIVE);
|
||||
GameObjectFunctions.m_pFind = IL2CPP::ResolveCall(UNITY_GAMEOBJECT_FIND);
|
||||
GameObjectFunctions.m_pFindGameObjectsWithTag = IL2CPP::ResolveCall(UNITY_GAMEOBJECT_FINDGAMEOBJECTWITHTAG);
|
||||
GameObjectFunctions.m_pGetComponent = IL2CPP::ResolveCall(UNITY_GAMEOBJECT_GETCOMPONENT);
|
||||
GameObjectFunctions.m_pGetComponents = IL2CPP::ResolveCall(UNITY_GAMEOBJECT_GETCOMPONENTS);
|
||||
GameObjectFunctions.m_pGetActive = IL2CPP::ResolveCall(UNITY_GAMEOBJECT_GETACTIVE);
|
||||
GameObjectFunctions.m_pGetLayer = IL2CPP::ResolveCall(UNITY_GAMEOBJECT_GETLAYER);
|
||||
GameObjectFunctions.m_pGetTransform = IL2CPP::ResolveCall(UNITY_GAMEOBJECT_GETTRANSFORM);
|
||||
GameObjectFunctions.m_pSetActive = IL2CPP::ResolveCall(UNITY_GAMEOBJECT_SETACTIVE);
|
||||
GameObjectFunctions.m_pSetLayer = IL2CPP::ResolveCall(UNITY_GAMEOBJECT_SETLAYER);
|
||||
}
|
||||
|
||||
CGameObject* CreatePrimitive(m_ePrimitiveType m_eType)
|
||||
{
|
||||
return reinterpret_cast<CGameObject*(UNITY_CALLING_CONVENTION)(m_ePrimitiveType)>(GameObjectFunctions.m_pCreatePrimitive)(m_eType);
|
||||
}
|
||||
|
||||
CGameObject* Find(const char* m_pName)
|
||||
{
|
||||
return reinterpret_cast<CGameObject*(UNITY_CALLING_CONVENTION)(System_String*)>(GameObjectFunctions.m_pFind)(IL2CPP::String::New(m_pName));
|
||||
}
|
||||
|
||||
il2cppArray<CGameObject*>* FindWithTag(const char* m_pTag)
|
||||
{
|
||||
return reinterpret_cast<il2cppArray<CGameObject*>*(UNITY_CALLING_CONVENTION)(void*)>(GameObjectFunctions.m_pFindGameObjectsWithTag)(IL2CPP::String::New(m_pTag));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
#pragma once
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
struct SGameObjectFunctions
|
||||
{
|
||||
void* m_pAddComponent = nullptr;
|
||||
void* m_pCreatePrimitive = nullptr;
|
||||
void* m_pFind = nullptr;
|
||||
void* m_pFindGameObjectsWithTag = nullptr;
|
||||
void* m_pGetComponent = nullptr;
|
||||
void* m_pGetComponents = nullptr;
|
||||
void* m_pGetActive = nullptr;
|
||||
void* m_pGetLayer = nullptr;
|
||||
void* m_pGetTransform = nullptr;
|
||||
void* m_pSetActive = nullptr;
|
||||
void* m_pSetLayer = nullptr;
|
||||
};
|
||||
extern SGameObjectFunctions GameObjectFunctions;
|
||||
|
||||
class CGameObject : public CObject
|
||||
{
|
||||
public:
|
||||
void AddComponent(il2cppObject* m_pSystemType)
|
||||
{
|
||||
reinterpret_cast<void(UNITY_CALLING_CONVENTION)(void*, void*)>(GameObjectFunctions.m_pAddComponent)(this, m_pSystemType);
|
||||
}
|
||||
|
||||
CComponent* GetComponent(const char* m_pName)
|
||||
{
|
||||
return reinterpret_cast<CComponent*(UNITY_CALLING_CONVENTION)(void*, System_String*)>(GameObjectFunctions.m_pGetComponent)(this, IL2CPP::String::New(m_pName));
|
||||
}
|
||||
|
||||
il2cppArray<CComponent*>* GetComponents(il2cppObject* m_pSystemType)
|
||||
{
|
||||
/*
|
||||
0 - Object
|
||||
1 - Type
|
||||
2 - Use search type as array return type
|
||||
3 - Recursive
|
||||
4 - Include inactive
|
||||
5 - Reverse
|
||||
6 - Result list
|
||||
*/
|
||||
return reinterpret_cast<Unity::il2cppArray<CComponent*>*(UNITY_CALLING_CONVENTION)(void*, void*, bool, bool, bool, bool, void*)>(GameObjectFunctions.m_pGetComponents)(this, m_pSystemType, false, false, true, false, nullptr);
|
||||
}
|
||||
|
||||
il2cppArray<CComponent*>* GetComponents(const char* m_pSystemTypeName)
|
||||
{
|
||||
il2cppClass* m_pClass = IL2CPP::Class::Find(m_pSystemTypeName);
|
||||
if (!m_pClass) return nullptr;
|
||||
|
||||
return GetComponents(IL2CPP::Class::GetSystemType(m_pClass));
|
||||
}
|
||||
|
||||
CComponent* GetComponentByIndex(il2cppObject* m_pSystemType, unsigned int m_uIndex = 0U)
|
||||
{
|
||||
il2cppArray<CComponent*>* m_pComponents = GetComponents(m_pSystemType);
|
||||
if (!m_pComponents || m_uIndex >= m_pComponents->m_uMaxLength) return nullptr;
|
||||
|
||||
return m_pComponents->operator[](m_uIndex);
|
||||
}
|
||||
|
||||
CComponent* GetComponentByIndex(const char* m_pSystemTypeName, unsigned int m_uIndex = 0U)
|
||||
{
|
||||
il2cppClass* m_pClass = IL2CPP::Class::Find(m_pSystemTypeName);
|
||||
if (!m_pClass) return nullptr;
|
||||
|
||||
return GetComponentByIndex(IL2CPP::Class::GetSystemType(m_pClass), m_uIndex);
|
||||
}
|
||||
|
||||
CTransform* GetTransform()
|
||||
{
|
||||
return reinterpret_cast<CTransform*(UNITY_CALLING_CONVENTION)(void*)>(GameObjectFunctions.m_pGetTransform)(this);
|
||||
}
|
||||
|
||||
bool GetActive()
|
||||
{
|
||||
return reinterpret_cast<bool(UNITY_CALLING_CONVENTION)(void*)>(GameObjectFunctions.m_pGetActive)(this);
|
||||
}
|
||||
|
||||
unsigned int GetLayer()
|
||||
{
|
||||
return reinterpret_cast<unsigned int(UNITY_CALLING_CONVENTION)(void*)>(GameObjectFunctions.m_pGetLayer)(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* (WARNING) when you use GameObject::Find and you set the object to unactive, you won't find it anymore with that slow function.
|
||||
*/
|
||||
void SetActive(bool m_bActive)
|
||||
{
|
||||
reinterpret_cast<void(UNITY_CALLING_CONVENTION)(void*, bool)>(GameObjectFunctions.m_pSetActive)(this, m_bActive);
|
||||
}
|
||||
|
||||
void SetLayer(unsigned int m_uLayer)
|
||||
{
|
||||
reinterpret_cast<void(UNITY_CALLING_CONVENTION)(void*, unsigned int)>(GameObjectFunctions.m_pSetLayer)(this, m_uLayer);
|
||||
}
|
||||
};
|
||||
|
||||
namespace GameObject
|
||||
{
|
||||
enum class m_ePrimitiveType : int
|
||||
{
|
||||
Default = 0,
|
||||
Sphere = 0,
|
||||
Capsule,
|
||||
Cylinder,
|
||||
Cube,
|
||||
Plane,
|
||||
Quad,
|
||||
};
|
||||
|
||||
void Initialize();
|
||||
|
||||
CGameObject* CreatePrimitive(m_ePrimitiveType m_eType);
|
||||
|
||||
CGameObject* Find(const char* m_pName);
|
||||
|
||||
il2cppArray<CGameObject*>* FindWithTag(const char* m_pTag);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#include "../../Includes.hpp"
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
SLayerMaskFunctions LayerMaskFunctions;
|
||||
|
||||
namespace LayerMask
|
||||
{
|
||||
void Initialize()
|
||||
{
|
||||
IL2CPP::SystemTypeCache::Initializer::Add(UNITY_LAYERMASK_CLASS);
|
||||
|
||||
LayerMaskFunctions.m_pLayerToName = IL2CPP::ResolveCall(UNITY_LAYERMASK_LAYERTONAME);
|
||||
LayerMaskFunctions.m_pNameToLayer = IL2CPP::ResolveCall(UNITY_LAYERMASK_NAMETOLAYER);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
struct SLayerMaskFunctions
|
||||
{
|
||||
void* m_pLayerToName = nullptr;
|
||||
void* m_pNameToLayer = nullptr;
|
||||
};
|
||||
extern SLayerMaskFunctions LayerMaskFunctions;
|
||||
|
||||
namespace LayerMask
|
||||
{
|
||||
void Initialize();
|
||||
|
||||
static System_String* LayerToName(unsigned int m_uLayer)
|
||||
{
|
||||
return reinterpret_cast<System_String*(UNITY_CALLING_CONVENTION)(unsigned int)>(LayerMaskFunctions.m_pLayerToName)(m_uLayer);
|
||||
}
|
||||
|
||||
static unsigned int NameToLayer(const char* m_pName)
|
||||
{
|
||||
return reinterpret_cast<unsigned int(UNITY_CALLING_CONVENTION)(void*)>(LayerMaskFunctions.m_pNameToLayer)(IL2CPP::String::New(m_pName));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#include "../../Includes.hpp"
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
SObjectFunctions ObjectFunctions;
|
||||
|
||||
namespace Object
|
||||
{
|
||||
void Initialize()
|
||||
{
|
||||
IL2CPP::SystemTypeCache::Initializer::Add(UNITY_OBJECT_CLASS);
|
||||
|
||||
ObjectFunctions.m_pDestroy = IL2CPP::ResolveCall(UNITY_OBJECT_DESTROY);
|
||||
ObjectFunctions.m_pFindObjectsOfType = IL2CPP::ResolveCall(UNITY_OBJECT_FINDOBJECTSOFTYPE);
|
||||
ObjectFunctions.m_pGetName = IL2CPP::ResolveCall(UNITY_OBJECT_GETNAME);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
struct SObjectFunctions
|
||||
{
|
||||
void* m_pDestroy = nullptr;
|
||||
void* m_pFindObjectsOfType = nullptr;
|
||||
void* m_pGetName = nullptr;
|
||||
};
|
||||
extern SObjectFunctions ObjectFunctions;
|
||||
|
||||
class CObject : public IL2CPP::CClass
|
||||
{
|
||||
public:
|
||||
void Destroy(float fTimeDelay = 0.f)
|
||||
{
|
||||
reinterpret_cast<void(UNITY_CALLING_CONVENTION)(void*, float)>(ObjectFunctions.m_pDestroy)(this, fTimeDelay);
|
||||
}
|
||||
|
||||
System_String* GetName()
|
||||
{
|
||||
return reinterpret_cast<System_String*(UNITY_CALLING_CONVENTION)(void*)>(ObjectFunctions.m_pGetName)(this);
|
||||
}
|
||||
};
|
||||
|
||||
namespace Object
|
||||
{
|
||||
void Initialize();
|
||||
|
||||
template<typename T>
|
||||
static il2cppArray<T*>* FindObjectsOfType(il2cppObject* m_pSystemType)
|
||||
{
|
||||
return reinterpret_cast<Unity::il2cppArray<T*>*(UNITY_CALLING_CONVENTION)(void*)>(ObjectFunctions.m_pFindObjectsOfType)(m_pSystemType);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static il2cppArray<T*>* FindObjectsOfType(const char* m_pSystemTypeName)
|
||||
{
|
||||
il2cppClass* m_pClass = IL2CPP::Class::Find(m_pSystemTypeName);
|
||||
if (!m_pClass) return nullptr;
|
||||
|
||||
return FindObjectsOfType<T>(IL2CPP::Class::GetSystemType(m_pClass));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static T* FindObjectOfType(il2cppObject* m_pSystemType)
|
||||
{
|
||||
il2cppArray<T*>* m_pArray = FindObjectsOfType<T>(m_pSystemType);
|
||||
if (!m_pArray || m_pArray->m_uMaxLength == 0U) return nullptr;
|
||||
|
||||
return m_pArray->m_pValues[0];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static T* FindObjectOfType(const char* m_pSystemTypeName)
|
||||
{
|
||||
il2cppClass* m_pClass = IL2CPP::Class::Find(m_pSystemTypeName);
|
||||
if (!m_pClass) return nullptr;
|
||||
|
||||
return FindObjectOfType<T>(IL2CPP::Class::GetSystemType(m_pClass));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
#include "../../Includes.hpp"
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
SRigidbodyFunctions RigidbodyFunctions;
|
||||
|
||||
namespace RigidBody
|
||||
{
|
||||
void Initialize()
|
||||
{
|
||||
IL2CPP::SystemTypeCache::Initializer::Add(UNITY_RIGIDBODY_CLASS);
|
||||
|
||||
RigidbodyFunctions.m_pGetDetectCollisions = IL2CPP::ResolveCall(UNITY_RIGIDBODY_GETDETECTCOLLISIONS);
|
||||
RigidbodyFunctions.m_pGetVelocity = IL2CPP::ResolveCall(UNITY_RIGIDBODY_GETVELOCITY);
|
||||
RigidbodyFunctions.m_pSetDetectCollisions = IL2CPP::ResolveCall(UNITY_RIGIDBODY_SETDETECTCOLLISIONS);
|
||||
RigidbodyFunctions.m_pSetVelocity = IL2CPP::ResolveCall(UNITY_RIGIDBODY_SETVELOCITY);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#pragma once
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
struct SRigidbodyFunctions
|
||||
{
|
||||
void* m_pGetDetectCollisions = nullptr;
|
||||
void* m_pGetVelocity = nullptr;
|
||||
void* m_pSetDetectCollisions = nullptr;
|
||||
void* m_pSetVelocity = nullptr;
|
||||
};
|
||||
extern SRigidbodyFunctions RigidbodyFunctions;
|
||||
|
||||
class CRigidbody : public IL2CPP::CClass
|
||||
{
|
||||
public:
|
||||
bool GetDetectCollisions()
|
||||
{
|
||||
return reinterpret_cast<bool(UNITY_CALLING_CONVENTION)(void*)>(RigidbodyFunctions.m_pGetDetectCollisions)(this);
|
||||
}
|
||||
|
||||
void SetDetectCollisions(bool m_bDetect)
|
||||
{
|
||||
reinterpret_cast<void(UNITY_CALLING_CONVENTION)(void*, bool)>(RigidbodyFunctions.m_pSetDetectCollisions)(this, m_bDetect);
|
||||
}
|
||||
|
||||
Vector3 GetVelocity()
|
||||
{
|
||||
Vector3 vRet;
|
||||
reinterpret_cast<void(UNITY_CALLING_CONVENTION)(void*, Vector3&)>(RigidbodyFunctions.m_pGetVelocity)(this, vRet);
|
||||
return vRet;
|
||||
}
|
||||
|
||||
void SetVelocity(Vector3 m_vVector)
|
||||
{
|
||||
reinterpret_cast<void(UNITY_CALLING_CONVENTION)(void*, Vector3)>(RigidbodyFunctions.m_pSetVelocity)(this, m_vVector);
|
||||
}
|
||||
};
|
||||
|
||||
namespace RigidBody
|
||||
{
|
||||
void Initialize();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#include "../../Includes.hpp"
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
STransformFunctions TransformFunctions;
|
||||
|
||||
namespace Transform
|
||||
{
|
||||
void Initialize()
|
||||
{
|
||||
IL2CPP::SystemTypeCache::Initializer::Add(UNITY_TRANSFORM_CLASS);
|
||||
|
||||
TransformFunctions.m_pGetParent = IL2CPP::ResolveCall(UNITY_TRANSFORM_GETPARENT);
|
||||
TransformFunctions.m_pGetRoot = IL2CPP::ResolveCall(UNITY_TRANSFORM_GETROOT);
|
||||
TransformFunctions.m_pGetChild = IL2CPP::ResolveCall(UNITY_TRANSFORM_GETCHILD);
|
||||
TransformFunctions.m_pGetChildCount = IL2CPP::ResolveCall(UNITY_TRANSFORM_GETCHILDCOUNT);
|
||||
TransformFunctions.m_pGetPosition = IL2CPP::ResolveCall(UNITY_TRANSFORM_GETPOSITION);
|
||||
TransformFunctions.m_pGetRotation = IL2CPP::ResolveCall(UNITY_TRANSFORM_GETROTATION);
|
||||
TransformFunctions.m_pGetLocalPosition = IL2CPP::ResolveCall(UNITY_TRANSFORM_GETLOCALPOSITION);
|
||||
TransformFunctions.m_pGetLocalScale = IL2CPP::ResolveCall(UNITY_TRANSFORM_GETLOCALSCALE);
|
||||
TransformFunctions.m_pSetPosition = IL2CPP::ResolveCall(UNITY_TRANSFORM_SETPOSITION);
|
||||
TransformFunctions.m_pSetRotation = IL2CPP::ResolveCall(UNITY_TRANSFORM_SETROTATION);
|
||||
TransformFunctions.m_pSetLocalPosition = IL2CPP::ResolveCall(UNITY_TRANSFORM_SETLOCALPOSITION);
|
||||
TransformFunctions.m_pSetLocalScale = IL2CPP::ResolveCall(UNITY_TRANSFORM_SETLOCALSCALE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
#pragma once
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
struct STransformFunctions
|
||||
{
|
||||
void* m_pGetParent = nullptr;
|
||||
void* m_pGetRoot = nullptr;
|
||||
void* m_pGetChild = nullptr;
|
||||
void* m_pGetChildCount = nullptr;
|
||||
void* m_pGetPosition = nullptr;
|
||||
void* m_pGetRotation = nullptr;
|
||||
void* m_pGetLocalPosition = nullptr;
|
||||
void* m_pGetLocalScale = nullptr;
|
||||
void* m_pSetPosition = nullptr;
|
||||
void* m_pSetRotation = nullptr;
|
||||
void* m_pSetLocalPosition = nullptr;
|
||||
void* m_pSetLocalScale = nullptr;
|
||||
};
|
||||
extern STransformFunctions TransformFunctions;
|
||||
|
||||
class CTransform : public IL2CPP::CClass
|
||||
{
|
||||
public:
|
||||
CTransform* GetParent()
|
||||
{
|
||||
return reinterpret_cast<CTransform*(UNITY_CALLING_CONVENTION)(void*)>(TransformFunctions.m_pGetParent)(this);
|
||||
}
|
||||
|
||||
CTransform* GetRoot()
|
||||
{
|
||||
return reinterpret_cast<CTransform*(UNITY_CALLING_CONVENTION)(void*)>(TransformFunctions.m_pGetRoot)(this);
|
||||
}
|
||||
|
||||
CTransform* GetChild(int m_iIndex)
|
||||
{
|
||||
return reinterpret_cast<CTransform*(UNITY_CALLING_CONVENTION)(void*, int)>(TransformFunctions.m_pGetChild)(this, m_iIndex);
|
||||
}
|
||||
|
||||
int GetChildCount()
|
||||
{
|
||||
return reinterpret_cast<int(UNITY_CALLING_CONVENTION)(void*)>(TransformFunctions.m_pGetChildCount)(this);
|
||||
}
|
||||
|
||||
Vector3 GetPosition()
|
||||
{
|
||||
Vector3 vRet;
|
||||
reinterpret_cast<void(UNITY_CALLING_CONVENTION)(void*, Vector3&)>(TransformFunctions.m_pGetPosition)(this, vRet);
|
||||
return vRet;
|
||||
}
|
||||
|
||||
Quaternion GetRotation()
|
||||
{
|
||||
Quaternion m_qRet;
|
||||
reinterpret_cast<void(UNITY_CALLING_CONVENTION)(void*, Quaternion&)>(TransformFunctions.m_pGetRotation)(this, m_qRet);
|
||||
return m_qRet;
|
||||
}
|
||||
|
||||
Vector3 GetLocalPosition()
|
||||
{
|
||||
Vector3 vRet;
|
||||
reinterpret_cast<void(UNITY_CALLING_CONVENTION)(void*, Vector3&)>(TransformFunctions.m_pGetLocalPosition)(this, vRet);
|
||||
return vRet;
|
||||
}
|
||||
|
||||
Vector3 GetLocalScale()
|
||||
{
|
||||
Vector3 vRet;
|
||||
reinterpret_cast<void(UNITY_CALLING_CONVENTION)(void*, Vector3&)>(TransformFunctions.m_pGetLocalScale)(this, vRet);
|
||||
return vRet;
|
||||
}
|
||||
|
||||
void SetPosition(Vector3 m_vVector)
|
||||
{
|
||||
reinterpret_cast<void(UNITY_CALLING_CONVENTION)(void*, Vector3)>(TransformFunctions.m_pSetPosition)(this, m_vVector);
|
||||
}
|
||||
|
||||
void SetRotation(Quaternion m_qQuat)
|
||||
{
|
||||
reinterpret_cast<void(UNITY_CALLING_CONVENTION)(void*, Quaternion)>(TransformFunctions.m_pSetRotation)(this, m_qQuat);
|
||||
}
|
||||
|
||||
void SetLocalPosition(Vector3 m_vVector)
|
||||
{
|
||||
reinterpret_cast<void(UNITY_CALLING_CONVENTION)(void*, Vector3)>(TransformFunctions.m_pSetLocalPosition)(this, m_vVector);
|
||||
}
|
||||
|
||||
void SetLocalScale(Vector3 m_vVector)
|
||||
{
|
||||
reinterpret_cast<void(UNITY_CALLING_CONVENTION)(void*, Vector3)>(TransformFunctions.m_pSetLocalScale)(this, m_vVector);
|
||||
}
|
||||
};
|
||||
|
||||
namespace Transform
|
||||
{
|
||||
void Initialize();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#include "../../Includes.hpp"
|
||||
// C+P Ready Template
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
S_TEMPLATEFunctions _TEMPLATEFunctions;
|
||||
|
||||
namespace _TEMPLATE
|
||||
{
|
||||
void Initialize()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
// C+P Ready Template
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
struct S_TEMPLATEFunctions
|
||||
{
|
||||
|
||||
};
|
||||
extern S_TEMPLATEFunctions _TEMPLATEFunctions;
|
||||
|
||||
class C_TEMPLATE : public IL2CPP::CClass
|
||||
{
|
||||
public:
|
||||
|
||||
};
|
||||
|
||||
namespace _TEMPLATE
|
||||
{
|
||||
void Initialize();
|
||||
}
|
||||
}
|
||||
110
DevourClient/Dependencies/IL2CPP_Resolver/Unity/Defines.hpp
Normal file
110
DevourClient/Dependencies/IL2CPP_Resolver/Unity/Defines.hpp
Normal file
@@ -0,0 +1,110 @@
|
||||
#pragma once
|
||||
// Calling Convention
|
||||
#define UNITY_CALLING_CONVENTION __fastcall*
|
||||
|
||||
// Camera
|
||||
#define UNITY_CAMERA_CLASS "UnityEngine.Camera"
|
||||
#define UNITY_CAMERA_GETCURRENT UNITY_CAMERA_CLASS"::get_current"
|
||||
#define UNITY_CAMERA_GETMAIN UNITY_CAMERA_CLASS"::get_main"
|
||||
#define UNITY_CAMERA_GETDEPTH UNITY_CAMERA_CLASS"::get_depth"
|
||||
#define UNITY_CAMERA_SETDEPTH UNITY_CAMERA_CLASS"::set_depth"
|
||||
#define UNITY_CAMERA_GETFIELDOFVIEW UNITY_CAMERA_CLASS"::get_fieldOfView"
|
||||
#define UNITY_CAMERA_SETFIELDOFVIEW UNITY_CAMERA_CLASS"::set_fieldOfView"
|
||||
#define UNITY_CAMERA_WORLDTOSCREEN UNITY_CAMERA_CLASS"::WorldToScreenPoint_Injected"
|
||||
|
||||
// Component
|
||||
#define UNITY_COMPONENT_CLASS "UnityEngine.Component"
|
||||
#define UNITY_COMPONENT_GETGAMEOBJECT UNITY_COMPONENT_CLASS"::get_gameObject"
|
||||
#define UNITY_COMPONENT_GETTRANSFORM UNITY_COMPONENT_CLASS"::get_transform"
|
||||
|
||||
// GameObject
|
||||
#define UNITY_GAMEOBJECT_CLASS "UnityEngine.GameObject"
|
||||
#define UNITY_GAMEOBJECT_ADDCOMPONENT UNITY_GAMEOBJECT_CLASS"::Internal_AddComponentWithType"
|
||||
#define UNITY_GAMEOBJECT_CREATEPRIMITIVE UNITY_GAMEOBJECT_CLASS"::CreatePrimitive"
|
||||
#define UNITY_GAMEOBJECT_FIND UNITY_GAMEOBJECT_CLASS"::Find"
|
||||
#define UNITY_GAMEOBJECT_GETCOMPONENT UNITY_GAMEOBJECT_CLASS"::GetComponentByName"
|
||||
#define UNITY_GAMEOBJECT_GETCOMPONENTS UNITY_GAMEOBJECT_CLASS"::GetComponentsInternal"
|
||||
#define UNITY_GAMEOBJECT_GETACTIVE UNITY_GAMEOBJECT_CLASS"::get_active"
|
||||
#define UNITY_GAMEOBJECT_GETLAYER UNITY_GAMEOBJECT_CLASS"::get_layer"
|
||||
#define UNITY_GAMEOBJECT_GETTRANSFORM UNITY_GAMEOBJECT_CLASS"::get_transform"
|
||||
#define UNITY_GAMEOBJECT_SETACTIVE UNITY_GAMEOBJECT_CLASS"::set_active"
|
||||
#define UNITY_GAMEOBJECT_SETLAYER UNITY_GAMEOBJECT_CLASS"::set_layer"
|
||||
#define UNITY_GAMEOBJECT_FINDGAMEOBJECTWITHTAG UNITY_GAMEOBJECT_CLASS"::FindGameObjectsWithTag"
|
||||
|
||||
// LayerMask
|
||||
#define UNITY_LAYERMASK_CLASS "UnityEngine.LayerMask"
|
||||
#define UNITY_LAYERMASK_LAYERTONAME UNITY_LAYERMASK_CLASS"::LayerToName"
|
||||
#define UNITY_LAYERMASK_NAMETOLAYER UNITY_LAYERMASK_CLASS"::NameToLayer"
|
||||
|
||||
// MonoBehaviour
|
||||
#define UNITY_MONOBEHAVIOUR_CLASS "UnityEngine.MonoBehaviour"
|
||||
|
||||
// Object
|
||||
#define UNITY_OBJECT_CLASS "UnityEngine.Object"
|
||||
#define UNITY_OBJECT_DESTROY UNITY_OBJECT_CLASS"::Destroy"
|
||||
#define UNITY_OBJECT_FINDOBJECTSOFTYPE UNITY_OBJECT_CLASS"::FindObjectsOfType"
|
||||
#define UNITY_OBJECT_GETNAME UNITY_OBJECT_CLASS"::GetName"
|
||||
|
||||
// Rigidbody
|
||||
#define UNITY_RIGIDBODY_CLASS "UnityEngine.Rigidbody"
|
||||
#define UNITY_RIGIDBODY_GETDETECTCOLLISIONS UNITY_RIGIDBODY_CLASS"::get_detectCollisions"
|
||||
#define UNITY_RIGIDBODY_GETVELOCITY UNITY_RIGIDBODY_CLASS"::get_velocity_Injected"
|
||||
#define UNITY_RIGIDBODY_SETDETECTCOLLISIONS UNITY_RIGIDBODY_CLASS"::set_detectCollisions"
|
||||
#define UNITY_RIGIDBODY_SETVELOCITY UNITY_RIGIDBODY_CLASS"::set_velocity_Injected"
|
||||
|
||||
// Transform
|
||||
#define UNITY_TRANSFORM_CLASS "UnityEngine.Transform"
|
||||
#define UNITY_TRANSFORM_GETPARENT UNITY_TRANSFORM_CLASS"::GetParent"
|
||||
#define UNITY_TRANSFORM_GETROOT UNITY_TRANSFORM_CLASS"::GetRoot"
|
||||
#define UNITY_TRANSFORM_GETCHILD UNITY_TRANSFORM_CLASS"::GetChild"
|
||||
#define UNITY_TRANSFORM_GETCHILDCOUNT UNITY_TRANSFORM_CLASS"::get_childCount"
|
||||
#define UNITY_TRANSFORM_GETPOSITION UNITY_TRANSFORM_CLASS"::get_position_Injected"
|
||||
#define UNITY_TRANSFORM_GETROTATION UNITY_TRANSFORM_CLASS"::get_rotation_Injected"
|
||||
#define UNITY_TRANSFORM_GETLOCALPOSITION UNITY_TRANSFORM_CLASS"::get_localPosition_Injected"
|
||||
#define UNITY_TRANSFORM_GETLOCALSCALE UNITY_TRANSFORM_CLASS"::get_localScale_Injected"
|
||||
#define UNITY_TRANSFORM_SETPOSITION UNITY_TRANSFORM_CLASS"::set_position_Injected"
|
||||
#define UNITY_TRANSFORM_SETROTATION UNITY_TRANSFORM_CLASS"::set_rotation_Injected"
|
||||
#define UNITY_TRANSFORM_SETLOCALPOSITION UNITY_TRANSFORM_CLASS"::set_localPosition_Injected"
|
||||
#define UNITY_TRANSFORM_SETLOCALSCALE UNITY_TRANSFORM_CLASS"::set_localScale_Injected"
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
enum m_eTypeEnum
|
||||
{
|
||||
Type_Void = 1,
|
||||
Type_Boolean = 2,
|
||||
Type_Character = 3,
|
||||
Type_Integer = 8,
|
||||
Type_Float = 12,
|
||||
Type_String = 14,
|
||||
Type_Pointer = 15,
|
||||
Type_ValueType = 17,
|
||||
Type_Class = 18,
|
||||
Type_Variable = 19,
|
||||
Type_Array = 20,
|
||||
Type_Enum = 85,
|
||||
};
|
||||
|
||||
enum m_eFieldAttribute
|
||||
{
|
||||
FieldAttribute_Compiler,
|
||||
FieldAttribute_Private,
|
||||
FieldAttribute_FamilyAndAssembly,
|
||||
FieldAttribute_Assembly,
|
||||
FieldAttribute_Family,
|
||||
FieldAttribute_FamilyOrAssembly,
|
||||
FieldAttribute_Public,
|
||||
FieldAttribute_AccessMask,
|
||||
FieldAttribute_Static = 16,
|
||||
FieldAttribute_InitOnly = 32,
|
||||
FieldAttribute_Literal = 64,
|
||||
FieldAttribute_NotSerialized = 128,
|
||||
FieldAttribute_HasRVA = 256,
|
||||
FieldAttribute_SpecialName = 512,
|
||||
FieldAttribute_RTSpecialName = 1024,
|
||||
FieldAttribute_HasMarshal = 4096,
|
||||
FieldAttribute_InvokeImpl = 8192,
|
||||
FieldAttribute_Default = 32768,
|
||||
FieldAttribute_Reserved = 38144,
|
||||
};
|
||||
}
|
||||
17
DevourClient/Dependencies/IL2CPP_Resolver/Unity/Includes.hpp
Normal file
17
DevourClient/Dependencies/IL2CPP_Resolver/Unity/Includes.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include "Defines.hpp"
|
||||
#include "Obfuscators.hpp"
|
||||
|
||||
// Structures
|
||||
#include "Structures/Includes.hpp"
|
||||
|
||||
// Class APIs - So they're accessible everywhere
|
||||
namespace Unity
|
||||
{
|
||||
class CCamera;
|
||||
class CComponent;
|
||||
class CGameObject;
|
||||
class CObject;
|
||||
class CRigidbody;
|
||||
class CTransform;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#include "../Includes.hpp"
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
namespace Obfuscators
|
||||
{
|
||||
// Should do the basic work
|
||||
std::string ROT_String(const char* pString, int iValue)
|
||||
{
|
||||
std::string sRet;
|
||||
size_t sSize = strlen(pString);
|
||||
for (size_t i = 0; sSize > i; ++i)
|
||||
{
|
||||
bool bIsUppercase = pString[i] >= 'A' && 'Z' >= pString[i];
|
||||
bool bIsLowercase = !bIsUppercase && pString[i] >= 'a' && 'z' >= pString[i];
|
||||
if (!bIsUppercase && !bIsLowercase)
|
||||
{
|
||||
sRet += pString[i];
|
||||
continue;
|
||||
}
|
||||
|
||||
int iNewValue = static_cast<int>(pString[i]) + iValue;
|
||||
if (bIsUppercase)
|
||||
{
|
||||
int iMaxValue = static_cast<int>('Z');
|
||||
while (iNewValue > iMaxValue) iNewValue = static_cast<int>('A') + (iNewValue - iMaxValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
int iMaxValue = static_cast<int>('z');
|
||||
while (iNewValue > iMaxValue) iNewValue = static_cast<int>('a') + (iNewValue - iMaxValue);
|
||||
}
|
||||
|
||||
sRet += static_cast<char>(iNewValue);
|
||||
}
|
||||
|
||||
sRet += '\0';
|
||||
return sRet;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
namespace Obfuscators
|
||||
{
|
||||
std::string ROT_String(const char* pString, int iValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
#pragma once
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
struct Vector2
|
||||
{
|
||||
float x, y;
|
||||
|
||||
Vector2() { x = y = 0.f; }
|
||||
Vector2(float f1, float f2) { x = f1; y = f2; }
|
||||
};
|
||||
|
||||
struct Vector3
|
||||
{
|
||||
float x, y, z;
|
||||
|
||||
Vector3() { x = y = z = 0.f; }
|
||||
Vector3(float f1, float f2, float f3) { x = f1; y = f2; z = f3; }
|
||||
|
||||
void ToVectors(Vector3* m_pForward, Vector3* m_pRight, Vector3* m_pUp)
|
||||
{
|
||||
float m_fDeg2Rad = static_cast<float>(M_PI) / 180.f;
|
||||
|
||||
float m_fSinX = sinf(x * m_fDeg2Rad);
|
||||
float m_fCosX = cosf(x * m_fDeg2Rad);
|
||||
|
||||
float m_fSinY = sinf(y * m_fDeg2Rad);
|
||||
float m_fCosY = cosf(y * m_fDeg2Rad);
|
||||
|
||||
float m_fSinZ = sinf(z * m_fDeg2Rad);
|
||||
float m_fCosZ = cosf(z * m_fDeg2Rad);
|
||||
|
||||
if (m_pForward)
|
||||
{
|
||||
m_pForward->x = m_fCosX * m_fCosY;
|
||||
m_pForward->y = -m_fSinX;
|
||||
m_pForward->z = m_fCosX * m_fSinY;
|
||||
}
|
||||
|
||||
if (m_pRight)
|
||||
{
|
||||
m_pRight->x = -1.f * m_fSinZ * m_fSinX * m_fCosY + -1.f * m_fCosZ * -m_fSinY;
|
||||
m_pRight->y = -1.f * m_fSinZ * m_fCosX;
|
||||
m_pRight->z = -1.f * m_fSinZ * m_fSinX * m_fSinY + -1.f * m_fCosZ * m_fCosY;
|
||||
}
|
||||
|
||||
if (m_pUp)
|
||||
{
|
||||
m_pUp->x = m_fCosZ * m_fSinX * m_fCosY + -m_fSinZ * -m_fSinY;
|
||||
m_pUp->y = m_fCosZ * m_fCosX;
|
||||
m_pUp->z = m_fCosZ * m_fSinX * m_fSinY + -m_fSinZ * m_fCosY;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Vector4
|
||||
{
|
||||
float x, y, z, w;
|
||||
|
||||
Vector4() { x = y = z = w = 0.f; }
|
||||
Vector4(float f1, float f2, float f3, float f4) { x = f1; y = f2; z = f3; w = f4; }
|
||||
};
|
||||
|
||||
struct Quaternion
|
||||
{
|
||||
float x, y, z, w;
|
||||
|
||||
Quaternion() { x = y = z = w = 0.f; }
|
||||
Quaternion(float f1, float f2, float f3, float f4) { x = f1; y = f2; z = f3; w = f4; }
|
||||
|
||||
Quaternion Euler(float m_fX, float m_fY, float m_fZ)
|
||||
{
|
||||
float m_fDeg2Rad = static_cast<float>(M_PI) / 180.f;
|
||||
|
||||
m_fX = m_fX * m_fDeg2Rad * 0.5f;
|
||||
m_fY = m_fY * m_fDeg2Rad * 0.5f;
|
||||
m_fZ = m_fZ * m_fDeg2Rad * 0.5f;
|
||||
|
||||
float m_fSinX = sinf(m_fX);
|
||||
float m_fCosX = cosf(m_fX);
|
||||
|
||||
float m_fSinY = sinf(m_fY);
|
||||
float m_fCosY = cosf(m_fY);
|
||||
|
||||
float m_fSinZ = sinf(m_fZ);
|
||||
float m_fCosZ = cosf(m_fZ);
|
||||
|
||||
x = m_fCosY * m_fSinX * m_fCosZ + m_fSinY * m_fCosX * m_fSinZ;
|
||||
y = m_fSinY * m_fCosX * m_fCosZ - m_fCosY * m_fSinX * m_fSinZ;
|
||||
z = m_fCosY * m_fCosX * m_fSinZ - m_fSinY * m_fSinX * m_fCosZ;
|
||||
w = m_fCosY * m_fCosX * m_fCosZ + m_fSinY * m_fSinX * m_fSinZ;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Quaternion Euler(Vector3 m_vRot)
|
||||
{
|
||||
return Euler(m_vRot.x, m_vRot.y, m_vRot.z);
|
||||
}
|
||||
|
||||
Vector3 ToEuler()
|
||||
{
|
||||
Vector3 m_vEuler;
|
||||
|
||||
float m_fDist = (x * x) + (y * y) + (z * z) + (w * w);
|
||||
|
||||
float m_fTest = x * w - y * z;
|
||||
if (m_fTest > 0.4995f * m_fDist)
|
||||
{
|
||||
m_vEuler.x = static_cast<float>(M_PI) * 0.5f;
|
||||
m_vEuler.y = 2.f * atan2f(y, x);
|
||||
m_vEuler.z = 0.f;
|
||||
}
|
||||
else if (m_fTest < -0.4995f * m_fDist)
|
||||
{
|
||||
m_vEuler.x = static_cast<float>(M_PI) * -0.5f;
|
||||
m_vEuler.y = -2.f * atan2f(y, x);
|
||||
m_vEuler.z = 0.f;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_vEuler.x = asinf(2.f * (w * x - y * z));
|
||||
m_vEuler.y = atan2f(2.f * w * y + 2.f * z * x, 1.f - 2.f * (x * x + y * y));
|
||||
m_vEuler.z = atan2f(2.f * w * z + 2.f * x * y, 1.f - 2.f * (z * z + x * x));
|
||||
}
|
||||
|
||||
float m_fRad2Deg = 180.f / static_cast<float>(M_PI);
|
||||
m_vEuler.x *= m_fRad2Deg;
|
||||
m_vEuler.y *= m_fRad2Deg;
|
||||
m_vEuler.z *= m_fRad2Deg;
|
||||
|
||||
return m_vEuler;
|
||||
}
|
||||
};
|
||||
|
||||
struct Bounds
|
||||
{
|
||||
Vector3 m_vCenter;
|
||||
Vector3 m_vExtents;
|
||||
};
|
||||
|
||||
struct Plane
|
||||
{
|
||||
Vector3 m_vNormal;
|
||||
float fDistance;
|
||||
};
|
||||
|
||||
struct Ray
|
||||
{
|
||||
Vector3 m_vOrigin;
|
||||
Vector3 m_vDirection;
|
||||
};
|
||||
|
||||
struct Rect
|
||||
{
|
||||
float fX, fY;
|
||||
float fWidth, fHeight;
|
||||
|
||||
Rect() { fX = fY = fWidth = fHeight = 0.f; }
|
||||
Rect(float f1, float f2, float f3, float f4) { fX = f1; fY = f2; fWidth = f3; fHeight = f4; }
|
||||
};
|
||||
|
||||
struct Color
|
||||
{
|
||||
float r, g, b, a;
|
||||
|
||||
Color() { r = g = b = a = 0.f; }
|
||||
Color(float fRed = 0.f, float fGreen = 0.f, float fBlue = 0.f, float fAlpha = 1.f) { r = fRed; g = fGreen; b = fBlue; a = fAlpha; }
|
||||
};
|
||||
|
||||
struct Matrix4x4
|
||||
{
|
||||
float m[4][4] = { 0 };
|
||||
|
||||
Matrix4x4() { }
|
||||
|
||||
float* operator[](int i) { return m[i]; }
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
#include "il2cpp.hpp"
|
||||
#include "il2cppArray.hpp"
|
||||
#include "il2cppDictionary.hpp"
|
||||
|
||||
#include "Engine.hpp"
|
||||
#include "System_String.hpp"
|
||||
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
struct System_String : il2cppObject
|
||||
{
|
||||
int m_iLength;
|
||||
wchar_t m_wString[1024];
|
||||
|
||||
void Clear()
|
||||
{
|
||||
if (!this) return;
|
||||
|
||||
memset(m_wString, 0, static_cast<size_t>(m_iLength) * 2);
|
||||
m_iLength = 0;
|
||||
}
|
||||
|
||||
std::string ToString()
|
||||
{
|
||||
if (!this) return "";
|
||||
|
||||
std::string sRet(static_cast<size_t>(m_iLength) + 1, '\0');
|
||||
WideCharToMultiByte(CP_UTF8, 0, m_wString, m_iLength, &sRet[0], m_iLength, 0, 0);
|
||||
return sRet;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
#pragma once
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
struct il2cppImage
|
||||
{
|
||||
const char* m_pName;
|
||||
const char* m_pNameNoExt;
|
||||
};
|
||||
|
||||
struct il2cppAssemblyName
|
||||
{
|
||||
const char* m_pName;
|
||||
const char* m_pCulture;
|
||||
const char* m_pHash;
|
||||
const char* m_pPublicKey;
|
||||
unsigned int m_uHash;
|
||||
int m_iHashLength;
|
||||
unsigned int m_uFlags;
|
||||
int m_iMajor;
|
||||
int m_iMinor;
|
||||
int m_iBuild;
|
||||
int m_bRevision;
|
||||
unsigned char m_uPublicKeyToken[8];
|
||||
};
|
||||
|
||||
struct il2cppAssembly
|
||||
{
|
||||
il2cppImage* m_pImage;
|
||||
unsigned int m_uToken;
|
||||
int m_ReferencedAssemblyStart;
|
||||
int m_ReferencedAssemblyCount;
|
||||
il2cppAssemblyName m_aName;
|
||||
};
|
||||
|
||||
struct il2cppClass
|
||||
{
|
||||
void* m_pImage;
|
||||
void* m_pGC;
|
||||
const char* m_pName;
|
||||
const char* m_pNamespace;
|
||||
void* m_pValue;
|
||||
void* m_pArgs;
|
||||
il2cppClass* m_pElementClass;
|
||||
il2cppClass* m_pCastClass;
|
||||
il2cppClass* m_pDeclareClass;
|
||||
il2cppClass* m_pParentClass;
|
||||
void* m_pGenericClass;
|
||||
void* m_pTypeDefinition;
|
||||
void* m_pInteropData;
|
||||
void* m_pFields;
|
||||
void* m_pEvents;
|
||||
void* m_pProperties;
|
||||
void** m_pMethods;
|
||||
il2cppClass** m_pNestedTypes;
|
||||
il2cppClass** m_ImplementedInterfaces;
|
||||
void* m_pInterfaceOffsets;
|
||||
void* m_pStaticFields;
|
||||
void* m_pRGCTX;
|
||||
};
|
||||
|
||||
struct il2cppObject
|
||||
{
|
||||
il2cppClass* m_pClass = nullptr;
|
||||
void* m_pMonitor = nullptr;
|
||||
};
|
||||
|
||||
struct il2cppType
|
||||
{
|
||||
union
|
||||
{
|
||||
void* m_pDummy;
|
||||
unsigned int m_uClassIndex;
|
||||
il2cppType* m_pType;
|
||||
void* m_pArray;
|
||||
unsigned int m_uGenericParameterIndex;
|
||||
void* m_pGenericClass;
|
||||
};
|
||||
unsigned int m_uAttributes : 16;
|
||||
unsigned int m_uType : 8;
|
||||
unsigned int m_uMods : 6;
|
||||
unsigned int m_uByref : 1;
|
||||
unsigned int m_uPinned : 1;
|
||||
};
|
||||
|
||||
struct il2cppFieldInfo
|
||||
{
|
||||
const char* m_pName;
|
||||
il2cppType* m_pType;
|
||||
il2cppClass* m_pParentClass;
|
||||
int m_iOffset;
|
||||
int m_iAttributeIndex;
|
||||
unsigned int m_uToken;
|
||||
};
|
||||
|
||||
struct il2cppParameterInfo
|
||||
{
|
||||
const char* m_pName;
|
||||
int m_iPosition;
|
||||
unsigned int m_uToken;
|
||||
il2cppType* m_pParameterType;
|
||||
};
|
||||
|
||||
struct il2cppMethodInfo
|
||||
{
|
||||
void* m_pMethodPointer;
|
||||
void* m_pInvokerMethod;
|
||||
const char* m_pName;
|
||||
il2cppClass* m_pClass;
|
||||
il2cppType* m_pReturnType;
|
||||
il2cppParameterInfo* m_pParameters;
|
||||
|
||||
union
|
||||
{
|
||||
void* m_pRGCTX;
|
||||
void* m_pMethodDefinition;
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
void* m_pGenericMethod;
|
||||
void* m_pGenericContainer;
|
||||
};
|
||||
|
||||
unsigned int m_uToken;
|
||||
unsigned short m_uFlags;
|
||||
unsigned short m_uFlags2;
|
||||
unsigned short m_uSlot;
|
||||
unsigned char m_uArgsCount;
|
||||
unsigned char m_uGeneric : 1;
|
||||
unsigned char m_uInflated : 1;
|
||||
unsigned char m_uWrapperType : 1;
|
||||
unsigned char m_uMarshaledFromNative : 1;
|
||||
};
|
||||
|
||||
struct il2cppPropertyInfo
|
||||
{
|
||||
il2cppClass* m_pParentClass;
|
||||
const char* m_pName;
|
||||
il2cppMethodInfo* m_pGet;
|
||||
il2cppMethodInfo* m_pSet;
|
||||
unsigned int m_uAttributes;
|
||||
unsigned int m_uToken;
|
||||
};
|
||||
|
||||
struct il2cppArrayBounds
|
||||
{
|
||||
uintptr_t m_uLength;
|
||||
int m_iLowerBound;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
#pragma once
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
template<typename T>
|
||||
struct il2cppArray : il2cppObject
|
||||
{
|
||||
il2cppArrayBounds* m_pBounds = nullptr;
|
||||
uintptr_t m_uMaxLength = 0;
|
||||
T* m_pValues = nullptr;
|
||||
|
||||
uintptr_t GetData()
|
||||
{
|
||||
return reinterpret_cast<uintptr_t>(&m_pValues);
|
||||
}
|
||||
|
||||
T& operator[](unsigned int m_uIndex)
|
||||
{
|
||||
return *reinterpret_cast<T*>(GetData() + sizeof(T) * m_uIndex);
|
||||
}
|
||||
|
||||
T& At(unsigned int m_uIndex)
|
||||
{
|
||||
return operator[](m_uIndex);
|
||||
}
|
||||
|
||||
void Insert(T* m_pArray, uintptr_t m_uSize, uintptr_t m_uIndex = 0)
|
||||
{
|
||||
if ((m_uSize + m_uIndex) >= m_uMaxLength)
|
||||
{
|
||||
if (m_uIndex >= m_uMaxLength)
|
||||
return;
|
||||
|
||||
m_uSize = m_uMaxLength - m_uIndex;
|
||||
}
|
||||
|
||||
for (uintptr_t u = 0; m_uSize > u; ++u)
|
||||
operator[](u + m_uIndex) = m_pArray[u];
|
||||
}
|
||||
|
||||
void Fill(T m_tValue)
|
||||
{
|
||||
for (uintptr_t u = 0; m_uMaxLength > u; ++u)
|
||||
operator[](u) = m_tValue;
|
||||
}
|
||||
|
||||
void RemoveAt(unsigned int m_uIndex)
|
||||
{
|
||||
if (m_uIndex >= m_uMaxLength)
|
||||
return;
|
||||
|
||||
if (m_uMaxLength > (m_uIndex + 1))
|
||||
{
|
||||
for (unsigned int u = m_uIndex; (static_cast<unsigned int>(m_uMaxLength) - m_uIndex) > u; ++u)
|
||||
operator[](u) = operator[](u + 1);
|
||||
}
|
||||
|
||||
--m_uMaxLength;
|
||||
}
|
||||
|
||||
void RemoveRange(unsigned int m_uIndex, unsigned int m_uCount)
|
||||
{
|
||||
if (m_uCount == 0)
|
||||
m_uCount = 1;
|
||||
|
||||
unsigned int m_uTotal = m_uIndex + m_uCount;
|
||||
if (m_uTotal >= m_uMaxLength)
|
||||
return;
|
||||
|
||||
if (m_uMaxLength > (m_uTotal + 1))
|
||||
{
|
||||
for (unsigned int u = m_uIndex; (static_cast<unsigned int>(m_uMaxLength) - m_uTotal) >= u; ++u)
|
||||
operator[](u) = operator[](u + m_uCount);
|
||||
}
|
||||
|
||||
m_uMaxLength -= m_uCount;
|
||||
}
|
||||
|
||||
void RemoveAll()
|
||||
{
|
||||
if (m_uMaxLength > 0)
|
||||
{
|
||||
memset(GetData(), 0, sizeof(T) * m_uMaxLength);
|
||||
m_uMaxLength = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Defined here because its basically same shit
|
||||
template<typename T>
|
||||
struct il2cppList : il2cppObject
|
||||
{
|
||||
il2cppArray<T>* m_pListArray;
|
||||
|
||||
il2cppArray<T>* ToArray() { return m_pListArray; }
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
namespace Unity
|
||||
{
|
||||
// Don't use! Untested
|
||||
template<typename T>
|
||||
struct il2cppDictionary : il2cppObject
|
||||
{
|
||||
il2cppArray<int>* m_pBuckets;
|
||||
il2cppArray<T>* m_pEntries;
|
||||
int m_iCount;
|
||||
int m_iVersion;
|
||||
int m_iFreeList;
|
||||
int m_iFreeCount;
|
||||
void* m_pComparer;
|
||||
void* m_pKeys;
|
||||
void* m_pValues;
|
||||
};
|
||||
}
|
||||
23
DevourClient/Dependencies/IL2CPP_Resolver/Utils/Helper.cpp
Normal file
23
DevourClient/Dependencies/IL2CPP_Resolver/Utils/Helper.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "../Includes.hpp"
|
||||
|
||||
namespace IL2CPP
|
||||
{
|
||||
namespace Helper
|
||||
{
|
||||
Unity::CComponent* GetMonoBehaviour()
|
||||
{
|
||||
Unity::il2cppArray<Unity::CGameObject*>* m_pObjects = Unity::Object::FindObjectsOfType<Unity::CGameObject>(UNITY_GAMEOBJECT_CLASS);
|
||||
for (uintptr_t u = 0U; m_pObjects->m_uMaxLength > u; ++u)
|
||||
{
|
||||
Unity::CGameObject* m_pObject = m_pObjects->operator[](static_cast<unsigned int>(u));
|
||||
if (!m_pObject) continue;
|
||||
|
||||
Unity::CComponent* m_pMonoBehaviour = m_pObject->GetComponentByIndex(UNITY_MONOBEHAVIOUR_CLASS);
|
||||
if (m_pMonoBehaviour)
|
||||
return m_pMonoBehaviour;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
namespace IL2CPP
|
||||
{
|
||||
namespace Helper
|
||||
{
|
||||
Unity::CComponent* GetMonoBehaviour();
|
||||
}
|
||||
}
|
||||
43
DevourClient/Dependencies/IL2CPP_Resolver/Utils/Joaat.hpp
Normal file
43
DevourClient/Dependencies/IL2CPP_Resolver/Utils/Joaat.hpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
|
||||
namespace IL2CPP
|
||||
{
|
||||
namespace Utils
|
||||
{
|
||||
inline unsigned int JOAAT(const char* str)
|
||||
{
|
||||
unsigned int m_uHash = 0;
|
||||
|
||||
while (*str)
|
||||
{
|
||||
m_uHash += *(str++);
|
||||
m_uHash += (m_uHash << 10);
|
||||
m_uHash ^= (m_uHash >> 6);
|
||||
}
|
||||
|
||||
m_uHash += (m_uHash << 3);
|
||||
m_uHash ^= (m_uHash >> 11);
|
||||
m_uHash += (m_uHash << 15);
|
||||
|
||||
return m_uHash;
|
||||
}
|
||||
|
||||
inline constexpr unsigned int JOAAT_CONSTEXPR(const char* str)
|
||||
{
|
||||
unsigned int m_uHash = 0;
|
||||
|
||||
while (*str)
|
||||
{
|
||||
m_uHash += *(str++);
|
||||
m_uHash += (m_uHash << 10);
|
||||
m_uHash ^= (m_uHash >> 6);
|
||||
}
|
||||
|
||||
m_uHash += (m_uHash << 3);
|
||||
m_uHash ^= (m_uHash >> 11);
|
||||
m_uHash += (m_uHash << 15);
|
||||
|
||||
return m_uHash;
|
||||
}
|
||||
}
|
||||
}
|
||||
31
DevourClient/Dependencies/IL2CPP_Resolver/Utils/VFunc.hpp
Normal file
31
DevourClient/Dependencies/IL2CPP_Resolver/Utils/VFunc.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
namespace VFunc
|
||||
{
|
||||
static void** Find_ASM(void** m_pVTable, int m_iCount, std::initializer_list<unsigned char> m_lASM)
|
||||
{
|
||||
int m_iASMSize = static_cast<int>(m_lASM.size());
|
||||
unsigned char* m_pBytes = const_cast<unsigned char*>(m_lASM.begin());
|
||||
|
||||
for (int i = 0; m_iCount > i; ++i)
|
||||
{
|
||||
void* m_pVFunc = m_pVTable[i];
|
||||
unsigned char* m_pVFuncBytes = reinterpret_cast<unsigned char*>(m_pVFunc);
|
||||
|
||||
bool m_bAllMatch = true;
|
||||
for (int b = 0; m_iASMSize > b; ++b)
|
||||
{
|
||||
if (m_pBytes[b] != m_pVFuncBytes[b])
|
||||
{
|
||||
m_bAllMatch = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_bAllMatch)
|
||||
return &m_pVTable[i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
125
DevourClient/Dependencies/IL2CPP_Resolver/il2cpp_resolver.cpp
Normal file
125
DevourClient/Dependencies/IL2CPP_Resolver/il2cpp_resolver.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
#include "il2cpp_resolver.hpp"
|
||||
|
||||
namespace IL2CPP
|
||||
{
|
||||
bool Initialize(bool m_bWaitForModule)
|
||||
{
|
||||
if (m_bWaitForModule)
|
||||
{
|
||||
while (!Data.m_hGameAseembly)
|
||||
{
|
||||
Data.m_hGameAseembly = GetModuleHandleA(IL2CPP_MAIN_MODULE);
|
||||
Sleep(1000); // Prevent high CPU usage!
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Data.m_hGameAseembly = GetModuleHandleA(IL2CPP_MAIN_MODULE);
|
||||
if (!Data.m_hGameAseembly) return false;
|
||||
}
|
||||
|
||||
if (!UnityAPI::Initialize()) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
namespace UnityAPI
|
||||
{
|
||||
m_eExportObfuscationType m_ExportObfuscation = m_eExportObfuscationType::None;
|
||||
int m_iROTObfuscationValue = -1;
|
||||
|
||||
void* ResolveExport(const char* m_pName)
|
||||
{
|
||||
switch (m_ExportObfuscation)
|
||||
{
|
||||
case m_eExportObfuscationType::ROT:
|
||||
{
|
||||
if (m_iROTObfuscationValue == -1) // Bruteforce
|
||||
{
|
||||
for (int i = 1; 26 > i; ++i)
|
||||
{
|
||||
void* pReturn = GetProcAddress(Data.m_hGameAseembly, &Unity::Obfuscators::ROT_String(m_pName, i)[0]);
|
||||
if (pReturn)
|
||||
{
|
||||
m_iROTObfuscationValue = i;
|
||||
return pReturn;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return GetProcAddress(Data.m_hGameAseembly, &Unity::Obfuscators::ROT_String(m_pName, m_iROTObfuscationValue)[0]);
|
||||
}
|
||||
default: return GetProcAddress(Data.m_hGameAseembly, m_pName);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool ResolveExport_Boolean(void** m_pAddress, const char* m_pName)
|
||||
{
|
||||
*m_pAddress = ResolveExport(m_pName);
|
||||
IL2CPP_ASSERT(*m_pAddress != nullptr && "Couldn't resolve export!");
|
||||
return *m_pAddress != nullptr;
|
||||
}
|
||||
|
||||
bool Initialize()
|
||||
{
|
||||
bool m_bInitExportResolved = false;
|
||||
for (int i = 0; m_eExportObfuscationType::MAX > i; ++i)
|
||||
{
|
||||
m_ExportObfuscation = static_cast<m_eExportObfuscationType>(i);
|
||||
if (ResolveExport(IL2CPP_INIT_EXPORT))
|
||||
{
|
||||
m_bInitExportResolved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IL2CPP_ASSERT(m_bInitExportResolved && "Couldn't resolve il2cpp_init!");
|
||||
if (!m_bInitExportResolved) return false;
|
||||
|
||||
std::unordered_map<const char*, void**> m_uExports =
|
||||
{
|
||||
{ IL2CPP_CLASS_FROM_NAME_EXPORT, &Data.Functions.m_pClassFromName },
|
||||
{ IL2CPP_CLASS_GET_FIELDS, &Data.Functions.m_pClassGetFields },
|
||||
{ IL2CPP_CLASS_GET_FIELD_FROM_NAME_EXPORT, &Data.Functions.m_pClassGetFieldFromName },
|
||||
{ IL2CPP_CLASS_GET_METHODS, &Data.Functions.m_pClassGetMethods },
|
||||
{ IL2CPP_CLASS_GET_METHOD_FROM_NAME_EXPORT, &Data.Functions.m_pClassGetMethodFromName },
|
||||
{ IL2CPP_CLASS_GET_PROPERTY_FROM_NAME_EXPORT, &Data.Functions.m_pClassGetPropertyFromName },
|
||||
{ IL2CPP_CLASS_GET_TYPE_EXPORT, &Data.Functions.m_pClassGetType },
|
||||
{ IL2CPP_DOMAIN_GET_EXPORT, &Data.Functions.m_pDomainGet },
|
||||
{ IL2CPP_DOMAIN_GET_ASSEMBLIES_EXPORT, &Data.Functions.m_pDomainGetAssemblies },
|
||||
{ IL2CPP_FREE_EXPORT, &Data.Functions.m_pFree },
|
||||
{ IL2CPP_IMAGE_GET_CLASS_EXPORT, &Data.Functions.m_pImageGetClass },
|
||||
{ IL2CPP_IMAGE_GET_CLASS_COUNT_EXPORT, &Data.Functions.m_pImageGetClassCount },
|
||||
{ IL2CPP_RESOLVE_FUNC_EXPORT, &Data.Functions.m_pResolveFunction },
|
||||
{ IL2CPP_STRING_NEW_EXPORT, &Data.Functions.m_pStringNew },
|
||||
{ IL2CPP_THREAD_ATTACH_EXPORT, &Data.Functions.m_pThreadAttach },
|
||||
{ IL2CPP_THREAD_DETACH_EXPORT, &Data.Functions.m_pThreadDetach },
|
||||
{ IL2CPP_TYPE_GET_OBJECT_EXPORT, &Data.Functions.m_pTypeGetObject },
|
||||
};
|
||||
|
||||
for (std::pair<const char*, void**> m_pExport : m_uExports)
|
||||
{
|
||||
if (!ResolveExport_Boolean(m_pExport.second, m_pExport.first))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Unity APIs
|
||||
Unity::Camera::Initialize();
|
||||
Unity::Component::Initialize();
|
||||
Unity::GameObject::Initialize();
|
||||
Unity::LayerMask::Initialize();
|
||||
Unity::Object::Initialize();
|
||||
Unity::RigidBody::Initialize();
|
||||
Unity::Transform::Initialize();
|
||||
|
||||
// Caches
|
||||
IL2CPP::SystemTypeCache::Initializer::PreCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
#pragma once
|
||||
#include "Includes.hpp"
|
||||
|
||||
namespace IL2CPP
|
||||
{
|
||||
/* Must be called once before using any other functions!
|
||||
* Args:
|
||||
* bWaitForModule: (Wait for GameAssembly - can result in infinite loop!)
|
||||
*/
|
||||
bool Initialize(bool m_bWaitForModule = false);
|
||||
|
||||
namespace UnityAPI
|
||||
{
|
||||
enum m_eExportObfuscationType
|
||||
{
|
||||
None = 0,
|
||||
ROT = 1,
|
||||
MAX = 2,
|
||||
};
|
||||
|
||||
extern m_eExportObfuscationType m_ExportObfuscation;
|
||||
|
||||
void* ResolveExport(const char* m_pName);
|
||||
|
||||
bool Initialize();
|
||||
}
|
||||
}
|
||||
1
DevourClient/Dependencies/Minhook/.gitkeep
Normal file
1
DevourClient/Dependencies/Minhook/.gitkeep
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
1
DevourClient/Dependencies/Minhook/include/.gitkeep
Normal file
1
DevourClient/Dependencies/Minhook/include/.gitkeep
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
185
DevourClient/Dependencies/Minhook/include/MinHook.h
Normal file
185
DevourClient/Dependencies/Minhook/include/MinHook.h
Normal file
@@ -0,0 +1,185 @@
|
||||
/*
|
||||
* MinHook - The Minimalistic API Hooking Library for x64/x86
|
||||
* Copyright (C) 2009-2017 Tsuda Kageyu.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if !(defined _M_IX86) && !(defined _M_X64) && !(defined __i386__) && !(defined __x86_64__)
|
||||
#error MinHook supports only x86 and x64 systems.
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
// MinHook Error Codes.
|
||||
typedef enum MH_STATUS
|
||||
{
|
||||
// Unknown error. Should not be returned.
|
||||
MH_UNKNOWN = -1,
|
||||
|
||||
// Successful.
|
||||
MH_OK = 0,
|
||||
|
||||
// MinHook is already initialized.
|
||||
MH_ERROR_ALREADY_INITIALIZED,
|
||||
|
||||
// MinHook is not initialized yet, or already uninitialized.
|
||||
MH_ERROR_NOT_INITIALIZED,
|
||||
|
||||
// The hook for the specified target function is already created.
|
||||
MH_ERROR_ALREADY_CREATED,
|
||||
|
||||
// The hook for the specified target function is not created yet.
|
||||
MH_ERROR_NOT_CREATED,
|
||||
|
||||
// The hook for the specified target function is already enabled.
|
||||
MH_ERROR_ENABLED,
|
||||
|
||||
// The hook for the specified target function is not enabled yet, or already
|
||||
// disabled.
|
||||
MH_ERROR_DISABLED,
|
||||
|
||||
// The specified pointer is invalid. It points the address of non-allocated
|
||||
// and/or non-executable region.
|
||||
MH_ERROR_NOT_EXECUTABLE,
|
||||
|
||||
// The specified target function cannot be hooked.
|
||||
MH_ERROR_UNSUPPORTED_FUNCTION,
|
||||
|
||||
// Failed to allocate memory.
|
||||
MH_ERROR_MEMORY_ALLOC,
|
||||
|
||||
// Failed to change the memory protection.
|
||||
MH_ERROR_MEMORY_PROTECT,
|
||||
|
||||
// The specified module is not loaded.
|
||||
MH_ERROR_MODULE_NOT_FOUND,
|
||||
|
||||
// The specified function is not found.
|
||||
MH_ERROR_FUNCTION_NOT_FOUND
|
||||
}
|
||||
MH_STATUS;
|
||||
|
||||
// Can be passed as a parameter to MH_EnableHook, MH_DisableHook,
|
||||
// MH_QueueEnableHook or MH_QueueDisableHook.
|
||||
#define MH_ALL_HOOKS NULL
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// Initialize the MinHook library. You must call this function EXACTLY ONCE
|
||||
// at the beginning of your program.
|
||||
MH_STATUS WINAPI MH_Initialize(VOID);
|
||||
|
||||
// Uninitialize the MinHook library. You must call this function EXACTLY
|
||||
// ONCE at the end of your program.
|
||||
MH_STATUS WINAPI MH_Uninitialize(VOID);
|
||||
|
||||
// Creates a hook for the specified target function, in disabled state.
|
||||
// Parameters:
|
||||
// pTarget [in] A pointer to the target function, which will be
|
||||
// overridden by the detour function.
|
||||
// pDetour [in] A pointer to the detour function, which will override
|
||||
// the target function.
|
||||
// ppOriginal [out] A pointer to the trampoline function, which will be
|
||||
// used to call the original target function.
|
||||
// This parameter can be NULL.
|
||||
MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal);
|
||||
|
||||
// Creates a hook for the specified API function, in disabled state.
|
||||
// Parameters:
|
||||
// pszModule [in] A pointer to the loaded module name which contains the
|
||||
// target function.
|
||||
// pszProcName [in] A pointer to the target function name, which will be
|
||||
// overridden by the detour function.
|
||||
// pDetour [in] A pointer to the detour function, which will override
|
||||
// the target function.
|
||||
// ppOriginal [out] A pointer to the trampoline function, which will be
|
||||
// used to call the original target function.
|
||||
// This parameter can be NULL.
|
||||
MH_STATUS WINAPI MH_CreateHookApi(
|
||||
LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal);
|
||||
|
||||
// Creates a hook for the specified API function, in disabled state.
|
||||
// Parameters:
|
||||
// pszModule [in] A pointer to the loaded module name which contains the
|
||||
// target function.
|
||||
// pszProcName [in] A pointer to the target function name, which will be
|
||||
// overridden by the detour function.
|
||||
// pDetour [in] A pointer to the detour function, which will override
|
||||
// the target function.
|
||||
// ppOriginal [out] A pointer to the trampoline function, which will be
|
||||
// used to call the original target function.
|
||||
// This parameter can be NULL.
|
||||
// ppTarget [out] A pointer to the target function, which will be used
|
||||
// with other functions.
|
||||
// This parameter can be NULL.
|
||||
MH_STATUS WINAPI MH_CreateHookApiEx(
|
||||
LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal, LPVOID *ppTarget);
|
||||
|
||||
// Removes an already created hook.
|
||||
// Parameters:
|
||||
// pTarget [in] A pointer to the target function.
|
||||
MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget);
|
||||
|
||||
// Enables an already created hook.
|
||||
// Parameters:
|
||||
// pTarget [in] A pointer to the target function.
|
||||
// If this parameter is MH_ALL_HOOKS, all created hooks are
|
||||
// enabled in one go.
|
||||
MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget);
|
||||
|
||||
// Disables an already created hook.
|
||||
// Parameters:
|
||||
// pTarget [in] A pointer to the target function.
|
||||
// If this parameter is MH_ALL_HOOKS, all created hooks are
|
||||
// disabled in one go.
|
||||
MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget);
|
||||
|
||||
// Queues to enable an already created hook.
|
||||
// Parameters:
|
||||
// pTarget [in] A pointer to the target function.
|
||||
// If this parameter is MH_ALL_HOOKS, all created hooks are
|
||||
// queued to be enabled.
|
||||
MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget);
|
||||
|
||||
// Queues to disable an already created hook.
|
||||
// Parameters:
|
||||
// pTarget [in] A pointer to the target function.
|
||||
// If this parameter is MH_ALL_HOOKS, all created hooks are
|
||||
// queued to be disabled.
|
||||
MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget);
|
||||
|
||||
// Applies all queued changes in one go.
|
||||
MH_STATUS WINAPI MH_ApplyQueued(VOID);
|
||||
|
||||
// Translates the MH_STATUS to its name as a string.
|
||||
const char * WINAPI MH_StatusToString(MH_STATUS status);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
1
DevourClient/Dependencies/Minhook/src/.gitkeep
Normal file
1
DevourClient/Dependencies/Minhook/src/.gitkeep
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
1
DevourClient/Dependencies/Minhook/src/HDE/.gitkeep
Normal file
1
DevourClient/Dependencies/Minhook/src/HDE/.gitkeep
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
324
DevourClient/Dependencies/Minhook/src/HDE/hde32.c
Normal file
324
DevourClient/Dependencies/Minhook/src/HDE/hde32.c
Normal file
@@ -0,0 +1,324 @@
|
||||
/*
|
||||
* Hacker Disassembler Engine 32 C
|
||||
* Copyright (c) 2008-2009, Vyacheslav Patkov.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(_M_IX86) || defined(__i386__)
|
||||
|
||||
#include <string.h>
|
||||
#include "hde32.h"
|
||||
#include "table32.h"
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#endif // defined(_M_IX86) || defined(__i386__)
|
||||
105
DevourClient/Dependencies/Minhook/src/HDE/hde32.h
Normal file
105
DevourClient/Dependencies/Minhook/src/HDE/hde32.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Hacker Disassembler Engine 32
|
||||
* Copyright (c) 2006-2009, Vyacheslav Patkov.
|
||||
* All rights reserved.
|
||||
*
|
||||
* hde32.h: C/C++ header file
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _HDE32_H_
|
||||
#define _HDE32_H_
|
||||
|
||||
/* stdint.h - C99 standard header
|
||||
* http://en.wikipedia.org/wiki/stdint.h
|
||||
*
|
||||
* if your compiler doesn't contain "stdint.h" header (for
|
||||
* example, Microsoft Visual C++), you can download file:
|
||||
* http://www.azillionmonkeys.com/qed/pstdint.h
|
||||
* and change next line to:
|
||||
* #include "pstdint.h"
|
||||
*/
|
||||
#include "pstdint.h"
|
||||
|
||||
#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)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* __cdecl */
|
||||
unsigned int hde32_disasm(const void *code, hde32s *hs);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HDE32_H_ */
|
||||
333
DevourClient/Dependencies/Minhook/src/HDE/hde64.c
Normal file
333
DevourClient/Dependencies/Minhook/src/HDE/hde64.c
Normal file
@@ -0,0 +1,333 @@
|
||||
/*
|
||||
* Hacker Disassembler Engine 64 C
|
||||
* Copyright (c) 2008-2009, Vyacheslav Patkov.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
|
||||
#include <string.h>
|
||||
#include "hde64.h"
|
||||
#include "table64.h"
|
||||
|
||||
unsigned int hde64_disasm(const void *code, hde64s *hs)
|
||||
{
|
||||
uint8_t x, c, *p = (uint8_t *)code, cflags, opcode, pref = 0;
|
||||
uint8_t *ht = hde64_table, m_mod, m_reg, m_rm, disp_size = 0;
|
||||
uint8_t op64 = 0;
|
||||
|
||||
memset(hs, 0, sizeof(hde64s));
|
||||
|
||||
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 ((c & 0xf0) == 0x40) {
|
||||
hs->flags |= F_PREFIX_REX;
|
||||
if ((hs->rex_w = (c & 0xf) >> 3) && (*p & 0xf8) == 0xb8)
|
||||
op64++;
|
||||
hs->rex_r = (c & 7) >> 2;
|
||||
hs->rex_x = (c & 3) >> 1;
|
||||
hs->rex_b = c & 1;
|
||||
if (((c = *p++) & 0xf0) == 0x40) {
|
||||
opcode = c;
|
||||
goto error_opcode;
|
||||
}
|
||||
}
|
||||
|
||||
if ((hs->opcode = c) == 0x0f) {
|
||||
hs->opcode2 = c = *p++;
|
||||
ht += DELTA_OPCODES;
|
||||
} else if (c >= 0xa0 && c <= 0xa3) {
|
||||
op64++;
|
||||
if (pref & PRE_67)
|
||||
pref |= PRE_66;
|
||||
else
|
||||
pref &= ~PRE_66;
|
||||
}
|
||||
|
||||
opcode = c;
|
||||
cflags = ht[ht[opcode / 4] + (opcode % 4)];
|
||||
|
||||
if (cflags == C_ERROR) {
|
||||
error_opcode:
|
||||
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 = hde64_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 = hde64_table + DELTA_FPU_MODRM + t*8;
|
||||
t = ht[m_reg] << m_rm;
|
||||
} else {
|
||||
ht = hde64_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 = hde64_table + DELTA_OP2_LOCK_OK;
|
||||
table_end = ht + DELTA_OP_ONLY_MEM - DELTA_OP2_LOCK_OK;
|
||||
} else {
|
||||
ht = hde64_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 = hde64_table + DELTA_OP2_ONLY_MEM;
|
||||
table_end = ht + sizeof(hde64_table) - DELTA_OP2_ONLY_MEM;
|
||||
} else {
|
||||
ht = hde64_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;
|
||||
}
|
||||
|
||||
if (m_mod != 3 && m_rm == 4) {
|
||||
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;
|
||||
}
|
||||
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 (op64) {
|
||||
hs->flags |= F_IMM64;
|
||||
hs->imm.imm64 = *(uint64_t *)p;
|
||||
p += 8;
|
||||
} else if (!(pref & PRE_66)) {
|
||||
hs->flags |= F_IMM32;
|
||||
hs->imm.imm32 = *(uint32_t *)p;
|
||||
p += 4;
|
||||
} else
|
||||
goto imm16_ok;
|
||||
}
|
||||
|
||||
|
||||
if (cflags & C_IMM16) {
|
||||
imm16_ok:
|
||||
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;
|
||||
}
|
||||
|
||||
#endif // defined(_M_X64) || defined(__x86_64__)
|
||||
112
DevourClient/Dependencies/Minhook/src/HDE/hde64.h
Normal file
112
DevourClient/Dependencies/Minhook/src/HDE/hde64.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Hacker Disassembler Engine 64
|
||||
* Copyright (c) 2008-2009, Vyacheslav Patkov.
|
||||
* All rights reserved.
|
||||
*
|
||||
* hde64.h: C/C++ header file
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _HDE64_H_
|
||||
#define _HDE64_H_
|
||||
|
||||
/* stdint.h - C99 standard header
|
||||
* http://en.wikipedia.org/wiki/stdint.h
|
||||
*
|
||||
* if your compiler doesn't contain "stdint.h" header (for
|
||||
* example, Microsoft Visual C++), you can download file:
|
||||
* http://www.azillionmonkeys.com/qed/pstdint.h
|
||||
* and change next line to:
|
||||
* #include "pstdint.h"
|
||||
*/
|
||||
#include "pstdint.h"
|
||||
|
||||
#define F_MODRM 0x00000001
|
||||
#define F_SIB 0x00000002
|
||||
#define F_IMM8 0x00000004
|
||||
#define F_IMM16 0x00000008
|
||||
#define F_IMM32 0x00000010
|
||||
#define F_IMM64 0x00000020
|
||||
#define F_DISP8 0x00000040
|
||||
#define F_DISP16 0x00000080
|
||||
#define F_DISP32 0x00000100
|
||||
#define F_RELATIVE 0x00000200
|
||||
#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_REX 0x40000000
|
||||
#define F_PREFIX_ANY 0x7f000000
|
||||
|
||||
#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 rex;
|
||||
uint8_t rex_w;
|
||||
uint8_t rex_r;
|
||||
uint8_t rex_x;
|
||||
uint8_t rex_b;
|
||||
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;
|
||||
uint64_t imm64;
|
||||
} imm;
|
||||
union {
|
||||
uint8_t disp8;
|
||||
uint16_t disp16;
|
||||
uint32_t disp32;
|
||||
} disp;
|
||||
uint32_t flags;
|
||||
} hde64s;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* __cdecl */
|
||||
unsigned int hde64_disasm(const void *code, hde64s *hs);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _HDE64_H_ */
|
||||
39
DevourClient/Dependencies/Minhook/src/HDE/pstdint.h
Normal file
39
DevourClient/Dependencies/Minhook/src/HDE/pstdint.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* MinHook - The Minimalistic API Hooking Library for x64/x86
|
||||
* Copyright (C) 2009-2017 Tsuda Kageyu. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
// Integer types for HDE.
|
||||
typedef INT8 int8_t;
|
||||
typedef INT16 int16_t;
|
||||
typedef INT32 int32_t;
|
||||
typedef INT64 int64_t;
|
||||
typedef UINT8 uint8_t;
|
||||
typedef UINT16 uint16_t;
|
||||
typedef UINT32 uint32_t;
|
||||
typedef UINT64 uint64_t;
|
||||
73
DevourClient/Dependencies/Minhook/src/HDE/table32.h
Normal file
73
DevourClient/Dependencies/Minhook/src/HDE/table32.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Hacker Disassembler Engine 32 C
|
||||
* Copyright (c) 2008-2009, Vyacheslav Patkov.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#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
|
||||
|
||||
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
|
||||
};
|
||||
74
DevourClient/Dependencies/Minhook/src/HDE/table64.h
Normal file
74
DevourClient/Dependencies/Minhook/src/HDE/table64.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Hacker Disassembler Engine 64 C
|
||||
* Copyright (c) 2008-2009, Vyacheslav Patkov.
|
||||
* All rights reserved.
|
||||
*
|
||||
*/
|
||||
|
||||
#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 0xfd
|
||||
#define DELTA_FPU_MODRM 0x104
|
||||
#define DELTA_PREFIXES 0x13c
|
||||
#define DELTA_OP_LOCK_OK 0x1ae
|
||||
#define DELTA_OP2_LOCK_OK 0x1c6
|
||||
#define DELTA_OP_ONLY_MEM 0x1d8
|
||||
#define DELTA_OP2_ONLY_MEM 0x1e7
|
||||
|
||||
unsigned char hde64_table[] = {
|
||||
0xa5,0xaa,0xa5,0xb8,0xa5,0xaa,0xa5,0xaa,0xa5,0xb8,0xa5,0xb8,0xa5,0xb8,0xa5,
|
||||
0xb8,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xac,0xc0,0xcc,0xc0,0xa1,0xa1,
|
||||
0xa1,0xa1,0xb1,0xa5,0xa5,0xa6,0xc0,0xc0,0xd7,0xda,0xe0,0xc0,0xe4,0xc0,0xea,
|
||||
0xea,0xe0,0xe0,0x98,0xc8,0xee,0xf1,0xa5,0xd3,0xa5,0xa5,0xa1,0xea,0x9e,0xc0,
|
||||
0xc0,0xc2,0xc0,0xe6,0x03,0x7f,0x11,0x7f,0x01,0x7f,0x01,0x3f,0x01,0x01,0xab,
|
||||
0x8b,0x90,0x64,0x5b,0x5b,0x5b,0x5b,0x5b,0x92,0x5b,0x5b,0x76,0x90,0x92,0x92,
|
||||
0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x6a,0x73,0x90,
|
||||
0x5b,0x52,0x52,0x52,0x52,0x5b,0x5b,0x5b,0x5b,0x77,0x7c,0x77,0x85,0x5b,0x5b,
|
||||
0x70,0x5b,0x7a,0xaf,0x76,0x76,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,0x5b,
|
||||
0x5b,0x5b,0x86,0x01,0x03,0x01,0x04,0x03,0xd5,0x03,0xd5,0x03,0xcc,0x01,0xbc,
|
||||
0x03,0xf0,0x03,0x03,0x04,0x00,0x50,0x50,0x50,0x50,0xff,0x20,0x20,0x20,0x20,
|
||||
0x01,0x01,0x01,0x01,0xc4,0x02,0x10,0xff,0xff,0xff,0x01,0x00,0x03,0x11,0xff,
|
||||
0x03,0xc4,0xc6,0xc8,0x02,0x10,0x00,0xff,0xcc,0x01,0x01,0x01,0x00,0x00,0x00,
|
||||
0x00,0x01,0x01,0x03,0x01,0xff,0xff,0xc0,0xc2,0x10,0x11,0x02,0x03,0x01,0x01,
|
||||
0x01,0xff,0xff,0xff,0x00,0x00,0x00,0xff,0x00,0x00,0xff,0xff,0xff,0xff,0x10,
|
||||
0x10,0x10,0x10,0x02,0x10,0x00,0x00,0xc6,0xc8,0x02,0x02,0x02,0x02,0x06,0x00,
|
||||
0x04,0x00,0x02,0xff,0x00,0xc0,0xc2,0x01,0x01,0x03,0x03,0x03,0xca,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,0x40,0x40,0x40,0x40,0x41,0x49,0x40,0x40,0x40,0x40,0x4c,0x42,0x40,0x40,
|
||||
0x40,0x40,0x40,0x40,0x40,0x40,0x4f,0x44,0x53,0x40,0x40,0x40,0x44,0x57,0x43,
|
||||
0x5c,0x40,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
|
||||
0x40,0x40,0x64,0x66,0x6e,0x6b,0x40,0x40,0x6a,0x46,0x40,0x40,0x44,0x46,0x40,
|
||||
0x40,0x5b,0x44,0x40,0x40,0x00,0x00,0x00,0x00,0x06,0x06,0x06,0x06,0x01,0x06,
|
||||
0x06,0x02,0x06,0x06,0x00,0x06,0x00,0x0a,0x0a,0x00,0x00,0x00,0x02,0x07,0x07,
|
||||
0x06,0x02,0x0d,0x06,0x06,0x06,0x0e,0x05,0x05,0x02,0x02,0x00,0x00,0x04,0x04,
|
||||
0x04,0x04,0x05,0x06,0x06,0x06,0x00,0x00,0x00,0x0e,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
|
||||
};
|
||||
312
DevourClient/Dependencies/Minhook/src/buffer.c
Normal file
312
DevourClient/Dependencies/Minhook/src/buffer.c
Normal file
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
* MinHook - The Minimalistic API Hooking Library for x64/x86
|
||||
* Copyright (C) 2009-2017 Tsuda Kageyu.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include "buffer.h"
|
||||
|
||||
// Size of each memory block. (= page size of VirtualAlloc)
|
||||
#define MEMORY_BLOCK_SIZE 0x1000
|
||||
|
||||
// Max range for seeking a memory block. (= 1024MB)
|
||||
#define MAX_MEMORY_RANGE 0x40000000
|
||||
|
||||
// Memory protection flags to check the executable address.
|
||||
#define PAGE_EXECUTE_FLAGS \
|
||||
(PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY)
|
||||
|
||||
// Memory slot.
|
||||
typedef struct _MEMORY_SLOT
|
||||
{
|
||||
union
|
||||
{
|
||||
struct _MEMORY_SLOT *pNext;
|
||||
UINT8 buffer[MEMORY_SLOT_SIZE];
|
||||
};
|
||||
} MEMORY_SLOT, *PMEMORY_SLOT;
|
||||
|
||||
// Memory block info. Placed at the head of each block.
|
||||
typedef struct _MEMORY_BLOCK
|
||||
{
|
||||
struct _MEMORY_BLOCK *pNext;
|
||||
PMEMORY_SLOT pFree; // First element of the free slot list.
|
||||
UINT usedCount;
|
||||
} MEMORY_BLOCK, *PMEMORY_BLOCK;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Global Variables:
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// First element of the memory block list.
|
||||
PMEMORY_BLOCK g_pMemoryBlocks;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
VOID InitializeBuffer(VOID)
|
||||
{
|
||||
// Nothing to do for now.
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
VOID UninitializeBuffer(VOID)
|
||||
{
|
||||
PMEMORY_BLOCK pBlock = g_pMemoryBlocks;
|
||||
g_pMemoryBlocks = NULL;
|
||||
|
||||
while (pBlock)
|
||||
{
|
||||
PMEMORY_BLOCK pNext = pBlock->pNext;
|
||||
VirtualFree(pBlock, 0, MEM_RELEASE);
|
||||
pBlock = pNext;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
static LPVOID FindPrevFreeRegion(LPVOID pAddress, LPVOID pMinAddr, DWORD dwAllocationGranularity)
|
||||
{
|
||||
ULONG_PTR tryAddr = (ULONG_PTR)pAddress;
|
||||
|
||||
// Round down to the allocation granularity.
|
||||
tryAddr -= tryAddr % dwAllocationGranularity;
|
||||
|
||||
// Start from the previous allocation granularity multiply.
|
||||
tryAddr -= dwAllocationGranularity;
|
||||
|
||||
while (tryAddr >= (ULONG_PTR)pMinAddr)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
if (VirtualQuery((LPVOID)tryAddr, &mbi, sizeof(mbi)) == 0)
|
||||
break;
|
||||
|
||||
if (mbi.State == MEM_FREE)
|
||||
return (LPVOID)tryAddr;
|
||||
|
||||
if ((ULONG_PTR)mbi.AllocationBase < dwAllocationGranularity)
|
||||
break;
|
||||
|
||||
tryAddr = (ULONG_PTR)mbi.AllocationBase - dwAllocationGranularity;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
static LPVOID FindNextFreeRegion(LPVOID pAddress, LPVOID pMaxAddr, DWORD dwAllocationGranularity)
|
||||
{
|
||||
ULONG_PTR tryAddr = (ULONG_PTR)pAddress;
|
||||
|
||||
// Round down to the allocation granularity.
|
||||
tryAddr -= tryAddr % dwAllocationGranularity;
|
||||
|
||||
// Start from the next allocation granularity multiply.
|
||||
tryAddr += dwAllocationGranularity;
|
||||
|
||||
while (tryAddr <= (ULONG_PTR)pMaxAddr)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
if (VirtualQuery((LPVOID)tryAddr, &mbi, sizeof(mbi)) == 0)
|
||||
break;
|
||||
|
||||
if (mbi.State == MEM_FREE)
|
||||
return (LPVOID)tryAddr;
|
||||
|
||||
tryAddr = (ULONG_PTR)mbi.BaseAddress + mbi.RegionSize;
|
||||
|
||||
// Round up to the next allocation granularity.
|
||||
tryAddr += dwAllocationGranularity - 1;
|
||||
tryAddr -= tryAddr % dwAllocationGranularity;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static PMEMORY_BLOCK GetMemoryBlock(LPVOID pOrigin)
|
||||
{
|
||||
PMEMORY_BLOCK pBlock;
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
ULONG_PTR minAddr;
|
||||
ULONG_PTR maxAddr;
|
||||
|
||||
SYSTEM_INFO si;
|
||||
GetSystemInfo(&si);
|
||||
minAddr = (ULONG_PTR)si.lpMinimumApplicationAddress;
|
||||
maxAddr = (ULONG_PTR)si.lpMaximumApplicationAddress;
|
||||
|
||||
// pOrigin ± 512MB
|
||||
if ((ULONG_PTR)pOrigin > MAX_MEMORY_RANGE && minAddr < (ULONG_PTR)pOrigin - MAX_MEMORY_RANGE)
|
||||
minAddr = (ULONG_PTR)pOrigin - MAX_MEMORY_RANGE;
|
||||
|
||||
if (maxAddr > (ULONG_PTR)pOrigin + MAX_MEMORY_RANGE)
|
||||
maxAddr = (ULONG_PTR)pOrigin + MAX_MEMORY_RANGE;
|
||||
|
||||
// Make room for MEMORY_BLOCK_SIZE bytes.
|
||||
maxAddr -= MEMORY_BLOCK_SIZE - 1;
|
||||
#endif
|
||||
|
||||
// Look the registered blocks for a reachable one.
|
||||
for (pBlock = g_pMemoryBlocks; pBlock != NULL; pBlock = pBlock->pNext)
|
||||
{
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
// Ignore the blocks too far.
|
||||
if ((ULONG_PTR)pBlock < minAddr || (ULONG_PTR)pBlock >= maxAddr)
|
||||
continue;
|
||||
#endif
|
||||
// The block has at least one unused slot.
|
||||
if (pBlock->pFree != NULL)
|
||||
return pBlock;
|
||||
}
|
||||
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
// Alloc a new block above if not found.
|
||||
{
|
||||
LPVOID pAlloc = pOrigin;
|
||||
while ((ULONG_PTR)pAlloc >= minAddr)
|
||||
{
|
||||
pAlloc = FindPrevFreeRegion(pAlloc, (LPVOID)minAddr, si.dwAllocationGranularity);
|
||||
if (pAlloc == NULL)
|
||||
break;
|
||||
|
||||
pBlock = (PMEMORY_BLOCK)VirtualAlloc(
|
||||
pAlloc, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||
if (pBlock != NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Alloc a new block below if not found.
|
||||
if (pBlock == NULL)
|
||||
{
|
||||
LPVOID pAlloc = pOrigin;
|
||||
while ((ULONG_PTR)pAlloc <= maxAddr)
|
||||
{
|
||||
pAlloc = FindNextFreeRegion(pAlloc, (LPVOID)maxAddr, si.dwAllocationGranularity);
|
||||
if (pAlloc == NULL)
|
||||
break;
|
||||
|
||||
pBlock = (PMEMORY_BLOCK)VirtualAlloc(
|
||||
pAlloc, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||
if (pBlock != NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
// In x86 mode, a memory block can be placed anywhere.
|
||||
pBlock = (PMEMORY_BLOCK)VirtualAlloc(
|
||||
NULL, MEMORY_BLOCK_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
|
||||
#endif
|
||||
|
||||
if (pBlock != NULL)
|
||||
{
|
||||
// Build a linked list of all the slots.
|
||||
PMEMORY_SLOT pSlot = (PMEMORY_SLOT)pBlock + 1;
|
||||
pBlock->pFree = NULL;
|
||||
pBlock->usedCount = 0;
|
||||
do
|
||||
{
|
||||
pSlot->pNext = pBlock->pFree;
|
||||
pBlock->pFree = pSlot;
|
||||
pSlot++;
|
||||
} while ((ULONG_PTR)pSlot - (ULONG_PTR)pBlock <= MEMORY_BLOCK_SIZE - MEMORY_SLOT_SIZE);
|
||||
|
||||
pBlock->pNext = g_pMemoryBlocks;
|
||||
g_pMemoryBlocks = pBlock;
|
||||
}
|
||||
|
||||
return pBlock;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
LPVOID AllocateBuffer(LPVOID pOrigin)
|
||||
{
|
||||
PMEMORY_SLOT pSlot;
|
||||
PMEMORY_BLOCK pBlock = GetMemoryBlock(pOrigin);
|
||||
if (pBlock == NULL)
|
||||
return NULL;
|
||||
|
||||
// Remove an unused slot from the list.
|
||||
pSlot = pBlock->pFree;
|
||||
pBlock->pFree = pSlot->pNext;
|
||||
pBlock->usedCount++;
|
||||
#ifdef _DEBUG
|
||||
// Fill the slot with INT3 for debugging.
|
||||
memset(pSlot, 0xCC, sizeof(MEMORY_SLOT));
|
||||
#endif
|
||||
return pSlot;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
VOID FreeBuffer(LPVOID pBuffer)
|
||||
{
|
||||
PMEMORY_BLOCK pBlock = g_pMemoryBlocks;
|
||||
PMEMORY_BLOCK pPrev = NULL;
|
||||
ULONG_PTR pTargetBlock = ((ULONG_PTR)pBuffer / MEMORY_BLOCK_SIZE) * MEMORY_BLOCK_SIZE;
|
||||
|
||||
while (pBlock != NULL)
|
||||
{
|
||||
if ((ULONG_PTR)pBlock == pTargetBlock)
|
||||
{
|
||||
PMEMORY_SLOT pSlot = (PMEMORY_SLOT)pBuffer;
|
||||
#ifdef _DEBUG
|
||||
// Clear the released slot for debugging.
|
||||
memset(pSlot, 0x00, sizeof(MEMORY_SLOT));
|
||||
#endif
|
||||
// Restore the released slot to the list.
|
||||
pSlot->pNext = pBlock->pFree;
|
||||
pBlock->pFree = pSlot;
|
||||
pBlock->usedCount--;
|
||||
|
||||
// Free if unused.
|
||||
if (pBlock->usedCount == 0)
|
||||
{
|
||||
if (pPrev)
|
||||
pPrev->pNext = pBlock->pNext;
|
||||
else
|
||||
g_pMemoryBlocks = pBlock->pNext;
|
||||
|
||||
VirtualFree(pBlock, 0, MEM_RELEASE);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
pPrev = pBlock;
|
||||
pBlock = pBlock->pNext;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
BOOL IsExecutableAddress(LPVOID pAddress)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION mi;
|
||||
VirtualQuery(pAddress, &mi, sizeof(mi));
|
||||
|
||||
return (mi.State == MEM_COMMIT && (mi.Protect & PAGE_EXECUTE_FLAGS));
|
||||
}
|
||||
42
DevourClient/Dependencies/Minhook/src/buffer.h
Normal file
42
DevourClient/Dependencies/Minhook/src/buffer.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* MinHook - The Minimalistic API Hooking Library for x64/x86
|
||||
* Copyright (C) 2009-2017 Tsuda Kageyu.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// Size of each memory slot.
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
#define MEMORY_SLOT_SIZE 64
|
||||
#else
|
||||
#define MEMORY_SLOT_SIZE 32
|
||||
#endif
|
||||
|
||||
VOID InitializeBuffer(VOID);
|
||||
VOID UninitializeBuffer(VOID);
|
||||
LPVOID AllocateBuffer(LPVOID pOrigin);
|
||||
VOID FreeBuffer(LPVOID pBuffer);
|
||||
BOOL IsExecutableAddress(LPVOID pAddress);
|
||||
889
DevourClient/Dependencies/Minhook/src/hook.c
Normal file
889
DevourClient/Dependencies/Minhook/src/hook.c
Normal file
@@ -0,0 +1,889 @@
|
||||
/*
|
||||
* MinHook - The Minimalistic API Hooking Library for x64/x86
|
||||
* Copyright (C) 2009-2017 Tsuda Kageyu.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <tlhelp32.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "../include/MinHook.h"
|
||||
#include "buffer.h"
|
||||
#include "trampoline.h"
|
||||
|
||||
#ifndef ARRAYSIZE
|
||||
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
|
||||
#endif
|
||||
|
||||
// Initial capacity of the HOOK_ENTRY buffer.
|
||||
#define INITIAL_HOOK_CAPACITY 32
|
||||
|
||||
// Initial capacity of the thread IDs buffer.
|
||||
#define INITIAL_THREAD_CAPACITY 128
|
||||
|
||||
// Special hook position values.
|
||||
#define INVALID_HOOK_POS UINT_MAX
|
||||
#define ALL_HOOKS_POS UINT_MAX
|
||||
|
||||
// Freeze() action argument defines.
|
||||
#define ACTION_DISABLE 0
|
||||
#define ACTION_ENABLE 1
|
||||
#define ACTION_APPLY_QUEUED 2
|
||||
|
||||
// Thread access rights for suspending/resuming threads.
|
||||
#define THREAD_ACCESS \
|
||||
(THREAD_SUSPEND_RESUME | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION | THREAD_SET_CONTEXT)
|
||||
|
||||
// Hook information.
|
||||
typedef struct _HOOK_ENTRY
|
||||
{
|
||||
LPVOID pTarget; // Address of the target function.
|
||||
LPVOID pDetour; // Address of the detour or relay function.
|
||||
LPVOID pTrampoline; // Address of the trampoline function.
|
||||
UINT8 backup[8]; // Original prologue of the target function.
|
||||
|
||||
UINT8 patchAbove : 1; // Uses the hot patch area.
|
||||
UINT8 isEnabled : 1; // Enabled.
|
||||
UINT8 queueEnable : 1; // Queued for enabling/disabling when != isEnabled.
|
||||
|
||||
UINT nIP : 4; // Count of the instruction boundaries.
|
||||
UINT8 oldIPs[8]; // Instruction boundaries of the target function.
|
||||
UINT8 newIPs[8]; // Instruction boundaries of the trampoline function.
|
||||
} HOOK_ENTRY, *PHOOK_ENTRY;
|
||||
|
||||
// Suspended threads for Freeze()/Unfreeze().
|
||||
typedef struct _FROZEN_THREADS
|
||||
{
|
||||
LPDWORD pItems; // Data heap
|
||||
UINT capacity; // Size of allocated data heap, items
|
||||
UINT size; // Actual number of data items
|
||||
} FROZEN_THREADS, *PFROZEN_THREADS;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Global Variables:
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Spin lock flag for EnterSpinLock()/LeaveSpinLock().
|
||||
volatile LONG g_isLocked = FALSE;
|
||||
|
||||
// Private heap handle. If not NULL, this library is initialized.
|
||||
HANDLE g_hHeap = NULL;
|
||||
|
||||
// Hook entries.
|
||||
struct
|
||||
{
|
||||
PHOOK_ENTRY pItems; // Data heap
|
||||
UINT capacity; // Size of allocated data heap, items
|
||||
UINT size; // Actual number of data items
|
||||
} g_hooks;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Returns INVALID_HOOK_POS if not found.
|
||||
static UINT FindHookEntry(LPVOID pTarget)
|
||||
{
|
||||
UINT i;
|
||||
for (i = 0; i < g_hooks.size; ++i)
|
||||
{
|
||||
if ((ULONG_PTR)pTarget == (ULONG_PTR)g_hooks.pItems[i].pTarget)
|
||||
return i;
|
||||
}
|
||||
|
||||
return INVALID_HOOK_POS;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static PHOOK_ENTRY AddHookEntry()
|
||||
{
|
||||
if (g_hooks.pItems == NULL)
|
||||
{
|
||||
g_hooks.capacity = INITIAL_HOOK_CAPACITY;
|
||||
g_hooks.pItems = (PHOOK_ENTRY)HeapAlloc(
|
||||
g_hHeap, 0, g_hooks.capacity * sizeof(HOOK_ENTRY));
|
||||
if (g_hooks.pItems == NULL)
|
||||
return NULL;
|
||||
}
|
||||
else if (g_hooks.size >= g_hooks.capacity)
|
||||
{
|
||||
PHOOK_ENTRY p = (PHOOK_ENTRY)HeapReAlloc(
|
||||
g_hHeap, 0, g_hooks.pItems, (g_hooks.capacity * 2) * sizeof(HOOK_ENTRY));
|
||||
if (p == NULL)
|
||||
return NULL;
|
||||
|
||||
g_hooks.capacity *= 2;
|
||||
g_hooks.pItems = p;
|
||||
}
|
||||
|
||||
return &g_hooks.pItems[g_hooks.size++];
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static void DeleteHookEntry(UINT pos)
|
||||
{
|
||||
if (pos < g_hooks.size - 1)
|
||||
g_hooks.pItems[pos] = g_hooks.pItems[g_hooks.size - 1];
|
||||
|
||||
g_hooks.size--;
|
||||
|
||||
if (g_hooks.capacity / 2 >= INITIAL_HOOK_CAPACITY && g_hooks.capacity / 2 >= g_hooks.size)
|
||||
{
|
||||
PHOOK_ENTRY p = (PHOOK_ENTRY)HeapReAlloc(
|
||||
g_hHeap, 0, g_hooks.pItems, (g_hooks.capacity / 2) * sizeof(HOOK_ENTRY));
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
g_hooks.capacity /= 2;
|
||||
g_hooks.pItems = p;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static DWORD_PTR FindOldIP(PHOOK_ENTRY pHook, DWORD_PTR ip)
|
||||
{
|
||||
UINT i;
|
||||
|
||||
if (pHook->patchAbove && ip == ((DWORD_PTR)pHook->pTarget - sizeof(JMP_REL)))
|
||||
return (DWORD_PTR)pHook->pTarget;
|
||||
|
||||
for (i = 0; i < pHook->nIP; ++i)
|
||||
{
|
||||
if (ip == ((DWORD_PTR)pHook->pTrampoline + pHook->newIPs[i]))
|
||||
return (DWORD_PTR)pHook->pTarget + pHook->oldIPs[i];
|
||||
}
|
||||
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
// Check relay function.
|
||||
if (ip == (DWORD_PTR)pHook->pDetour)
|
||||
return (DWORD_PTR)pHook->pTarget;
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static DWORD_PTR FindNewIP(PHOOK_ENTRY pHook, DWORD_PTR ip)
|
||||
{
|
||||
UINT i;
|
||||
for (i = 0; i < pHook->nIP; ++i)
|
||||
{
|
||||
if (ip == ((DWORD_PTR)pHook->pTarget + pHook->oldIPs[i]))
|
||||
return (DWORD_PTR)pHook->pTrampoline + pHook->newIPs[i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static void ProcessThreadIPs(HANDLE hThread, UINT pos, UINT action)
|
||||
{
|
||||
// If the thread suspended in the overwritten area,
|
||||
// move IP to the proper address.
|
||||
|
||||
CONTEXT c;
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
DWORD64 *pIP = &c.Rip;
|
||||
#else
|
||||
DWORD *pIP = &c.Eip;
|
||||
#endif
|
||||
UINT count;
|
||||
|
||||
c.ContextFlags = CONTEXT_CONTROL;
|
||||
if (!GetThreadContext(hThread, &c))
|
||||
return;
|
||||
|
||||
if (pos == ALL_HOOKS_POS)
|
||||
{
|
||||
pos = 0;
|
||||
count = g_hooks.size;
|
||||
}
|
||||
else
|
||||
{
|
||||
count = pos + 1;
|
||||
}
|
||||
|
||||
for (; pos < count; ++pos)
|
||||
{
|
||||
PHOOK_ENTRY pHook = &g_hooks.pItems[pos];
|
||||
BOOL enable;
|
||||
DWORD_PTR ip;
|
||||
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_DISABLE:
|
||||
enable = FALSE;
|
||||
break;
|
||||
|
||||
case ACTION_ENABLE:
|
||||
enable = TRUE;
|
||||
break;
|
||||
|
||||
default: // ACTION_APPLY_QUEUED
|
||||
enable = pHook->queueEnable;
|
||||
break;
|
||||
}
|
||||
if (pHook->isEnabled == enable)
|
||||
continue;
|
||||
|
||||
if (enable)
|
||||
ip = FindNewIP(pHook, *pIP);
|
||||
else
|
||||
ip = FindOldIP(pHook, *pIP);
|
||||
|
||||
if (ip != 0)
|
||||
{
|
||||
*pIP = ip;
|
||||
SetThreadContext(hThread, &c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static VOID EnumerateThreads(PFROZEN_THREADS pThreads)
|
||||
{
|
||||
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
|
||||
if (hSnapshot != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
THREADENTRY32 te;
|
||||
te.dwSize = sizeof(THREADENTRY32);
|
||||
if (Thread32First(hSnapshot, &te))
|
||||
{
|
||||
do
|
||||
{
|
||||
if (te.dwSize >= (FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) + sizeof(DWORD))
|
||||
&& te.th32OwnerProcessID == GetCurrentProcessId()
|
||||
&& te.th32ThreadID != GetCurrentThreadId())
|
||||
{
|
||||
if (pThreads->pItems == NULL)
|
||||
{
|
||||
pThreads->capacity = INITIAL_THREAD_CAPACITY;
|
||||
pThreads->pItems
|
||||
= (LPDWORD)HeapAlloc(g_hHeap, 0, pThreads->capacity * sizeof(DWORD));
|
||||
if (pThreads->pItems == NULL)
|
||||
break;
|
||||
}
|
||||
else if (pThreads->size >= pThreads->capacity)
|
||||
{
|
||||
LPDWORD p = (LPDWORD)HeapReAlloc(
|
||||
g_hHeap, 0, pThreads->pItems, (pThreads->capacity * 2) * sizeof(DWORD));
|
||||
if (p == NULL)
|
||||
break;
|
||||
|
||||
pThreads->capacity *= 2;
|
||||
pThreads->pItems = p;
|
||||
}
|
||||
pThreads->pItems[pThreads->size++] = te.th32ThreadID;
|
||||
}
|
||||
|
||||
te.dwSize = sizeof(THREADENTRY32);
|
||||
} while (Thread32Next(hSnapshot, &te));
|
||||
}
|
||||
CloseHandle(hSnapshot);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static VOID Freeze(PFROZEN_THREADS pThreads, UINT pos, UINT action)
|
||||
{
|
||||
pThreads->pItems = NULL;
|
||||
pThreads->capacity = 0;
|
||||
pThreads->size = 0;
|
||||
EnumerateThreads(pThreads);
|
||||
|
||||
if (pThreads->pItems != NULL)
|
||||
{
|
||||
UINT i;
|
||||
for (i = 0; i < pThreads->size; ++i)
|
||||
{
|
||||
HANDLE hThread = OpenThread(THREAD_ACCESS, FALSE, pThreads->pItems[i]);
|
||||
if (hThread != NULL)
|
||||
{
|
||||
SuspendThread(hThread);
|
||||
ProcessThreadIPs(hThread, pos, action);
|
||||
CloseHandle(hThread);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static VOID Unfreeze(PFROZEN_THREADS pThreads)
|
||||
{
|
||||
if (pThreads->pItems != NULL)
|
||||
{
|
||||
UINT i;
|
||||
for (i = 0; i < pThreads->size; ++i)
|
||||
{
|
||||
HANDLE hThread = OpenThread(THREAD_ACCESS, FALSE, pThreads->pItems[i]);
|
||||
if (hThread != NULL)
|
||||
{
|
||||
ResumeThread(hThread);
|
||||
CloseHandle(hThread);
|
||||
}
|
||||
}
|
||||
|
||||
HeapFree(g_hHeap, 0, pThreads->pItems);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static MH_STATUS EnableHookLL(UINT pos, BOOL enable)
|
||||
{
|
||||
PHOOK_ENTRY pHook = &g_hooks.pItems[pos];
|
||||
DWORD oldProtect;
|
||||
SIZE_T patchSize = sizeof(JMP_REL);
|
||||
LPBYTE pPatchTarget = (LPBYTE)pHook->pTarget;
|
||||
|
||||
if (pHook->patchAbove)
|
||||
{
|
||||
pPatchTarget -= sizeof(JMP_REL);
|
||||
patchSize += sizeof(JMP_REL_SHORT);
|
||||
}
|
||||
|
||||
if (!VirtualProtect(pPatchTarget, patchSize, PAGE_EXECUTE_READWRITE, &oldProtect))
|
||||
return MH_ERROR_MEMORY_PROTECT;
|
||||
|
||||
if (enable)
|
||||
{
|
||||
PJMP_REL pJmp = (PJMP_REL)pPatchTarget;
|
||||
pJmp->opcode = 0xE9;
|
||||
pJmp->operand = (UINT32)((LPBYTE)pHook->pDetour - (pPatchTarget + sizeof(JMP_REL)));
|
||||
|
||||
if (pHook->patchAbove)
|
||||
{
|
||||
PJMP_REL_SHORT pShortJmp = (PJMP_REL_SHORT)pHook->pTarget;
|
||||
pShortJmp->opcode = 0xEB;
|
||||
pShortJmp->operand = (UINT8)(0 - (sizeof(JMP_REL_SHORT) + sizeof(JMP_REL)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pHook->patchAbove)
|
||||
memcpy(pPatchTarget, pHook->backup, sizeof(JMP_REL) + sizeof(JMP_REL_SHORT));
|
||||
else
|
||||
memcpy(pPatchTarget, pHook->backup, sizeof(JMP_REL));
|
||||
}
|
||||
|
||||
VirtualProtect(pPatchTarget, patchSize, oldProtect, &oldProtect);
|
||||
|
||||
// Just-in-case measure.
|
||||
FlushInstructionCache(GetCurrentProcess(), pPatchTarget, patchSize);
|
||||
|
||||
pHook->isEnabled = enable;
|
||||
pHook->queueEnable = enable;
|
||||
|
||||
return MH_OK;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static MH_STATUS EnableAllHooksLL(BOOL enable)
|
||||
{
|
||||
MH_STATUS status = MH_OK;
|
||||
UINT i, first = INVALID_HOOK_POS;
|
||||
|
||||
for (i = 0; i < g_hooks.size; ++i)
|
||||
{
|
||||
if (g_hooks.pItems[i].isEnabled != enable)
|
||||
{
|
||||
first = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (first != INVALID_HOOK_POS)
|
||||
{
|
||||
FROZEN_THREADS threads;
|
||||
Freeze(&threads, ALL_HOOKS_POS, enable ? ACTION_ENABLE : ACTION_DISABLE);
|
||||
|
||||
for (i = first; i < g_hooks.size; ++i)
|
||||
{
|
||||
if (g_hooks.pItems[i].isEnabled != enable)
|
||||
{
|
||||
status = EnableHookLL(i, enable);
|
||||
if (status != MH_OK)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Unfreeze(&threads);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static VOID EnterSpinLock(VOID)
|
||||
{
|
||||
SIZE_T spinCount = 0;
|
||||
|
||||
// Wait until the flag is FALSE.
|
||||
while (InterlockedCompareExchange(&g_isLocked, TRUE, FALSE) != FALSE)
|
||||
{
|
||||
// No need to generate a memory barrier here, since InterlockedCompareExchange()
|
||||
// generates a full memory barrier itself.
|
||||
|
||||
// Prevent the loop from being too busy.
|
||||
if (spinCount < 32)
|
||||
Sleep(0);
|
||||
else
|
||||
Sleep(1);
|
||||
|
||||
spinCount++;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static VOID LeaveSpinLock(VOID)
|
||||
{
|
||||
// No need to generate a memory barrier here, since InterlockedExchange()
|
||||
// generates a full memory barrier itself.
|
||||
|
||||
InterlockedExchange(&g_isLocked, FALSE);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
MH_STATUS WINAPI MH_Initialize(VOID)
|
||||
{
|
||||
MH_STATUS status = MH_OK;
|
||||
|
||||
EnterSpinLock();
|
||||
|
||||
if (g_hHeap == NULL)
|
||||
{
|
||||
g_hHeap = HeapCreate(0, 0, 0);
|
||||
if (g_hHeap != NULL)
|
||||
{
|
||||
// Initialize the internal function buffer.
|
||||
InitializeBuffer();
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MH_ERROR_MEMORY_ALLOC;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MH_ERROR_ALREADY_INITIALIZED;
|
||||
}
|
||||
|
||||
LeaveSpinLock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
MH_STATUS WINAPI MH_Uninitialize(VOID)
|
||||
{
|
||||
MH_STATUS status = MH_OK;
|
||||
|
||||
EnterSpinLock();
|
||||
|
||||
if (g_hHeap != NULL)
|
||||
{
|
||||
status = EnableAllHooksLL(FALSE);
|
||||
if (status == MH_OK)
|
||||
{
|
||||
// Free the internal function buffer.
|
||||
|
||||
// HeapFree is actually not required, but some tools detect a false
|
||||
// memory leak without HeapFree.
|
||||
|
||||
UninitializeBuffer();
|
||||
|
||||
HeapFree(g_hHeap, 0, g_hooks.pItems);
|
||||
HeapDestroy(g_hHeap);
|
||||
|
||||
g_hHeap = NULL;
|
||||
|
||||
g_hooks.pItems = NULL;
|
||||
g_hooks.capacity = 0;
|
||||
g_hooks.size = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MH_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
LeaveSpinLock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal)
|
||||
{
|
||||
MH_STATUS status = MH_OK;
|
||||
|
||||
EnterSpinLock();
|
||||
|
||||
if (g_hHeap != NULL)
|
||||
{
|
||||
if (IsExecutableAddress(pTarget) && IsExecutableAddress(pDetour))
|
||||
{
|
||||
UINT pos = FindHookEntry(pTarget);
|
||||
if (pos == INVALID_HOOK_POS)
|
||||
{
|
||||
LPVOID pBuffer = AllocateBuffer(pTarget);
|
||||
if (pBuffer != NULL)
|
||||
{
|
||||
TRAMPOLINE ct;
|
||||
|
||||
ct.pTarget = pTarget;
|
||||
ct.pDetour = pDetour;
|
||||
ct.pTrampoline = pBuffer;
|
||||
if (CreateTrampolineFunction(&ct))
|
||||
{
|
||||
PHOOK_ENTRY pHook = AddHookEntry();
|
||||
if (pHook != NULL)
|
||||
{
|
||||
pHook->pTarget = ct.pTarget;
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
pHook->pDetour = ct.pRelay;
|
||||
#else
|
||||
pHook->pDetour = ct.pDetour;
|
||||
#endif
|
||||
pHook->pTrampoline = ct.pTrampoline;
|
||||
pHook->patchAbove = ct.patchAbove;
|
||||
pHook->isEnabled = FALSE;
|
||||
pHook->queueEnable = FALSE;
|
||||
pHook->nIP = ct.nIP;
|
||||
memcpy(pHook->oldIPs, ct.oldIPs, ARRAYSIZE(ct.oldIPs));
|
||||
memcpy(pHook->newIPs, ct.newIPs, ARRAYSIZE(ct.newIPs));
|
||||
|
||||
// Back up the target function.
|
||||
|
||||
if (ct.patchAbove)
|
||||
{
|
||||
memcpy(
|
||||
pHook->backup,
|
||||
(LPBYTE)pTarget - sizeof(JMP_REL),
|
||||
sizeof(JMP_REL) + sizeof(JMP_REL_SHORT));
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(pHook->backup, pTarget, sizeof(JMP_REL));
|
||||
}
|
||||
|
||||
if (ppOriginal != NULL)
|
||||
*ppOriginal = pHook->pTrampoline;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MH_ERROR_MEMORY_ALLOC;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MH_ERROR_UNSUPPORTED_FUNCTION;
|
||||
}
|
||||
|
||||
if (status != MH_OK)
|
||||
{
|
||||
FreeBuffer(pBuffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MH_ERROR_MEMORY_ALLOC;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MH_ERROR_ALREADY_CREATED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MH_ERROR_NOT_EXECUTABLE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MH_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
LeaveSpinLock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget)
|
||||
{
|
||||
MH_STATUS status = MH_OK;
|
||||
|
||||
EnterSpinLock();
|
||||
|
||||
if (g_hHeap != NULL)
|
||||
{
|
||||
UINT pos = FindHookEntry(pTarget);
|
||||
if (pos != INVALID_HOOK_POS)
|
||||
{
|
||||
if (g_hooks.pItems[pos].isEnabled)
|
||||
{
|
||||
FROZEN_THREADS threads;
|
||||
Freeze(&threads, pos, ACTION_DISABLE);
|
||||
|
||||
status = EnableHookLL(pos, FALSE);
|
||||
|
||||
Unfreeze(&threads);
|
||||
}
|
||||
|
||||
if (status == MH_OK)
|
||||
{
|
||||
FreeBuffer(g_hooks.pItems[pos].pTrampoline);
|
||||
DeleteHookEntry(pos);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MH_ERROR_NOT_CREATED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MH_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
LeaveSpinLock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static MH_STATUS EnableHook(LPVOID pTarget, BOOL enable)
|
||||
{
|
||||
MH_STATUS status = MH_OK;
|
||||
|
||||
EnterSpinLock();
|
||||
|
||||
if (g_hHeap != NULL)
|
||||
{
|
||||
if (pTarget == MH_ALL_HOOKS)
|
||||
{
|
||||
status = EnableAllHooksLL(enable);
|
||||
}
|
||||
else
|
||||
{
|
||||
FROZEN_THREADS threads;
|
||||
UINT pos = FindHookEntry(pTarget);
|
||||
if (pos != INVALID_HOOK_POS)
|
||||
{
|
||||
if (g_hooks.pItems[pos].isEnabled != enable)
|
||||
{
|
||||
Freeze(&threads, pos, ACTION_ENABLE);
|
||||
|
||||
status = EnableHookLL(pos, enable);
|
||||
|
||||
Unfreeze(&threads);
|
||||
}
|
||||
else
|
||||
{
|
||||
status = enable ? MH_ERROR_ENABLED : MH_ERROR_DISABLED;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MH_ERROR_NOT_CREATED;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MH_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
LeaveSpinLock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget)
|
||||
{
|
||||
return EnableHook(pTarget, TRUE);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget)
|
||||
{
|
||||
return EnableHook(pTarget, FALSE);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static MH_STATUS QueueHook(LPVOID pTarget, BOOL queueEnable)
|
||||
{
|
||||
MH_STATUS status = MH_OK;
|
||||
|
||||
EnterSpinLock();
|
||||
|
||||
if (g_hHeap != NULL)
|
||||
{
|
||||
if (pTarget == MH_ALL_HOOKS)
|
||||
{
|
||||
UINT i;
|
||||
for (i = 0; i < g_hooks.size; ++i)
|
||||
g_hooks.pItems[i].queueEnable = queueEnable;
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT pos = FindHookEntry(pTarget);
|
||||
if (pos != INVALID_HOOK_POS)
|
||||
{
|
||||
g_hooks.pItems[pos].queueEnable = queueEnable;
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MH_ERROR_NOT_CREATED;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MH_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
LeaveSpinLock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget)
|
||||
{
|
||||
return QueueHook(pTarget, TRUE);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget)
|
||||
{
|
||||
return QueueHook(pTarget, FALSE);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
MH_STATUS WINAPI MH_ApplyQueued(VOID)
|
||||
{
|
||||
MH_STATUS status = MH_OK;
|
||||
UINT i, first = INVALID_HOOK_POS;
|
||||
|
||||
EnterSpinLock();
|
||||
|
||||
if (g_hHeap != NULL)
|
||||
{
|
||||
for (i = 0; i < g_hooks.size; ++i)
|
||||
{
|
||||
if (g_hooks.pItems[i].isEnabled != g_hooks.pItems[i].queueEnable)
|
||||
{
|
||||
first = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (first != INVALID_HOOK_POS)
|
||||
{
|
||||
FROZEN_THREADS threads;
|
||||
Freeze(&threads, ALL_HOOKS_POS, ACTION_APPLY_QUEUED);
|
||||
|
||||
for (i = first; i < g_hooks.size; ++i)
|
||||
{
|
||||
PHOOK_ENTRY pHook = &g_hooks.pItems[i];
|
||||
if (pHook->isEnabled != pHook->queueEnable)
|
||||
{
|
||||
status = EnableHookLL(i, pHook->queueEnable);
|
||||
if (status != MH_OK)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Unfreeze(&threads);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
status = MH_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
LeaveSpinLock();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
MH_STATUS WINAPI MH_CreateHookApiEx(
|
||||
LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour,
|
||||
LPVOID *ppOriginal, LPVOID *ppTarget)
|
||||
{
|
||||
HMODULE hModule;
|
||||
LPVOID pTarget;
|
||||
|
||||
hModule = GetModuleHandleW(pszModule);
|
||||
if (hModule == NULL)
|
||||
return MH_ERROR_MODULE_NOT_FOUND;
|
||||
|
||||
pTarget = (LPVOID)GetProcAddress(hModule, pszProcName);
|
||||
if (pTarget == NULL)
|
||||
return MH_ERROR_FUNCTION_NOT_FOUND;
|
||||
|
||||
if(ppTarget != NULL)
|
||||
*ppTarget = pTarget;
|
||||
|
||||
return MH_CreateHook(pTarget, pDetour, ppOriginal);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
MH_STATUS WINAPI MH_CreateHookApi(
|
||||
LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal)
|
||||
{
|
||||
return MH_CreateHookApiEx(pszModule, pszProcName, pDetour, ppOriginal, NULL);
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
const char * WINAPI MH_StatusToString(MH_STATUS status)
|
||||
{
|
||||
#define MH_ST2STR(x) \
|
||||
case x: \
|
||||
return #x;
|
||||
|
||||
switch (status) {
|
||||
MH_ST2STR(MH_UNKNOWN)
|
||||
MH_ST2STR(MH_OK)
|
||||
MH_ST2STR(MH_ERROR_ALREADY_INITIALIZED)
|
||||
MH_ST2STR(MH_ERROR_NOT_INITIALIZED)
|
||||
MH_ST2STR(MH_ERROR_ALREADY_CREATED)
|
||||
MH_ST2STR(MH_ERROR_NOT_CREATED)
|
||||
MH_ST2STR(MH_ERROR_ENABLED)
|
||||
MH_ST2STR(MH_ERROR_DISABLED)
|
||||
MH_ST2STR(MH_ERROR_NOT_EXECUTABLE)
|
||||
MH_ST2STR(MH_ERROR_UNSUPPORTED_FUNCTION)
|
||||
MH_ST2STR(MH_ERROR_MEMORY_ALLOC)
|
||||
MH_ST2STR(MH_ERROR_MEMORY_PROTECT)
|
||||
MH_ST2STR(MH_ERROR_MODULE_NOT_FOUND)
|
||||
MH_ST2STR(MH_ERROR_FUNCTION_NOT_FOUND)
|
||||
}
|
||||
|
||||
#undef MH_ST2STR
|
||||
|
||||
return "(unknown)";
|
||||
}
|
||||
320
DevourClient/Dependencies/Minhook/src/trampoline.c
Normal file
320
DevourClient/Dependencies/Minhook/src/trampoline.c
Normal file
@@ -0,0 +1,320 @@
|
||||
/*
|
||||
* MinHook - The Minimalistic API Hooking Library for x64/x86
|
||||
* Copyright (C) 2009-2017 Tsuda Kageyu.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
#ifndef ARRAYSIZE
|
||||
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
|
||||
#endif
|
||||
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
#include "./hde/hde64.h"
|
||||
typedef hde64s HDE;
|
||||
#define HDE_DISASM(code, hs) hde64_disasm(code, hs)
|
||||
#else
|
||||
#include "./hde/hde32.h"
|
||||
typedef hde32s HDE;
|
||||
#define HDE_DISASM(code, hs) hde32_disasm(code, hs)
|
||||
#endif
|
||||
|
||||
#include "trampoline.h"
|
||||
#include "buffer.h"
|
||||
|
||||
// Maximum size of a trampoline function.
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
#define TRAMPOLINE_MAX_SIZE (MEMORY_SLOT_SIZE - sizeof(JMP_ABS))
|
||||
#else
|
||||
#define TRAMPOLINE_MAX_SIZE MEMORY_SLOT_SIZE
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
static BOOL IsCodePadding(LPBYTE pInst, UINT size)
|
||||
{
|
||||
UINT i;
|
||||
|
||||
if (pInst[0] != 0x00 && pInst[0] != 0x90 && pInst[0] != 0xCC)
|
||||
return FALSE;
|
||||
|
||||
for (i = 1; i < size; ++i)
|
||||
{
|
||||
if (pInst[i] != pInst[0])
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
BOOL CreateTrampolineFunction(PTRAMPOLINE ct)
|
||||
{
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
CALL_ABS call = {
|
||||
0xFF, 0x15, 0x00000002, // FF15 00000002: CALL [RIP+8]
|
||||
0xEB, 0x08, // EB 08: JMP +10
|
||||
0x0000000000000000ULL // Absolute destination address
|
||||
};
|
||||
JMP_ABS jmp = {
|
||||
0xFF, 0x25, 0x00000000, // FF25 00000000: JMP [RIP+6]
|
||||
0x0000000000000000ULL // Absolute destination address
|
||||
};
|
||||
JCC_ABS jcc = {
|
||||
0x70, 0x0E, // 7* 0E: J** +16
|
||||
0xFF, 0x25, 0x00000000, // FF25 00000000: JMP [RIP+6]
|
||||
0x0000000000000000ULL // Absolute destination address
|
||||
};
|
||||
#else
|
||||
CALL_REL call = {
|
||||
0xE8, // E8 xxxxxxxx: CALL +5+xxxxxxxx
|
||||
0x00000000 // Relative destination address
|
||||
};
|
||||
JMP_REL jmp = {
|
||||
0xE9, // E9 xxxxxxxx: JMP +5+xxxxxxxx
|
||||
0x00000000 // Relative destination address
|
||||
};
|
||||
JCC_REL jcc = {
|
||||
0x0F, 0x80, // 0F8* xxxxxxxx: J** +6+xxxxxxxx
|
||||
0x00000000 // Relative destination address
|
||||
};
|
||||
#endif
|
||||
|
||||
UINT8 oldPos = 0;
|
||||
UINT8 newPos = 0;
|
||||
ULONG_PTR jmpDest = 0; // Destination address of an internal jump.
|
||||
BOOL finished = FALSE; // Is the function completed?
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
UINT8 instBuf[16];
|
||||
#endif
|
||||
|
||||
ct->patchAbove = FALSE;
|
||||
ct->nIP = 0;
|
||||
|
||||
do
|
||||
{
|
||||
HDE hs;
|
||||
UINT copySize;
|
||||
LPVOID pCopySrc;
|
||||
ULONG_PTR pOldInst = (ULONG_PTR)ct->pTarget + oldPos;
|
||||
ULONG_PTR pNewInst = (ULONG_PTR)ct->pTrampoline + newPos;
|
||||
|
||||
copySize = HDE_DISASM((LPVOID)pOldInst, &hs);
|
||||
if (hs.flags & F_ERROR)
|
||||
return FALSE;
|
||||
|
||||
pCopySrc = (LPVOID)pOldInst;
|
||||
if (oldPos >= sizeof(JMP_REL))
|
||||
{
|
||||
// The trampoline function is long enough.
|
||||
// Complete the function with the jump to the target function.
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
jmp.address = pOldInst;
|
||||
#else
|
||||
jmp.operand = (UINT32)(pOldInst - (pNewInst + sizeof(jmp)));
|
||||
#endif
|
||||
pCopySrc = &jmp;
|
||||
copySize = sizeof(jmp);
|
||||
|
||||
finished = TRUE;
|
||||
}
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
else if ((hs.modrm & 0xC7) == 0x05)
|
||||
{
|
||||
// Instructions using RIP relative addressing. (ModR/M = 00???101B)
|
||||
|
||||
// Modify the RIP relative address.
|
||||
PUINT32 pRelAddr;
|
||||
|
||||
// Avoid using memcpy to reduce the footprint.
|
||||
#ifndef _MSC_VER
|
||||
memcpy(instBuf, (LPBYTE)pOldInst, copySize);
|
||||
#else
|
||||
__movsb(instBuf, (LPBYTE)pOldInst, copySize);
|
||||
#endif
|
||||
pCopySrc = instBuf;
|
||||
|
||||
// Relative address is stored at (instruction length - immediate value length - 4).
|
||||
pRelAddr = (PUINT32)(instBuf + hs.len - ((hs.flags & 0x3C) >> 2) - 4);
|
||||
*pRelAddr
|
||||
= (UINT32)((pOldInst + hs.len + (INT32)hs.disp.disp32) - (pNewInst + hs.len));
|
||||
|
||||
// Complete the function if JMP (FF /4).
|
||||
if (hs.opcode == 0xFF && hs.modrm_reg == 4)
|
||||
finished = TRUE;
|
||||
}
|
||||
#endif
|
||||
else if (hs.opcode == 0xE8)
|
||||
{
|
||||
// Direct relative CALL
|
||||
ULONG_PTR dest = pOldInst + hs.len + (INT32)hs.imm.imm32;
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
call.address = dest;
|
||||
#else
|
||||
call.operand = (UINT32)(dest - (pNewInst + sizeof(call)));
|
||||
#endif
|
||||
pCopySrc = &call;
|
||||
copySize = sizeof(call);
|
||||
}
|
||||
else if ((hs.opcode & 0xFD) == 0xE9)
|
||||
{
|
||||
// Direct relative JMP (EB or E9)
|
||||
ULONG_PTR dest = pOldInst + hs.len;
|
||||
|
||||
if (hs.opcode == 0xEB) // isShort jmp
|
||||
dest += (INT8)hs.imm.imm8;
|
||||
else
|
||||
dest += (INT32)hs.imm.imm32;
|
||||
|
||||
// Simply copy an internal jump.
|
||||
if ((ULONG_PTR)ct->pTarget <= dest
|
||||
&& dest < ((ULONG_PTR)ct->pTarget + sizeof(JMP_REL)))
|
||||
{
|
||||
if (jmpDest < dest)
|
||||
jmpDest = dest;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
jmp.address = dest;
|
||||
#else
|
||||
jmp.operand = (UINT32)(dest - (pNewInst + sizeof(jmp)));
|
||||
#endif
|
||||
pCopySrc = &jmp;
|
||||
copySize = sizeof(jmp);
|
||||
|
||||
// Exit the function If it is not in the branch
|
||||
finished = (pOldInst >= jmpDest);
|
||||
}
|
||||
}
|
||||
else if ((hs.opcode & 0xF0) == 0x70
|
||||
|| (hs.opcode & 0xFC) == 0xE0
|
||||
|| (hs.opcode2 & 0xF0) == 0x80)
|
||||
{
|
||||
// Direct relative Jcc
|
||||
ULONG_PTR dest = pOldInst + hs.len;
|
||||
|
||||
if ((hs.opcode & 0xF0) == 0x70 // Jcc
|
||||
|| (hs.opcode & 0xFC) == 0xE0) // LOOPNZ/LOOPZ/LOOP/JECXZ
|
||||
dest += (INT8)hs.imm.imm8;
|
||||
else
|
||||
dest += (INT32)hs.imm.imm32;
|
||||
|
||||
// Simply copy an internal jump.
|
||||
if ((ULONG_PTR)ct->pTarget <= dest
|
||||
&& dest < ((ULONG_PTR)ct->pTarget + sizeof(JMP_REL)))
|
||||
{
|
||||
if (jmpDest < dest)
|
||||
jmpDest = dest;
|
||||
}
|
||||
else if ((hs.opcode & 0xFC) == 0xE0)
|
||||
{
|
||||
// LOOPNZ/LOOPZ/LOOP/JCXZ/JECXZ to the outside are not supported.
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT8 cond = ((hs.opcode != 0x0F ? hs.opcode : hs.opcode2) & 0x0F);
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
// Invert the condition in x64 mode to simplify the conditional jump logic.
|
||||
jcc.opcode = 0x71 ^ cond;
|
||||
jcc.address = dest;
|
||||
#else
|
||||
jcc.opcode1 = 0x80 | cond;
|
||||
jcc.operand = (UINT32)(dest - (pNewInst + sizeof(jcc)));
|
||||
#endif
|
||||
pCopySrc = &jcc;
|
||||
copySize = sizeof(jcc);
|
||||
}
|
||||
}
|
||||
else if ((hs.opcode & 0xFE) == 0xC2)
|
||||
{
|
||||
// RET (C2 or C3)
|
||||
|
||||
// Complete the function if not in a branch.
|
||||
finished = (pOldInst >= jmpDest);
|
||||
}
|
||||
|
||||
// Can't alter the instruction length in a branch.
|
||||
if (pOldInst < jmpDest && copySize != hs.len)
|
||||
return FALSE;
|
||||
|
||||
// Trampoline function is too large.
|
||||
if ((newPos + copySize) > TRAMPOLINE_MAX_SIZE)
|
||||
return FALSE;
|
||||
|
||||
// Trampoline function has too many instructions.
|
||||
if (ct->nIP >= ARRAYSIZE(ct->oldIPs))
|
||||
return FALSE;
|
||||
|
||||
ct->oldIPs[ct->nIP] = oldPos;
|
||||
ct->newIPs[ct->nIP] = newPos;
|
||||
ct->nIP++;
|
||||
|
||||
// Avoid using memcpy to reduce the footprint.
|
||||
#ifndef _MSC_VER
|
||||
memcpy((LPBYTE)ct->pTrampoline + newPos, pCopySrc, copySize);
|
||||
#else
|
||||
__movsb((LPBYTE)ct->pTrampoline + newPos, pCopySrc, copySize);
|
||||
#endif
|
||||
newPos += copySize;
|
||||
oldPos += hs.len;
|
||||
}
|
||||
while (!finished);
|
||||
|
||||
// Is there enough place for a long jump?
|
||||
if (oldPos < sizeof(JMP_REL)
|
||||
&& !IsCodePadding((LPBYTE)ct->pTarget + oldPos, sizeof(JMP_REL) - oldPos))
|
||||
{
|
||||
// Is there enough place for a short jump?
|
||||
if (oldPos < sizeof(JMP_REL_SHORT)
|
||||
&& !IsCodePadding((LPBYTE)ct->pTarget + oldPos, sizeof(JMP_REL_SHORT) - oldPos))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Can we place the long jump above the function?
|
||||
if (!IsExecutableAddress((LPBYTE)ct->pTarget - sizeof(JMP_REL)))
|
||||
return FALSE;
|
||||
|
||||
if (!IsCodePadding((LPBYTE)ct->pTarget - sizeof(JMP_REL), sizeof(JMP_REL)))
|
||||
return FALSE;
|
||||
|
||||
ct->patchAbove = TRUE;
|
||||
}
|
||||
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
// Create a relay function.
|
||||
jmp.address = (ULONG_PTR)ct->pDetour;
|
||||
|
||||
ct->pRelay = (LPBYTE)ct->pTrampoline + newPos;
|
||||
memcpy(ct->pRelay, &jmp, sizeof(jmp));
|
||||
#endif
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
105
DevourClient/Dependencies/Minhook/src/trampoline.h
Normal file
105
DevourClient/Dependencies/Minhook/src/trampoline.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* MinHook - The Minimalistic API Hooking Library for x64/x86
|
||||
* Copyright (C) 2009-2017 Tsuda Kageyu.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
// Structs for writing x86/x64 instructions.
|
||||
|
||||
// 8-bit relative jump.
|
||||
typedef struct _JMP_REL_SHORT
|
||||
{
|
||||
UINT8 opcode; // EB xx: JMP +2+xx
|
||||
UINT8 operand;
|
||||
} JMP_REL_SHORT, *PJMP_REL_SHORT;
|
||||
|
||||
// 32-bit direct relative jump/call.
|
||||
typedef struct _JMP_REL
|
||||
{
|
||||
UINT8 opcode; // E9/E8 xxxxxxxx: JMP/CALL +5+xxxxxxxx
|
||||
UINT32 operand; // Relative destination address
|
||||
} JMP_REL, *PJMP_REL, CALL_REL;
|
||||
|
||||
// 64-bit indirect absolute jump.
|
||||
typedef struct _JMP_ABS
|
||||
{
|
||||
UINT8 opcode0; // FF25 00000000: JMP [+6]
|
||||
UINT8 opcode1;
|
||||
UINT32 dummy;
|
||||
UINT64 address; // Absolute destination address
|
||||
} JMP_ABS, *PJMP_ABS;
|
||||
|
||||
// 64-bit indirect absolute call.
|
||||
typedef struct _CALL_ABS
|
||||
{
|
||||
UINT8 opcode0; // FF15 00000002: CALL [+6]
|
||||
UINT8 opcode1;
|
||||
UINT32 dummy0;
|
||||
UINT8 dummy1; // EB 08: JMP +10
|
||||
UINT8 dummy2;
|
||||
UINT64 address; // Absolute destination address
|
||||
} CALL_ABS;
|
||||
|
||||
// 32-bit direct relative conditional jumps.
|
||||
typedef struct _JCC_REL
|
||||
{
|
||||
UINT8 opcode0; // 0F8* xxxxxxxx: J** +6+xxxxxxxx
|
||||
UINT8 opcode1;
|
||||
UINT32 operand; // Relative destination address
|
||||
} JCC_REL;
|
||||
|
||||
// 64bit indirect absolute conditional jumps that x64 lacks.
|
||||
typedef struct _JCC_ABS
|
||||
{
|
||||
UINT8 opcode; // 7* 0E: J** +16
|
||||
UINT8 dummy0;
|
||||
UINT8 dummy1; // FF25 00000000: JMP [+6]
|
||||
UINT8 dummy2;
|
||||
UINT32 dummy3;
|
||||
UINT64 address; // Absolute destination address
|
||||
} JCC_ABS;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
typedef struct _TRAMPOLINE
|
||||
{
|
||||
LPVOID pTarget; // [In] Address of the target function.
|
||||
LPVOID pDetour; // [In] Address of the detour function.
|
||||
LPVOID pTrampoline; // [In] Buffer address for the trampoline and relay function.
|
||||
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
LPVOID pRelay; // [Out] Address of the relay function.
|
||||
#endif
|
||||
BOOL patchAbove; // [Out] Should use the hot patch area?
|
||||
UINT nIP; // [Out] Number of the instruction boundaries.
|
||||
UINT8 oldIPs[8]; // [Out] Instruction boundaries of the target function.
|
||||
UINT8 newIPs[8]; // [Out] Instruction boundaries of the trampoline function.
|
||||
} TRAMPOLINE, *PTRAMPOLINE;
|
||||
|
||||
BOOL CreateTrampolineFunction(PTRAMPOLINE ct);
|
||||
123
DevourClient/Dependencies/imgui/imconfig.h
Normal file
123
DevourClient/Dependencies/imgui/imconfig.h
Normal file
@@ -0,0 +1,123 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// COMPILE-TIME OPTIONS FOR DEAR IMGUI
|
||||
// Runtime options (clipboard callbacks, enabling various features, etc.) can generally be set via the ImGuiIO structure.
|
||||
// You can use ImGui::SetAllocatorFunctions() before calling ImGui::CreateContext() to rewire memory allocation functions.
|
||||
//-----------------------------------------------------------------------------
|
||||
// A) You may edit imconfig.h (and not overwrite it when updating Dear ImGui, or maintain a patch/rebased branch with your modifications to it)
|
||||
// B) or '#define IMGUI_USER_CONFIG "my_imgui_config.h"' in your project and then add directives in your own file without touching this template.
|
||||
//-----------------------------------------------------------------------------
|
||||
// You need to make sure that configuration settings are defined consistently _everywhere_ Dear ImGui is used, which include the imgui*.cpp
|
||||
// files but also _any_ of your code that uses Dear ImGui. This is because some compile-time options have an affect on data structures.
|
||||
// Defining those options in imconfig.h will ensure every compilation unit gets to see the same data structure layouts.
|
||||
// Call IMGUI_CHECKVERSION() from your .cpp files to verify that the data structures your files are using are matching the ones imgui.cpp is using.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#pragma once
|
||||
|
||||
//---- Define assertion handler. Defaults to calling assert().
|
||||
// If your macro uses multiple statements, make sure is enclosed in a 'do { .. } while (0)' block so it can be used as a single statement.
|
||||
//#define IM_ASSERT(_EXPR) MyAssert(_EXPR)
|
||||
//#define IM_ASSERT(_EXPR) ((void)(_EXPR)) // Disable asserts
|
||||
|
||||
//---- Define attributes of all API symbols declarations, e.g. for DLL under Windows
|
||||
// Using Dear ImGui via a shared library is not recommended, because of function call overhead and because we don't guarantee backward nor forward ABI compatibility.
|
||||
// DLL users: heaps and globals are not shared across DLL boundaries! You will need to call SetCurrentContext() + SetAllocatorFunctions()
|
||||
// for each static/DLL boundary you are calling from. Read "Context and Memory Allocators" section of imgui.cpp for more details.
|
||||
//#define IMGUI_API __declspec( dllexport )
|
||||
//#define IMGUI_API __declspec( dllimport )
|
||||
|
||||
//---- Don't define obsolete functions/enums/behaviors. Consider enabling from time to time after updating to avoid using soon-to-be obsolete function/names.
|
||||
//#define IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
|
||||
//---- Disable all of Dear ImGui or don't implement standard windows.
|
||||
// It is very strongly recommended to NOT disable the demo windows during development. Please read comments in imgui_demo.cpp.
|
||||
//#define IMGUI_DISABLE // Disable everything: all headers and source files will be empty.
|
||||
//#define IMGUI_DISABLE_DEMO_WINDOWS // Disable demo windows: ShowDemoWindow()/ShowStyleEditor() will be empty. Not recommended.
|
||||
//#define IMGUI_DISABLE_METRICS_WINDOW // Disable metrics/debugger and other debug tools: ShowMetricsWindow() and ShowStackToolWindow() will be empty.
|
||||
|
||||
//---- Don't implement some functions to reduce linkage requirements.
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_CLIPBOARD_FUNCTIONS // [Win32] Don't implement default clipboard handler. Won't use and link with OpenClipboard/GetClipboardData/CloseClipboard etc. (user32.lib/.a, kernel32.lib/.a)
|
||||
//#define IMGUI_ENABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with Visual Studio] Implement default IME handler (require imm32.lib/.a, auto-link for Visual Studio, -limm32 on command-line for MinGW)
|
||||
//#define IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS // [Win32] [Default with non-Visual Studio compilers] Don't implement default IME handler (won't require imm32.lib/.a)
|
||||
//#define IMGUI_DISABLE_WIN32_FUNCTIONS // [Win32] Won't use and link with any Win32 function (clipboard, ime).
|
||||
//#define IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS // [OSX] Implement default OSX clipboard handler (need to link with '-framework ApplicationServices', this is why this is not the default).
|
||||
//#define IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS // Don't implement ImFormatString/ImFormatStringV so you can implement them yourself (e.g. if you don't want to link with vsnprintf)
|
||||
//#define IMGUI_DISABLE_DEFAULT_MATH_FUNCTIONS // Don't implement ImFabs/ImSqrt/ImPow/ImFmod/ImCos/ImSin/ImAcos/ImAtan2 so you can implement them yourself.
|
||||
//#define IMGUI_DISABLE_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle at all (replace them with dummies)
|
||||
//#define IMGUI_DISABLE_DEFAULT_FILE_FUNCTIONS // Don't implement ImFileOpen/ImFileClose/ImFileRead/ImFileWrite and ImFileHandle so you can implement them yourself if you don't want to link with fopen/fclose/fread/fwrite. This will also disable the LogToTTY() function.
|
||||
//#define IMGUI_DISABLE_DEFAULT_ALLOCATORS // Don't implement default allocators calling malloc()/free() to avoid linking with them. You will need to call ImGui::SetAllocatorFunctions().
|
||||
//#define IMGUI_DISABLE_SSE // Disable use of SSE intrinsics even if available
|
||||
|
||||
//---- Include imgui_user.h at the end of imgui.h as a convenience
|
||||
//#define IMGUI_INCLUDE_IMGUI_USER_H
|
||||
|
||||
//---- Pack colors to BGRA8 instead of RGBA8 (to avoid converting from one to another)
|
||||
//#define IMGUI_USE_BGRA_PACKED_COLOR
|
||||
|
||||
//---- Use 32-bit for ImWchar (default is 16-bit) to support unicode planes 1-16. (e.g. point beyond 0xFFFF like emoticons, dingbats, symbols, shapes, ancient languages, etc...)
|
||||
//#define IMGUI_USE_WCHAR32
|
||||
|
||||
//---- Avoid multiple STB libraries implementations, or redefine path/filenames to prioritize another version
|
||||
// By default the embedded implementations are declared static and not available outside of Dear ImGui sources files.
|
||||
//#define IMGUI_STB_TRUETYPE_FILENAME "my_folder/stb_truetype.h"
|
||||
//#define IMGUI_STB_RECT_PACK_FILENAME "my_folder/stb_rect_pack.h"
|
||||
//#define IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION
|
||||
//#define IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION
|
||||
|
||||
//---- Use stb_printf's faster implementation of vsnprintf instead of the one from libc (unless IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS is defined)
|
||||
// Requires 'stb_sprintf.h' to be available in the include path. Compatibility checks of arguments and formats done by clang and GCC will be disabled in order to support the extra formats provided by STB sprintf.
|
||||
// #define IMGUI_USE_STB_SPRINTF
|
||||
|
||||
//---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui)
|
||||
// Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided).
|
||||
// On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'.
|
||||
//#define IMGUI_ENABLE_FREETYPE
|
||||
|
||||
//---- Use stb_truetype to build and rasterize the font atlas (default)
|
||||
// The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend.
|
||||
//#define IMGUI_ENABLE_STB_TRUETYPE
|
||||
|
||||
//---- Define constructor and implicit cast operators to convert back<>forth between your math types and ImVec2/ImVec4.
|
||||
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
|
||||
/*
|
||||
#define IM_VEC2_CLASS_EXTRA \
|
||||
ImVec2(const MyVec2& f) { x = f.x; y = f.y; } \
|
||||
operator MyVec2() const { return MyVec2(x,y); }
|
||||
|
||||
#define IM_VEC4_CLASS_EXTRA \
|
||||
ImVec4(const MyVec4& f) { x = f.x; y = f.y; z = f.z; w = f.w; } \
|
||||
operator MyVec4() const { return MyVec4(x,y,z,w); }
|
||||
*/
|
||||
|
||||
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
|
||||
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
|
||||
// Another way to allow large meshes while keeping 16-bit indices is to handle ImDrawCmd::VtxOffset in your renderer.
|
||||
// Read about ImGuiBackendFlags_RendererHasVtxOffset for details.
|
||||
//#define ImDrawIdx unsigned int
|
||||
|
||||
//---- Override ImDrawCallback signature (will need to modify renderer backends accordingly)
|
||||
//struct ImDrawList;
|
||||
//struct ImDrawCmd;
|
||||
//typedef void (*MyImDrawCallback)(const ImDrawList* draw_list, const ImDrawCmd* cmd, void* my_renderer_user_data);
|
||||
//#define ImDrawCallback MyImDrawCallback
|
||||
|
||||
//---- Debug Tools: Macro to break in Debugger
|
||||
// (use 'Metrics->Tools->Item Picker' to pick widgets with the mouse and break into them for easy debugging.)
|
||||
//#define IM_DEBUG_BREAK IM_ASSERT(0)
|
||||
//#define IM_DEBUG_BREAK __debugbreak()
|
||||
|
||||
//---- Debug Tools: Have the Item Picker break in the ItemAdd() function instead of ItemHoverable(),
|
||||
// (which comes earlier in the code, will catch a few extra items, allow picking items other than Hovered one.)
|
||||
// This adds a small runtime cost which is why it is not enabled by default.
|
||||
//#define IMGUI_DEBUG_TOOL_ITEM_PICKER_EX
|
||||
|
||||
//---- Debug Tools: Enable slower asserts
|
||||
//#define IMGUI_DEBUG_PARANOID
|
||||
|
||||
//---- Tip: You can add extra functions within the ImGui:: namespace, here or in your own headers files.
|
||||
/*
|
||||
namespace ImGui
|
||||
{
|
||||
void MyFunction(const char* name, const MyMatrix44& v);
|
||||
}
|
||||
*/
|
||||
12628
DevourClient/Dependencies/imgui/imgui.cpp
Normal file
12628
DevourClient/Dependencies/imgui/imgui.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2916
DevourClient/Dependencies/imgui/imgui.h
Normal file
2916
DevourClient/Dependencies/imgui/imgui.h
Normal file
File diff suppressed because it is too large
Load Diff
4182
DevourClient/Dependencies/imgui/imgui_draw.cpp
Normal file
4182
DevourClient/Dependencies/imgui/imgui_draw.cpp
Normal file
File diff suppressed because it is too large
Load Diff
594
DevourClient/Dependencies/imgui/imgui_impl_dx11.cpp
Normal file
594
DevourClient/Dependencies/imgui/imgui_impl_dx11.cpp
Normal file
@@ -0,0 +1,594 @@
|
||||
// dear imgui: Renderer Backend for DirectX11
|
||||
// This needs to be used along with a Platform Backend (e.g. Win32)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-05-19: DirectX11: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement)
|
||||
// 2021-02-18: DirectX11: Change blending equation to preserve alpha in output buffer.
|
||||
// 2019-08-01: DirectX11: Fixed code querying the Geometry Shader state (would generally error with Debug layer enabled).
|
||||
// 2019-07-21: DirectX11: Backup, clear and restore Geometry Shader is any is bound when calling ImGui_ImplDX10_RenderDrawData. Clearing Hull/Domain/Compute shaders without backup/restore.
|
||||
// 2019-05-29: DirectX11: Added support for large mesh (64K+ vertices), enable ImGuiBackendFlags_RendererHasVtxOffset flag.
|
||||
// 2019-04-30: DirectX11: Added support for special ImDrawCallback_ResetRenderState callback to reset render state.
|
||||
// 2018-12-03: Misc: Added #pragma comment statement to automatically link with d3dcompiler.lib when using D3DCompile().
|
||||
// 2018-11-30: Misc: Setting up io.BackendRendererName so it can be displayed in the About Window.
|
||||
// 2018-08-01: DirectX11: Querying for IDXGIFactory instead of IDXGIFactory1 to increase compatibility.
|
||||
// 2018-07-13: DirectX11: Fixed unreleased resources in Init and Shutdown functions.
|
||||
// 2018-06-08: Misc: Extracted imgui_impl_dx11.cpp/.h away from the old combined DX11+Win32 example.
|
||||
// 2018-06-08: DirectX11: Use draw_data->DisplayPos and draw_data->DisplaySize to setup projection matrix and clipping rectangle.
|
||||
// 2018-02-16: Misc: Obsoleted the io.RenderDrawListsFn callback and exposed ImGui_ImplDX11_RenderDrawData() in the .h file so you can call it yourself.
|
||||
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
|
||||
// 2016-05-07: DirectX11: Disabling depth-write.
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_dx11.h"
|
||||
|
||||
// DirectX
|
||||
#include <stdio.h>
|
||||
#include <d3d11.h>
|
||||
#include <d3dcompiler.h>
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib, "d3dcompiler") // Automatically link with d3dcompiler.lib as we are using D3DCompile() below.
|
||||
#endif
|
||||
|
||||
// DirectX11 data
|
||||
struct ImGui_ImplDX11_Data
|
||||
{
|
||||
ID3D11Device* pd3dDevice;
|
||||
ID3D11DeviceContext* pd3dDeviceContext;
|
||||
IDXGIFactory* pFactory;
|
||||
ID3D11Buffer* pVB;
|
||||
ID3D11Buffer* pIB;
|
||||
ID3D11VertexShader* pVertexShader;
|
||||
ID3D11InputLayout* pInputLayout;
|
||||
ID3D11Buffer* pVertexConstantBuffer;
|
||||
ID3D11PixelShader* pPixelShader;
|
||||
ID3D11SamplerState* pFontSampler;
|
||||
ID3D11ShaderResourceView* pFontTextureView;
|
||||
ID3D11RasterizerState* pRasterizerState;
|
||||
ID3D11BlendState* pBlendState;
|
||||
ID3D11DepthStencilState* pDepthStencilState;
|
||||
int VertexBufferSize;
|
||||
int IndexBufferSize;
|
||||
|
||||
ImGui_ImplDX11_Data() { memset(this, 0, sizeof(*this)); VertexBufferSize = 5000; IndexBufferSize = 10000; }
|
||||
};
|
||||
|
||||
struct VERTEX_CONSTANT_BUFFER
|
||||
{
|
||||
float mvp[4][4];
|
||||
};
|
||||
|
||||
// Backend data stored in io.BackendRendererUserData to allow support for multiple Dear ImGui contexts
|
||||
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||
static ImGui_ImplDX11_Data* ImGui_ImplDX11_GetBackendData()
|
||||
{
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplDX11_Data*)ImGui::GetIO().BackendRendererUserData : NULL;
|
||||
}
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplDX11_SetupRenderState(ImDrawData* draw_data, ID3D11DeviceContext* ctx)
|
||||
{
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
|
||||
// Setup viewport
|
||||
D3D11_VIEWPORT vp;
|
||||
memset(&vp, 0, sizeof(D3D11_VIEWPORT));
|
||||
vp.Width = draw_data->DisplaySize.x;
|
||||
vp.Height = draw_data->DisplaySize.y;
|
||||
vp.MinDepth = 0.0f;
|
||||
vp.MaxDepth = 1.0f;
|
||||
vp.TopLeftX = vp.TopLeftY = 0;
|
||||
ctx->RSSetViewports(1, &vp);
|
||||
|
||||
// Setup shader and vertex buffers
|
||||
unsigned int stride = sizeof(ImDrawVert);
|
||||
unsigned int offset = 0;
|
||||
ctx->IASetInputLayout(bd->pInputLayout);
|
||||
ctx->IASetVertexBuffers(0, 1, &bd->pVB, &stride, &offset);
|
||||
ctx->IASetIndexBuffer(bd->pIB, sizeof(ImDrawIdx) == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT, 0);
|
||||
ctx->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
|
||||
ctx->VSSetShader(bd->pVertexShader, NULL, 0);
|
||||
ctx->VSSetConstantBuffers(0, 1, &bd->pVertexConstantBuffer);
|
||||
ctx->PSSetShader(bd->pPixelShader, NULL, 0);
|
||||
ctx->PSSetSamplers(0, 1, &bd->pFontSampler);
|
||||
ctx->GSSetShader(NULL, NULL, 0);
|
||||
ctx->HSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
ctx->DSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
ctx->CSSetShader(NULL, NULL, 0); // In theory we should backup and restore this as well.. very infrequently used..
|
||||
|
||||
// Setup blend state
|
||||
const float blend_factor[4] = { 0.f, 0.f, 0.f, 0.f };
|
||||
ctx->OMSetBlendState(bd->pBlendState, blend_factor, 0xffffffff);
|
||||
ctx->OMSetDepthStencilState(bd->pDepthStencilState, 0);
|
||||
ctx->RSSetState(bd->pRasterizerState);
|
||||
}
|
||||
|
||||
// Render function
|
||||
void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
// Avoid rendering when minimized
|
||||
if (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f)
|
||||
return;
|
||||
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
ID3D11DeviceContext* ctx = bd->pd3dDeviceContext;
|
||||
|
||||
// Create and grow vertex/index buffers if needed
|
||||
if (!bd->pVB || bd->VertexBufferSize < draw_data->TotalVtxCount)
|
||||
{
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = NULL; }
|
||||
bd->VertexBufferSize = draw_data->TotalVtxCount + 5000;
|
||||
D3D11_BUFFER_DESC desc;
|
||||
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
|
||||
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
desc.ByteWidth = bd->VertexBufferSize * sizeof(ImDrawVert);
|
||||
desc.BindFlags = D3D11_BIND_VERTEX_BUFFER;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
desc.MiscFlags = 0;
|
||||
if (bd->pd3dDevice->CreateBuffer(&desc, NULL, &bd->pVB) < 0)
|
||||
return;
|
||||
}
|
||||
if (!bd->pIB || bd->IndexBufferSize < draw_data->TotalIdxCount)
|
||||
{
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = NULL; }
|
||||
bd->IndexBufferSize = draw_data->TotalIdxCount + 10000;
|
||||
D3D11_BUFFER_DESC desc;
|
||||
memset(&desc, 0, sizeof(D3D11_BUFFER_DESC));
|
||||
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
desc.ByteWidth = bd->IndexBufferSize * sizeof(ImDrawIdx);
|
||||
desc.BindFlags = D3D11_BIND_INDEX_BUFFER;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
if (bd->pd3dDevice->CreateBuffer(&desc, NULL, &bd->pIB) < 0)
|
||||
return;
|
||||
}
|
||||
|
||||
// Upload vertex/index data into a single contiguous GPU buffer
|
||||
D3D11_MAPPED_SUBRESOURCE vtx_resource, idx_resource;
|
||||
if (ctx->Map(bd->pVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &vtx_resource) != S_OK)
|
||||
return;
|
||||
if (ctx->Map(bd->pIB, 0, D3D11_MAP_WRITE_DISCARD, 0, &idx_resource) != S_OK)
|
||||
return;
|
||||
ImDrawVert* vtx_dst = (ImDrawVert*)vtx_resource.pData;
|
||||
ImDrawIdx* idx_dst = (ImDrawIdx*)idx_resource.pData;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
memcpy(vtx_dst, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
|
||||
memcpy(idx_dst, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
vtx_dst += cmd_list->VtxBuffer.Size;
|
||||
idx_dst += cmd_list->IdxBuffer.Size;
|
||||
}
|
||||
ctx->Unmap(bd->pVB, 0);
|
||||
ctx->Unmap(bd->pIB, 0);
|
||||
|
||||
// Setup orthographic projection matrix into our constant buffer
|
||||
// Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
|
||||
{
|
||||
D3D11_MAPPED_SUBRESOURCE mapped_resource;
|
||||
if (ctx->Map(bd->pVertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mapped_resource) != S_OK)
|
||||
return;
|
||||
VERTEX_CONSTANT_BUFFER* constant_buffer = (VERTEX_CONSTANT_BUFFER*)mapped_resource.pData;
|
||||
float L = draw_data->DisplayPos.x;
|
||||
float R = draw_data->DisplayPos.x + draw_data->DisplaySize.x;
|
||||
float T = draw_data->DisplayPos.y;
|
||||
float B = draw_data->DisplayPos.y + draw_data->DisplaySize.y;
|
||||
float mvp[4][4] =
|
||||
{
|
||||
{ 2.0f/(R-L), 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 2.0f/(T-B), 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.5f, 0.0f },
|
||||
{ (R+L)/(L-R), (T+B)/(B-T), 0.5f, 1.0f },
|
||||
};
|
||||
memcpy(&constant_buffer->mvp, mvp, sizeof(mvp));
|
||||
ctx->Unmap(bd->pVertexConstantBuffer, 0);
|
||||
}
|
||||
|
||||
// Backup DX state that will be modified to restore it afterwards (unfortunately this is very ugly looking and verbose. Close your eyes!)
|
||||
struct BACKUP_DX11_STATE
|
||||
{
|
||||
UINT ScissorRectsCount, ViewportsCount;
|
||||
D3D11_RECT ScissorRects[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
|
||||
D3D11_VIEWPORT Viewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
|
||||
ID3D11RasterizerState* RS;
|
||||
ID3D11BlendState* BlendState;
|
||||
FLOAT BlendFactor[4];
|
||||
UINT SampleMask;
|
||||
UINT StencilRef;
|
||||
ID3D11DepthStencilState* DepthStencilState;
|
||||
ID3D11ShaderResourceView* PSShaderResource;
|
||||
ID3D11SamplerState* PSSampler;
|
||||
ID3D11PixelShader* PS;
|
||||
ID3D11VertexShader* VS;
|
||||
ID3D11GeometryShader* GS;
|
||||
UINT PSInstancesCount, VSInstancesCount, GSInstancesCount;
|
||||
ID3D11ClassInstance *PSInstances[256], *VSInstances[256], *GSInstances[256]; // 256 is max according to PSSetShader documentation
|
||||
D3D11_PRIMITIVE_TOPOLOGY PrimitiveTopology;
|
||||
ID3D11Buffer* IndexBuffer, *VertexBuffer, *VSConstantBuffer;
|
||||
UINT IndexBufferOffset, VertexBufferStride, VertexBufferOffset;
|
||||
DXGI_FORMAT IndexBufferFormat;
|
||||
ID3D11InputLayout* InputLayout;
|
||||
};
|
||||
BACKUP_DX11_STATE old = {};
|
||||
old.ScissorRectsCount = old.ViewportsCount = D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE;
|
||||
ctx->RSGetScissorRects(&old.ScissorRectsCount, old.ScissorRects);
|
||||
ctx->RSGetViewports(&old.ViewportsCount, old.Viewports);
|
||||
ctx->RSGetState(&old.RS);
|
||||
ctx->OMGetBlendState(&old.BlendState, old.BlendFactor, &old.SampleMask);
|
||||
ctx->OMGetDepthStencilState(&old.DepthStencilState, &old.StencilRef);
|
||||
ctx->PSGetShaderResources(0, 1, &old.PSShaderResource);
|
||||
ctx->PSGetSamplers(0, 1, &old.PSSampler);
|
||||
old.PSInstancesCount = old.VSInstancesCount = old.GSInstancesCount = 256;
|
||||
ctx->PSGetShader(&old.PS, old.PSInstances, &old.PSInstancesCount);
|
||||
ctx->VSGetShader(&old.VS, old.VSInstances, &old.VSInstancesCount);
|
||||
ctx->VSGetConstantBuffers(0, 1, &old.VSConstantBuffer);
|
||||
ctx->GSGetShader(&old.GS, old.GSInstances, &old.GSInstancesCount);
|
||||
|
||||
ctx->IAGetPrimitiveTopology(&old.PrimitiveTopology);
|
||||
ctx->IAGetIndexBuffer(&old.IndexBuffer, &old.IndexBufferFormat, &old.IndexBufferOffset);
|
||||
ctx->IAGetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset);
|
||||
ctx->IAGetInputLayout(&old.InputLayout);
|
||||
|
||||
// Setup desired DX state
|
||||
ImGui_ImplDX11_SetupRenderState(draw_data, ctx);
|
||||
|
||||
// Render command lists
|
||||
// (Because we merged all buffers into a single one, we maintain our own offset into them)
|
||||
int global_idx_offset = 0;
|
||||
int global_vtx_offset = 0;
|
||||
ImVec2 clip_off = draw_data->DisplayPos;
|
||||
for (int n = 0; n < draw_data->CmdListsCount; n++)
|
||||
{
|
||||
const ImDrawList* cmd_list = draw_data->CmdLists[n];
|
||||
for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
|
||||
{
|
||||
const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];
|
||||
if (pcmd->UserCallback != NULL)
|
||||
{
|
||||
// User callback, registered via ImDrawList::AddCallback()
|
||||
// (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
||||
if (pcmd->UserCallback == ImDrawCallback_ResetRenderState)
|
||||
ImGui_ImplDX11_SetupRenderState(draw_data, ctx);
|
||||
else
|
||||
pcmd->UserCallback(cmd_list, pcmd);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Project scissor/clipping rectangles into framebuffer space
|
||||
ImVec2 clip_min(pcmd->ClipRect.x - clip_off.x, pcmd->ClipRect.y - clip_off.y);
|
||||
ImVec2 clip_max(pcmd->ClipRect.z - clip_off.x, pcmd->ClipRect.w - clip_off.y);
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
// Apply scissor/clipping rectangle
|
||||
const D3D11_RECT r = { (LONG)clip_min.x, (LONG)clip_min.y, (LONG)clip_max.x, (LONG)clip_max.y };
|
||||
ctx->RSSetScissorRects(1, &r);
|
||||
|
||||
// Bind texture, Draw
|
||||
ID3D11ShaderResourceView* texture_srv = (ID3D11ShaderResourceView*)pcmd->GetTexID();
|
||||
ctx->PSSetShaderResources(0, 1, &texture_srv);
|
||||
ctx->DrawIndexed(pcmd->ElemCount, pcmd->IdxOffset + global_idx_offset, pcmd->VtxOffset + global_vtx_offset);
|
||||
}
|
||||
}
|
||||
global_idx_offset += cmd_list->IdxBuffer.Size;
|
||||
global_vtx_offset += cmd_list->VtxBuffer.Size;
|
||||
}
|
||||
|
||||
// Restore modified DX state
|
||||
ctx->RSSetScissorRects(old.ScissorRectsCount, old.ScissorRects);
|
||||
ctx->RSSetViewports(old.ViewportsCount, old.Viewports);
|
||||
ctx->RSSetState(old.RS); if (old.RS) old.RS->Release();
|
||||
ctx->OMSetBlendState(old.BlendState, old.BlendFactor, old.SampleMask); if (old.BlendState) old.BlendState->Release();
|
||||
ctx->OMSetDepthStencilState(old.DepthStencilState, old.StencilRef); if (old.DepthStencilState) old.DepthStencilState->Release();
|
||||
ctx->PSSetShaderResources(0, 1, &old.PSShaderResource); if (old.PSShaderResource) old.PSShaderResource->Release();
|
||||
ctx->PSSetSamplers(0, 1, &old.PSSampler); if (old.PSSampler) old.PSSampler->Release();
|
||||
ctx->PSSetShader(old.PS, old.PSInstances, old.PSInstancesCount); if (old.PS) old.PS->Release();
|
||||
for (UINT i = 0; i < old.PSInstancesCount; i++) if (old.PSInstances[i]) old.PSInstances[i]->Release();
|
||||
ctx->VSSetShader(old.VS, old.VSInstances, old.VSInstancesCount); if (old.VS) old.VS->Release();
|
||||
ctx->VSSetConstantBuffers(0, 1, &old.VSConstantBuffer); if (old.VSConstantBuffer) old.VSConstantBuffer->Release();
|
||||
ctx->GSSetShader(old.GS, old.GSInstances, old.GSInstancesCount); if (old.GS) old.GS->Release();
|
||||
for (UINT i = 0; i < old.VSInstancesCount; i++) if (old.VSInstances[i]) old.VSInstances[i]->Release();
|
||||
ctx->IASetPrimitiveTopology(old.PrimitiveTopology);
|
||||
ctx->IASetIndexBuffer(old.IndexBuffer, old.IndexBufferFormat, old.IndexBufferOffset); if (old.IndexBuffer) old.IndexBuffer->Release();
|
||||
ctx->IASetVertexBuffers(0, 1, &old.VertexBuffer, &old.VertexBufferStride, &old.VertexBufferOffset); if (old.VertexBuffer) old.VertexBuffer->Release();
|
||||
ctx->IASetInputLayout(old.InputLayout); if (old.InputLayout) old.InputLayout->Release();
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX11_CreateFontsTexture()
|
||||
{
|
||||
// Build texture atlas
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
unsigned char* pixels;
|
||||
int width, height;
|
||||
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||||
|
||||
// Upload texture to graphics system
|
||||
{
|
||||
D3D11_TEXTURE2D_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.Width = width;
|
||||
desc.Height = height;
|
||||
desc.MipLevels = 1;
|
||||
desc.ArraySize = 1;
|
||||
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
desc.SampleDesc.Count = 1;
|
||||
desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
desc.CPUAccessFlags = 0;
|
||||
|
||||
ID3D11Texture2D* pTexture = NULL;
|
||||
D3D11_SUBRESOURCE_DATA subResource;
|
||||
subResource.pSysMem = pixels;
|
||||
subResource.SysMemPitch = desc.Width * 4;
|
||||
subResource.SysMemSlicePitch = 0;
|
||||
bd->pd3dDevice->CreateTexture2D(&desc, &subResource, &pTexture);
|
||||
IM_ASSERT(pTexture != NULL);
|
||||
|
||||
// Create texture view
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
|
||||
ZeroMemory(&srvDesc, sizeof(srvDesc));
|
||||
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
|
||||
srvDesc.Texture2D.MipLevels = desc.MipLevels;
|
||||
srvDesc.Texture2D.MostDetailedMip = 0;
|
||||
bd->pd3dDevice->CreateShaderResourceView(pTexture, &srvDesc, &bd->pFontTextureView);
|
||||
pTexture->Release();
|
||||
}
|
||||
|
||||
// Store our identifier
|
||||
io.Fonts->SetTexID((ImTextureID)bd->pFontTextureView);
|
||||
|
||||
// Create texture sampler
|
||||
{
|
||||
D3D11_SAMPLER_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR;
|
||||
desc.AddressU = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
desc.AddressV = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
desc.AddressW = D3D11_TEXTURE_ADDRESS_WRAP;
|
||||
desc.MipLODBias = 0.f;
|
||||
desc.ComparisonFunc = D3D11_COMPARISON_ALWAYS;
|
||||
desc.MinLOD = 0.f;
|
||||
desc.MaxLOD = 0.f;
|
||||
bd->pd3dDevice->CreateSamplerState(&desc, &bd->pFontSampler);
|
||||
}
|
||||
}
|
||||
|
||||
bool ImGui_ImplDX11_CreateDeviceObjects()
|
||||
{
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
if (!bd->pd3dDevice)
|
||||
return false;
|
||||
if (bd->pFontSampler)
|
||||
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
|
||||
// By using D3DCompile() from <d3dcompiler.h> / d3dcompiler.lib, we introduce a dependency to a given version of d3dcompiler_XX.dll (see D3DCOMPILER_DLL_A)
|
||||
// If you would like to use this DX11 sample code but remove this dependency you can:
|
||||
// 1) compile once, save the compiled shader blobs into a file or source code and pass them to CreateVertexShader()/CreatePixelShader() [preferred solution]
|
||||
// 2) use code to detect any version of the DLL and grab a pointer to D3DCompile from the DLL.
|
||||
// See https://github.com/ocornut/imgui/pull/638 for sources and details.
|
||||
|
||||
// Create the vertex shader
|
||||
{
|
||||
static const char* vertexShader =
|
||||
"cbuffer vertexBuffer : register(b0) \
|
||||
{\
|
||||
float4x4 ProjectionMatrix; \
|
||||
};\
|
||||
struct VS_INPUT\
|
||||
{\
|
||||
float2 pos : POSITION;\
|
||||
float4 col : COLOR0;\
|
||||
float2 uv : TEXCOORD0;\
|
||||
};\
|
||||
\
|
||||
struct PS_INPUT\
|
||||
{\
|
||||
float4 pos : SV_POSITION;\
|
||||
float4 col : COLOR0;\
|
||||
float2 uv : TEXCOORD0;\
|
||||
};\
|
||||
\
|
||||
PS_INPUT main(VS_INPUT input)\
|
||||
{\
|
||||
PS_INPUT output;\
|
||||
output.pos = mul( ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f));\
|
||||
output.col = input.col;\
|
||||
output.uv = input.uv;\
|
||||
return output;\
|
||||
}";
|
||||
|
||||
ID3DBlob* vertexShaderBlob;
|
||||
if (FAILED(D3DCompile(vertexShader, strlen(vertexShader), NULL, NULL, NULL, "main", "vs_4_0", 0, 0, &vertexShaderBlob, NULL)))
|
||||
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||
if (bd->pd3dDevice->CreateVertexShader(vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), NULL, &bd->pVertexShader) != S_OK)
|
||||
{
|
||||
vertexShaderBlob->Release();
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create the input layout
|
||||
D3D11_INPUT_ELEMENT_DESC local_layout[] =
|
||||
{
|
||||
{ "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, pos), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, (UINT)IM_OFFSETOF(ImDrawVert, uv), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
{ "COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, (UINT)IM_OFFSETOF(ImDrawVert, col), D3D11_INPUT_PER_VERTEX_DATA, 0 },
|
||||
};
|
||||
if (bd->pd3dDevice->CreateInputLayout(local_layout, 3, vertexShaderBlob->GetBufferPointer(), vertexShaderBlob->GetBufferSize(), &bd->pInputLayout) != S_OK)
|
||||
{
|
||||
vertexShaderBlob->Release();
|
||||
return false;
|
||||
}
|
||||
vertexShaderBlob->Release();
|
||||
|
||||
// Create the constant buffer
|
||||
{
|
||||
D3D11_BUFFER_DESC desc;
|
||||
desc.ByteWidth = sizeof(VERTEX_CONSTANT_BUFFER);
|
||||
desc.Usage = D3D11_USAGE_DYNAMIC;
|
||||
desc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
|
||||
desc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
|
||||
desc.MiscFlags = 0;
|
||||
bd->pd3dDevice->CreateBuffer(&desc, NULL, &bd->pVertexConstantBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
// Create the pixel shader
|
||||
{
|
||||
static const char* pixelShader =
|
||||
"struct PS_INPUT\
|
||||
{\
|
||||
float4 pos : SV_POSITION;\
|
||||
float4 col : COLOR0;\
|
||||
float2 uv : TEXCOORD0;\
|
||||
};\
|
||||
sampler sampler0;\
|
||||
Texture2D texture0;\
|
||||
\
|
||||
float4 main(PS_INPUT input) : SV_Target\
|
||||
{\
|
||||
float4 out_col = input.col * texture0.Sample(sampler0, input.uv); \
|
||||
return out_col; \
|
||||
}";
|
||||
|
||||
ID3DBlob* pixelShaderBlob;
|
||||
if (FAILED(D3DCompile(pixelShader, strlen(pixelShader), NULL, NULL, NULL, "main", "ps_4_0", 0, 0, &pixelShaderBlob, NULL)))
|
||||
return false; // NB: Pass ID3DBlob* pErrorBlob to D3DCompile() to get error showing in (const char*)pErrorBlob->GetBufferPointer(). Make sure to Release() the blob!
|
||||
if (bd->pd3dDevice->CreatePixelShader(pixelShaderBlob->GetBufferPointer(), pixelShaderBlob->GetBufferSize(), NULL, &bd->pPixelShader) != S_OK)
|
||||
{
|
||||
pixelShaderBlob->Release();
|
||||
return false;
|
||||
}
|
||||
pixelShaderBlob->Release();
|
||||
}
|
||||
|
||||
// Create the blending setup
|
||||
{
|
||||
D3D11_BLEND_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.AlphaToCoverageEnable = false;
|
||||
desc.RenderTarget[0].BlendEnable = true;
|
||||
desc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA;
|
||||
desc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA;
|
||||
desc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD;
|
||||
desc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE;
|
||||
desc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA;
|
||||
desc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD;
|
||||
desc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
|
||||
bd->pd3dDevice->CreateBlendState(&desc, &bd->pBlendState);
|
||||
}
|
||||
|
||||
// Create the rasterizer state
|
||||
{
|
||||
D3D11_RASTERIZER_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.FillMode = D3D11_FILL_SOLID;
|
||||
desc.CullMode = D3D11_CULL_NONE;
|
||||
desc.ScissorEnable = true;
|
||||
desc.DepthClipEnable = true;
|
||||
bd->pd3dDevice->CreateRasterizerState(&desc, &bd->pRasterizerState);
|
||||
}
|
||||
|
||||
// Create depth-stencil State
|
||||
{
|
||||
D3D11_DEPTH_STENCIL_DESC desc;
|
||||
ZeroMemory(&desc, sizeof(desc));
|
||||
desc.DepthEnable = false;
|
||||
desc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
|
||||
desc.DepthFunc = D3D11_COMPARISON_ALWAYS;
|
||||
desc.StencilEnable = false;
|
||||
desc.FrontFace.StencilFailOp = desc.FrontFace.StencilDepthFailOp = desc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
|
||||
desc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
|
||||
desc.BackFace = desc.FrontFace;
|
||||
bd->pd3dDevice->CreateDepthStencilState(&desc, &bd->pDepthStencilState);
|
||||
}
|
||||
|
||||
ImGui_ImplDX11_CreateFontsTexture();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX11_InvalidateDeviceObjects()
|
||||
{
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
if (!bd->pd3dDevice)
|
||||
return;
|
||||
|
||||
if (bd->pFontSampler) { bd->pFontSampler->Release(); bd->pFontSampler = NULL; }
|
||||
if (bd->pFontTextureView) { bd->pFontTextureView->Release(); bd->pFontTextureView = NULL; ImGui::GetIO().Fonts->SetTexID(NULL); } // We copied data->pFontTextureView to io.Fonts->TexID so let's clear that as well.
|
||||
if (bd->pIB) { bd->pIB->Release(); bd->pIB = NULL; }
|
||||
if (bd->pVB) { bd->pVB->Release(); bd->pVB = NULL; }
|
||||
if (bd->pBlendState) { bd->pBlendState->Release(); bd->pBlendState = NULL; }
|
||||
if (bd->pDepthStencilState) { bd->pDepthStencilState->Release(); bd->pDepthStencilState = NULL; }
|
||||
if (bd->pRasterizerState) { bd->pRasterizerState->Release(); bd->pRasterizerState = NULL; }
|
||||
if (bd->pPixelShader) { bd->pPixelShader->Release(); bd->pPixelShader = NULL; }
|
||||
if (bd->pVertexConstantBuffer) { bd->pVertexConstantBuffer->Release(); bd->pVertexConstantBuffer = NULL; }
|
||||
if (bd->pInputLayout) { bd->pInputLayout->Release(); bd->pInputLayout = NULL; }
|
||||
if (bd->pVertexShader) { bd->pVertexShader->Release(); bd->pVertexShader = NULL; }
|
||||
}
|
||||
|
||||
bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(io.BackendRendererUserData == NULL && "Already initialized a renderer backend!");
|
||||
|
||||
// Setup backend capabilities flags
|
||||
ImGui_ImplDX11_Data* bd = IM_NEW(ImGui_ImplDX11_Data)();
|
||||
io.BackendRendererUserData = (void*)bd;
|
||||
io.BackendRendererName = "imgui_impl_dx11";
|
||||
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes.
|
||||
|
||||
// Get factory from device
|
||||
IDXGIDevice* pDXGIDevice = NULL;
|
||||
IDXGIAdapter* pDXGIAdapter = NULL;
|
||||
IDXGIFactory* pFactory = NULL;
|
||||
|
||||
if (device->QueryInterface(IID_PPV_ARGS(&pDXGIDevice)) == S_OK)
|
||||
if (pDXGIDevice->GetParent(IID_PPV_ARGS(&pDXGIAdapter)) == S_OK)
|
||||
if (pDXGIAdapter->GetParent(IID_PPV_ARGS(&pFactory)) == S_OK)
|
||||
{
|
||||
bd->pd3dDevice = device;
|
||||
bd->pd3dDeviceContext = device_context;
|
||||
bd->pFactory = pFactory;
|
||||
}
|
||||
if (pDXGIDevice) pDXGIDevice->Release();
|
||||
if (pDXGIAdapter) pDXGIAdapter->Release();
|
||||
bd->pd3dDevice->AddRef();
|
||||
bd->pd3dDeviceContext->AddRef();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplDX11_Shutdown()
|
||||
{
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
IM_ASSERT(bd != NULL && "No renderer backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
if (bd->pFactory) { bd->pFactory->Release(); }
|
||||
if (bd->pd3dDevice) { bd->pd3dDevice->Release(); }
|
||||
if (bd->pd3dDeviceContext) { bd->pd3dDeviceContext->Release(); }
|
||||
io.BackendRendererName = NULL;
|
||||
io.BackendRendererUserData = NULL;
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
void ImGui_ImplDX11_NewFrame()
|
||||
{
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
IM_ASSERT(bd != NULL && "Did you call ImGui_ImplDX11_Init()?");
|
||||
|
||||
if (!bd->pFontSampler)
|
||||
ImGui_ImplDX11_CreateDeviceObjects();
|
||||
}
|
||||
26
DevourClient/Dependencies/imgui/imgui_impl_dx11.h
Normal file
26
DevourClient/Dependencies/imgui/imgui_impl_dx11.h
Normal file
@@ -0,0 +1,26 @@
|
||||
// dear imgui: Renderer Backend for DirectX11
|
||||
// This needs to be used along with a Platform Backend (e.g. Win32)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID!
|
||||
// [X] Renderer: Support for large meshes (64k+ vertices) with 16-bit indices.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
|
||||
struct ID3D11Device;
|
||||
struct ID3D11DeviceContext;
|
||||
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context);
|
||||
IMGUI_IMPL_API void ImGui_ImplDX11_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX11_NewFrame();
|
||||
IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data);
|
||||
|
||||
// Use if you want to reset your rendering device without losing Dear ImGui state.
|
||||
IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects();
|
||||
IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects();
|
||||
629
DevourClient/Dependencies/imgui/imgui_impl_win32.cpp
Normal file
629
DevourClient/Dependencies/imgui/imgui_impl_win32.cpp
Normal file
@@ -0,0 +1,629 @@
|
||||
// dear imgui: Platform Backend for Windows (standard windows API for 32 and 64 bits applications)
|
||||
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE).
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_impl_win32.h"
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
#include <dwmapi.h>
|
||||
|
||||
// Configuration flags to add in your imconfig.h file:
|
||||
//#define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD // Disable gamepad support. This was meaningful before <1.81 but we now load XInput dynamically so the option is now less relevant.
|
||||
|
||||
// Using XInput for gamepad (will load DLL dynamically)
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
#include <xinput.h>
|
||||
typedef DWORD (WINAPI *PFN_XInputGetCapabilities)(DWORD, DWORD, XINPUT_CAPABILITIES*);
|
||||
typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
|
||||
#endif
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2021-12-16: Inputs: Fill VK_LCONTROL/VK_RCONTROL/VK_LSHIFT/VK_RSHIFT/VK_LMENU/VK_RMENU for completeness.
|
||||
// 2021-08-17: Calling io.AddFocusEvent() on WM_SETFOCUS/WM_KILLFOCUS messages.
|
||||
// 2021-08-02: Inputs: Fixed keyboard modifiers being reported when host window doesn't have focus.
|
||||
// 2021-07-29: Inputs: MousePos is correctly reported when the host platform window is hovered but not focused (using TrackMouseEvent() to receive WM_MOUSELEAVE events).
|
||||
// 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX).
|
||||
// 2021-06-08: Fixed ImGui_ImplWin32_EnableDpiAwareness() and ImGui_ImplWin32_GetDpiScaleForMonitor() to handle Windows 8.1/10 features without a manifest (per-monitor DPI, and properly calls SetProcessDpiAwareness() on 8.1).
|
||||
// 2021-03-23: Inputs: Clearing keyboard down array when losing focus (WM_KILLFOCUS).
|
||||
// 2021-02-18: Added ImGui_ImplWin32_EnableAlphaCompositing(). Non Visual Studio users will need to link with dwmapi.lib (MinGW/gcc: use -ldwmapi).
|
||||
// 2021-02-17: Fixed ImGui_ImplWin32_EnableDpiAwareness() attempting to get SetProcessDpiAwareness from shcore.dll on Windows 8 whereas it is only supported on Windows 8.1.
|
||||
// 2021-01-25: Inputs: Dynamically loading XInput DLL.
|
||||
// 2020-12-04: Misc: Fixed setting of io.DisplaySize to invalid/uninitialized data when after hwnd has been closed.
|
||||
// 2020-03-03: Inputs: Calling AddInputCharacterUTF16() to support surrogate pairs leading to codepoint >= 0x10000 (for more complete CJK inputs)
|
||||
// 2020-02-17: Added ImGui_ImplWin32_EnableDpiAwareness(), ImGui_ImplWin32_GetDpiScaleForHwnd(), ImGui_ImplWin32_GetDpiScaleForMonitor() helper functions.
|
||||
// 2020-01-14: Inputs: Added support for #define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD/IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT.
|
||||
// 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor.
|
||||
// 2019-05-11: Inputs: Don't filter value from WM_CHAR before calling AddInputCharacter().
|
||||
// 2019-01-17: Misc: Using GetForegroundWindow()+IsChild() instead of GetActiveWindow() to be compatible with windows created in a different thread or parent.
|
||||
// 2019-01-17: Inputs: Added support for mouse buttons 4 and 5 via WM_XBUTTON* messages.
|
||||
// 2019-01-15: Inputs: Added support for XInput gamepads (if ImGuiConfigFlags_NavEnableGamepad is set by user application).
|
||||
// 2018-11-30: Misc: Setting up io.BackendPlatformName so it can be displayed in the About Window.
|
||||
// 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor.
|
||||
// 2018-06-10: Inputs: Fixed handling of mouse wheel messages to support fine position messages (typically sent by track-pads).
|
||||
// 2018-06-08: Misc: Extracted imgui_impl_win32.cpp/.h away from the old combined DX9/DX10/DX11/DX12 examples.
|
||||
// 2018-03-20: Misc: Setup io.BackendFlags ImGuiBackendFlags_HasMouseCursors and ImGuiBackendFlags_HasSetMousePos flags + honor ImGuiConfigFlags_NoMouseCursorChange flag.
|
||||
// 2018-02-20: Inputs: Added support for mouse cursors (ImGui::GetMouseCursor() value and WM_SETCURSOR message handling).
|
||||
// 2018-02-06: Inputs: Added mapping for ImGuiKey_Space.
|
||||
// 2018-02-06: Inputs: Honoring the io.WantSetMousePos by repositioning the mouse (when using navigation and ImGuiConfigFlags_NavMoveMouse is set).
|
||||
// 2018-02-06: Misc: Removed call to ImGui::Shutdown() which is not available from 1.60 WIP, user needs to call CreateContext/DestroyContext themselves.
|
||||
// 2018-01-20: Inputs: Added Horizontal Mouse Wheel support.
|
||||
// 2018-01-08: Inputs: Added mapping for ImGuiKey_Insert.
|
||||
// 2018-01-05: Inputs: Added WM_LBUTTONDBLCLK double-click handlers for window classes with the CS_DBLCLKS flag.
|
||||
// 2017-10-23: Inputs: Added WM_SYSKEYDOWN / WM_SYSKEYUP handlers so e.g. the VK_MENU key can be read.
|
||||
// 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mouse positions outside the client area when dragging.
|
||||
// 2016-11-12: Inputs: Only call Win32 ::SetCursor(NULL) when io.MouseDrawCursor is set.
|
||||
|
||||
struct ImGui_ImplWin32_Data
|
||||
{
|
||||
HWND hWnd;
|
||||
HWND MouseHwnd;
|
||||
bool MouseTracked;
|
||||
INT64 Time;
|
||||
INT64 TicksPerSecond;
|
||||
ImGuiMouseCursor LastMouseCursor;
|
||||
bool HasGamepad;
|
||||
bool WantUpdateHasGamepad;
|
||||
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
HMODULE XInputDLL;
|
||||
PFN_XInputGetCapabilities XInputGetCapabilities;
|
||||
PFN_XInputGetState XInputGetState;
|
||||
#endif
|
||||
|
||||
ImGui_ImplWin32_Data() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Backend data stored in io.BackendPlatformUserData to allow support for multiple Dear ImGui contexts
|
||||
// It is STRONGLY preferred that you use docking branch with multi-viewports (== single Dear ImGui context + multiple windows) instead of multiple Dear ImGui contexts.
|
||||
// FIXME: multi-context support is not well tested and probably dysfunctional in this backend.
|
||||
// FIXME: some shared resources (mouse cursor shape, gamepad) are mishandled when using multi-context.
|
||||
static ImGui_ImplWin32_Data* ImGui_ImplWin32_GetBackendData()
|
||||
{
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplWin32_Data*)ImGui::GetIO().BackendPlatformUserData : NULL;
|
||||
}
|
||||
|
||||
// Functions
|
||||
bool ImGui_ImplWin32_Init(void* hwnd)
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(io.BackendPlatformUserData == NULL && "Already initialized a platform backend!");
|
||||
|
||||
INT64 perf_frequency, perf_counter;
|
||||
if (!::QueryPerformanceFrequency((LARGE_INTEGER*)&perf_frequency))
|
||||
return false;
|
||||
if (!::QueryPerformanceCounter((LARGE_INTEGER*)&perf_counter))
|
||||
return false;
|
||||
|
||||
// Setup backend capabilities flags
|
||||
ImGui_ImplWin32_Data* bd = IM_NEW(ImGui_ImplWin32_Data)();
|
||||
io.BackendPlatformUserData = (void*)bd;
|
||||
io.BackendPlatformName = "imgui_impl_win32";
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional)
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
|
||||
|
||||
bd->hWnd = (HWND)hwnd;
|
||||
bd->WantUpdateHasGamepad = true;
|
||||
bd->TicksPerSecond = perf_frequency;
|
||||
bd->Time = perf_counter;
|
||||
bd->LastMouseCursor = ImGuiMouseCursor_COUNT;
|
||||
|
||||
io.ImeWindowHandle = hwnd;
|
||||
|
||||
// Keyboard mapping. Dear ImGui will use those indices to peek into the io.KeysDown[] array that we will update during the application lifetime.
|
||||
io.KeyMap[ImGuiKey_Tab] = VK_TAB;
|
||||
io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT;
|
||||
io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT;
|
||||
io.KeyMap[ImGuiKey_UpArrow] = VK_UP;
|
||||
io.KeyMap[ImGuiKey_DownArrow] = VK_DOWN;
|
||||
io.KeyMap[ImGuiKey_PageUp] = VK_PRIOR;
|
||||
io.KeyMap[ImGuiKey_PageDown] = VK_NEXT;
|
||||
io.KeyMap[ImGuiKey_Home] = VK_HOME;
|
||||
io.KeyMap[ImGuiKey_End] = VK_END;
|
||||
io.KeyMap[ImGuiKey_Insert] = VK_INSERT;
|
||||
io.KeyMap[ImGuiKey_Delete] = VK_DELETE;
|
||||
io.KeyMap[ImGuiKey_Backspace] = VK_BACK;
|
||||
io.KeyMap[ImGuiKey_Space] = VK_SPACE;
|
||||
io.KeyMap[ImGuiKey_Enter] = VK_RETURN;
|
||||
io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE;
|
||||
io.KeyMap[ImGuiKey_KeyPadEnter] = VK_RETURN;
|
||||
io.KeyMap[ImGuiKey_A] = 'A';
|
||||
io.KeyMap[ImGuiKey_C] = 'C';
|
||||
io.KeyMap[ImGuiKey_V] = 'V';
|
||||
io.KeyMap[ImGuiKey_X] = 'X';
|
||||
io.KeyMap[ImGuiKey_Y] = 'Y';
|
||||
io.KeyMap[ImGuiKey_Z] = 'Z';
|
||||
|
||||
// Dynamically load XInput library
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
const char* xinput_dll_names[] =
|
||||
{
|
||||
"xinput1_4.dll", // Windows 8+
|
||||
"xinput1_3.dll", // DirectX SDK
|
||||
"xinput9_1_0.dll", // Windows Vista, Windows 7
|
||||
"xinput1_2.dll", // DirectX SDK
|
||||
"xinput1_1.dll" // DirectX SDK
|
||||
};
|
||||
for (int n = 0; n < IM_ARRAYSIZE(xinput_dll_names); n++)
|
||||
if (HMODULE dll = ::LoadLibraryA(xinput_dll_names[n]))
|
||||
{
|
||||
bd->XInputDLL = dll;
|
||||
bd->XInputGetCapabilities = (PFN_XInputGetCapabilities)::GetProcAddress(dll, "XInputGetCapabilities");
|
||||
bd->XInputGetState = (PFN_XInputGetState)::GetProcAddress(dll, "XInputGetState");
|
||||
break;
|
||||
}
|
||||
#endif // IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ImGui_ImplWin32_Shutdown()
|
||||
{
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
IM_ASSERT(bd != NULL && "No platform backend to shutdown, or already shutdown?");
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
// Unload XInput library
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
if (bd->XInputDLL)
|
||||
::FreeLibrary(bd->XInputDLL);
|
||||
#endif // IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
|
||||
io.BackendPlatformName = NULL;
|
||||
io.BackendPlatformUserData = NULL;
|
||||
IM_DELETE(bd);
|
||||
}
|
||||
|
||||
static bool ImGui_ImplWin32_UpdateMouseCursor()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange)
|
||||
return false;
|
||||
|
||||
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
|
||||
if (imgui_cursor == ImGuiMouseCursor_None || io.MouseDrawCursor)
|
||||
{
|
||||
// Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
|
||||
::SetCursor(NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Show OS mouse cursor
|
||||
LPTSTR win32_cursor = IDC_ARROW;
|
||||
switch (imgui_cursor)
|
||||
{
|
||||
case ImGuiMouseCursor_Arrow: win32_cursor = IDC_ARROW; break;
|
||||
case ImGuiMouseCursor_TextInput: win32_cursor = IDC_IBEAM; break;
|
||||
case ImGuiMouseCursor_ResizeAll: win32_cursor = IDC_SIZEALL; break;
|
||||
case ImGuiMouseCursor_ResizeEW: win32_cursor = IDC_SIZEWE; break;
|
||||
case ImGuiMouseCursor_ResizeNS: win32_cursor = IDC_SIZENS; break;
|
||||
case ImGuiMouseCursor_ResizeNESW: win32_cursor = IDC_SIZENESW; break;
|
||||
case ImGuiMouseCursor_ResizeNWSE: win32_cursor = IDC_SIZENWSE; break;
|
||||
case ImGuiMouseCursor_Hand: win32_cursor = IDC_HAND; break;
|
||||
case ImGuiMouseCursor_NotAllowed: win32_cursor = IDC_NO; break;
|
||||
}
|
||||
::SetCursor(::LoadCursor(NULL, win32_cursor));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ImGui_ImplWin32_UpdateMousePos()
|
||||
{
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
IM_ASSERT(bd->hWnd != 0);
|
||||
|
||||
const ImVec2 mouse_pos_prev = io.MousePos;
|
||||
io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX);
|
||||
|
||||
// Obtain focused and hovered window. We forward mouse input when focused or when hovered (and no other window is capturing)
|
||||
HWND focused_window = ::GetForegroundWindow();
|
||||
HWND hovered_window = bd->MouseHwnd;
|
||||
HWND mouse_window = NULL;
|
||||
if (hovered_window && (hovered_window == bd->hWnd || ::IsChild(hovered_window, bd->hWnd)))
|
||||
mouse_window = hovered_window;
|
||||
else if (focused_window && (focused_window == bd->hWnd || ::IsChild(focused_window, bd->hWnd)))
|
||||
mouse_window = focused_window;
|
||||
if (mouse_window == NULL)
|
||||
return;
|
||||
|
||||
// Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
|
||||
if (io.WantSetMousePos)
|
||||
{
|
||||
POINT pos = { (int)mouse_pos_prev.x, (int)mouse_pos_prev.y };
|
||||
if (::ClientToScreen(bd->hWnd, &pos))
|
||||
::SetCursorPos(pos.x, pos.y);
|
||||
}
|
||||
|
||||
// Set Dear ImGui mouse position from OS position
|
||||
POINT pos;
|
||||
if (::GetCursorPos(&pos) && ::ScreenToClient(mouse_window, &pos))
|
||||
io.MousePos = ImVec2((float)pos.x, (float)pos.y);
|
||||
}
|
||||
|
||||
// Gamepad navigation mapping
|
||||
static void ImGui_ImplWin32_UpdateGamepads()
|
||||
{
|
||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
memset(io.NavInputs, 0, sizeof(io.NavInputs));
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) == 0)
|
||||
return;
|
||||
|
||||
// Calling XInputGetState() every frame on disconnected gamepads is unfortunately too slow.
|
||||
// Instead we refresh gamepad availability by calling XInputGetCapabilities() _only_ after receiving WM_DEVICECHANGE.
|
||||
if (bd->WantUpdateHasGamepad)
|
||||
{
|
||||
XINPUT_CAPABILITIES caps;
|
||||
bd->HasGamepad = bd->XInputGetCapabilities ? (bd->XInputGetCapabilities(0, XINPUT_FLAG_GAMEPAD, &caps) == ERROR_SUCCESS) : false;
|
||||
bd->WantUpdateHasGamepad = false;
|
||||
}
|
||||
|
||||
io.BackendFlags &= ~ImGuiBackendFlags_HasGamepad;
|
||||
XINPUT_STATE xinput_state;
|
||||
if (bd->HasGamepad && bd->XInputGetState && bd->XInputGetState(0, &xinput_state) == ERROR_SUCCESS)
|
||||
{
|
||||
const XINPUT_GAMEPAD& gamepad = xinput_state.Gamepad;
|
||||
io.BackendFlags |= ImGuiBackendFlags_HasGamepad;
|
||||
|
||||
#define MAP_BUTTON(NAV_NO, BUTTON_ENUM) { io.NavInputs[NAV_NO] = (gamepad.wButtons & BUTTON_ENUM) ? 1.0f : 0.0f; }
|
||||
#define MAP_ANALOG(NAV_NO, VALUE, V0, V1) { float vn = (float)(VALUE - V0) / (float)(V1 - V0); if (vn > 1.0f) vn = 1.0f; if (vn > 0.0f && io.NavInputs[NAV_NO] < vn) io.NavInputs[NAV_NO] = vn; }
|
||||
MAP_BUTTON(ImGuiNavInput_Activate, XINPUT_GAMEPAD_A); // Cross / A
|
||||
MAP_BUTTON(ImGuiNavInput_Cancel, XINPUT_GAMEPAD_B); // Circle / B
|
||||
MAP_BUTTON(ImGuiNavInput_Menu, XINPUT_GAMEPAD_X); // Square / X
|
||||
MAP_BUTTON(ImGuiNavInput_Input, XINPUT_GAMEPAD_Y); // Triangle / Y
|
||||
MAP_BUTTON(ImGuiNavInput_DpadLeft, XINPUT_GAMEPAD_DPAD_LEFT); // D-Pad Left
|
||||
MAP_BUTTON(ImGuiNavInput_DpadRight, XINPUT_GAMEPAD_DPAD_RIGHT); // D-Pad Right
|
||||
MAP_BUTTON(ImGuiNavInput_DpadUp, XINPUT_GAMEPAD_DPAD_UP); // D-Pad Up
|
||||
MAP_BUTTON(ImGuiNavInput_DpadDown, XINPUT_GAMEPAD_DPAD_DOWN); // D-Pad Down
|
||||
MAP_BUTTON(ImGuiNavInput_FocusPrev, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB
|
||||
MAP_BUTTON(ImGuiNavInput_FocusNext, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB
|
||||
MAP_BUTTON(ImGuiNavInput_TweakSlow, XINPUT_GAMEPAD_LEFT_SHOULDER); // L1 / LB
|
||||
MAP_BUTTON(ImGuiNavInput_TweakFast, XINPUT_GAMEPAD_RIGHT_SHOULDER); // R1 / RB
|
||||
MAP_ANALOG(ImGuiNavInput_LStickLeft, gamepad.sThumbLX, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32768);
|
||||
MAP_ANALOG(ImGuiNavInput_LStickRight, gamepad.sThumbLX, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
|
||||
MAP_ANALOG(ImGuiNavInput_LStickUp, gamepad.sThumbLY, +XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, +32767);
|
||||
MAP_ANALOG(ImGuiNavInput_LStickDown, gamepad.sThumbLY, -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE, -32767);
|
||||
#undef MAP_BUTTON
|
||||
#undef MAP_ANALOG
|
||||
}
|
||||
#endif // #ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||
}
|
||||
|
||||
void ImGui_ImplWin32_NewFrame()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
IM_ASSERT(bd != NULL && "Did you call ImGui_ImplWin32_Init()?");
|
||||
|
||||
// Setup display size (every frame to accommodate for window resizing)
|
||||
RECT rect = { 0, 0, 0, 0 };
|
||||
::GetClientRect(bd->hWnd, &rect);
|
||||
io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top));
|
||||
|
||||
// Setup time step
|
||||
INT64 current_time = 0;
|
||||
::QueryPerformanceCounter((LARGE_INTEGER*)¤t_time);
|
||||
io.DeltaTime = (float)(current_time - bd->Time) / bd->TicksPerSecond;
|
||||
bd->Time = current_time;
|
||||
|
||||
// Update OS mouse position
|
||||
ImGui_ImplWin32_UpdateMousePos();
|
||||
|
||||
// Update OS mouse cursor with the cursor requested by imgui
|
||||
ImGuiMouseCursor mouse_cursor = io.MouseDrawCursor ? ImGuiMouseCursor_None : ImGui::GetMouseCursor();
|
||||
if (bd->LastMouseCursor != mouse_cursor)
|
||||
{
|
||||
bd->LastMouseCursor = mouse_cursor;
|
||||
ImGui_ImplWin32_UpdateMouseCursor();
|
||||
}
|
||||
|
||||
// Update game controllers (if enabled and available)
|
||||
ImGui_ImplWin32_UpdateGamepads();
|
||||
}
|
||||
|
||||
// Allow compilation with old Windows SDK. MinGW doesn't have default _WIN32_WINNT/WINVER versions.
|
||||
#ifndef WM_MOUSEHWHEEL
|
||||
#define WM_MOUSEHWHEEL 0x020E
|
||||
#endif
|
||||
#ifndef DBT_DEVNODES_CHANGED
|
||||
#define DBT_DEVNODES_CHANGED 0x0007
|
||||
#endif
|
||||
|
||||
// Win32 message handler (process Win32 mouse/keyboard inputs, etc.)
|
||||
// Call from your application's message handler.
|
||||
// When implementing your own backend, you can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if Dear ImGui wants to use your inputs.
|
||||
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application.
|
||||
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application.
|
||||
// Generally you may always pass all inputs to Dear ImGui, and hide them from your application based on those two flags.
|
||||
// PS: In this Win32 handler, we use the capture API (GetCapture/SetCapture/ReleaseCapture) to be able to read mouse coordinates when dragging mouse outside of our window bounds.
|
||||
// PS: We treat DBLCLK messages as regular mouse down messages, so this code will work on windows classes that have the CS_DBLCLKS flag set. Our own example app code doesn't set this flag.
|
||||
#if 0
|
||||
// Copy this line into your .cpp file to forward declare the function.
|
||||
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
#endif
|
||||
IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (ImGui::GetCurrentContext() == NULL)
|
||||
return 0;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData();
|
||||
|
||||
switch (msg)
|
||||
{
|
||||
case WM_MOUSEMOVE:
|
||||
// We need to call TrackMouseEvent in order to receive WM_MOUSELEAVE events
|
||||
bd->MouseHwnd = hwnd;
|
||||
if (!bd->MouseTracked)
|
||||
{
|
||||
TRACKMOUSEEVENT tme = { sizeof(tme), TME_LEAVE, hwnd, 0 };
|
||||
::TrackMouseEvent(&tme);
|
||||
bd->MouseTracked = true;
|
||||
}
|
||||
break;
|
||||
case WM_MOUSELEAVE:
|
||||
if (bd->MouseHwnd == hwnd)
|
||||
bd->MouseHwnd = NULL;
|
||||
bd->MouseTracked = false;
|
||||
break;
|
||||
case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK:
|
||||
case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK:
|
||||
case WM_MBUTTONDOWN: case WM_MBUTTONDBLCLK:
|
||||
case WM_XBUTTONDOWN: case WM_XBUTTONDBLCLK:
|
||||
{
|
||||
int button = 0;
|
||||
if (msg == WM_LBUTTONDOWN || msg == WM_LBUTTONDBLCLK) { button = 0; }
|
||||
if (msg == WM_RBUTTONDOWN || msg == WM_RBUTTONDBLCLK) { button = 1; }
|
||||
if (msg == WM_MBUTTONDOWN || msg == WM_MBUTTONDBLCLK) { button = 2; }
|
||||
if (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONDBLCLK) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
|
||||
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == NULL)
|
||||
::SetCapture(hwnd);
|
||||
io.MouseDown[button] = true;
|
||||
return 0;
|
||||
}
|
||||
case WM_LBUTTONUP:
|
||||
case WM_RBUTTONUP:
|
||||
case WM_MBUTTONUP:
|
||||
case WM_XBUTTONUP:
|
||||
{
|
||||
int button = 0;
|
||||
if (msg == WM_LBUTTONUP) { button = 0; }
|
||||
if (msg == WM_RBUTTONUP) { button = 1; }
|
||||
if (msg == WM_MBUTTONUP) { button = 2; }
|
||||
if (msg == WM_XBUTTONUP) { button = (GET_XBUTTON_WPARAM(wParam) == XBUTTON1) ? 3 : 4; }
|
||||
io.MouseDown[button] = false;
|
||||
if (!ImGui::IsAnyMouseDown() && ::GetCapture() == hwnd)
|
||||
::ReleaseCapture();
|
||||
return 0;
|
||||
}
|
||||
case WM_MOUSEWHEEL:
|
||||
io.MouseWheel += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
|
||||
return 0;
|
||||
case WM_MOUSEHWHEEL:
|
||||
io.MouseWheelH += (float)GET_WHEEL_DELTA_WPARAM(wParam) / (float)WHEEL_DELTA;
|
||||
return 0;
|
||||
case WM_KEYDOWN:
|
||||
case WM_KEYUP:
|
||||
case WM_SYSKEYDOWN:
|
||||
case WM_SYSKEYUP:
|
||||
{
|
||||
bool down = (msg == WM_KEYDOWN || msg == WM_SYSKEYDOWN);
|
||||
if (wParam < 256)
|
||||
io.KeysDown[wParam] = down;
|
||||
if (wParam == VK_CONTROL)
|
||||
{
|
||||
io.KeysDown[VK_LCONTROL] = ((::GetKeyState(VK_LCONTROL) & 0x8000) != 0);
|
||||
io.KeysDown[VK_RCONTROL] = ((::GetKeyState(VK_RCONTROL) & 0x8000) != 0);
|
||||
io.KeyCtrl = io.KeysDown[VK_LCONTROL] || io.KeysDown[VK_RCONTROL];
|
||||
}
|
||||
if (wParam == VK_SHIFT)
|
||||
{
|
||||
io.KeysDown[VK_LSHIFT] = ((::GetKeyState(VK_LSHIFT) & 0x8000) != 0);
|
||||
io.KeysDown[VK_RSHIFT] = ((::GetKeyState(VK_RSHIFT) & 0x8000) != 0);
|
||||
io.KeyShift = io.KeysDown[VK_LSHIFT] || io.KeysDown[VK_RSHIFT];
|
||||
}
|
||||
if (wParam == VK_MENU)
|
||||
{
|
||||
io.KeysDown[VK_LMENU] = ((::GetKeyState(VK_LMENU) & 0x8000) != 0);
|
||||
io.KeysDown[VK_RMENU] = ((::GetKeyState(VK_RMENU) & 0x8000) != 0);
|
||||
io.KeyAlt = io.KeysDown[VK_LMENU] || io.KeysDown[VK_RMENU];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
case WM_SETFOCUS:
|
||||
case WM_KILLFOCUS:
|
||||
io.AddFocusEvent(msg == WM_SETFOCUS);
|
||||
return 0;
|
||||
case WM_CHAR:
|
||||
// You can also use ToAscii()+GetKeyboardState() to retrieve characters.
|
||||
if (wParam > 0 && wParam < 0x10000)
|
||||
io.AddInputCharacterUTF16((unsigned short)wParam);
|
||||
return 0;
|
||||
case WM_SETCURSOR:
|
||||
if (LOWORD(lParam) == HTCLIENT && ImGui_ImplWin32_UpdateMouseCursor())
|
||||
return 1;
|
||||
return 0;
|
||||
case WM_DEVICECHANGE:
|
||||
if ((UINT)wParam == DBT_DEVNODES_CHANGED)
|
||||
bd->WantUpdateHasGamepad = true;
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// DPI-related helpers (optional)
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// - Use to enable DPI awareness without having to create an application manifest.
|
||||
// - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps.
|
||||
// - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc.
|
||||
// but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime,
|
||||
// neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies.
|
||||
//---------------------------------------------------------------------------------------------------------
|
||||
// This is the scheme successfully used by GLFW (from which we borrowed some of the code) and other apps aiming to be highly portable.
|
||||
// ImGui_ImplWin32_EnableDpiAwareness() is just a helper called by main.cpp, we don't call it automatically.
|
||||
// If you are trying to implement your own backend for your own engine, you may ignore that noise.
|
||||
//---------------------------------------------------------------------------------------------------------
|
||||
|
||||
// Perform our own check with RtlVerifyVersionInfo() instead of using functions from <VersionHelpers.h> as they
|
||||
// require a manifest to be functional for checks above 8.1. See https://github.com/ocornut/imgui/issues/4200
|
||||
static BOOL _IsWindowsVersionOrGreater(WORD major, WORD minor, WORD)
|
||||
{
|
||||
typedef LONG(WINAPI* PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*, ULONG, ULONGLONG);
|
||||
static PFN_RtlVerifyVersionInfo RtlVerifyVersionInfoFn = NULL;
|
||||
if (RtlVerifyVersionInfoFn == NULL)
|
||||
if (HMODULE ntdllModule = ::GetModuleHandleA("ntdll.dll"))
|
||||
RtlVerifyVersionInfoFn = (PFN_RtlVerifyVersionInfo)GetProcAddress(ntdllModule, "RtlVerifyVersionInfo");
|
||||
if (RtlVerifyVersionInfoFn == NULL)
|
||||
return FALSE;
|
||||
|
||||
RTL_OSVERSIONINFOEXW versionInfo = { };
|
||||
ULONGLONG conditionMask = 0;
|
||||
versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
|
||||
versionInfo.dwMajorVersion = major;
|
||||
versionInfo.dwMinorVersion = minor;
|
||||
VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||
VER_SET_CONDITION(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||
return (RtlVerifyVersionInfoFn(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, conditionMask) == 0) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
#define _IsWindowsVistaOrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0600), LOBYTE(0x0600), 0) // _WIN32_WINNT_VISTA
|
||||
#define _IsWindows8OrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0602), LOBYTE(0x0602), 0) // _WIN32_WINNT_WIN8
|
||||
#define _IsWindows8Point1OrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0603), LOBYTE(0x0603), 0) // _WIN32_WINNT_WINBLUE
|
||||
#define _IsWindows10OrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0A00), LOBYTE(0x0A00), 0) // _WIN32_WINNT_WINTHRESHOLD / _WIN32_WINNT_WIN10
|
||||
|
||||
#ifndef DPI_ENUMS_DECLARED
|
||||
typedef enum { PROCESS_DPI_UNAWARE = 0, PROCESS_SYSTEM_DPI_AWARE = 1, PROCESS_PER_MONITOR_DPI_AWARE = 2 } PROCESS_DPI_AWARENESS;
|
||||
typedef enum { MDT_EFFECTIVE_DPI = 0, MDT_ANGULAR_DPI = 1, MDT_RAW_DPI = 2, MDT_DEFAULT = MDT_EFFECTIVE_DPI } MONITOR_DPI_TYPE;
|
||||
#endif
|
||||
#ifndef _DPI_AWARENESS_CONTEXTS_
|
||||
DECLARE_HANDLE(DPI_AWARENESS_CONTEXT);
|
||||
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE (DPI_AWARENESS_CONTEXT)-3
|
||||
#endif
|
||||
#ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2
|
||||
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 (DPI_AWARENESS_CONTEXT)-4
|
||||
#endif
|
||||
typedef HRESULT(WINAPI* PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS); // Shcore.lib + dll, Windows 8.1+
|
||||
typedef HRESULT(WINAPI* PFN_GetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*); // Shcore.lib + dll, Windows 8.1+
|
||||
typedef DPI_AWARENESS_CONTEXT(WINAPI* PFN_SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); // User32.lib + dll, Windows 10 v1607+ (Creators Update)
|
||||
|
||||
// Helper function to enable DPI awareness without setting up a manifest
|
||||
void ImGui_ImplWin32_EnableDpiAwareness()
|
||||
{
|
||||
if (_IsWindows10OrGreater())
|
||||
{
|
||||
static HINSTANCE user32_dll = ::LoadLibraryA("user32.dll"); // Reference counted per-process
|
||||
if (PFN_SetThreadDpiAwarenessContext SetThreadDpiAwarenessContextFn = (PFN_SetThreadDpiAwarenessContext)::GetProcAddress(user32_dll, "SetThreadDpiAwarenessContext"))
|
||||
{
|
||||
SetThreadDpiAwarenessContextFn(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (_IsWindows8Point1OrGreater())
|
||||
{
|
||||
static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process
|
||||
if (PFN_SetProcessDpiAwareness SetProcessDpiAwarenessFn = (PFN_SetProcessDpiAwareness)::GetProcAddress(shcore_dll, "SetProcessDpiAwareness"))
|
||||
{
|
||||
SetProcessDpiAwarenessFn(PROCESS_PER_MONITOR_DPI_AWARE);
|
||||
return;
|
||||
}
|
||||
}
|
||||
#if _WIN32_WINNT >= 0x0600
|
||||
::SetProcessDPIAware();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(_MSC_VER) && !defined(NOGDI)
|
||||
#pragma comment(lib, "gdi32") // Link with gdi32.lib for GetDeviceCaps(). MinGW will require linking with '-lgdi32'
|
||||
#endif
|
||||
|
||||
float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor)
|
||||
{
|
||||
UINT xdpi = 96, ydpi = 96;
|
||||
if (_IsWindows8Point1OrGreater())
|
||||
{
|
||||
static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process
|
||||
static PFN_GetDpiForMonitor GetDpiForMonitorFn = NULL;
|
||||
if (GetDpiForMonitorFn == NULL && shcore_dll != NULL)
|
||||
GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor");
|
||||
if (GetDpiForMonitorFn != NULL)
|
||||
{
|
||||
GetDpiForMonitorFn((HMONITOR)monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi);
|
||||
IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert!
|
||||
return xdpi / 96.0f;
|
||||
}
|
||||
}
|
||||
#ifndef NOGDI
|
||||
const HDC dc = ::GetDC(NULL);
|
||||
xdpi = ::GetDeviceCaps(dc, LOGPIXELSX);
|
||||
ydpi = ::GetDeviceCaps(dc, LOGPIXELSY);
|
||||
IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert!
|
||||
::ReleaseDC(NULL, dc);
|
||||
#endif
|
||||
return xdpi / 96.0f;
|
||||
}
|
||||
|
||||
float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd)
|
||||
{
|
||||
HMONITOR monitor = ::MonitorFromWindow((HWND)hwnd, MONITOR_DEFAULTTONEAREST);
|
||||
return ImGui_ImplWin32_GetDpiScaleForMonitor(monitor);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------
|
||||
// Transparency related helpers (optional)
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma comment(lib, "dwmapi") // Link with dwmapi.lib. MinGW will require linking with '-ldwmapi'
|
||||
#endif
|
||||
|
||||
// [experimental]
|
||||
// Borrowed from GLFW's function updateFramebufferTransparency() in src/win32_window.c
|
||||
// (the Dwm* functions are Vista era functions but we are borrowing logic from GLFW)
|
||||
void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd)
|
||||
{
|
||||
if (!_IsWindowsVistaOrGreater())
|
||||
return;
|
||||
|
||||
BOOL composition;
|
||||
if (FAILED(::DwmIsCompositionEnabled(&composition)) || !composition)
|
||||
return;
|
||||
|
||||
BOOL opaque;
|
||||
DWORD color;
|
||||
if (_IsWindows8OrGreater() || (SUCCEEDED(::DwmGetColorizationColor(&color, &opaque)) && !opaque))
|
||||
{
|
||||
HRGN region = ::CreateRectRgn(0, 0, -1, -1);
|
||||
DWM_BLURBEHIND bb = {};
|
||||
bb.dwFlags = DWM_BB_ENABLE | DWM_BB_BLURREGION;
|
||||
bb.hRgnBlur = region;
|
||||
bb.fEnable = TRUE;
|
||||
::DwmEnableBlurBehindWindow((HWND)hwnd, &bb);
|
||||
::DeleteObject(region);
|
||||
}
|
||||
else
|
||||
{
|
||||
DWM_BLURBEHIND bb = {};
|
||||
bb.dwFlags = DWM_BB_ENABLE;
|
||||
::DwmEnableBlurBehindWindow((HWND)hwnd, &bb);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------
|
||||
42
DevourClient/Dependencies/imgui/imgui_impl_win32.h
Normal file
42
DevourClient/Dependencies/imgui/imgui_impl_win32.h
Normal file
@@ -0,0 +1,42 @@
|
||||
// dear imgui: Platform Backend for Windows (standard windows API for 32 and 64 bits applications)
|
||||
// This needs to be used along with a Renderer (e.g. DirectX11, OpenGL3, Vulkan..)
|
||||
|
||||
// Implemented features:
|
||||
// [X] Platform: Clipboard support (for Win32 this is actually part of core dear imgui)
|
||||
// [X] Platform: Mouse cursor shape and visibility. Disable with 'io.ConfigFlags |= ImGuiConfigFlags_NoMouseCursorChange'.
|
||||
// [X] Platform: Keyboard arrays indexed using VK_* Virtual Key Codes, e.g. ImGui::IsKeyPressed(VK_SPACE).
|
||||
// [X] Platform: Gamepad support. Enabled with 'io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
// Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need.
|
||||
// If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp.
|
||||
// Read online: https://github.com/ocornut/imgui/tree/master/docs
|
||||
|
||||
#pragma once
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
|
||||
IMGUI_IMPL_API bool ImGui_ImplWin32_Init(void* hwnd);
|
||||
IMGUI_IMPL_API void ImGui_ImplWin32_Shutdown();
|
||||
IMGUI_IMPL_API void ImGui_ImplWin32_NewFrame();
|
||||
|
||||
// Win32 message handler your application need to call.
|
||||
// - Intentionally commented out in a '#if 0' block to avoid dragging dependencies on <windows.h> from this helper.
|
||||
// - You should COPY the line below into your .cpp code to forward declare the function and then you can call it.
|
||||
#if 0
|
||||
extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
#endif
|
||||
|
||||
// DPI-related helpers (optional)
|
||||
// - Use to enable DPI awareness without having to create an application manifest.
|
||||
// - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps.
|
||||
// - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc.
|
||||
// but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime,
|
||||
// neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies.
|
||||
IMGUI_IMPL_API void ImGui_ImplWin32_EnableDpiAwareness();
|
||||
IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd); // HWND hwnd
|
||||
IMGUI_IMPL_API float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor); // HMONITOR monitor
|
||||
|
||||
// Transparency related helpers (optional) [experimental]
|
||||
// - Use to enable alpha compositing transparency with the desktop.
|
||||
// - Use together with e.g. clearing your framebuffer with zero-alpha.
|
||||
IMGUI_IMPL_API void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd); // HWND hwnd
|
||||
2859
DevourClient/Dependencies/imgui/imgui_internal.h
Normal file
2859
DevourClient/Dependencies/imgui/imgui_internal.h
Normal file
File diff suppressed because it is too large
Load Diff
72
DevourClient/Dependencies/imgui/imgui_stdlib.cpp
Normal file
72
DevourClient/Dependencies/imgui/imgui_stdlib.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
// dear imgui: wrappers for C++ standard library (STL) types (std::string, etc.)
|
||||
// This is also an example of how you may wrap your own similar types.
|
||||
|
||||
// Changelog:
|
||||
// - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string
|
||||
|
||||
#include "imgui.h"
|
||||
#include "imgui_stdlib.h"
|
||||
|
||||
struct InputTextCallback_UserData
|
||||
{
|
||||
std::string* Str;
|
||||
ImGuiInputTextCallback ChainCallback;
|
||||
void* ChainCallbackUserData;
|
||||
};
|
||||
|
||||
static int InputTextCallback(ImGuiInputTextCallbackData* data)
|
||||
{
|
||||
InputTextCallback_UserData* user_data = (InputTextCallback_UserData*)data->UserData;
|
||||
if (data->EventFlag == ImGuiInputTextFlags_CallbackResize)
|
||||
{
|
||||
// Resize string callback
|
||||
// If for some reason we refuse the new length (BufTextLen) and/or capacity (BufSize) we need to set them back to what we want.
|
||||
std::string* str = user_data->Str;
|
||||
IM_ASSERT(data->Buf == str->c_str());
|
||||
str->resize(data->BufTextLen);
|
||||
data->Buf = (char*)str->c_str();
|
||||
}
|
||||
else if (user_data->ChainCallback)
|
||||
{
|
||||
// Forward to user callback, if any
|
||||
data->UserData = user_data->ChainCallbackUserData;
|
||||
return user_data->ChainCallback(data);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ImGui::InputText(const char* label, std::string* str, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
|
||||
{
|
||||
IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0);
|
||||
flags |= ImGuiInputTextFlags_CallbackResize;
|
||||
|
||||
InputTextCallback_UserData cb_user_data;
|
||||
cb_user_data.Str = str;
|
||||
cb_user_data.ChainCallback = callback;
|
||||
cb_user_data.ChainCallbackUserData = user_data;
|
||||
return InputText(label, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data);
|
||||
}
|
||||
|
||||
bool ImGui::InputTextMultiline(const char* label, std::string* str, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
|
||||
{
|
||||
IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0);
|
||||
flags |= ImGuiInputTextFlags_CallbackResize;
|
||||
|
||||
InputTextCallback_UserData cb_user_data;
|
||||
cb_user_data.Str = str;
|
||||
cb_user_data.ChainCallback = callback;
|
||||
cb_user_data.ChainCallbackUserData = user_data;
|
||||
return InputTextMultiline(label, (char*)str->c_str(), str->capacity() + 1, size, flags, InputTextCallback, &cb_user_data);
|
||||
}
|
||||
|
||||
bool ImGui::InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags, ImGuiInputTextCallback callback, void* user_data)
|
||||
{
|
||||
IM_ASSERT((flags & ImGuiInputTextFlags_CallbackResize) == 0);
|
||||
flags |= ImGuiInputTextFlags_CallbackResize;
|
||||
|
||||
InputTextCallback_UserData cb_user_data;
|
||||
cb_user_data.Str = str;
|
||||
cb_user_data.ChainCallback = callback;
|
||||
cb_user_data.ChainCallbackUserData = user_data;
|
||||
return InputTextWithHint(label, hint, (char*)str->c_str(), str->capacity() + 1, flags, InputTextCallback, &cb_user_data);
|
||||
}
|
||||
18
DevourClient/Dependencies/imgui/imgui_stdlib.h
Normal file
18
DevourClient/Dependencies/imgui/imgui_stdlib.h
Normal file
@@ -0,0 +1,18 @@
|
||||
// dear imgui: wrappers for C++ standard library (STL) types (std::string, etc.)
|
||||
// This is also an example of how you may wrap your own similar types.
|
||||
|
||||
// Changelog:
|
||||
// - v0.10: Initial version. Added InputText() / InputTextMultiline() calls with std::string
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace ImGui
|
||||
{
|
||||
// ImGui::InputText() with std::string
|
||||
// Because text input needs dynamic resizing, we need to setup a callback to grow the capacity
|
||||
IMGUI_API bool InputText(const char* label, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
|
||||
IMGUI_API bool InputTextMultiline(const char* label, std::string* str, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
|
||||
IMGUI_API bool InputTextWithHint(const char* label, const char* hint, std::string* str, ImGuiInputTextFlags flags = 0, ImGuiInputTextCallback callback = NULL, void* user_data = NULL);
|
||||
}
|
||||
4049
DevourClient/Dependencies/imgui/imgui_tables.cpp
Normal file
4049
DevourClient/Dependencies/imgui/imgui_tables.cpp
Normal file
File diff suppressed because it is too large
Load Diff
8305
DevourClient/Dependencies/imgui/imgui_widgets.cpp
Normal file
8305
DevourClient/Dependencies/imgui/imgui_widgets.cpp
Normal file
File diff suppressed because it is too large
Load Diff
639
DevourClient/Dependencies/imgui/imstb_rectpack.h
Normal file
639
DevourClient/Dependencies/imgui/imstb_rectpack.h
Normal file
@@ -0,0 +1,639 @@
|
||||
// [DEAR IMGUI]
|
||||
// This is a slightly modified version of stb_rect_pack.h 1.00.
|
||||
// Those changes would need to be pushed into nothings/stb:
|
||||
// - Added STBRP__CDECL
|
||||
// Grep for [DEAR IMGUI] to find the changes.
|
||||
|
||||
// stb_rect_pack.h - v1.00 - public domain - rectangle packing
|
||||
// Sean Barrett 2014
|
||||
//
|
||||
// Useful for e.g. packing rectangular textures into an atlas.
|
||||
// Does not do rotation.
|
||||
//
|
||||
// Not necessarily the awesomest packing method, but better than
|
||||
// the totally naive one in stb_truetype (which is primarily what
|
||||
// this is meant to replace).
|
||||
//
|
||||
// Has only had a few tests run, may have issues.
|
||||
//
|
||||
// More docs to come.
|
||||
//
|
||||
// No memory allocations; uses qsort() and assert() from stdlib.
|
||||
// Can override those by defining STBRP_SORT and STBRP_ASSERT.
|
||||
//
|
||||
// This library currently uses the Skyline Bottom-Left algorithm.
|
||||
//
|
||||
// Please note: better rectangle packers are welcome! Please
|
||||
// implement them to the same API, but with a different init
|
||||
// function.
|
||||
//
|
||||
// Credits
|
||||
//
|
||||
// Library
|
||||
// Sean Barrett
|
||||
// Minor features
|
||||
// Martins Mozeiko
|
||||
// github:IntellectualKitty
|
||||
//
|
||||
// Bugfixes / warning fixes
|
||||
// Jeremy Jaussaud
|
||||
// Fabian Giesen
|
||||
//
|
||||
// Version history:
|
||||
//
|
||||
// 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
|
||||
// 0.99 (2019-02-07) warning fixes
|
||||
// 0.11 (2017-03-03) return packing success/fail result
|
||||
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings
|
||||
// 0.09 (2016-08-27) fix compiler warnings
|
||||
// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
|
||||
// 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
|
||||
// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
|
||||
// 0.05: added STBRP_ASSERT to allow replacing assert
|
||||
// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
|
||||
// 0.01: initial release
|
||||
//
|
||||
// LICENSE
|
||||
//
|
||||
// See end of file for license information.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// INCLUDE SECTION
|
||||
//
|
||||
|
||||
#ifndef STB_INCLUDE_STB_RECT_PACK_H
|
||||
#define STB_INCLUDE_STB_RECT_PACK_H
|
||||
|
||||
#define STB_RECT_PACK_VERSION 1
|
||||
|
||||
#ifdef STBRP_STATIC
|
||||
#define STBRP_DEF static
|
||||
#else
|
||||
#define STBRP_DEF extern
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct stbrp_context stbrp_context;
|
||||
typedef struct stbrp_node stbrp_node;
|
||||
typedef struct stbrp_rect stbrp_rect;
|
||||
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
typedef int stbrp_coord;
|
||||
#else
|
||||
typedef unsigned short stbrp_coord;
|
||||
#endif
|
||||
|
||||
STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
|
||||
// Assign packed locations to rectangles. The rectangles are of type
|
||||
// 'stbrp_rect' defined below, stored in the array 'rects', and there
|
||||
// are 'num_rects' many of them.
|
||||
//
|
||||
// Rectangles which are successfully packed have the 'was_packed' flag
|
||||
// set to a non-zero value and 'x' and 'y' store the minimum location
|
||||
// on each axis (i.e. bottom-left in cartesian coordinates, top-left
|
||||
// if you imagine y increasing downwards). Rectangles which do not fit
|
||||
// have the 'was_packed' flag set to 0.
|
||||
//
|
||||
// You should not try to access the 'rects' array from another thread
|
||||
// while this function is running, as the function temporarily reorders
|
||||
// the array while it executes.
|
||||
//
|
||||
// To pack into another rectangle, you need to call stbrp_init_target
|
||||
// again. To continue packing into the same rectangle, you can call
|
||||
// this function again. Calling this multiple times with multiple rect
|
||||
// arrays will probably produce worse packing results than calling it
|
||||
// a single time with the full rectangle array, but the option is
|
||||
// available.
|
||||
//
|
||||
// The function returns 1 if all of the rectangles were successfully
|
||||
// packed and 0 otherwise.
|
||||
|
||||
struct stbrp_rect
|
||||
{
|
||||
// reserved for your use:
|
||||
int id;
|
||||
|
||||
// input:
|
||||
stbrp_coord w, h;
|
||||
|
||||
// output:
|
||||
stbrp_coord x, y;
|
||||
int was_packed; // non-zero if valid packing
|
||||
|
||||
}; // 16 bytes, nominally
|
||||
|
||||
|
||||
STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
|
||||
// Initialize a rectangle packer to:
|
||||
// pack a rectangle that is 'width' by 'height' in dimensions
|
||||
// using temporary storage provided by the array 'nodes', which is 'num_nodes' long
|
||||
//
|
||||
// You must call this function every time you start packing into a new target.
|
||||
//
|
||||
// There is no "shutdown" function. The 'nodes' memory must stay valid for
|
||||
// the following stbrp_pack_rects() call (or calls), but can be freed after
|
||||
// the call (or calls) finish.
|
||||
//
|
||||
// Note: to guarantee best results, either:
|
||||
// 1. make sure 'num_nodes' >= 'width'
|
||||
// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
|
||||
//
|
||||
// If you don't do either of the above things, widths will be quantized to multiples
|
||||
// of small integers to guarantee the algorithm doesn't run out of temporary storage.
|
||||
//
|
||||
// If you do #2, then the non-quantized algorithm will be used, but the algorithm
|
||||
// may run out of temporary storage and be unable to pack some rectangles.
|
||||
|
||||
STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
|
||||
// Optionally call this function after init but before doing any packing to
|
||||
// change the handling of the out-of-temp-memory scenario, described above.
|
||||
// If you call init again, this will be reset to the default (false).
|
||||
|
||||
|
||||
STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
|
||||
// Optionally select which packing heuristic the library should use. Different
|
||||
// heuristics will produce better/worse results for different data sets.
|
||||
// If you call init again, this will be reset to the default.
|
||||
|
||||
enum
|
||||
{
|
||||
STBRP_HEURISTIC_Skyline_default=0,
|
||||
STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
|
||||
STBRP_HEURISTIC_Skyline_BF_sortHeight
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// the details of the following structures don't matter to you, but they must
|
||||
// be visible so you can handle the memory allocations for them
|
||||
|
||||
struct stbrp_node
|
||||
{
|
||||
stbrp_coord x,y;
|
||||
stbrp_node *next;
|
||||
};
|
||||
|
||||
struct stbrp_context
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
int align;
|
||||
int init_mode;
|
||||
int heuristic;
|
||||
int num_nodes;
|
||||
stbrp_node *active_head;
|
||||
stbrp_node *free_head;
|
||||
stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPLEMENTATION SECTION
|
||||
//
|
||||
|
||||
#ifdef STB_RECT_PACK_IMPLEMENTATION
|
||||
#ifndef STBRP_SORT
|
||||
#include <stdlib.h>
|
||||
#define STBRP_SORT qsort
|
||||
#endif
|
||||
|
||||
#ifndef STBRP_ASSERT
|
||||
#include <assert.h>
|
||||
#define STBRP_ASSERT assert
|
||||
#endif
|
||||
|
||||
// [DEAR IMGUI] Added STBRP__CDECL
|
||||
#ifdef _MSC_VER
|
||||
#define STBRP__NOTUSED(v) (void)(v)
|
||||
#define STBRP__CDECL __cdecl
|
||||
#else
|
||||
#define STBRP__NOTUSED(v) (void)sizeof(v)
|
||||
#define STBRP__CDECL
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
STBRP__INIT_skyline = 1
|
||||
};
|
||||
|
||||
STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
|
||||
{
|
||||
switch (context->init_mode) {
|
||||
case STBRP__INIT_skyline:
|
||||
STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
|
||||
context->heuristic = heuristic;
|
||||
break;
|
||||
default:
|
||||
STBRP_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
|
||||
{
|
||||
if (allow_out_of_mem)
|
||||
// if it's ok to run out of memory, then don't bother aligning them;
|
||||
// this gives better packing, but may fail due to OOM (even though
|
||||
// the rectangles easily fit). @TODO a smarter approach would be to only
|
||||
// quantize once we've hit OOM, then we could get rid of this parameter.
|
||||
context->align = 1;
|
||||
else {
|
||||
// if it's not ok to run out of memory, then quantize the widths
|
||||
// so that num_nodes is always enough nodes.
|
||||
//
|
||||
// I.e. num_nodes * align >= width
|
||||
// align >= width / num_nodes
|
||||
// align = ceil(width/num_nodes)
|
||||
|
||||
context->align = (context->width + context->num_nodes-1) / context->num_nodes;
|
||||
}
|
||||
}
|
||||
|
||||
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
|
||||
{
|
||||
int i;
|
||||
#ifndef STBRP_LARGE_RECTS
|
||||
STBRP_ASSERT(width <= 0xffff && height <= 0xffff);
|
||||
#endif
|
||||
|
||||
for (i=0; i < num_nodes-1; ++i)
|
||||
nodes[i].next = &nodes[i+1];
|
||||
nodes[i].next = NULL;
|
||||
context->init_mode = STBRP__INIT_skyline;
|
||||
context->heuristic = STBRP_HEURISTIC_Skyline_default;
|
||||
context->free_head = &nodes[0];
|
||||
context->active_head = &context->extra[0];
|
||||
context->width = width;
|
||||
context->height = height;
|
||||
context->num_nodes = num_nodes;
|
||||
stbrp_setup_allow_out_of_mem(context, 0);
|
||||
|
||||
// node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
|
||||
context->extra[0].x = 0;
|
||||
context->extra[0].y = 0;
|
||||
context->extra[0].next = &context->extra[1];
|
||||
context->extra[1].x = (stbrp_coord) width;
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
context->extra[1].y = (1<<30);
|
||||
#else
|
||||
context->extra[1].y = 65535;
|
||||
#endif
|
||||
context->extra[1].next = NULL;
|
||||
}
|
||||
|
||||
// find minimum y position if it starts at x1
|
||||
static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
|
||||
{
|
||||
stbrp_node *node = first;
|
||||
int x1 = x0 + width;
|
||||
int min_y, visited_width, waste_area;
|
||||
|
||||
STBRP__NOTUSED(c);
|
||||
|
||||
STBRP_ASSERT(first->x <= x0);
|
||||
|
||||
#if 0
|
||||
// skip in case we're past the node
|
||||
while (node->next->x <= x0)
|
||||
++node;
|
||||
#else
|
||||
STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
|
||||
#endif
|
||||
|
||||
STBRP_ASSERT(node->x <= x0);
|
||||
|
||||
min_y = 0;
|
||||
waste_area = 0;
|
||||
visited_width = 0;
|
||||
while (node->x < x1) {
|
||||
if (node->y > min_y) {
|
||||
// raise min_y higher.
|
||||
// we've accounted for all waste up to min_y,
|
||||
// but we'll now add more waste for everything we've visted
|
||||
waste_area += visited_width * (node->y - min_y);
|
||||
min_y = node->y;
|
||||
// the first time through, visited_width might be reduced
|
||||
if (node->x < x0)
|
||||
visited_width += node->next->x - x0;
|
||||
else
|
||||
visited_width += node->next->x - node->x;
|
||||
} else {
|
||||
// add waste area
|
||||
int under_width = node->next->x - node->x;
|
||||
if (under_width + visited_width > width)
|
||||
under_width = width - visited_width;
|
||||
waste_area += under_width * (min_y - node->y);
|
||||
visited_width += under_width;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
*pwaste = waste_area;
|
||||
return min_y;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x,y;
|
||||
stbrp_node **prev_link;
|
||||
} stbrp__findresult;
|
||||
|
||||
static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
|
||||
{
|
||||
int best_waste = (1<<30), best_x, best_y = (1 << 30);
|
||||
stbrp__findresult fr;
|
||||
stbrp_node **prev, *node, *tail, **best = NULL;
|
||||
|
||||
// align to multiple of c->align
|
||||
width = (width + c->align - 1);
|
||||
width -= width % c->align;
|
||||
STBRP_ASSERT(width % c->align == 0);
|
||||
|
||||
// if it can't possibly fit, bail immediately
|
||||
if (width > c->width || height > c->height) {
|
||||
fr.prev_link = NULL;
|
||||
fr.x = fr.y = 0;
|
||||
return fr;
|
||||
}
|
||||
|
||||
node = c->active_head;
|
||||
prev = &c->active_head;
|
||||
while (node->x + width <= c->width) {
|
||||
int y,waste;
|
||||
y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
|
||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
|
||||
// bottom left
|
||||
if (y < best_y) {
|
||||
best_y = y;
|
||||
best = prev;
|
||||
}
|
||||
} else {
|
||||
// best-fit
|
||||
if (y + height <= c->height) {
|
||||
// can only use it if it first vertically
|
||||
if (y < best_y || (y == best_y && waste < best_waste)) {
|
||||
best_y = y;
|
||||
best_waste = waste;
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
prev = &node->next;
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
best_x = (best == NULL) ? 0 : (*best)->x;
|
||||
|
||||
// if doing best-fit (BF), we also have to try aligning right edge to each node position
|
||||
//
|
||||
// e.g, if fitting
|
||||
//
|
||||
// ____________________
|
||||
// |____________________|
|
||||
//
|
||||
// into
|
||||
//
|
||||
// | |
|
||||
// | ____________|
|
||||
// |____________|
|
||||
//
|
||||
// then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
|
||||
//
|
||||
// This makes BF take about 2x the time
|
||||
|
||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
|
||||
tail = c->active_head;
|
||||
node = c->active_head;
|
||||
prev = &c->active_head;
|
||||
// find first node that's admissible
|
||||
while (tail->x < width)
|
||||
tail = tail->next;
|
||||
while (tail) {
|
||||
int xpos = tail->x - width;
|
||||
int y,waste;
|
||||
STBRP_ASSERT(xpos >= 0);
|
||||
// find the left position that matches this
|
||||
while (node->next->x <= xpos) {
|
||||
prev = &node->next;
|
||||
node = node->next;
|
||||
}
|
||||
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
|
||||
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
|
||||
if (y + height <= c->height) {
|
||||
if (y <= best_y) {
|
||||
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
|
||||
best_x = xpos;
|
||||
STBRP_ASSERT(y <= best_y);
|
||||
best_y = y;
|
||||
best_waste = waste;
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
tail = tail->next;
|
||||
}
|
||||
}
|
||||
|
||||
fr.prev_link = best;
|
||||
fr.x = best_x;
|
||||
fr.y = best_y;
|
||||
return fr;
|
||||
}
|
||||
|
||||
static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
|
||||
{
|
||||
// find best position according to heuristic
|
||||
stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
|
||||
stbrp_node *node, *cur;
|
||||
|
||||
// bail if:
|
||||
// 1. it failed
|
||||
// 2. the best node doesn't fit (we don't always check this)
|
||||
// 3. we're out of memory
|
||||
if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
|
||||
res.prev_link = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
// on success, create new node
|
||||
node = context->free_head;
|
||||
node->x = (stbrp_coord) res.x;
|
||||
node->y = (stbrp_coord) (res.y + height);
|
||||
|
||||
context->free_head = node->next;
|
||||
|
||||
// insert the new node into the right starting point, and
|
||||
// let 'cur' point to the remaining nodes needing to be
|
||||
// stiched back in
|
||||
|
||||
cur = *res.prev_link;
|
||||
if (cur->x < res.x) {
|
||||
// preserve the existing one, so start testing with the next one
|
||||
stbrp_node *next = cur->next;
|
||||
cur->next = node;
|
||||
cur = next;
|
||||
} else {
|
||||
*res.prev_link = node;
|
||||
}
|
||||
|
||||
// from here, traverse cur and free the nodes, until we get to one
|
||||
// that shouldn't be freed
|
||||
while (cur->next && cur->next->x <= res.x + width) {
|
||||
stbrp_node *next = cur->next;
|
||||
// move the current node to the free list
|
||||
cur->next = context->free_head;
|
||||
context->free_head = cur;
|
||||
cur = next;
|
||||
}
|
||||
|
||||
// stitch the list back in
|
||||
node->next = cur;
|
||||
|
||||
if (cur->x < res.x + width)
|
||||
cur->x = (stbrp_coord) (res.x + width);
|
||||
|
||||
#ifdef _DEBUG
|
||||
cur = context->active_head;
|
||||
while (cur->x < context->width) {
|
||||
STBRP_ASSERT(cur->x < cur->next->x);
|
||||
cur = cur->next;
|
||||
}
|
||||
STBRP_ASSERT(cur->next == NULL);
|
||||
|
||||
{
|
||||
int count=0;
|
||||
cur = context->active_head;
|
||||
while (cur) {
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
cur = context->free_head;
|
||||
while (cur) {
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
STBRP_ASSERT(count == context->num_nodes+2);
|
||||
}
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// [DEAR IMGUI] Added STBRP__CDECL
|
||||
static int STBRP__CDECL rect_height_compare(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
const stbrp_rect *q = (const stbrp_rect *) b;
|
||||
if (p->h > q->h)
|
||||
return -1;
|
||||
if (p->h < q->h)
|
||||
return 1;
|
||||
return (p->w > q->w) ? -1 : (p->w < q->w);
|
||||
}
|
||||
|
||||
// [DEAR IMGUI] Added STBRP__CDECL
|
||||
static int STBRP__CDECL rect_original_order(const void *a, const void *b)
|
||||
{
|
||||
const stbrp_rect *p = (const stbrp_rect *) a;
|
||||
const stbrp_rect *q = (const stbrp_rect *) b;
|
||||
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
|
||||
}
|
||||
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
#define STBRP__MAXVAL 0xffffffff
|
||||
#else
|
||||
#define STBRP__MAXVAL 0xffff
|
||||
#endif
|
||||
|
||||
STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
|
||||
{
|
||||
int i, all_rects_packed = 1;
|
||||
|
||||
// we use the 'was_packed' field internally to allow sorting/unsorting
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
rects[i].was_packed = i;
|
||||
}
|
||||
|
||||
// sort according to heuristic
|
||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
|
||||
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
if (rects[i].w == 0 || rects[i].h == 0) {
|
||||
rects[i].x = rects[i].y = 0; // empty rect needs no space
|
||||
} else {
|
||||
stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
|
||||
if (fr.prev_link) {
|
||||
rects[i].x = (stbrp_coord) fr.x;
|
||||
rects[i].y = (stbrp_coord) fr.y;
|
||||
} else {
|
||||
rects[i].x = rects[i].y = STBRP__MAXVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// unsort
|
||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
|
||||
|
||||
// set was_packed flags and all_rects_packed status
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
|
||||
if (!rects[i].was_packed)
|
||||
all_rects_packed = 0;
|
||||
}
|
||||
|
||||
// return the all_rects_packed status
|
||||
return all_rects_packed;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
------------------------------------------------------------------------------
|
||||
This software is available under 2 licenses -- choose whichever you prefer.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE A - MIT License
|
||||
Copyright (c) 2017 Sean Barrett
|
||||
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.
|
||||
------------------------------------------------------------------------------
|
||||
ALTERNATIVE B - Public Domain (www.unlicense.org)
|
||||
This is free and unencumbered software released into the public domain.
|
||||
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
|
||||
software, either in source code form or as a compiled binary, for any purpose,
|
||||
commercial or non-commercial, and by any means.
|
||||
In jurisdictions that recognize copyright laws, the author or authors of this
|
||||
software dedicate any and all copyright interest in the software to the public
|
||||
domain. We make this dedication for the benefit of the public at large and to
|
||||
the detriment of our heirs and successors. We intend this dedication to be an
|
||||
overt act of relinquishment in perpetuity of all present and future rights to
|
||||
this software under copyright law.
|
||||
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 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.
|
||||
------------------------------------------------------------------------------
|
||||
*/
|
||||
1449
DevourClient/Dependencies/imgui/imstb_textedit.h
Normal file
1449
DevourClient/Dependencies/imgui/imstb_textedit.h
Normal file
File diff suppressed because it is too large
Load Diff
4903
DevourClient/Dependencies/imgui/imstb_truetype.h
Normal file
4903
DevourClient/Dependencies/imgui/imstb_truetype.h
Normal file
File diff suppressed because it is too large
Load Diff
99
DevourClient/DevourClient.filters
Normal file
99
DevourClient/DevourClient.filters
Normal file
@@ -0,0 +1,99 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Fichiers sources">
|
||||
<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="Fichiers d%27en-tête">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Fichiers de ressources">
|
||||
<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>
|
||||
<ClInclude Include="framework.h">
|
||||
<Filter>Fichiers d%27en-tête</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="pch.h">
|
||||
<Filter>Fichiers d%27en-tête</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Memory\sigscan.h">
|
||||
<Filter>Fichiers d%27en-tête</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Utils\Output\Output.hpp">
|
||||
<Filter>Fichiers d%27en-tête</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Hooks\Hooks.hpp">
|
||||
<Filter>Fichiers d%27en-tête</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Features\Menu.hpp">
|
||||
<Filter>Fichiers d%27en-tête</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Dependencies\imgui\imconfig.h">
|
||||
<Filter>Fichiers d%27en-tête</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Dependencies\imgui\imgui_impl_dx11.h">
|
||||
<Filter>Fichiers d%27en-tête</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Dependencies\imgui\imgui_impl_win32.h">
|
||||
<Filter>Fichiers d%27en-tête</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Dependencies\imgui\imgui_internal.h">
|
||||
<Filter>Fichiers d%27en-tête</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Dependencies\imgui\imstb_rectpack.h">
|
||||
<Filter>Fichiers d%27en-tête</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Dependencies\imgui\imstb_textedit.h">
|
||||
<Filter>Fichiers d%27en-tête</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Dependencies\imgui\imstb_truetype.h">
|
||||
<Filter>Fichiers d%27en-tête</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="dllmain.hpp">
|
||||
<Filter>Fichiers d%27en-tête</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Dependencies\imgui\imgui.h">
|
||||
<Filter>Fichiers d%27en-tête</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Dependencies\imgui\imgui_impl_metal.h">
|
||||
<Filter>Fichiers d%27en-tête</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<Filter>Fichiers sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="pch.cpp">
|
||||
<Filter>Fichiers sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Utils\Output\Output.cpp">
|
||||
<Filter>Fichiers sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Hooks\Hooks.cpp">
|
||||
<Filter>Fichiers sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Features\Menu.cpp">
|
||||
<Filter>Fichiers sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Dependencies\imgui\imgui_draw.cpp">
|
||||
<Filter>Fichiers sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Dependencies\imgui\imgui_impl_win32.cpp">
|
||||
<Filter>Fichiers sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Dependencies\imgui\imgui_widgets.cpp">
|
||||
<Filter>Fichiers sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Dependencies\imgui\imgui.cpp">
|
||||
<Filter>Fichiers sources</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Dependencies\imgui\imgui_tables.cpp">
|
||||
<Filter>Fichiers sources</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
6
DevourClient/DevourClient.user
Normal file
6
DevourClient/DevourClient.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>
|
||||
366
DevourClient/DevourClient.vcxproj
Normal file
366
DevourClient/DevourClient.vcxproj
Normal file
@@ -0,0 +1,366 @@
|
||||
<?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="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>16.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{c7cbebbd-cef6-40c5-b6f5-2098545bb8a5}</ProjectGuid>
|
||||
<RootNamespace>DevourClient</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>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>MultiByte</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 Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<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 Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<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>
|
||||
<IncludePath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(SolutionDir)DevourClient\Dependencies;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IncludePath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(SolutionDir)DevourClient\Dependencies\Minhook\include;$(SolutionDir)DevourClient\Dependencies;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(SolutionDir)DevourClient\Dependencies;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x86;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<IncludePath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(SolutionDir)DevourClient\Dependencies\Minhook\include;$(SolutionDir)DevourClient\Dependencies;$(IncludePath)</IncludePath>
|
||||
<LibraryPath>C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<VcpkgUseStatic>false</VcpkgUseStatic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Vcpkg">
|
||||
<VcpkgUseStatic>false</VcpkgUseStatic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<VcpkgUseStatic>false</VcpkgUseStatic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Vcpkg">
|
||||
<VcpkgUseStatic>false</VcpkgUseStatic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Vcpkg">
|
||||
<VcpkgEnabled>false</VcpkgEnabled>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;DLL1_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalOptions>/NODEFAULTLIB:LIBCMT /NODEFAULTLIB:LIBCMTD %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;DLL1_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalOptions>/NODEFAULTLIB:LIBCMT /NODEFAULTLIB:LIBCMTD %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;DLL1_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalOptions>/NODEFAULTLIB:LIBCMT /NODEFAULTLIB:LIBCMTD %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;DLL1_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalOptions>/NODEFAULTLIB:LIBCMT /NODEFAULTLIB:LIBCMTD %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)include;</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalOptions>/NODEFAULTLIB:LIBCMT /NODEFAULTLIB:LIBCMTD %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_SILENCE_ALL_CXX17_DEPRECATION_WARNINGS</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)include;</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
<AdditionalOptions>/NODEFAULTLIB:LIBCMT /NODEFAULTLIB:LIBCMTD %(AdditionalOptions)</AdditionalOptions>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Cache.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Data.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Defines.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Functions\Callback.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Functions\Class.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Functions\Domain.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Functions\ResolveCall.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Functions\String.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Functions\Thread.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Includes.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\il2cpp_resolver.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Unity\API\Camera.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Unity\API\Component.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Unity\API\GameObject.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Unity\API\LayerMask.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Unity\API\Object.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Unity\API\Rigidbody.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Unity\API\Transform.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Unity\API\_TEMPLATE_API.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Unity\Defines.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Unity\Includes.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Unity\Obfuscators.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Unity\Structures\Engine.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Unity\Structures\il2cpp.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Unity\Structures\il2cppArray.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Unity\Structures\il2cppDictionary.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Unity\Structures\Includes.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Unity\Structures\System_String.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Utils\Helper.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Utils\Joaat.hpp" />
|
||||
<ClInclude Include="Dependencies\IL2CPP_Resolver\Utils\VFunc.hpp" />
|
||||
<ClInclude Include="Dependencies\imgui\imconfig.h" />
|
||||
<ClInclude Include="Dependencies\imgui\imgui.h" />
|
||||
<ClInclude Include="Dependencies\imgui\imgui_impl_dx11.h" />
|
||||
<ClInclude Include="Dependencies\imgui\imgui_impl_metal.h" />
|
||||
<ClInclude Include="Dependencies\imgui\imgui_impl_win32.h" />
|
||||
<ClInclude Include="Dependencies\imgui\imgui_internal.h" />
|
||||
<ClInclude Include="Dependencies\imgui\imgui_stdlib.h" />
|
||||
<ClInclude Include="Dependencies\imgui\imstb_rectpack.h" />
|
||||
<ClInclude Include="Dependencies\imgui\imstb_textedit.h" />
|
||||
<ClInclude Include="Dependencies\imgui\imstb_truetype.h" />
|
||||
<ClInclude Include="Dependencies\Minhook\include\MinHook.h" />
|
||||
<ClInclude Include="Dependencies\Minhook\src\buffer.h" />
|
||||
<ClInclude Include="Dependencies\Minhook\src\HDE\hde32.h" />
|
||||
<ClInclude Include="Dependencies\Minhook\src\HDE\hde64.h" />
|
||||
<ClInclude Include="Dependencies\Minhook\src\HDE\pstdint.h" />
|
||||
<ClInclude Include="Dependencies\Minhook\src\HDE\table32.h" />
|
||||
<ClInclude Include="Dependencies\Minhook\src\HDE\table64.h" />
|
||||
<ClInclude Include="Dependencies\Minhook\src\trampoline.h" />
|
||||
<ClInclude Include="dllmain.hpp" />
|
||||
<ClInclude Include="Features\Menu.hpp" />
|
||||
<ClInclude Include="Features\Misc\Misc.hpp" />
|
||||
<ClInclude Include="framework.h" />
|
||||
<ClInclude Include="Hooks\Hooks.hpp" />
|
||||
<ClInclude Include="pch.h" />
|
||||
<ClInclude Include="Callbacks\OnUpdate.hpp" />
|
||||
<ClInclude Include="Utils\Dumper\Dumper.hpp" />
|
||||
<ClInclude Include="Utils\Output\Output.hpp" />
|
||||
<ClInclude Include="Utils\Players\Players.hpp" />
|
||||
<ClInclude Include="Utils\Settings\Settings.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Dependencies\IL2CPP_Resolver\Cache.cpp" />
|
||||
<ClCompile Include="Dependencies\IL2CPP_Resolver\Data.cpp" />
|
||||
<ClCompile Include="Dependencies\IL2CPP_Resolver\Functions\Callback.cpp" />
|
||||
<ClCompile Include="Dependencies\IL2CPP_Resolver\Functions\Class.cpp" />
|
||||
<ClCompile Include="Dependencies\IL2CPP_Resolver\Functions\String.cpp" />
|
||||
<ClCompile Include="Dependencies\IL2CPP_Resolver\Functions\Thread.cpp" />
|
||||
<ClCompile Include="Dependencies\IL2CPP_Resolver\il2cpp_resolver.cpp" />
|
||||
<ClCompile Include="Dependencies\IL2CPP_Resolver\Unity\API\Camera.cpp" />
|
||||
<ClCompile Include="Dependencies\IL2CPP_Resolver\Unity\API\Component.cpp" />
|
||||
<ClCompile Include="Dependencies\IL2CPP_Resolver\Unity\API\GameObject.cpp" />
|
||||
<ClCompile Include="Dependencies\IL2CPP_Resolver\Unity\API\LayerMask.cpp" />
|
||||
<ClCompile Include="Dependencies\IL2CPP_Resolver\Unity\API\Object.cpp" />
|
||||
<ClCompile Include="Dependencies\IL2CPP_Resolver\Unity\API\Rigidbody.cpp" />
|
||||
<ClCompile Include="Dependencies\IL2CPP_Resolver\Unity\API\Transform.cpp" />
|
||||
<ClCompile Include="Dependencies\IL2CPP_Resolver\Unity\API\_TEMPLATE_API.cpp" />
|
||||
<ClCompile Include="Dependencies\IL2CPP_Resolver\Unity\Obfuscators.cpp" />
|
||||
<ClCompile Include="Dependencies\IL2CPP_Resolver\Utils\Helper.cpp" />
|
||||
<ClCompile Include="Dependencies\imgui\imgui.cpp" />
|
||||
<ClCompile Include="Dependencies\imgui\imgui_draw.cpp" />
|
||||
<ClCompile Include="Dependencies\imgui\imgui_impl_dx11.cpp" />
|
||||
<ClCompile Include="Dependencies\imgui\imgui_impl_win32.cpp" />
|
||||
<ClCompile Include="Dependencies\imgui\imgui_stdlib.cpp" />
|
||||
<ClCompile Include="Dependencies\imgui\imgui_tables.cpp" />
|
||||
<ClCompile Include="Dependencies\imgui\imgui_widgets.cpp" />
|
||||
<ClCompile Include="Dependencies\Minhook\src\buffer.c" />
|
||||
<ClCompile Include="Dependencies\Minhook\src\HDE\hde32.c" />
|
||||
<ClCompile Include="Dependencies\Minhook\src\HDE\hde64.c" />
|
||||
<ClCompile Include="Dependencies\Minhook\src\hook.c" />
|
||||
<ClCompile Include="Dependencies\Minhook\src\trampoline.c" />
|
||||
<ClCompile Include="dllmain.cpp" />
|
||||
<ClCompile Include="Features\Menu.cpp" />
|
||||
<ClCompile Include="Features\Misc\Misc.cpp" />
|
||||
<ClCompile Include="Hooks\Hooks.cpp" />
|
||||
<ClCompile Include="pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Callbacks\OnUpdate.cpp" />
|
||||
<ClCompile Include="Utils\Dumper\Dumper.cpp" />
|
||||
<ClCompile Include="Utils\Output\Output.cpp" />
|
||||
<ClCompile Include="Utils\Players\Players.cpp" />
|
||||
<ClCompile Include="Utils\Settings\Settings.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
6
DevourClient/DevourClient.vcxproj.user
Normal file
6
DevourClient/DevourClient.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>
|
||||
281
DevourClient/Features/Menu.cpp
Normal file
281
DevourClient/Features/Menu.cpp
Normal file
@@ -0,0 +1,281 @@
|
||||
#include "Menu.hpp"
|
||||
#include "../Utils/Output/Output.hpp"
|
||||
#include "../dllmain.hpp"
|
||||
#include "../Utils/Settings/Settings.hpp"
|
||||
#include "../Utils/Dumper/Dumper.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
void InitStyle()
|
||||
{
|
||||
ImGui::StyleColorsDark();
|
||||
|
||||
auto& Style = ImGui::GetStyle();
|
||||
|
||||
Style.WindowRounding = 8.000f;
|
||||
Style.FrameRounding = 4.000f;
|
||||
|
||||
Style.Colors[ImGuiCol_WindowBg] = ImColor(0, 0, 0, 240);
|
||||
Style.Colors[ImGuiCol_TitleBg] = ImColor(1, 1, 1, 240);
|
||||
Style.Colors[ImGuiCol_TitleBgActive] = ImColor(1, 1, 1, 240);
|
||||
Style.Colors[ImGuiCol_TitleBgCollapsed] = ImColor(0, 0, 0, 240);
|
||||
Style.Colors[ImGuiCol_Button] = ImColor(46, 53, 62, 20);
|
||||
Style.Colors[ImGuiCol_ButtonHovered] = ImColor(46, 53, 62, 255);
|
||||
Style.Colors[ImGuiCol_ButtonActive] = ImColor(46, 53, 62, 255);
|
||||
Style.Colors[ImGuiCol_CheckMark] = ImColor(183, 185, 189, 255);
|
||||
Style.Colors[ImGuiCol_FrameBg] = ImColor(60, 66, 76, 138);
|
||||
Style.Colors[ImGuiCol_FrameBgActive] = ImColor(60, 66, 76, 171);
|
||||
Style.Colors[ImGuiCol_FrameBgHovered] = ImColor(60, 66, 76, 102);
|
||||
Style.Alpha = 0.8f;
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
io.Fonts->AddFontFromFileTTF("C:\\Windows\\Fonts\\tahoma.ttf", 13.000f);
|
||||
}
|
||||
|
||||
void DrawVisualsTab() {
|
||||
ImGui::Checkbox("Big flashlight", &settings::big_flashlight);
|
||||
|
||||
bool open_flcolor_popup = ImGui::ColorButton("flashlightcolor", ImVec4(settings::flashlight_color[0], settings::flashlight_color[1], settings::flashlight_color[2], settings::flashlight_color[3]));
|
||||
if (open_flcolor_popup)
|
||||
{
|
||||
ImGui::OpenPopup("flashlightcolorpicker");
|
||||
}
|
||||
if (ImGui::BeginPopup("flashlightcolorpicker")) {
|
||||
ImGui::ColorPicker4("Flashlight color", (float*)&settings::flashlight_color);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("Flashlight color");
|
||||
|
||||
ImGui::Checkbox("Unlimited UV", &settings::unlimited_uv);
|
||||
ImGui::Checkbox("Fullbright", &settings::fullbright);
|
||||
|
||||
ImGui::Checkbox("Player ESP", &settings::player_esp);
|
||||
ImGui::SameLine();
|
||||
bool open_pelcolor_popup = ImGui::ColorButton("playerespcolor", ImVec4(settings::player_esp_color[0], settings::player_esp_color[1], settings::player_esp_color[2], settings::player_esp_color[3]));
|
||||
if (open_pelcolor_popup)
|
||||
{
|
||||
ImGui::OpenPopup("playeresppop");
|
||||
}
|
||||
if (ImGui::BeginPopup("playeresppop")) {
|
||||
ImGui::ColorPicker4("Player ESP color", (float*)&settings::player_esp_color);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Player snaplines", &settings::player_snaplines);
|
||||
ImGui::SameLine();
|
||||
bool open_pslcolor_popup = ImGui::ColorButton("playersncolor", ImVec4(settings::player_snaplines_color[0], settings::player_snaplines_color[1], settings::player_snaplines_color[2], settings::player_snaplines_color[3]));
|
||||
if (open_pslcolor_popup)
|
||||
{
|
||||
ImGui::OpenPopup("playersnpop");
|
||||
}
|
||||
if (ImGui::BeginPopup("playersnpop")) {
|
||||
ImGui::ColorPicker4("Player snaplines color", (float*)&settings::flashlight_color);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Azazel ESP", &settings::azazel_esp);
|
||||
ImGui::SameLine();
|
||||
bool open_azacolor_popup = ImGui::ColorButton("azaespcolor", ImVec4(settings::azazel_esp_color[0], settings::azazel_esp_color[1], settings::azazel_esp_color[2], settings::azazel_esp_color[3]));
|
||||
if (open_azacolor_popup)
|
||||
{
|
||||
ImGui::OpenPopup("azaesppop");
|
||||
}
|
||||
if (ImGui::BeginPopup("azaesppop")) {
|
||||
ImGui::ColorPicker4("Azazel ESP color", (float*)&settings::azazel_esp_color);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Azazel snaplines", &settings::azazel_snaplines);
|
||||
ImGui::SameLine();
|
||||
bool open_azascolor_popup = ImGui::ColorButton("azasncolor", ImVec4(settings::azazel_snaplines_color[0], settings::azazel_snaplines_color[1], settings::azazel_snaplines_color[2], settings::azazel_snaplines_color[3]));
|
||||
if (open_azascolor_popup)
|
||||
{
|
||||
ImGui::OpenPopup("azasnpop");
|
||||
}
|
||||
if (ImGui::BeginPopup("azasnpop")) {
|
||||
ImGui::ColorPicker4("Azazel snaplines color", (float*)&settings::azazel_snaplines_color);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Item ESP", &settings::item_esp);
|
||||
ImGui::SameLine();
|
||||
bool open_icolor_popup = ImGui::ColorButton("iespcolor", ImVec4(settings::item_esp_color[0], settings::item_esp_color[1], settings::item_esp_color[2], settings::item_esp_color[3]));
|
||||
if (open_icolor_popup)
|
||||
{
|
||||
ImGui::OpenPopup("iesppop");
|
||||
}
|
||||
if (ImGui::BeginPopup("iesppop")) {
|
||||
ImGui::ColorPicker4("Item ESP color", (float*)&settings::item_esp_color);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Demon ESP", &settings::item_esp);
|
||||
ImGui::SameLine();
|
||||
bool open_dcolor_popup = ImGui::ColorButton("despcolor", ImVec4(settings::demon_esp_color[0], settings::demon_esp_color[1], settings::demon_esp_color[2], settings::demon_esp_color[3]));
|
||||
if (open_dcolor_popup)
|
||||
{
|
||||
ImGui::OpenPopup("desppop");
|
||||
}
|
||||
if (ImGui::BeginPopup("desppop")) {
|
||||
ImGui::ColorPicker4("Demon ESP color", (float*)&settings::demon_esp_color);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Goat/Rat ESP", &settings::goat_esp);
|
||||
ImGui::SameLine();
|
||||
bool open_gcolor_popup = ImGui::ColorButton("gespcolor", ImVec4(settings::goat_esp_color[0], settings::goat_esp_color[1], settings::goat_esp_color[2], settings::goat_esp_color[3]));
|
||||
if (open_gcolor_popup)
|
||||
{
|
||||
ImGui::OpenPopup("gesppop");
|
||||
}
|
||||
if (ImGui::BeginPopup("gesppop")) {
|
||||
ImGui::ColorPicker4("Goat ESP color", (float*)&settings::goat_esp_color);
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
}
|
||||
|
||||
void DrawEntitiesTab() {
|
||||
if (ImGui::Button("TP items to you")) {
|
||||
//call tp items
|
||||
}
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::Text("Azazel & Demons");
|
||||
const char* azazel_demons_items[] = { "Sam", "Molly", "Anna", "Zara", "Ghost", "Inmate", "Demon"};
|
||||
static int entity_current = 0;
|
||||
ImGui::Combo("##a", &entity_current, azazel_demons_items, IM_ARRAYSIZE(azazel_demons_items));
|
||||
if (ImGui::Button("Spawn")) {
|
||||
//call spawn function
|
||||
}
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::Text("Items");
|
||||
const char* items_items[] = { "Hay", "First aid", "Battery", "Gasoline", "Fuse", "Food", "Egg", "Bleach", "Ritual Book", "Matchbox"};
|
||||
static int item_current = 0;
|
||||
ImGui::Combo("##i", &item_current, items_items, IM_ARRAYSIZE(items_items));
|
||||
if (ImGui::Button("Spawn")) {
|
||||
//call spawn function
|
||||
}
|
||||
|
||||
ImGui::Spacing();
|
||||
ImGui::Text("Animals");
|
||||
const char* animals_items[] = { "Rat", "Goat", "Spider"};
|
||||
static int animal_current = 0;
|
||||
ImGui::Combo("##an", &animal_current, animals_items, IM_ARRAYSIZE(animals_items));
|
||||
if (ImGui::Button("Spawn")) {
|
||||
//call spawn function
|
||||
}
|
||||
}
|
||||
|
||||
void DrawMapSpecificTab() {
|
||||
if (ImGui::Button("Instant win")) {
|
||||
//call instant win
|
||||
}
|
||||
}
|
||||
|
||||
void DrawMiscTab() {
|
||||
ImGui::Checkbox("Chat spam", &settings::chat_spam);
|
||||
ImGui::InputText("Message", &settings::message);
|
||||
|
||||
if (ImGui::Button("Unlock Achievements")) {
|
||||
//Unlock Achievements
|
||||
}
|
||||
|
||||
if (ImGui::Button("Unlock Doors")) {
|
||||
//Unlock Achievements
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Unlock all", &settings::unlock_all);
|
||||
|
||||
ImGui::Checkbox("Spoof level", &settings::spoof_level);
|
||||
ImGui::InputInt("New level", &settings::new_level);
|
||||
//normalize level
|
||||
if (settings::new_level > 666) {
|
||||
settings::new_level = 666;
|
||||
}
|
||||
else if (settings::new_level < 0) {
|
||||
settings::new_level = 0;
|
||||
}
|
||||
|
||||
ImGui::Checkbox("Change Steam name", &settings::steam_name_spoof);
|
||||
ImGui::InputText("New name", &settings::new_name);
|
||||
|
||||
ImGui::Checkbox("Change server name", &settings::server_name_spoof);
|
||||
ImGui::InputText("New name", &settings::server_name);
|
||||
|
||||
ImGui::Checkbox("Fly", &settings::fly);
|
||||
|
||||
if (ImGui::Button("Make random noise")) {
|
||||
//call make random noise
|
||||
}
|
||||
|
||||
ImGui::Checkbox("EXP modifier", &settings::exp_modifier);
|
||||
ImGui::SliderInt("Amount", &settings::new_exp, 0, 5000);
|
||||
|
||||
ImGui::Checkbox("Walk in lobby", &settings::walk_in_lobby);
|
||||
|
||||
ImGui::Checkbox("Change player speed", &settings::change_player_speed);
|
||||
ImGui::SliderInt("Multiplier", &settings::new_speed, 0, 10);
|
||||
|
||||
#if _DEBUG
|
||||
ImGui::Spacing();
|
||||
std::string component = "PlayerCharacterBehaviour";
|
||||
ImGui::InputText("##PlayerCharacterBehaviour", &component);
|
||||
if (ImGui::Button("Dump component")) {
|
||||
Dump(component);
|
||||
}
|
||||
#endif
|
||||
|
||||
ImGui::Spacing();
|
||||
if (ImGui::Button("Unhook")) {
|
||||
CreateThread(0, 0, EjectThread, 0, 0, 0); //Unhooking
|
||||
}
|
||||
}
|
||||
|
||||
tabs current_tab = tabs::VISUALS;
|
||||
void DrawMenu(bool open_menu) {
|
||||
ImGui::SetNextWindowSize(ImVec2(240.000f, 300.000f), ImGuiCond_Once);
|
||||
ImGui::Begin("Devour Client", NULL, 2);
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Visuals")) {//, ImVec2(0.000f, 0.000f))) {
|
||||
current_tab = tabs::VISUALS;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Entities", ImVec2(0.000f, 0.000f))) {
|
||||
current_tab = tabs::ENTITIES;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Map specific", ImVec2(0.000f, 0.000f))) {
|
||||
current_tab = tabs::MAP_SPECIFIC;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Misc", ImVec2(0.000f, 0.000f))) {
|
||||
current_tab = tabs::MISC;
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
switch (current_tab) {
|
||||
case tabs::VISUALS:
|
||||
DrawVisualsTab();
|
||||
break;
|
||||
case tabs::ENTITIES:
|
||||
DrawEntitiesTab();
|
||||
break;
|
||||
case tabs::MAP_SPECIFIC:
|
||||
DrawMapSpecificTab();
|
||||
break;
|
||||
case tabs::MISC:
|
||||
DrawMiscTab();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
18
DevourClient/Features/Menu.hpp
Normal file
18
DevourClient/Features/Menu.hpp
Normal file
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
#pragma warning(push, 0)
|
||||
#include "imgui/imgui.h"
|
||||
#include "imgui/imgui_impl_win32.h"
|
||||
#include "imgui/imgui_impl_dx11.h"
|
||||
#include "imgui/imgui_stdlib.h"
|
||||
#pragma warning(pop)
|
||||
|
||||
enum class tabs {
|
||||
VISUALS,
|
||||
ENTITIES,
|
||||
MAP_SPECIFIC,
|
||||
MISC
|
||||
};
|
||||
|
||||
void InitStyle();
|
||||
void DrawMenu(bool open_menu);
|
||||
0
DevourClient/Features/Misc/Misc.cpp
Normal file
0
DevourClient/Features/Misc/Misc.cpp
Normal file
3
DevourClient/Features/Misc/Misc.hpp
Normal file
3
DevourClient/Features/Misc/Misc.hpp
Normal file
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
//misc hacks go here
|
||||
212
DevourClient/Hooks/Hooks.cpp
Normal file
212
DevourClient/Hooks/Hooks.cpp
Normal file
@@ -0,0 +1,212 @@
|
||||
#include "Hooks.hpp"
|
||||
#include "../Utils/Output/Output.hpp"
|
||||
#include "../Features/Menu.hpp"
|
||||
#include "../dllmain.hpp"
|
||||
|
||||
#pragma warning(push, 0) //important cuz dx11 throws so much warnings
|
||||
#include <d3d11.h>
|
||||
#pragma warning(pop)
|
||||
#pragma comment (lib, "d3d11.lib" )
|
||||
|
||||
/*
|
||||
//Code about hooking stuff
|
||||
//Exemple of hooked function :
|
||||
typedef int (__stdcall* TEST)(); //We define the function, must be the EXACT same definition as the original one
|
||||
TEST test_org = NULL;
|
||||
int __stdcall test_hook() //MUST BE the original calling convention
|
||||
{
|
||||
std::cout << "called" << std::endl;
|
||||
return test_org(); //if we want to call the original one, we can just return 1 otherwise
|
||||
}
|
||||
|
||||
//Exemple :
|
||||
MH_STATUS status_test = MH_CreateHook((LPVOID*)test_sig, &test_hook, reinterpret_cast<LPVOID*>(&test_org));
|
||||
//We say that for every call to the test_sig address we want to redirect it to the address of the function named test_hook (& gives the pointer to it)
|
||||
//We can store the original pointer to the original function into test_org if we want to call the org later --> trampoline hook
|
||||
//original_sum can be NULL if we don't want to trampoline hook
|
||||
|
||||
if (status_test != MH_OK) { //If it failed
|
||||
print(MH_StatusToString(status)); //If we are in debug mode, we print the fail status into the console
|
||||
return 0; //We exit
|
||||
}
|
||||
*/
|
||||
|
||||
typedef HRESULT(__stdcall* D3D11PresentHook) (IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags);
|
||||
D3D11PresentHook phookD3D11Present = NULL;
|
||||
|
||||
ID3D11Device* pDevice = NULL;
|
||||
ID3D11DeviceContext* pContext = NULL;
|
||||
|
||||
extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
HWND window = NULL;
|
||||
WNDPROC oWndProc;
|
||||
bool open_menu = false;
|
||||
LRESULT __stdcall WndProc(const HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
if (open_menu && ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
if (io.WantCaptureMouse && open_menu) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return CallWindowProc(oWndProc, hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
static bool pressed = false;
|
||||
bool initonce = false;
|
||||
ID3D11RenderTargetView* mainRenderTargetViewD3D11 = NULL;
|
||||
|
||||
HRESULT __stdcall hookD3D11Present(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags) {
|
||||
|
||||
if (!initonce)
|
||||
{
|
||||
if (SUCCEEDED(pSwapChain->GetDevice(__uuidof(ID3D11Device), (void**)&pDevice)))
|
||||
{
|
||||
pDevice->GetImmediateContext(&pContext);
|
||||
DXGI_SWAP_CHAIN_DESC sd;
|
||||
pSwapChain->GetDesc(&sd);
|
||||
window = sd.OutputWindow;
|
||||
ID3D11Texture2D* pBackBuffer;
|
||||
pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
|
||||
pDevice->CreateRenderTargetView(pBackBuffer, NULL, &mainRenderTargetViewD3D11);
|
||||
pBackBuffer->Release();
|
||||
oWndProc = (WNDPROC)SetWindowLongPtr(window, GWLP_WNDPROC, (LONG_PTR)WndProc);
|
||||
ImGui::CreateContext();
|
||||
InitStyle();
|
||||
ImGui_ImplWin32_Init(window);
|
||||
ImGui_ImplDX11_Init(pDevice, pContext);
|
||||
initonce = true;
|
||||
}
|
||||
else
|
||||
return phookD3D11Present(pSwapChain, SyncInterval, Flags);
|
||||
}
|
||||
|
||||
if (GetKeyState(VK_INSERT) & 0x8000)
|
||||
pressed = true;
|
||||
|
||||
else if (!(GetKeyState(VK_INSERT) & 0x8000) && pressed) {
|
||||
open_menu = !open_menu;
|
||||
pressed = false;
|
||||
}
|
||||
|
||||
ImGui_ImplDX11_NewFrame();
|
||||
ImGui_ImplWin32_NewFrame();
|
||||
ImGui::NewFrame();
|
||||
|
||||
if (open_menu) {
|
||||
DrawMenu(open_menu);
|
||||
}
|
||||
|
||||
ImGui::GetIO().MouseDrawCursor = open_menu;
|
||||
|
||||
ImGui::EndFrame();
|
||||
ImGui::Render();
|
||||
|
||||
ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
|
||||
|
||||
return phookD3D11Present(pSwapChain, SyncInterval, Flags);
|
||||
}
|
||||
|
||||
DWORD_PTR* pSwapChainVtable = NULL;
|
||||
DWORD_PTR* pContextVTable = NULL;
|
||||
DWORD_PTR* pDeviceVTable = NULL;
|
||||
IDXGISwapChain* pSwapChain;
|
||||
bool HookDX11() {
|
||||
HMODULE hDXGIDLL = 0;
|
||||
do
|
||||
{
|
||||
hDXGIDLL = GetModuleHandle("dxgi.dll");
|
||||
Sleep(200);
|
||||
} while (!hDXGIDLL);
|
||||
Sleep(100);
|
||||
|
||||
oWndProc = (WNDPROC)SetWindowLongPtr(window, GWLP_WNDPROC, (LONG_PTR)WndProc);
|
||||
|
||||
D3D_FEATURE_LEVEL requestedLevels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1 };
|
||||
D3D_FEATURE_LEVEL obtainedLevel;
|
||||
ID3D11Device* d3dDevice = nullptr;
|
||||
ID3D11DeviceContext* d3dContext = nullptr;
|
||||
|
||||
DXGI_SWAP_CHAIN_DESC scd;
|
||||
ZeroMemory(&scd, sizeof(scd));
|
||||
scd.BufferCount = 1;
|
||||
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
|
||||
scd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
|
||||
scd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
|
||||
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
|
||||
|
||||
scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
|
||||
scd.OutputWindow = GetForegroundWindow();
|
||||
scd.SampleDesc.Count = 1;
|
||||
scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
scd.Windowed = true;
|
||||
|
||||
// LibOVR 0.4.3 requires that the width and height for the backbuffer is set even if
|
||||
// you use windowed mode, despite being optional according to the D3D11 documentation.
|
||||
scd.BufferDesc.Width = 1;
|
||||
scd.BufferDesc.Height = 1;
|
||||
scd.BufferDesc.RefreshRate.Numerator = 0;
|
||||
scd.BufferDesc.RefreshRate.Denominator = 1;
|
||||
|
||||
UINT createFlags = 0;
|
||||
#ifdef _DEBUG
|
||||
// This flag gives you some quite wonderful debug text. Not wonderful for performance, though!
|
||||
createFlags |= D3D11_CREATE_DEVICE_DEBUG;
|
||||
#endif
|
||||
|
||||
IDXGISwapChain* d3dSwapChain = 0;
|
||||
|
||||
if (FAILED(D3D11CreateDeviceAndSwapChain(
|
||||
nullptr,
|
||||
D3D_DRIVER_TYPE_HARDWARE,
|
||||
nullptr,
|
||||
createFlags,
|
||||
requestedLevels,
|
||||
sizeof(requestedLevels) / sizeof(D3D_FEATURE_LEVEL),
|
||||
D3D11_SDK_VERSION,
|
||||
&scd,
|
||||
&pSwapChain,
|
||||
&pDevice,
|
||||
&obtainedLevel,
|
||||
&pContext)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
pSwapChainVtable = (DWORD_PTR*)pSwapChain;
|
||||
pSwapChainVtable = (DWORD_PTR*)pSwapChainVtable[0];
|
||||
|
||||
pContextVTable = (DWORD_PTR*)pContext;
|
||||
pContextVTable = (DWORD_PTR*)pContextVTable[0];
|
||||
|
||||
pDeviceVTable = (DWORD_PTR*)pDevice;
|
||||
pDeviceVTable = (DWORD_PTR*)pDeviceVTable[0];
|
||||
|
||||
if (MH_CreateHook((DWORD_PTR*)pSwapChainVtable[8], hookD3D11Present, reinterpret_cast<void**>(&phookD3D11Present)) != MH_OK) { return false; }
|
||||
if (MH_EnableHook((DWORD_PTR*)pSwapChainVtable[8]) != MH_OK) { return false; }
|
||||
|
||||
DWORD dwOld;
|
||||
VirtualProtect(phookD3D11Present, 2, PAGE_EXECUTE_READWRITE, &dwOld);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InitializeHooks() {
|
||||
return MH_Initialize() == MH_OK;
|
||||
}
|
||||
|
||||
void DisableHooks() {
|
||||
MH_DisableHook(MH_ALL_HOOKS);
|
||||
MH_Uninitialize();
|
||||
ImGui_ImplDX11_Shutdown();
|
||||
ImGui_ImplWin32_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
if (mainRenderTargetViewD3D11) { mainRenderTargetViewD3D11->Release(); mainRenderTargetViewD3D11 = NULL; }
|
||||
if (pContext) { pContext->Release(); pContext = NULL; }
|
||||
if (pDevice) { pDevice->Release(); pDevice = NULL; }
|
||||
pSwapChain->Release();
|
||||
SetWindowLongPtr(window, GWLP_WNDPROC, (LONG_PTR)(oWndProc));
|
||||
}
|
||||
14
DevourClient/Hooks/Hooks.hpp
Normal file
14
DevourClient/Hooks/Hooks.hpp
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
#include <MinHook.h>
|
||||
|
||||
#pragma warning(push, 0)
|
||||
#include "imgui/imgui.h"
|
||||
#include "imgui/imgui_impl_win32.h"
|
||||
#include "imgui/imgui_impl_dx11.h"
|
||||
#pragma warning(pop)
|
||||
|
||||
bool HookDX11();
|
||||
|
||||
bool InitializeHooks();
|
||||
void DisableHooks();
|
||||
35
DevourClient/Utils/Dumper/Dumper.cpp
Normal file
35
DevourClient/Utils/Dumper/Dumper.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
#include "Dumper.hpp"
|
||||
#include "../Output/Output.hpp"
|
||||
|
||||
void Dump(std::string component) {
|
||||
print("\n\n\n");
|
||||
print("Dumping %s\n\n", component.c_str());
|
||||
auto list = Unity::Object::FindObjectsOfType<Unity::CComponent>(component.c_str());
|
||||
for (int i = 0; i < list->m_uMaxLength + 1; i++)
|
||||
{
|
||||
if (!list->operator[](i))
|
||||
continue;
|
||||
|
||||
Unity::CGameObject* object = list->operator[](i)->GetMemberValue<Unity::CGameObject*>("gameObject");
|
||||
|
||||
print("%s\n", object->GetName()->ToString().c_str()); //SurvivalPlayer(Clone)
|
||||
|
||||
auto components = object->GetComponents(UNITY_COMPONENT_CLASS);
|
||||
for (int n = 0; n < components->m_uMaxLength; n++)
|
||||
{
|
||||
if (!components->operator[](n))
|
||||
continue;
|
||||
|
||||
print("| -> %s::%s\n", components->operator[](n)->m_Object.m_pClass->m_pNamespace, components->operator[](n)->m_Object.m_pClass->m_pName);
|
||||
|
||||
}
|
||||
Unity::CComponent* BoltEntity = object->GetComponent("BoltEntity");
|
||||
if (BoltEntity)
|
||||
{
|
||||
print("|-------- owner:%d \n", BoltEntity->CallMethod<bool>("get_IsOwner")); //local player check?
|
||||
if (BoltEntity->CallMethod<bool>("get_IsOwner"))
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
4
DevourClient/Utils/Dumper/Dumper.hpp
Normal file
4
DevourClient/Utils/Dumper/Dumper.hpp
Normal file
@@ -0,0 +1,4 @@
|
||||
#pragma once
|
||||
#include "../Dependencies/IL2CPP_Resolver/il2cpp_resolver.hpp"
|
||||
|
||||
void Dump(std::string component);
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user