|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
Zephiles Advanced Cheater Reputation: 0
Joined: 04 Feb 2016 Posts: 56
|
Posted: Tue Jun 14, 2016 10:29 pm Post subject: CE Request |
|
|
Since Cheat Engine cannot handle results that are bigger than 4 bytes, I was wondering if this would be a possibility:
The current addresses that I am looking at are 8 bytes long and are in the form of Big Endian. They are used to handle the main clock in the game. Because of this, I was wondering if a custom type could be made that would take these 8 bytes and then convert them into minutes.
An example would be that if the clock was currently at 10:45 (10 hours 45 minutes), then the displayed time in Cheat Engine would be 645. So can this sort of thing be done?
Edit: Something similar to this has been done by mgr.inz.Player. This is what he has:
Code: |
alloc(ConvertRoutine,1024)
alloc(TypeName,256)
alloc(ByteSize,4)
alloc(data,16)
label(data1)
label(data2)
alloc(UsesFloat,1)
TypeName:
db 'toFloat(QWord Big Endian)',0
ByteSize:
dd 8
data1:
dq ffffffffffffffff
data2:
dd 5F800000
data3:
dd (float)1000.0
UsesFloat:
db 1
ConvertRoutine:
[64-bit]
lea rsp,[rsp-8]
mov rax,[rcx]
bswap rax
mov [rsp],rax
bt [rsp+4],1F
fild qword ptr [rsp] // dividend
jae @f
fadd [data2]
@@:
bt [data1+4],1F
fild qword ptr [data1] // divisor
jae @f
fadd [data2]
@@:
fdivp
fmul [data3]
fstp [rsp]
mov eax,[rsp]
lea rsp,[rsp+8]
ret
[/64-bit]
|
With this custom type, the values would be like this:
0x0000000000000001 would be 5.421010862E-17
0x0000000000000002 would be 1.084202172E-16
0x8000000000000000 would be 500
0xF000000000000000 would be 937.5
0xFF00000000000000 would be 996.09375
0xFFFFFFFFFFFFFFFF would be 1000.0
|
|
Back to top |
|
|
Zephiles Advanced Cheater Reputation: 0
Joined: 04 Feb 2016 Posts: 56
|
Posted: Mon Jun 20, 2016 4:55 pm Post subject: |
|
|
Since I'm not getting any responses, is it safe to assume this isn't doable?
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25291 Location: The netherlands
|
Posted: Mon Jun 20, 2016 5:36 pm Post subject: |
|
|
it can be done. just as you said, convert it to a human readable value.
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 140
Joined: 06 Jul 2014 Posts: 4297
|
Posted: Mon Jun 20, 2016 6:08 pm Post subject: |
|
|
You can read from & write to that address directly using the bytes, right? Use Lua or even asm to convert it to/from whatever type of value you want.
If you would like someone else to do this, provide more information. Namely, the function that relates that qword to the actual time. If you don't know how to get that, copy and paste a dozen or so states approximately evenly distributed across the full range of values (with respect to either the time in the game or that qword) including that qword, the time it is in the game, and what you want the displayed value to be.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
|
Zephiles Advanced Cheater Reputation: 0
Joined: 04 Feb 2016 Posts: 56
|
Posted: Sat Jun 25, 2016 5:02 pm Post subject: |
|
|
After getting help from some people, I have figured out that the clock speed of the game that I am using this for is 40,500,000/sec, or 2,430,000,000/min. So basically, for the custom type that I am requesting, you would just need to calculate the current value in 8 Byte Big Endian, and then divide the result by 2430000000.
I would assume you would only need to edit the current 4 Byte Big Endian custom type a bit to calculate for 8 bytes instead of 4, and then add in the division afterwards.
Since it's apparently this simple, is any additional information required to make this custom type? I would attempt to make this myself, but I really don't have a clue how to do it.
|
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 140
Joined: 06 Jul 2014 Posts: 4297
|
Posted: Sat Jun 25, 2016 6:16 pm Post subject: |
|
|
As has already been said in a previous topic of yours (among other topics), custom types cannot completely support value types larger than 4 bytes.
Here's a couple Lua functions that will do what you want.
Code: | function readTimeMinutes(address)
local b,r = readBytes(address, 8, true),0
for _,v in ipairs(b) do
r = (r << 8) | v
end
return r / 2430000000
end
function writeTimeMinutes(address, value)
value = math.floor(tonumber(value) * 2430000000)
local b = {}
for i=0,7 do
b[8-i] = (value >> i*8) & 0xff
end
writeBytes(address, b)
end |
If you're fine with a precision around 1.77 minutes, it's possible to make a custom type that only writes to the most significant dword.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
|
Zephiles Advanced Cheater Reputation: 0
Joined: 04 Feb 2016 Posts: 56
|
Posted: Sat Jun 25, 2016 7:13 pm Post subject: |
|
|
OK, so how exactly do I use these functions with my table?
|
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 140
Joined: 06 Jul 2014 Posts: 4297
|
Posted: Sat Jun 25, 2016 8:32 pm Post subject: |
|
|
Any way you want (using Lua).
Code: | autoAssemble("globalalloc(timeMinutes,8)")
local minutesBackup = 0
if timeUpdateT then timeUpdateT.destroy() end
timeUpdateT = createTimer()
timeUpdateT.Interval = 100
timeUpdateT.OnTimer = function(sender)
local real = readTimeMinutes(address)
local user = readDouble("timeMinutes")
if user == minutesBackup then
writeDouble("timeMinutes", real)
minutesBackup = real
else
writeTimeMinutes(address, user)
minutesBackup = user
end
end |
Replace "address" with the address of the time in game (e.g. if you register it as a symbol, use "symbolname" w/ quotes). The symbol timeMinutes contains the time in minutes as a double.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
|
Zephiles Advanced Cheater Reputation: 0
Joined: 04 Feb 2016 Posts: 56
|
Posted: Sat Jun 25, 2016 9:59 pm Post subject: |
|
|
Ok I ran the script earlier and it worked, but now it's not working. I'm getting an error every time I try to run the script now. I have no idea what went wrong. This is what it says:
Error:[string "autoAssemble("globalalloc(timeMinutes,")..."]:8: attempt to call a nil value (global 'readTimeMinutes')
And it keeps looping this until i forcefully close it via task manager.
|
|
Back to top |
|
|
panraven Grandmaster Cheater Reputation: 55
Joined: 01 Oct 2008 Posts: 942
|
Posted: Sat Jun 25, 2016 10:10 pm Post subject: |
|
|
4byte most positive number is 0x7fffffff, which is 2147483647.
If the time usage is within 0-2147days range, the 8bytes value can be express like 2147 days 23hr 59min 59sec as 2147235959 (2147*24*60*60-1 = 0xb0fd5ff ) as largest expressed value.
The point is we don't need to express the custom type result 4byte into all the 8byte possible range with low precision (ie. cut the lower 4bytes, or divide 2430000000 ), we can limit the possible range so that the result type can be fit into 4byte acoording to usage with good precision of 1sec.
The valid 8byte range with highest ~2147day and 1 sec precision is roughly 0xb0fd600 x 40500000 = 0x 1AB404 AECCC000, within 8byte range . For 8byte value higher than this number, we can treat it as invalid value.
Code: | typename="be8bTimer" --shown as the typename in ce
bytecount=8 --number of bytes of this type
functionbasename="b8t"
function b8t_bytestovalue(b0,b1,b2,b3,b4,b5,b6,b7)
local time = byteTableToQword{b7,b6,b5,b4,b3,b2,b1,b0}
local sec = math.floor(time / 40500000)
if sec>=0 and sec < 0xB0fd600 then
local ss = sec % 60
local mm = math.floor(sec/60) % 60
local hh = math.floor(sec/3600) % 24
local dd = math.floor(sec/86400)
return dd*1000000+hh*10000+mm*100+ss
else
return 0x80000000
end
end
function b8t_valuetobytes(i,address)
local b = readBytes(address,8,true)
if i>=0 and i<=2147235959 then
local ss = i % 100
if ss<60 then
local mm = math.floor(i/100)%100
if mm<60 then
local hh = math.floor(i/10000)%100
if hh<24 then
local dd = math.floor(i/1000000)
local sec = dd*86400+hh*3600+mm*60+ss
local time = sec*40500000
b = qwordToByteTable(time)
for i=1,4 do
local j = 9-i
b[i],b[j]=b[j],b[i] -- reverse
end
end
end
end
end
local UnPack = table.unpack or unpack
return UnPack(b)
end
return typename,bytecount,functionbasename |
Try use 'bigger than' with a suitable time value for 1st search,
and use suitable search alignment for faster scan.
If the time usage is to express more than 2147 days, this plan won't work.
bye~
Description: |
|
Filesize: |
14.1 KB |
Viewed: |
6894 Time(s) |
|
_________________
- Retarded.
Last edited by panraven on Sat Jun 25, 2016 10:33 pm; edited 1 time in total |
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 140
Joined: 06 Jul 2014 Posts: 4297
|
Posted: Sat Jun 25, 2016 10:25 pm Post subject: |
|
|
Zephiles wrote: | I have no idea what went wrong.
...attempt to call a nil value (global 'readTimeMinutes') |
You didn't define readTimeMinutes or writeTimeMinutes. Since that Lua code I previously posted calls those functions, you need those functions in order to run that code. So, copy those two function declarations and paste them before that script.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
|
Zephiles Advanced Cheater Reputation: 0
Joined: 04 Feb 2016 Posts: 56
|
Posted: Sat Jun 25, 2016 10:51 pm Post subject: |
|
|
ParkourPenguin whenever I close the game, I also get that error. Is there any way to prevent that?
And panraven, thanks for your custom type as well!
|
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 140
Joined: 06 Jul 2014 Posts: 4297
|
Posted: Sun Jun 26, 2016 8:57 am Post subject: |
|
|
You aren't getting that exact same error since those functions are still defined, but it will fail when it tries to look up values belonging to the process.
Code: | function readTimeMinutes(address)
local b,r = readBytes(address, 8, true),0
if not b then return nil end
for _,v in ipairs(b) do
r = (r << 8) | v
end
return r / 2430000000
end
function writeTimeMinutes(address, value)
value = math.floor(tonumber(value) * 2430000000)
local b = {}
for i=0,7 do
b[8-i] = (value >> i*8) & 0xff
end
return writeBytes(address, b)
end
autoAssemble("globalalloc(timeMinutes,8)")
local minutesBackup = 0
if timeUpdateT then timeUpdateT.destroy() end
timeUpdateT = createTimer()
timeUpdateT.Interval = 100
timeUpdateT.OnTimer = function(sender)
local b = errorOnLookupFailure(false)
local real = readTimeMinutes(address)
local user = readDouble("timeMinutes")
if real and user then
if user == minutesBackup then
writeDouble("timeMinutes", real)
minutesBackup = real
else
writeTimeMinutes(address, user)
minutesBackup = user
end
else
sender.Enabled = false
end
errorOnLookupFailure(b)
end |
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
|
Zephiles Advanced Cheater Reputation: 0
Joined: 04 Feb 2016 Posts: 56
|
Posted: Sun Jun 26, 2016 12:32 pm Post subject: |
|
|
Alright this works, but now there's just one small problem left.
If I reopen the game and execute the script again, the previous value that was in the address will not be reset/cleared.
|
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 140
Joined: 06 Jul 2014 Posts: 4297
|
Posted: Sun Jun 26, 2016 12:35 pm Post subject: |
|
|
Code: | ...
autoAssemble([[globalalloc(timeMinutes,8)
timeMinutes:
dq 0]])
... |
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You can download files in this forum
|
|