 |
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
Rawing Cheater
Reputation: 0
Joined: 01 May 2010 Posts: 42 Location: Austria
|
Posted: Thu Dec 26, 2013 3:01 am Post subject: Filter scan results by whether they're being accessed |
|
|
Hi again.
I'd like to know if there's a way to filter scan results by whether they're constantly being accessed (Think of the "find out what accessed this address" function).
The reason for this is simple:
What I'm searching for is a pointer to a value of the player model - the value affects how the player looks. This value, and therefore the pointer I'm looking for, is being accessed/read several times a second, probably because the game is busy rendering the player model.
This means that anything that points to this value, but isn't accessed 30+ times a second, is useless to me - but I can't manually add every scan result to the address list, then find out what accesses this value, for 50+ addresses.
I don't expect Cheat Engine to have a feature like this, but there might be a way to do this with a lua script, right? There doesn't seem to be a lua function to "find out what accesses this address", however.
_________________
Game over! Die again! |
|
Back to top |
|
 |
Dark Byte Site Admin
Reputation: 470
Joined: 09 May 2003 Posts: 25779 Location: The netherlands
|
Posted: Thu Dec 26, 2013 5:58 am Post subject: |
|
|
you can use
Code: |
debug_setBreakpoint(address, 4, bptAccess)
|
But, since onBreakpoint doesn't tell you which breakpoint caused the bp and the register states are shown after it has been executed, you should only set 1 bp at a time. (Not that it makes much difference, since you can set a max of 4 at a time anyhow)
In the debugger_onBreakpoint() then increase a counter for the address that it has been called
e.g:
Code: |
function debugger_onBreakpoint()
counter++
debug_continueFromBreakpoint(co_run)
return 1
end
|
So, set a breakpoint for one address, wait a minute, then unset the breakpoint with debug_removeBreakpoint(address).
Check the count and if it's big enough add it to a list of valid addresses
Set the count to 0
And set the breakpoint to the next address.
After about 50+ minutes you'll then have a list of addresses that got accessed.
And this is why it's not a build in feature of cheat engine
Remember that alt tabbing to the game may also take a while, so you may want to start the whole lookup a bit delayed so you don't skip the first addresses
_________________
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 |
|
 |
Rawing Cheater
Reputation: 0
Joined: 01 May 2010 Posts: 42 Location: Austria
|
Posted: Thu Dec 26, 2013 7:18 am Post subject: |
|
|
Thanks for the quick reply.
I just tried this with the Cheat Engine Tutorial, since I figured it needed to poll some values, and it didn't work. I skipped to step 2, found the health value, and found it's being accessed about 10 times per second. My little lua script, however, was unable to detect that.
Code: | addrs= getAddressList()
scan= getCurrentMemscan()
found= createFoundList(scan)
accessed= {}
i= 1
function checkAccessed()
debug_setBreakpoint(addr, 4, bptAccess)
sleep(300)
end
function debugger_onBreakpoint()
debug_continueFromBreakpoint(co_run)
accessed[i]= addr
i= i+1
print(addr..' is accessed')
end
foundlist_initialize(found)
c= foundlist_getCount(found)-1
while c>=0 do
addr= foundlist_getAddress(found, c)
print(addr)
checkAccessed()
c= c-1
end
foundlist_deinitialize(found) |
Just to make this clear: You want me to make a breakpoint at the location of the value? That seems kind of weird to me, since there's no code at that place - it's a value, after all.
EDIT: Scratch everything I said, I forgot to use debug_removeBreakpoint(addr). I'll fix and complete it, then post it here in case anyone wants to use it.
_________________
Game over! Die again! |
|
Back to top |
|
 |
Dark Byte Site Admin
Reputation: 470
Joined: 09 May 2003 Posts: 25779 Location: The netherlands
|
Posted: Thu Dec 26, 2013 7:37 am Post subject: |
|
|
bptAccess sets a data breakpoint. Without it, or using bptExecute, it would be a code breakpoint
Also don't use sleep as the debugger will wait till that sleep is done becore it calls onBreakpoint(best use a timer, or run the code in a thread and don't touch the gui)
_________________
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 |
|
 |
Rawing Cheater
Reputation: 0
Joined: 01 May 2010 Posts: 42 Location: Austria
|
Posted: Thu Dec 26, 2013 8:52 am Post subject: |
|
|
Yep, I just noticed the timing's weird. For some reason, onBreakpoint gets called AFTER the
Code: | c= foundlist_getCount(found)-1 |
line, effectively preventing the code from working. But I fail to see how a timer or thread can solve this. I need a way to block execution for some time (while I'm waiting for something to spring the breakpoint), how do I do that with a timer or thread?
Thx for the info on the data breakpoint, btw. Didn't know something like that existed.
_________________
Game over! Die again! |
|
Back to top |
|
 |
Dark Byte Site Admin
Reputation: 470
Joined: 09 May 2003 Posts: 25779 Location: The netherlands
|
Posted: Thu Dec 26, 2013 9:07 am Post subject: |
|
|
split this:
Code: |
while c>=0 do
addr= foundlist_getAddress(found, c)
print(addr)
checkAccessed()
c= c-1
end
foundlist_deinitialize(found)
|
into a timer that runs every few seconds
e.g:
Code: |
i=0
function onTimer(t)
if i<foundlist_getCount(found) then
addr= foundlist_getAddress(found, i)
print(string.format("%x",addr))
checkAccessed()
i=i+1
else
foundlist_deinitialize(found)
print("done")
t.destroy()
end
end
|
_________________
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 |
|
 |
Rawing Cheater
Reputation: 0
Joined: 01 May 2010 Posts: 42 Location: Austria
|
Posted: Thu Dec 26, 2013 9:55 am Post subject: |
|
|
Oh, I thought I needed to keep the "main thread" alive. Welp.
Anyway, I got it to work thanks to you, though there're a few racing conditions (simultaneous call of onBreakpoint and timer_tick = ouch ouch ouch), but what the hell. Thanks.
Here's the code, free to steal for anyone.
Code: | timeout= 200
function debugger_onBreakpoint()
debug_removeBreakpoint(addr)
mr= addresslist_createMemoryRecord(addrs)
memoryrecord_setDescription(mr, 'script-generated result')
memoryrecord_setAddress(mr, addr)
memoryrecord_setType(mr, vtDword)
debug_continueFromBreakpoint(co_run)
end
function timer_tick(timer)
if addr~=nil then
debug_removeBreakpoint(addr)
i= i+1
end
if i>=count then
object_destroy(timer)
object_destroy(found)
return
end
addr= foundlist_getAddress(found, i)
debug_setBreakpoint(addr, 4, bptAccess)
end
addrs= getAddressList()
scan= getCurrentMemscan()
found= createFoundList(scan)
foundlist_initialize(found)
i= 0
addr= nil
count= foundlist_getCount(found)
timer= createTimer(nil, false)
timer_setInterval(timer, timeout)
timer_onTimer(timer, timer_tick)
timer_setEnabled(timer, true) |
No GUI, no progress bar. It filters your current scan results and puts all those that are being accessed into your address list. Change the first line to whatever fits your needs.
Edit: I noticed two problems.
1) Whenever the script is executed, the memory browser opens.
2) After the script has been executed, a memory scan often produces an "Access Violation" error box, and "find out what accesses this address" often causes the program CE is attached to to crash.
What's up with that?
_________________
Game over! Die again! |
|
Back to top |
|
 |
Dark Byte Site Admin
Reputation: 470
Joined: 09 May 2003 Posts: 25779 Location: The netherlands
|
Posted: Fri Dec 27, 2013 9:56 am Post subject: |
|
|
1: In the onBReakpoint routine you must return 1 to indicate that you don't wish the gui to be updated.
2: That is because you have created a secondary foundlist, overriding the foundlist in cheat engine's gui. (you could also just use the foundlist of the gui instead of creating a new one)
Find out what accesses crash not sure. It depends on the game. I recommend waiting a few seconds between removing a breakpoint and adding a new one, since there may be a backlog of breaks waiting. (e.g 10 threads may have broken on that address, but so far you've only handled 1. You need to handle the 9 others before you can reuse that specific hardware breakpoint)
If you add a new one to soon, the data might be lost that a certain breakpoint should be ignored instead of emulated as unhandled (Especially since there are only 4 hardware breakpoints that can be used)
_________________
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 |
|
 |
Rawing Cheater
Reputation: 0
Joined: 01 May 2010 Posts: 42 Location: Austria
|
Posted: Sat Dec 28, 2013 4:09 am Post subject: |
|
|
Thanks again for your help.
I didn't change the code to wait between removing/adding breakpoints because I didn't want to mess with the timer or add a sleep, but it seems to work perfectly now regardless. Even the crash on "find out what accesses this address" seems to be gone, though I didn't test that extensively.
I also added the feature to set a minimum number of accesses per address.
Code: | timeout= 250 --how long to count accesses for each address [milliseconds]
minimum_accesses= 1 --how often each address must be accessed in order to pass the filter [integers > 0]
print_info= true --whether or not to display how often each address has been accessed [true/false]
function debugger_onBreakpoint()
accessed= accessed+1
if count>=minimum_accesses then
add_address= true
end
debug_continueFromBreakpoint(co_run)
return 1
end
function timer_tick(timer)
if addr~=nil then
debug_removeBreakpoint(addr)
if accessed>=minimum_accesses then
mr= addresslist_createMemoryRecord(addrs)
memoryrecord_setDescription(mr, 'accessed '..accessed..' time'..(accessed==1 and '' or 's')..' in '..timeout..'ms')
memoryrecord_setAddress(mr, addr)
memoryrecord_setType(mr, vtDword)
end
if print_info and accessed>0 then
print(addr..' has been accessed '..accessed..' time'..(accessed==1 and '' or 's')..'.')
end
i= i+1
end
if i>=count then
object_destroy(timer)
print('Done.')
return
end
addr= foundlist_getAddress(found, i)
accessed= 0
add_address= false
debug_setBreakpoint(addr, 4, bptAccess)
end
addrs= getAddressList()
scan= getCurrentMemscan()
found= memscan_getAttachedFoundlist(scan)
i= 0
addr= nil
count= foundlist_getCount(found)
timer= createTimer(nil, false)
timer_setInterval(timer, timeout)
timer_onTimer(timer, timer_tick)
timer_setEnabled(timer, true)
|
_________________
Game over! Die again! |
|
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
|
|