Advertisement
Guest User

improved Speedhackv3.lua

a guest
Apr 18th, 2025
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.74 KB | None | 0 0
  1. --Copyright Cheat Engine
  2.  
  3. --local
  4. UnityEngineTimeSetTimeScaleMethod=nil
  5.  
  6. function getOriginalCodeAndFiller(address, farjmp)
  7.   local original,filler
  8.  
  9.   if type(address)~='number' then
  10.     address=getAddressSafe(address)
  11.   end
  12.  
  13.   if address==nil then
  14.     return nil, 'invalid address'
  15.   end
  16.  
  17.   local sl=createStringList()
  18.   local d=createDisassembler()
  19.   local size=0
  20.   local jmpsize=not farjmp and 5 or 14
  21.  
  22.  
  23.   while size<jmpsize do
  24.     d.disassemble(address)
  25.     local ldd=d.LastDisassembleData
  26.     local inst=ldd.opcode..' '..ldd.parameters
  27.     sl.add(inst)
  28.     size=size+#ldd.bytes
  29.     address=address+#ldd.bytes
  30.   end
  31.  
  32.   original=sl.Text
  33.   if size-jmpsize>0 then
  34.     filler=string.format("nop %x", size-jmpsize)
  35.   else
  36.     filler=''
  37.   end
  38.  
  39.   sl.destroy()
  40.   d.destroy()
  41.   return original,filler
  42. end
  43.  
  44.  
  45. function hookSpeedFunctions()
  46.   --print("hookSpeedFunctions")
  47.   if getAddressSafe("speedhack_wantedspeed")~=nil then
  48.   --  print("already hooked")
  49.     return true
  50.   end
  51.  
  52.   UnityEngineTimeSetTimeScaleMethod=nil
  53.  
  54.   local r,r2=injectCEHelperLib()
  55.  
  56.   if not r then
  57.     messageDialog('error in injectCEHelperLib(): '..r2, mtError,mbOK)
  58.     return false
  59.   end
  60.  
  61.   local result, data=autoAssemble([[
  62.     globalalloc(speedhack_wantedspeed,4)
  63.     speedhack_wantedspeed:
  64.     dd (float)1
  65.  
  66.  
  67. {$asm}
  68.  
  69.   ]])
  70.  
  71.   if not result then
  72.     messageDialog(data)
  73.     return
  74.   end
  75.  
  76.  -- print("allocated speedhack_wantedspeed")
  77.  
  78.   if monoSettings.Value["SkipMonoSpeedhack"]~='1' then
  79.     local hasMono=getAddressSafe('mono_thread_attach',false,true) or getAddressSafe('il2cpp_thread_attach',false,true)
  80.  
  81.     if hasMono then
  82.       LaunchMonoDataCollector()
  83.      
  84.       local r=mono_findClass("UnityEngine","Time")
  85.       if r then
  86.  
  87.         UnityEngineTimeSetTimeScaleMethod=mono_class_findMethod(r,"set_timeScale")
  88.         if UnityEngineTimeSetTimeScaleMethod then    
  89.  
  90.           local set_timeScale
  91.  
  92.          
  93.           if mono_isil2cpp() then
  94.             set_timeScale=mono_compile_method(UnityEngineTimeSetTimeScaleMethod)
  95.           else          
  96.             set_timeScale=getAddressSafe("UnityEngine.Time:set_timeScale")
  97.           end
  98.          
  99.           if set_timeScale then  
  100.             local originalcode,filler=getOriginalCodeAndFiller(set_timeScale, true)
  101.          
  102.             if originalcode then            
  103.               local s=string.format([[
  104. alloc(set_timeScaleEntryHook,128)
  105. label(returnhere)
  106. set_timeScaleEntryHook:
  107. mov rax,speedhack_wantedspeed
  108. movss xmm0,[rax]
  109. %s
  110. jmp returnhere
  111.  
  112. %x:
  113. jmp far set_timeScaleEntryHook
  114. %s
  115.  
  116. returnhere:]], originalcode, set_timeScale, filler)
  117.               local r,err=autoAssemble(s)
  118.               if r then return true end --just this should be enough
  119.  
  120.               --print(s)
  121.              
  122.               return true
  123.             end
  124.           end
  125.         else
  126.           print("no UnityEngineTimeSetTimeScaleMethod")
  127.         end
  128.       end
  129.     end
  130.   end
  131.  
  132.    
  133.  
  134.   local gtcaddress=getAddressSafe('kernel32.gettickcount64')
  135.   if gtcaddress==nil then
  136.     waitforExports()
  137.     gtcaddress=getAddressSafe('kernel32.gettickcount64')
  138.  
  139.     if (gtcaddress==nil) then
  140.       reinitializeSymbolhandler()
  141.       gtcaddress=getAddressSafe('kernel32.gettickcount64')
  142.       if (gtcaddress==nil) then
  143.         messageDialog('Failure finding kernel32.gettickcount64', mtError, mbOK)
  144.         return false
  145.       end
  146.     end
  147.   end
  148.  
  149.  
  150.   local originalcode,filler=getOriginalCodeAndFiller(gtcaddress)
  151.  
  152.   if originalcode then
  153.     local s=string.format([[
  154.  
  155. alloc(gtc_originalcode,64,"kernel32.gettickcount64")
  156. label(gtc_returnhere)
  157. label(gtchook_exit)
  158.  
  159. {$c}
  160.  
  161. #include <stdint.h>
  162. #include <stddef.h>
  163. #include <celib.h>
  164. #include <windowslite.h>
  165.  
  166. __stdcall uint64_t gtc_originalcode(void);
  167. float gtc_speed=1.0f;
  168. uint64_t gtc_initialtime=0;
  169. uint64_t gtc_initialoffset=0;
  170. CRITICAL_SECTION gtc_cs;
  171.  
  172. void *gtc_initonce=(void*)0;
  173. int gtc_intialized=0;
  174.  
  175.  
  176. extern float speedhack_wantedspeed;
  177.  
  178. __stdcall int InitOnceExecuteOnce(void *InitOnce, void* InitFn, void* Parameter, void *Context);
  179.  
  180.  
  181. __stdcall int initgtc_cs(void *InitOnce, void *Parameter, void *lpContext) {
  182.   InitializeCriticalSection(&gtc_cs);
  183.   gtc_intialized=1;
  184.   return TRUE;
  185. }
  186.  
  187.  
  188.  
  189. __stdcall uint64_t new_gettickcount(void)
  190. {
  191.   uint64_t newtime;
  192.  
  193.   uint64_t currenttime;
  194.   float wantedspeed; //small issue with tcc where you can not compare against extern directly
  195.  
  196.  
  197.   currenttime=gtc_originalcode();
  198.  
  199.   if (gtc_intialized==0) //only set to true once the cs has been initialized
  200.     InitOnceExecuteOnce(&gtc_initonce, initgtc_cs, NULL, NULL);
  201.  
  202.   //after here, gtc_cs is initialized
  203.   EnterCriticalSection(&gtc_cs);
  204.  
  205.  
  206.  
  207.  
  208.   //csenter(&gtc_cs);
  209.   wantedspeed=speedhack_wantedspeed;
  210.  
  211.   if (gtc_initialtime==0)
  212.   {
  213.     gtc_initialtime=currenttime;
  214.     gtc_initialoffset=currenttime;
  215.   }
  216.  
  217.   newtime=(currenttime-gtc_initialtime)*gtc_speed;
  218.   newtime=newtime+gtc_initialoffset; //don't put in in the calculation above, as it gets converted to float, and truncated
  219.  
  220.  if (gtc_speed!=wantedspeed)
  221.  {
  222.    //the user wants to change the speed
  223.    gtc_initialoffset=newtime;
  224.    gtc_initialtime=currenttime;
  225.    gtc_speed=speedhack_wantedspeed;
  226.  }
  227.  
  228.  
  229.  
  230.  LeaveCriticalSection(&gtc_cs);
  231.  
  232.  
  233.  return newtime;
  234.  
  235. }
  236. {$asm}
  237.  
  238.  
  239. gtc_originalcode:
  240. %s
  241.  
  242. gtchook_exit:
  243. jmp gtc_returnhere
  244.  
  245. kernel32.gettickcount64:
  246. jmp new_gettickcount
  247. %s
  248.  
  249. gtc_returnhere:
  250.  
  251.  
  252. kernel32.timeGetTime:
  253. jmp new_gettickcount
  254.  
  255. kernel32.getTickCount:
  256. jmp new_gettickcount
  257.  
  258. ]],originalcode, filler)
  259.  
  260.    local result, data=autoAssemble(s)
  261.  
  262.    if not result then
  263.      if data==nil then
  264.        data=' (no reason)'
  265.      end
  266.      messageDialog('Failure hooking kernel32.gettickcount64:'..data, mtError, mbOK)
  267.    end
  268.  end;
  269.  
  270.  
  271. --queryPerformanceCounter
  272.  local qpcaddress=getAddressSafe('ntdll.RtlQueryPerformanceCounter')
  273.  if qpcaddress==nil then
  274.    waitforExports()
  275.    qpcaddress=getAddressSafe('ntdll.RtlQueryPerformanceCounter')
  276.  
  277.    if (qpcaddress==nil) then
  278.      reinitializeSymbolhandler()
  279.      qpcaddress=getAddressSafe('ntdll.RtlQueryPerformanceCounter')
  280.      if (qpcaddress==nil) then
  281.        messageDialog('Failure finding kernel32.gettickcount64', mtError, mbOK)
  282.        return false
  283.      end
  284.    end
  285.  end
  286.  
  287.  
  288.  local originalcode,filler=getOriginalCodeAndFiller(qpcaddress)
  289.  
  290.  if originalcode then
  291.  
  292.  
  293.  --speedhack does not disable. Just sets speed to 1 when done
  294.  
  295.    local s=string.format([[
  296.  
  297. alloc(qpc_originalcode,64,"ntdll.RtlQueryPerformanceCounter")
  298. label(qpc_returnhere)
  299. label(qpchook_exit)
  300.  
  301. {$c}
  302. #include <stdint.h>
  303. #include <stddef.h>
  304. #include <celib.h>
  305. #include <windowslite.h>
  306.  
  307.  
  308. __stdcall int  qpc_originalcode(uint64_t *count);
  309. float qpc_speed=1.0f;
  310. uint64_t qpc_initialtime=0;
  311. uint64_t qpc_initialoffset=0;
  312. CRITICAL_SECTION qpc_cs;
  313.  
  314. void *qpc_initonce=(void*)0;
  315. int qpc_intialized=0;
  316.  
  317.  
  318. uint64_t qpc_lastresult=0;
  319.  
  320. extern float speedhack_wantedspeed;
  321.  
  322. __stdcall int InitOnceExecuteOnce(void *InitOnce, void* InitFn, void* Parameter, void *Context);
  323.  
  324.  
  325. __stdcall int initqpc_cs(void *InitOnce, void *Parameter, void *lpContext) {
  326.  InitializeCriticalSection(&qpc_cs);
  327.  qpc_intialized=1;
  328.  return TRUE;
  329. }
  330.  
  331.  
  332.  
  333.  
  334.  
  335. __stdcall int  new_RtlQueryPerformanceCounter(uint64_t *count)
  336. {
  337.  uint64_t newtime;
  338.  
  339.  uint64_t currenttime;
  340.  uint64_t newwantedspeed;
  341.  
  342.  
  343.  float wantedspeed; //small issue with tcc where you can not compare against extern directly
  344.  
  345.  if (qpc_intialized==0) //only set to true once the cs has been initialized
  346.    InitOnceExecuteOnce(&qpc_initonce, initqpc_cs, NULL, NULL);
  347.  
  348.  //after here, gtc_cs is initialized
  349.  EnterCriticalSection(&qpc_cs);
  350.  
  351.  
  352.  int result=qpc_originalcode(&currenttime);
  353.  
  354.  
  355.  
  356.  
  357.  wantedspeed=speedhack_wantedspeed;
  358.  
  359.  if (qpc_initialtime==0)
  360.  {
  361.    qpc_initialtime=currenttime;
  362.    qpc_initialoffset=currenttime;
  363.  }
  364.  
  365.  newtime=(currenttime-qpc_initialtime)*qpc_speed;
  366.  
  367.  newtime=newtime+qpc_initialoffset;
  368.  if (qpc_speed!=wantedspeed)
  369.  {
  370.    //the user wants to change the speed
  371.    qpc_initialoffset=newtime;
  372.    qpc_initialtime=currenttime;
  373.    qpc_speed=speedhack_wantedspeed;
  374.  }
  375.  
  376.  LeaveCriticalSection(&qpc_cs);
  377.  
  378.  
  379.  
  380.  *count=newtime;
  381.  
  382.  return result;
  383.  
  384. }
  385. {$asm}
  386.  
  387.  
  388. qpc_originalcode:
  389. %s
  390.  
  391. qpchook_exit:
  392. jmp qpc_returnhere
  393.  
  394. ntdll.RtlQueryPerformanceCounter:
  395. jmp new_RtlQueryPerformanceCounter
  396. %s
  397.  
  398. qpc_returnhere:
  399.  
  400.  
  401. ]],originalcode, filler)
  402.  
  403.    local result2, data2=autoAssemble(s)
  404.    
  405.    if not result2 then
  406.      if data2==nil then
  407.        data2=' (no reason)'
  408.      end
  409.      messageDialog('Failure hooking ntdll.RtlQueryPerformanceCounter:'..data2, mtError, mbOK)
  410.    end
  411.    
  412.  end;
  413.  
  414.  return result or result2
  415. end
  416.  
  417.  
  418.  
  419. registerSpeedhackCallbacks(function() --OnActivate
  420.  if (not isConnectedToCEServer()) and targetIsX86() then
  421.    local result, errormsg
  422.    
  423.    
  424.    if getAddressSafe("speedhack_wantedspeed")==nil then
  425.      --still needs hooking
  426.      result,errormsg=hookSpeedFunctions()
  427.    else
  428.      result=true
  429.    end
  430.        
  431.    return true, result, errormsg
  432.  else
  433.    return false
  434.  end
  435. end,
  436.  
  437. function(speed) --OnSetSpeed(speed)
  438.  if (not isConnectedToCEServer()) and targetIsX86() then
  439.    local result, errormsg
  440.    if getAddressSafe("new_gettickcount")==nil or getAddressSafe("speedhack_wantedspeed")==nil then
  441.  
  442.      result,errormsg=hookSpeedFunctions()
  443.      if not result then return true, false, errormsg end
  444.    end
  445.  
  446.    writeFloat("speedhack_wantedspeed", speed)
  447.    
  448.    if UnityEngineTimeSetTimeScaleMethod then
  449.      mono_invoke_method(nil,UnityEngineTimeSetTimeScaleMethod,nil,{speed})
  450.    end
  451.    
  452.    result=true      
  453.    
  454.    return true, true
  455.  else
  456.    return false
  457.  end
  458. end)
  459.  
  460.  
  461.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement