View difference between Paste ID: Z10neT2x and 7Ma3GknW
SHOW: | | - or go back to the newest paste.
1
#include <Windows.h>
2
#include <stdio.h>
3
4
#include <cstring>
5
6
DWORD64   GObjObjects_offset = NULL;
7
DWORD64   Names_offset = NULL;
8
DWORD   Offset_Name = 0x10;
9
10
MODULEINFO GetModuleInfo(LPCTSTR lpModuleName)
11
{
12
	MODULEINFO miInfos = { NULL };
13
14
	HMODULE hmModule = GetModuleHandle(lpModuleName);
15
16
	if (hmModule)
17
	{
18
		GetModuleInformation(GetCurrentProcess(), hmModule, &miInfos, sizeof(MODULEINFO));
19
	}
20
21
	return miInfos;
22
}
23
bool bDataCompare(const BYTE *pData, const BYTE *bMask, const char *szMask)
24
{
25
	for (; *szMask; ++szMask, ++pData, ++bMask) if (*szMask == 'x' && *pData != *bMask) return false;
26
	return (*szMask) == NULL;
27
}
28
DWORD64 FindPatternx64(DWORD64 dwAddress, DWORD64 dwLen, BYTE *bMask, char *szMask)
29
{
30
	for (DWORD64 i = 0; i < dwLen; i++)
31
		if (bDataCompare((BYTE*)(dwAddress + i), bMask, szMask)) return (DWORD64)(dwAddress + i);
32
	return 0;
33
}
34
35
template < class T > struct TArray
36
{
37
	T*              Data;
38
	DWORD   Num;
39
	DWORD   Max;
40
};
41
42
struct UObject
43
{
44
	UCHAR   Unknown[0x10];       // unknowed data
45
	DWORD   NameIndex;                              // struct FName
46
};
47
48
class FUObjectItem
49
{
50
public:
51
	UObject * Object;
52
	__int32 Flags;
53
	__int32 ClusterIndex;
54
	__int32 SerialNumber;
55
	char unknowndata_00[0x4]; //New
56
};
57
58
class TUObjectArray
59
{
60
public:
61
	FUObjectItem * Objects;
62
	__int32 MaxElements;
63
	__int32 NumElements;
64
};
65
66
class FUObjectArray
67
{
68
public:
69
	__int32 ObjFirstGCIndex; //0x0000
70
	__int32 ObjLastNonGCIndex; //0x0004
71
	__int32 MaxObjectsNotConsideredByGC; //0x0008
72
	__int32 OpenForDisregardForGC; //0x000C
73
74
	TUObjectArray ObjObjects;
75
};
76
77
struct FNameEntry
78
{
79
	int Index;
80
	char pad_0x0004[0x4];
81
	FNameEntry* HashNext;
82
	char AnsiName[1024];
83
};
84
85
template<typename ElementType, __int32 MaxTotalElements, __int32 ElementsPerChunk>
86
class TStaticIndirectArrayThreadSafeRead
87
{
88
public:
89
	__int32 Num() const
90
	{
91
		return numElements;
92
	}
93
94
	bool IsValidIndex(__int32 index) const
95
	{
96
		return index >= 0 && index < Num() && GetById(index) != nullptr;
97
	}
98
99
	ElementType const* const& GetById(__int32 index) const
100
	{
101
		return *GetItemPtr(index);
102
	}
103
104
private:
105
	ElementType const* const* GetItemPtr(__int32 Index) const
106
	{
107
		const __int32 ChunkIndex = Index / ElementsPerChunk;
108
		const __int32 WithinChunkIndex = Index % ElementsPerChunk;
109
		const auto Chunk = chunks[ChunkIndex];
110
		return Chunk + WithinChunkIndex;
111
	}
112
113
	enum
114
	{
115
		ChunkTableSize = (MaxTotalElements + ElementsPerChunk - 1) / ElementsPerChunk
116
	};
117
118
	ElementType** chunks[ChunkTableSize];
119
	__int32 numElements;
120
	__int32 numChunks;
121
};
122
123
using TNameEntryArray = TStaticIndirectArrayThreadSafeRead<FNameEntry, 2 * 1024 * 1024, 16384>;
124
FUObjectArray* GObjObjects =NULL;
125
TNameEntryArray* Names = NULL;
126
127
char* GetName(UObject* Object)
128
{
129
	DWORD64 NameIndex = *(PDWORD64)((DWORD64)Object + Offset_Name);
130
131
	if (NameIndex < 0 || NameIndex > Names->Num())
132
	{
133
		static char ret[256];
134
		sprintf_s(ret, "INVALID NAME INDEX : %i > %i", NameIndex, Names->Num());
135
		return ret;
136
	}
137
	else
138
	{
139
		return (char*)Names->GetById(NameIndex)->AnsiName;
140
	}
141
}
142
143
void ObjectDump()
144
{
145
	FILE* Log = NULL;
146
	fopen_s(&Log, "ObjectDump.txt", "w+");
147
148
	for (DWORD64 i = 0x0; i < GObjObjects->ObjObjects.NumElements; i++)
149
	{
150
		if (!GObjObjects->ObjObjects.Objects[i].Object) { continue; }
151
152
		fprintf(Log, "UObject[%06i] %-50s 0x%llX\n", i, GetName(GObjObjects->ObjObjects.Objects[i].Object), GObjObjects->ObjObjects.Objects[i].Object);
153
	}
154
155
	fclose(Log);
156
}
157
158
void NameDump()
159
{
160
	FILE* Log = NULL;
161
	fopen_s(&Log, "NameDump.txt", "w+");
162
163
	for (DWORD64 i = 0x0; i < Names->Num(); i++)
164
	{
165
		if (!Names->GetById(i)) { continue; }
166
167
		fprintf(Log, "Name[%06i] %s\n", i, Names->GetById(i)->AnsiName);
168
	}
169
170
	fclose(Log);
171
}
172
173
void onAttach()
174
{
175
	AllocConsole();
176
	freopen("CONOUT$", "w", stdout);
177
178
	MODULEINFO miGame = GetModuleInfo(NULL);
179
180
	GObjObjects_offset = (DWORD64)((DWORD64)miGame.lpBaseOfDll + 0x425AD00);
181
	Names_offset = (*(DWORD64*)((DWORD64)miGame.lpBaseOfDll + 0x42561D8));
182
183
	GObjObjects = (FUObjectArray*)GObjObjects_offset;
184
	Names = (TNameEntryArray*)Names_offset;
185
186
	NameDump();
187
	ObjectDump();
188
}
189
190
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved)
191
{
192
	switch (dwReason)
193
	{
194
	case DLL_PROCESS_ATTACH:
195
		DisableThreadLibraryCalls(hModule);
196
		CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)onAttach, NULL, 0, NULL);
197
		return true;
198
		break;
199
200
	case DLL_PROCESS_DETACH:
201
		return true;
202
		break;
203
	}
204
}