1- -- Framework to make Game Guradian scipt creation easier for games built with Unity
2- -- To get class names, field offsets use Il2CppDumper
3- -- https://github.com/Perfare/Il2CppDumper
1+ -- https://github.com/HTCheater/Il2CppExplorer
42ht = {}
53-- Output debug messages
64ht [" debug" ] = false
75-- Let people know you are using my framework :D
86ht [" printAdvert" ] = true
97-- Exit if selected process isn't Unity game
108ht [" exitOnNotUnityGame" ] = true
9+ -- Exit if metadata isn't loaded
10+ ht [" exitOnEarlyStart" ] = true
1111-- Contains start address of libil2cpp.so once either ht.getLib or ht.patchLib or ht.editFunction was called
1212ht [" libStart" ] = 0x0
1313-- Contains end address of libil2cpp.so once either ht.getLib or ht.patchLib or ht.editFunction was called
4949local isx64 = gg .getTargetInfo ().x64
5050local metadata = gg .getRangesList (" global-metadata.dat" )
5151
52- if (# metadata == 0 and ht .debug ) then
53- print (" Metadata isn't loaded, reboot the script and make sure unity game is selected" )
52+ if # metadata == 0 then
53+ if ht .exitOnEarlyStart then
54+ os.exit ()
55+ end
56+ ht .print (" Metadata isn't loaded, reboot the script and make sure unity game is selected" )
5457end
5558
5659if # metadata > 0 then
@@ -197,8 +200,9 @@ function ht.patchLib(offset, offsetX32, patchedBytes, patchedBytesX32)
197200 patchedBytes = patchedBytesX32
198201 offset = offsetX32
199202 end
200- if ((patchedBytes == nil or offset == nil ) and ht .debug ) then
201- print (" ❌There is no valid patch for current architecture" )
203+ if (patchedBytes == nil or offset == nil ) then
204+ ht .print (" ❌There is no valid patch for current architecture" )
205+ return
202206 end
203207 local currAddress = ht .libStart + offset
204208 for k , v in ipairs (patchedBytes ) do
@@ -283,55 +287,53 @@ function ht.getLib()
283287 ht .libStart = libil2cpp .start
284288 ht .libEnd = libil2cpp [" end" ]
285289 end
286- if ht .libStart == 0x0 and debug then
287- print (" Failed to get libil2cpp.so address, try entering the game first" )
290+ if ht .libStart == 0x0 then
291+ ht . print (" Failed to get libil2cpp.so address, try entering the game first" )
288292 end
289293end
290294
291295-- Get field value in instance from instances table specified by index
292296
293297function ht .getFieldValue (instancesTable , offset , offsetX32 , type , index )
294298 if instancesTable == nil then
295- print (" ❌Instances table is nil" )
299+ ht .print (" ❌Instances table is nil" )
300+ return nil
296301 end
297302 local instance = instancesTable [index ]
298- if instance == nil and ht . debug then
299- print (" ❌Wrong index (no results found?)" )
303+ if instance == nil then
304+ ht . print (" ❌Wrong index (no results found?)" )
300305 return nil
301306 end
302307 if not isx64 then
303308 offset = offsetX32
304309 end
305- if offset == nil and debug then
306- print (" ❌Offset for this architecture is not specified" )
307- return
310+ if offset == nil then
311+ ht . print (" ❌Offset for this architecture is not specified" )
312+ return nil
308313 end
309- local t = {}
310- t [1 ] = {}
311- t [1 ].address = instance .address + offset
312- t [1 ].flags = type
313- t = gg .getValues (t )
314- return t [1 ].value
314+ return ht .readValue (instance .address + offset , type )
315315end
316316
317317-- Edit field value in instance from instances table specified by index
318318
319319function ht .editFieldValue (instancesTable , offset , offsetX32 , type , index , value )
320320 if instancesTable == nil then
321- print (" ❌Instances table is nil" )
321+ ht .print (" ❌Instances table is nil" )
322+ return nil
322323 end
323324 local instance = instancesTable [index ]
324- if instance == nil and ht . debug then
325- print (" ❌Wrong index (no results found?)" )
326- return
325+ if instance == nil then
326+ ht . print (" ❌Wrong index (no results found?)" )
327+ return nil
327328 end
328329 if not isx64 then
329330 offset = offsetX32
330331 end
331- if offset == nil and debug then
332- print (" ❌Offset for this architecture is not specified" )
333- return
332+ if offset == nil then
333+ ht . print (" ❌Offset for this architecture is not specified" )
334+ return nil
334335 end
336+
335337 local t = {}
336338 t [1 ] = {}
337339 t [1 ].address = instance .address + offset
@@ -365,15 +367,12 @@ function ht.editFunction(className, functionName, patchedBytes, patchedBytesX32)
365367 gg .refineNumber (stringBytes [1 ], gg .TYPE_BYTE )
366368
367369 if gg .getResultsCount () == 0 then
368- if debug then
369- print (" Can't find " .. functionName .. " in metadata" )
370- end
371-
370+ ht .print (" Can't find " .. functionName .. " in metadata" )
372371 local r = {}
373372 return r
374373 end
375374
376- local addr = 0x0
375+ local addr = 0x0
377376
378377 for index , result in pairs (gg .getResults (100000 )) do
379378 for k , v in pairs (gg .getRangesList (" libc_malloc" )) do
@@ -404,9 +403,7 @@ function ht.editFunction(className, functionName, patchedBytes, patchedBytesX32)
404403 end
405404
406405 if addr == 0 then
407- if debug then
408- print (" There is no valid pointer for " .. className )
409- end
406+ ht .print (" There is no valid pointer for " .. className )
410407 return
411408 end
412409
@@ -416,7 +413,7 @@ function ht.editFunction(className, functionName, patchedBytes, patchedBytesX32)
416413
417414 addr = addr - ht .libStart
418415
419- ht .patchLib (addr , addr , patchedBytes , patchedBytesX32 )
416+ ht .patchLib (addr , addr , patchedBytes , patchedBytesX32 )
420417end
421418
422419function ht .isFunctionPointer (address , className )
@@ -472,7 +469,7 @@ function ht.readValue(addr, type)
472469 return t [1 ].value
473470end
474471
475- -- returns DWORD value
472+ -- returns dword value
476473function ht .readInt (addr )
477474 return ht .readValue (addr , gg .TYPE_DWORD )
478475end
486483function ht .readPointer (addr )
487484 return ht .readValue (addr , isx64 and gg .TYPE_QWORD or gg .TYPE_DWORD )
488485end
486+
487+ -- Print debug messages
488+ function ht .print (str )
489+ if ht .debug then
490+ print (str )
491+ end
492+ end
0 commit comments