diff --git a/Dumper/Dumper.vcxproj b/Dumper/Dumper.vcxproj
index 2342c8b..11acf15 100644
--- a/Dumper/Dumper.vcxproj
+++ b/Dumper/Dumper.vcxproj
@@ -67,6 +67,7 @@
stdcpplatest
FastCall
true
+ Async
Console
@@ -87,7 +88,7 @@
FastCall
ProgramDatabase
false
- Sync
+ Async
AnySuitable
true
Default
diff --git a/Dumper/defs.h b/Dumper/defs.h
index 93b1538..bf8eaa3 100644
--- a/Dumper/defs.h
+++ b/Dumper/defs.h
@@ -1,4 +1,5 @@
#pragma once
+#include
#ifdef GetObject
#undef GetObject
@@ -18,14 +19,4 @@ enum class STATUS {
INVALID_IMAGE,
FILE_NOT_OPEN,
ZERO_PACKAGES
-};
-
-typedef signed char int8;
-typedef short int16;
-typedef int int32;
-typedef long long int64;
-
-typedef unsigned char uint8;
-typedef unsigned short uint16;
-typedef unsigned int uint32;
-typedef unsigned long long uint64;
+};
\ No newline at end of file
diff --git a/Dumper/engine.cpp b/Dumper/engine.cpp
index 6f6c96b..5d00cd5 100644
--- a/Dumper/engine.cpp
+++ b/Dumper/engine.cpp
@@ -10,64 +10,6 @@ Offsets offsets;
ansi_fn Decrypt_ANSI = nullptr;
// wide_fn Decrypt_WIDE = nullptr;
-struct {
- uint16 Stride = 4;
- struct {
- uint16 Size = 24;
- } FUObjectItem;
- struct {
- uint16 Number = 8;
- } FName;
- struct {
- uint16 Info = 4;
- uint16 WideBit = 0;
- uint16 LenBit = 1;
- uint16 HeaderSize = 6;
- } FNameEntry;
- struct {
- uint16 Index = 0xC;
- uint16 Class = 0x10;
- uint16 Name = 0x18;
- uint16 Outer = 0x28;
- } UObject;
- struct {
- uint16 Next = 0x30;
- } UField;
- struct {
- uint16 SuperStruct = 0x48;
- uint16 Children = 0x50;
- uint16 ChildProperties = 0x58;
- uint16 PropertiesSize = 0x60;
- } UStruct;
- struct {
- uint16 Names = 0x48;
- } UEnum;
- struct {
- uint16 FunctionFlags = 0xB8;
- uint16 Func = 0xB8 + 0x28; // ue3-ue4, always +0x28 from flags location.
- } UFunction;
- struct {
- uint16 Class = 0x8;
- uint16 Next = 0x20;
- uint16 Name = 0x28;
- } FField;
- struct {
- uint16 ArrayDim = 0x38;
- uint16 ElementSize = 0x3C;
- uint16 PropertyFlags = 0x40;
- uint16 Offset = 0x4C;
- uint16 Size = 0x80;
- } FProperty;
- struct {
- uint16 ArrayDim = 0;
- uint16 ElementSize = 0;
- uint16 PropertyFlags = 0;
- uint16 Offset = 0;
- uint16 Size = 0; // sizeof(UProperty)
- } UProperty;
-} DeadByDaylight;
-static_assert(sizeof(DeadByDaylight) == sizeof(Offsets));
-
struct {
uint16 Stride = 2;
struct {
@@ -123,44 +65,44 @@ struct {
uint16 Offset = 0;
uint16 Size = 0; // sizeof(UProperty)
} UProperty;
-} RogueCompany;
-static_assert(sizeof(RogueCompany) == sizeof(Offsets));
+} Default;
+static_assert(sizeof(Default) == sizeof(Offsets));
struct {
- uint16 Stride = 2;
+ uint16 Stride = 4;
struct {
uint16 Size = 24;
} FUObjectItem;
struct {
- uint16 Number = 4;
+ uint16 Number = 8;
} FName;
struct {
- uint16 Info = 0;
+ uint16 Info = 4;
uint16 WideBit = 0;
- uint16 LenBit = 6;
- uint16 HeaderSize = 2;
+ uint16 LenBit = 1;
+ uint16 HeaderSize = 6;
} FNameEntry;
struct {
uint16 Index = 0xC;
uint16 Class = 0x10;
uint16 Name = 0x18;
- uint16 Outer = 0x20;
+ uint16 Outer = 0x28;
} UObject;
struct {
- uint16 Next = 0x28;
+ uint16 Next = 0x30;
} UField;
struct {
- uint16 SuperStruct = 0x40;
- uint16 Children = 0x48;
- uint16 ChildProperties = 0x50;
- uint16 PropertiesSize = 0x58;
+ uint16 SuperStruct = 0x48;
+ uint16 Children = 0x50;
+ uint16 ChildProperties = 0x58;
+ uint16 PropertiesSize = 0x60;
} UStruct;
struct {
- uint16 Names = 0x40;
+ uint16 Names = 0x48;
} UEnum;
struct {
- uint16 FunctionFlags = 0xB0;
- uint16 Func = 0xB0 + 0x30;
+ uint16 FunctionFlags = 0xB8;
+ uint16 Func = 0xB8 + 0x28; // ue3-ue4, always +0x28 from flags location.
} UFunction;
struct {
uint16 Class = 0x8;
@@ -172,7 +114,7 @@ struct {
uint16 ElementSize = 0x3C;
uint16 PropertyFlags = 0x40;
uint16 Offset = 0x4C;
- uint16 Size = 0x78;
+ uint16 Size = 0x80;
} FProperty;
struct {
uint16 ArrayDim = 0;
@@ -181,13 +123,13 @@ struct {
uint16 Offset = 0;
uint16 Size = 0; // sizeof(UProperty)
} UProperty;
-} Scavengers;
-static_assert(sizeof(Scavengers) == sizeof(Offsets));
+} DeadByDaylight;
+static_assert(sizeof(DeadByDaylight) == sizeof(Offsets));
struct {
uint16 Stride = 2;
struct {
- uint16 Size = 32;
+ uint16 Size = 24;
} FUObjectItem;
struct {
uint16 Number = 4;
@@ -218,7 +160,7 @@ struct {
} UEnum;
struct {
uint16 FunctionFlags = 0xB0;
- uint16 Func = 0xB0 + 0x28;
+ uint16 Func = 0xB0 + 0x30;
} UFunction;
struct {
uint16 Class = 0x8;
@@ -239,13 +181,13 @@ struct {
uint16 Offset = 0;
uint16 Size = 0; // sizeof(UProperty)
} UProperty;
-} Brickadia;
-static_assert(sizeof(Brickadia) == sizeof(Offsets));
+} Scavengers;
+static_assert(sizeof(Scavengers) == sizeof(Offsets));
struct {
uint16 Stride = 2;
struct {
- uint16 Size = 24;
+ uint16 Size = 32;
} FUObjectItem;
struct {
uint16 Number = 4;
@@ -297,67 +239,8 @@ struct {
uint16 Offset = 0;
uint16 Size = 0; // sizeof(UProperty)
} UProperty;
-} Fortnite;
-static_assert(sizeof(Fortnite) == sizeof(Offsets));
-
-
-struct {
- uint16 Stride = 2;
- struct {
- uint16 Size = 24;
- } FUObjectItem;
- struct {
- uint16 Number = 4;
- } FName;
- struct {
- uint16 Info = 0;
- uint16 WideBit = 0;
- uint16 LenBit = 6;
- uint16 HeaderSize = 2;
- } FNameEntry;
- struct {
- uint16 Index = 0xC;
- uint16 Class = 0x10;
- uint16 Name = 0x18;
- uint16 Outer = 0x20;
- } UObject;
- struct {
- uint16 Next = 0x28;
- } UField;
- struct {
- uint16 SuperStruct = 0x40;
- uint16 Children = 0x48;
- uint16 ChildProperties = 0x50;
- uint16 PropertiesSize = 0x58;
- } UStruct;
- struct {
- uint16 Names = 0x40;
- } UEnum;
- struct {
- uint16 FunctionFlags = 0xB0;
- uint16 Func = 0xB0 + 0x28;
- } UFunction;
- struct {
- uint16 Class = 0x8;
- uint16 Next = 0x20;
- uint16 Name = 0x28;
- } FField;
- struct {
- uint16 ArrayDim = 0x38;
- uint16 ElementSize = 0x3C;
- uint16 PropertyFlags = 0x40;
- uint16 Offset = 0x4C;
- uint16 Size = 0x78;
- } FProperty;
- struct {
- uint16 ArrayDim = 0;
- uint16 ElementSize = 0;
- uint16 PropertyFlags = 0;
- uint16 Offset = 0;
- uint16 Size = 0; // sizeof(UProperty)
- } UProperty;
-} TheIsle;
-static_assert(sizeof(TheIsle) == sizeof(Offsets));
+} Brickadia;
+static_assert(sizeof(Brickadia) == sizeof(Offsets));
struct {
void* offsets; // address to filled offsets structure
@@ -366,7 +249,7 @@ struct {
std::function*)> callback;
} engines[] = {
{ // RogueCompany | PropWitchHuntModule-Win64-Shipping | Scum
- &RogueCompany,
+ &Default,
{"\x48\x8D\x0D\x00\x00\x00\x00\xE8\x00\x00\x00\x00\xC6\x05\x00\x00\x00\x00\x01\x0F\x10\x03\x4C\x8D\x44\x24\x20\x48\x8B\xC8", 30},
{"\x48\x8B\x05\x00\x00\x00\x00\x48\x8B\x0C\xC8\x48\x8D\x04\xD1\xEB", 16},
nullptr
@@ -390,13 +273,13 @@ struct {
nullptr
},
{ // POLYGON-Win64-Shipping
- &RogueCompany,
+ &Default,
{"\x48\x8D\x35\x00\x00\x00\x00\xEB\x16", 9},
{"\x48\x8d\x1d\x00\x00\x00\x00\x39\x44\x24\x68", 11},
nullptr
},
{ // FortniteClient-Win64-Shipping
- &Fortnite,
+ &Default,
{"\x4C\x8D\x35\x00\x00\x00\x00\x0F\x10\x07\x83\xFB\x01", 13},
{"\x48\x8B\x05\x00\x00\x00\x00\x48\x8B\x0C\xC8\x48\x8D\x04\xD1\xEB", 16},
[](std::pair* s) {
@@ -424,9 +307,8 @@ struct {
return false;
}
},
- {
- // TheIsleClient-Win64-Shipping
- &TheIsle,
+ { // TheIsleClient-Win64-Shipping
+ &Default,
{"\x48\x8D\x05\x00\x00\x00\x00\xEB\x13", 9},
{"\x48\x8B\x05\x00\x00\x00\x00\x48\x8B\x0C\xC8\x48\x8D\x04\xD1\xEB\x03", 17},
nullptr
@@ -434,16 +316,16 @@ struct {
};
std::unordered_map games = {
- {"RogueCompany", &engines[0]},
- {"SCUM", &engines[0]},
- {"PropWitchHuntModule-Win64-Shipping", &engines[0]},
- {"HLL-Win64-Shipping", &engines[0]},
- {"Scavenger-Win64-Shipping", &engines[1]},
- {"DeadByDaylight-Win64-Shipping", &engines[2]},
- {"Brickadia-Win64-Shipping", &engines[3]},
- {"POLYGON-Win64-Shipping", &engines[4]},
- {"FortniteClient-Win64-Shipping", &engines[5]},
- {"TheIsleClient-Win64-Shipping", &engines[6]}
+ {"RogueCompany", &engines[0]},
+ {"SCUM", &engines[0]},
+ {"PropWitchHuntModule-Win64-Shipping", &engines[0]},
+ {"HLL-Win64-Shipping", &engines[0]},
+ {"Scavenger-Win64-Shipping", &engines[1]},
+ {"DeadByDaylight-Win64-Shipping", &engines[2]},
+ {"Brickadia-Win64-Shipping", &engines[3]},
+ {"POLYGON-Win64-Shipping", &engines[4]},
+ {"FortniteClient-Win64-Shipping", &engines[5]},
+ {"TheIsleClient-Win64-Shipping", &engines[6]}
};
STATUS EngineInit(std::string game, void* image) {
@@ -478,7 +360,14 @@ STATUS EngineInit(std::string game, void* image) {
ObjObjects = *(decltype(ObjObjects)*)objects;
auto entry = UE_FNameEntry(NamePoolData.GetEntry(0));
- if (*(uint32*)entry.String().data() != 'enoN') return STATUS::ENGINE_FAILED;
+
+ // exception handler exclusively for Decrypt_ANSI
+ try {
+ if (*(uint32*)entry.String().data() != 'enoN') return STATUS::ENGINE_FAILED;
+ }
+ catch (...) {
+ return STATUS::ENGINE_FAILED;
+ }
return STATUS::SUCCESS;
}
diff --git a/Dumper/generic.cpp b/Dumper/generic.cpp
index bb19d57..ee2ef5f 100644
--- a/Dumper/generic.cpp
+++ b/Dumper/generic.cpp
@@ -28,7 +28,7 @@ void FNamePool::DumpBlock(uint32 blockId, uint32 blockSize, std::function callback) const {
- for (uint32 i = 0u; i < CurrentBlock; i++) {
+ for (uint32 i = 0; i < CurrentBlock; i++) {
DumpBlock(i, offsets.Stride * 65536, callback);
}
DumpBlock(CurrentBlock, CurrentByteCursor, callback);
@@ -73,7 +73,7 @@ void TUObjectArray::ForEachObjectOfClass(const UE_UClass cmp, std::function
#include
#include
+#include
#include "engine.h"
#include "memory.h"
#include "wrappers.h"
@@ -118,8 +119,7 @@ std::string UE_UObject::GetCppName() const {
}
bool UE_UObject::IsA(UE_UClass cmp) const {
- for (auto super = GetClass(); super;
- super = super.GetSuper().Cast()) {
+ for (auto super = GetClass(); super; super = super.GetSuper().Cast()) {
if (super == cmp) {
return true;
}
@@ -676,210 +676,147 @@ uint64 UE_FProperty::GetPropertyFlags() const {
return Read(object + offsets.FProperty.PropertyFlags);
}
-std::unordered_map> types = {
- {
- "StructProperty",
- [](const UE_FProperty *prop, type &type) {
- auto obj = prop->Cast();
- type = {PropertyType::StructProperty, obj.GetTypeStr()};
- }
- },
- {
- "ObjectProperty",
- [](const UE_FProperty *prop, type &type) {
- auto obj = prop->Cast();
- type = {PropertyType::ObjectProperty, obj.GetTypeStr()};
- }
- },
- {
- "SoftObjectProperty",
- [](const UE_FProperty *prop, type &type) {
- auto obj = prop->Cast();
- type = {PropertyType::SoftObjectProperty, "struct TSoftObjectPtr<" + obj.GetPropertyClass().GetCppName() + ">"};
- }
- },
- {
- "FloatProperty",
- [](const UE_FProperty *prop, type &type) {
- type = {PropertyType::FloatProperty, "float"};
- }
- },
- {
- "ByteProperty",
- [](const UE_FProperty *prop, type &type) {
- auto obj = prop->Cast();
- type = {PropertyType::ByteProperty, obj.GetTypeStr()};
- }
- },
- {
- "BoolProperty",
- [](const UE_FProperty *prop, type &type) {
- auto obj = prop->Cast();
- type = {PropertyType::BoolProperty, obj.GetTypeStr()};
- }
- },
- {
- "IntProperty",
- [](const UE_FProperty *prop, type &type) {
- type = {PropertyType::IntProperty, "int32_t"};
- }
- },
- {
- "Int8Property",
- [](const UE_FProperty *prop, type &type) {
- type = {PropertyType::Int8Property, "int8_t"};
- }
- },
- {
- "Int16Property",
- [](const UE_FProperty *prop, type &type) {
- type = {PropertyType::Int16Property, "int16_t"};
- }
- },
- {
- "Int64Property",
- [](const UE_FProperty *prop, type &type) {
- type = {PropertyType::Int64Property, "int64_t"};
- }
- },
- {
- "UInt16Property",
- [](const UE_FProperty *prop, type& type) {
- type = {PropertyType::UInt16Property, "uint16_t"};
- }
- },
- {
- "UInt32Property",
- [](const UE_FProperty *prop, type &type) {
- type = {PropertyType::UInt32Property, "uint32_t"};
- }
- },
- {
- "UInt64Property",
- [](const UE_FProperty *prop, type &type) {
- type = {PropertyType::UInt64Property, "uint64_t"};
- }
- },
- {
- "NameProperty",
- [](const UE_FProperty *prop, type &type) {
- type = {PropertyType::NameProperty, "struct FName"};
- }
- },
- {
- "DelegateProperty",
- [](const UE_FProperty *prop, type &type) {
- type = {PropertyType::DelegateProperty, "struct FDelegate"};
- }
- },
- {
- "SetProperty",
- [](const UE_FProperty *prop, type &type) {
- auto obj = prop->Cast();
- type = {PropertyType::SetProperty, obj.GetTypeStr()};
- }
- },
- {
- "ArrayProperty",
- [](const UE_FProperty *prop, type &type) {
- auto obj = prop->Cast();
- type = {PropertyType::ArrayProperty, obj.GetTypeStr()};
- }
- },
- {
- "WeakObjectProperty",
- [](const UE_FProperty *prop, type &type) {
- auto obj = prop->Cast();
- type = {PropertyType::WeakObjectProperty, "struct TWeakObjectPtr<" + obj.GetTypeStr() + ">"};
- }
- },
- {
- "StrProperty",
- [](const UE_FProperty *prop, type &type) {
- type = {PropertyType::StrProperty, "struct FString"};
- }
- },
- {
- "TextProperty",
- [](const UE_FProperty* prop, type& type) {
- type = {PropertyType::TextProperty, "struct FText"};
- }
- },
- {
- "MulticastSparseDelegateProperty",
- [](const UE_FProperty* prop, type& type) {
- type = {PropertyType::MulticastSparseDelegateProperty, "struct FMulticastSparseDelegate"};
- }
- },
- {
- "EnumProperty",
- [](const UE_FProperty* prop, type& type) {
- auto obj = prop->Cast();
- type = {PropertyType::EnumProperty, obj.GetTypeStr()};
- }
- },
- {
- "DoubleProperty",
- [](const UE_FProperty* prop, type& type) {
- type = {PropertyType::DoubleProperty, "double"};
- }
- },
- {
- "MulticastDelegateProperty",
- [](const UE_FProperty* prop, type& type) {
- type = {PropertyType::MulticastDelegateProperty, "FMulticastDelegate"};
- }
- },
- {
- "ClassProperty",
- [](const UE_FProperty* prop, type& type) {
- auto obj = prop->Cast();
- type = {PropertyType::ClassProperty, obj.GetTypeStr()};
- }
- },
- {
- "MulticastInlineDelegateProperty",
- [](const UE_FProperty* prop, type& type) {
- type = {PropertyType::MulticastDelegateProperty, "struct FMulticastInlineDelegate"};
- }
- },
- {
- "MapProperty",
- [](const UE_FProperty* prop, type& type) {
- auto obj = prop->Cast();
- type = {PropertyType::MapProperty, obj.GetTypeStr()};
- }
- },
- {
- "InterfaceProperty",
- [](const UE_FProperty* prop, type& type) {
- auto obj = prop->Cast();
- type = {PropertyType::InterfaceProperty, obj.GetTypeStr()};
- }
- },
- {
- "FieldPathProperty",
- [](const UE_FProperty* prop, type& type) {
- auto obj = prop->Cast();
- type = { PropertyType::FieldPathProperty, obj.GetTypeStr() };
- }
- },
- {
- "SoftClassProperty",
- [](const UE_FProperty* prop, type& type) {
- type = {PropertyType::SoftClassProperty, "struct TSoftClassPtr"};
- }
- }
-};
-
type UE_FProperty::GetType() const {
auto objectClass = Read(object + offsets.FField.Class);
type type = {PropertyType::Unknown, objectClass.GetName()};
- auto fn = types.find(type.second);
+ auto& str = type.second;
+ auto hash = Hash(str.c_str(), str.size());
+ switch (hash) {
+ case HASH("StructProperty"): {
+ auto obj = this->Cast();
+ type = { PropertyType::StructProperty, obj.GetTypeStr() };
+ break;
+ }
+ case HASH("ObjectProperty"): {
+ auto obj = this->Cast();
+ type = { PropertyType::ObjectProperty, obj.GetTypeStr() };
+ break;
+ }
+ case HASH("SoftObjectProperty"): {
+ auto obj = this->Cast();
+ type = { PropertyType::SoftObjectProperty, "struct TSoftObjectPtr<" + obj.GetPropertyClass().GetCppName() + ">" };
+ break;
+ }
+ case HASH("FloatProperty"): {
+ type = { PropertyType::FloatProperty, "float" };
+ break;
+ }
+ case HASH("ByteProperty"): {
+ auto obj = this->Cast();
+ type = { PropertyType::ByteProperty, obj.GetTypeStr() };
+ break;
+ }
+ case HASH("BoolProperty"): {
+ auto obj = this->Cast();
+ type = { PropertyType::BoolProperty, obj.GetTypeStr() };
+ break;
+ }
+ case HASH("IntProperty"): {
+ type = { PropertyType::IntProperty, "int32_t" };
+ break;
+ }
+ case HASH("Int8Property"): {
+ type = { PropertyType::Int8Property, "int8_t" };
+ break;
+ }
+ case HASH("Int16Property"): {
+ type = { PropertyType::Int16Property, "int16_t" };
+ break;
+ }
+ case HASH("Int64Property"): {
+ type = { PropertyType::Int64Property, "int64_t" };
+ break;
+ }
+ case HASH("UInt16Property"): {
+ type = { PropertyType::UInt16Property, "uint16_t" };
+ break;
+ }
+ case HASH("UInt32Property"): {
+ type = { PropertyType::UInt32Property, "uint32_t" };
+ break;
+ }
+ case HASH("UInt64Property"): {
+ type = { PropertyType::UInt64Property, "uint64_t" };
+ break;
+ }
+ case HASH("NameProperty"): {
+ type = { PropertyType::NameProperty, "struct FName" };
+ break;
+ }
+ case HASH("DelegateProperty"): {
+ type = { PropertyType::DelegateProperty, "struct FDelegate" };
+ break;
+ }
+ case HASH("SetProperty"): {
+ auto obj = this->Cast();
+ type = { PropertyType::SetProperty, obj.GetTypeStr() };
+ break;
+ }
+ case HASH("ArrayProperty"): {
+ auto obj = this->Cast();
+ type = { PropertyType::ArrayProperty, obj.GetTypeStr() };
+ break;
+ }
+ case HASH("WeakObjectProperty"): {
+ auto obj = this->Cast();
+ type = { PropertyType::WeakObjectProperty, "struct TWeakObjectPtr<" + obj.GetTypeStr() + ">" };
- if (fn != types.end()) {
- fn->second(this, type);
+ break;
+ }
+ case HASH("StrProperty"): {
+ type = { PropertyType::StrProperty, "struct FString" };
+ break;
+ }
+ case HASH("TextProperty"): {
+ type = { PropertyType::TextProperty, "struct FText" };
+ break;
+ }
+ case HASH("MulticastSparseDelegateProperty"): {
+ type = { PropertyType::MulticastSparseDelegateProperty, "struct FMulticastSparseDelegate" };
+ break;
+ }
+ case HASH("EnumProperty"): {
+ auto obj = this->Cast();
+ type = { PropertyType::EnumProperty, obj.GetTypeStr() };
+ break;
+ }
+ case HASH("DoubleProperty"): {
+ type = { PropertyType::DoubleProperty, "double" };
+ break;
+ }
+ case HASH("MulticastDelegateProperty"): {
+ type = { PropertyType::MulticastDelegateProperty, "FMulticastDelegate" };
+ break;
+ }
+ case HASH("ClassProperty"): {
+ auto obj = this->Cast();
+ type = { PropertyType::ClassProperty, obj.GetTypeStr() };
+ break;
+ }
+ case HASH("MulticastInlineDelegateProperty"): {
+ type = { PropertyType::MulticastDelegateProperty, "struct FMulticastInlineDelegate" };
+ break;
+ }
+ case HASH("MapProperty"): {
+ auto obj = this->Cast();
+ type = { PropertyType::MapProperty, obj.GetTypeStr() };
+ break;
+ }
+ case HASH("InterfaceProperty"): {
+ auto obj = this->Cast();
+ type = { PropertyType::InterfaceProperty, obj.GetTypeStr() };
+ break;
+ }
+ case HASH("FieldPathProperty"): {
+ auto obj = this->Cast();
+ type = { PropertyType::FieldPathProperty, obj.GetTypeStr() };
+ break;
+ }
+ case HASH("SoftClassProperty"): {
+ type = { PropertyType::SoftClassProperty, "struct TSoftClassPtr" };
+ break;
+ }
}
return type;
diff --git a/README.md b/README.md
index c7b28aa..fa45e2c 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,4 @@
### Edit engine.cpp in order to add support for your game
-
### Currently supported games:
- Fortnite
- Rogue Company
@@ -10,7 +9,8 @@
- SCUM
- Scavengers
- The Isle
-
+### Supported engine versions:
+- UE 4.23-4.27
### Usage:
```
.\Dumper.exe -[options]
@@ -23,4 +23,4 @@ Options:
'-f packageNameHere' - specifies package where we should look for pointers in paddings (can take a lot of time)
```
### Todo:
-- Analyze functions to get offsets to referenced fields
+- Analyze functions to get offsets to referenced fields
\ No newline at end of file
diff --git a/include/hash/hash.h b/include/hash/hash.h
new file mode 100644
index 0000000..7eaff48
--- /dev/null
+++ b/include/hash/hash.h
@@ -0,0 +1,23 @@
+#pragma once
+#include
+
+constexpr uint64 Prime = 1099511628211;
+constexpr uint64 Basis = 14695981039346656037;
+
+template< typename Type >
+constexpr uint64 HashCompute(uint64 hash, const Type* const data, uint64 size) {
+ const auto element = (uint64)(data[0]);
+ return (size == 0) ? hash : HashCompute((hash * Prime) ^ element, data + 1, size - 1);
+}
+
+template< typename Type >
+constexpr uint64 Hash(const Type* const data, uint64 size){
+ return HashCompute(Basis, data, size);
+}
+
+#define HASH( Data ) \
+ [ & ]() \
+ { \
+ constexpr auto hash = Hash( Data, sizeof(Data) - 1 ); \
+ return hash; \
+ }()
\ No newline at end of file
diff --git a/include/types.h b/include/types.h
new file mode 100644
index 0000000..b7fea6e
--- /dev/null
+++ b/include/types.h
@@ -0,0 +1,9 @@
+typedef signed char int8;
+typedef short int16;
+typedef int int32;
+typedef long long int64;
+
+typedef unsigned char uint8;
+typedef unsigned short uint16;
+typedef unsigned int uint32;
+typedef unsigned long long uint64;
\ No newline at end of file