Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


asyncAob aobscan* in async executing memory record

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Extensions
View previous topic :: View next topic  
Author Message
panraven
Grandmaster Cheater
Reputation: 54

Joined: 01 Oct 2008
Posts: 938

PostPosted: Wed Aug 02, 2017 9:41 pm    Post subject: asyncAob aobscan* in async executing memory record This post has 1 review(s) Reply with quote

Only for ce 6.7+

---

IMPORTANCE:
it seems timer created within an async executing memory record will not ever fire.


---

This is a custom AA command to turn aobscan* command
(aobscan/aobscanModule/aobscanRegion) run in async
execution for a memory record , will error when run in
autoAssemble since it need the memory record ID to properly
run.

Code:

command:
asyncAob( MRID,  timeout,  tryinterval,  <=aobscan* command=>)


It will try run the aobscan* command in period of tryinterval (sec) until the aob is found or timeout (sec) reach.
The MRID should be provided in a lua block befoe the command like:
Code:

{$lua}
return string.format("define(MRID,%d)",memrec.ID)
{$asm}
...
asyncAob(MRID, 10, 2,   aobscan(symbol+0c,ff 22 33 44 55 01 02 03) )
...

the Lua variable memrec is only appear in a Lua block of a memory record,
which is the memory record itself.
check test script below.

Just before the actual scan, the associated symbol in aobscan command will be unregistered.
When the aob found, the associated symbol will be automatic registered.

extra: allow symbol offset
eg:
aobscan( symbol +0c, 11 22 33 ...)
if the aob pattern start at 0x10000, then the symbol is registered as 0x1000c, handy to adjust hack point.


---

Attached is a *.CT disguised as *.Lua. remove .lua extension for test.

The custom command asyncAob is defined in Lua engine.
Read the testing memory record script for more detail.

bye~



asyncAob.CT.lua
 Description:

Download
 Filename:  asyncAob.CT.lua
 Filesize:  3.73 KB
 Downloaded:  1617 Time(s)


_________________
- Retarded.
Back to top
View user's profile Send private message
mgr.inz.Player
I post too much
Reputation: 217

Joined: 07 Nov 2008
Posts: 4438
Location: W kraju nad Wisla. UTC+01:00

PostPosted: Fri Aug 04, 2017 11:44 am    Post subject: Reply with quote

Interesting idea. Here my attempt:

The script. Can be used as Lua Extension/Plugin (so, autorun CE folder) or add it to main memory record as Lua block:
Code:
function tryFindingAOB(sc, mr, timeout, aobType, name, a, b, c)
  if sc then return 'define('..name..', 00000000)' end
  if not mr.Async then print'Only Async memory records. Check "execute asynchronous" option.'; error() end
  if not mathrandominit then math.randomseed(os.time()); mathrandominit=true end

  local command,script = '',''
  local dummySymbol = 'itsjustadummysymbol'..math.random(1E9,9E9)..(mr.ID)
  aobType=aobType:lower()

  if     aobType=='aobscan' and a then
    command = 'aobscan('..name..','..a..')'
  elseif aobType=='aobscanmodule' and a and b then
    command = 'aobscanmodule('..name..','..a..','..b..')'
  elseif aobType=='aobscanregion' and a and b and c then
    command = 'aobscanregion('..name..','..a..','..b..','..c..')'
  else print'wrong "tryFindingAOB" syntax'; error() end

  script = command..'\r\nlabel('..dummySymbol..')\r\n'..name..':\r\n'..
           dummySymbol..':\r\nregistersymbol('..dummySymbol..')'

  local origDesc = mr.Description
  local found = false
  local counter = 1

  while (mr.AsyncProcessingTime < timeout * 1000) and (not found) do
    mr.Description = origDesc..' try:'..counter..' timeout:'..((timeout*1000 - mr.AsyncProcessingTime)//100)/10
    found = autoAssemble(script)
    counter = counter + 1
    sleep(100) -- some delay between tries
  end

  mr.Description = origDesc

  if found then
    local address = getAddressSafe(dummySymbol) or 0
    unregisterSymbol(dummySymbol)
    return 'define('..name..','..string.format(' %08X',address)..')'
  else
    error()
  end
end



then your AA script can be this (timeout set to 20 seconds):
Code:
[ENABLE]
{$Lua}
  return tryFindingAOB(syntaxcheck,memrec,20,'aobscan','aobGod','ff 22 33 44 55 01 02 03')
{$Asm}
...
...



instead of
Code:
[ENABLE]
aobscan(aobGod,ff 22 33 44 55 01 02 03)
...
...






or
Code:
[ENABLE]
{$Lua}
  return tryFindingAOB(syntaxcheck,memrec,20,'aobscanmodule','aobGod','modulename.exe','ff 22 33 44 55 01 02 03')
{$Asm}
...
...



instead of
Code:
[ENABLE]
aobscanmodule(aobGod,modulename.exe,ff 22 33 44 55 01 02 03)
...
...

_________________
Back to top
View user's profile Send private message MSN Messenger
panraven
Grandmaster Cheater
Reputation: 54

Joined: 01 Oct 2008
Posts: 938

PostPosted: Fri Aug 04, 2017 12:59 pm    Post subject: Reply with quote

Thanks response~

Would you please confirm or explain that timer created within async memory record will not run?

I've try make a timer within memory record to print some text or change the MainForm Caption in OnTimer function. Without async, it run as expected, with async it just silent. I even make an error (to evaluate 1 + nil) within OnTimer function, async memory record will silent such error too!

_________________
- Retarded.
Back to top
View user's profile Send private message
mgr.inz.Player
I post too much
Reputation: 217

Joined: 07 Nov 2008
Posts: 4438
Location: W kraju nad Wisla. UTC+01:00

PostPosted: Fri Aug 04, 2017 1:54 pm    Post subject: Reply with quote

google fu - TTimer created by TThread - https://www.experts-exchange.com/questions/21834535/TTimer-created-by-TThread.html


But, you can use another TThread. In CE Lua it would be something like this:
Code:
[ENABLE]
{$Lua}
  if syntaxcheck then return end

  function threadFunction(th)
    th.freeOnTerminate(false)
    th.Name = 'myThread'
    while not th.Terminated do
      myvar=myvar+1
      synchronize(function() MainForm.Caption = 'myvar '..myvar end)
      sleep(2000)
    end
  end

  myvar=0
  myThread = createNativeThreadSuspended(threadFunction)
  myThread.resume()
{$Asm}

[DISABLE]
{$Lua}
  if syntaxcheck then return end

  if myThread then
     myThread.terminate()
     myThread.waitfor()
     myThread.destroy()
     myThread=nil
  end
{$Asm}

_________________
Back to top
View user's profile Send private message MSN Messenger
panraven
Grandmaster Cheater
Reputation: 54

Joined: 01 Oct 2008
Posts: 938

PostPosted: Fri Aug 04, 2017 4:12 pm    Post subject: Reply with quote

oh, I see.

I instead from your code found that this work, without create another native thread. Seem synchronize is the key?

Code:

local function callnext(n,f,...)
  local params = table.pack(...)
  local t = createTimer()
  t.interval = n
  t.OnTimer = function(tm)
    tm.Destroy()
    pcall(f,table.unpack(params,1,params.n))
  end
end

if syntaxcheck then return end
if not tonumber(MainForm.Caption) then MainForm.Caption = '0' end

synchronize(callnext,1,function() MainForm.Caption=tostring(1 + tonumber(MainForm.Caption)) end)

_________________
- Retarded.
Back to top
View user's profile Send private message
mgr.inz.Player
I post too much
Reputation: 217

Joined: 07 Nov 2008
Posts: 4438
Location: W kraju nad Wisla. UTC+01:00

PostPosted: Sat Aug 05, 2017 5:15 pm    Post subject: Reply with quote

With synchronize you will create TTimer object, and this object will work in main thread... Somewhat pointless.

If you have some heavy operations inside OnTimer function, CE GUI will freeze from time to time. The point of using Async memrec is to run everything in other thread, not main thread. And synchronize is not needed if you do not touch GUI.

Imagine there's more CPU intense operation than "myvar=myvar+1", let's say it takes 1 second, if inside onTimer it will freeze CE for one second every Interval seconds. My example doesn't have this issue.

_________________
Back to top
View user's profile Send private message MSN Messenger
panraven
Grandmaster Cheater
Reputation: 54

Joined: 01 Oct 2008
Posts: 938

PostPosted: Sat Aug 05, 2017 7:05 pm    Post subject: Reply with quote

I think timer function should be lightweight anyway, there should be alternative to do heavy job like aobscan inside a timer function.

And that one of alternative is this async memory record. There may be case need to spawn yet another native thread from an async memory record, but it is enough if a synchronize call done the job.

btw, would you like make me an example how can memscan's OnGuiUpdate work?

Usually when using memscan we add the waitTillDone() to block execution till scan done, then get the scan result to some variable to futher proces; it will freeze UI normally, which seems prevent OnGuiUpdate function properly. If not using waitTillDone, then how to pass the scan result to script (lua or AA) for further process? (some kind of jquery deffered /promise/ future?)

If I want to make an AA custom scan command with the memscan, but also want it work in aysnc memory record execution with OnGuiUpdatem , and also let the OnGuiUpdate work in non-async case , how it can be done? (I try insert synchronize here or there but no success)

Thank you~

_________________
- Retarded.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 457

Joined: 09 May 2003
Posts: 25252
Location: The netherlands

PostPosted: Sat Aug 05, 2017 7:31 pm    Post subject: Reply with quote

GUIUpdate is just for drawing progressbars, I recommend OnScanDone

Code:

memscan.OnScanDone=function(ms)
  --do something with the results
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
View user's profile Send private message MSN Messenger
panraven
Grandmaster Cheater
Reputation: 54

Joined: 01 Oct 2008
Posts: 938

PostPosted: Sat Aug 05, 2017 8:35 pm    Post subject: Reply with quote

but the OnGuiUpdate function signature seems suggest it can draw or
print other thing, after all the ms can attach a progress bar, seems
redundant to another function to draw in another progress bar.

This part of the custom scan so far
Code:

  local ms = createMemScan(MainForm.progressbar)
  local done,r = false
  ms.OnScanDone = function(m)
      done = true
      r = m.Result
      m.Destroy()
      ms = nil 
  end
  ms.OnlyOneResult = true
  ms.firstScan(soExactValue, vtByteArray, rtRounded, aob, '', 1, -1, '', fsmNotAligned, '', true, true, false, false)

--  ms.WaitTillDone() -- not use

  while not done do
   sleep(100)
    synchronize(processMessages) --- <--- is it using right?
-- without this and in NON ASYNC case, it seems change of 'done' can't be seen and cause inf looping
-- ok when in ASYNC case
  end

  if ms then ms.Destroy()end
  if not r then return nil,aob ..' not found' end
  return fmt("define(%s,%X)",sym,r)


using OnScanDone with a sleep loop seems has no help of making some fancy ui (eg. text base progress info) update.

_________________
- Retarded.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 457

Joined: 09 May 2003
Posts: 25252
Location: The netherlands

PostPosted: Sun Aug 06, 2017 2:00 am    Post subject: Reply with quote

Both OnScanDone and OnGuiUpdate execute in the main thread, so they both can access gui functions.

instead of synchronize(processMessages) use
Code:

if inMainThread() then
  checkSynchronize()
end


Also, do gui updates using synchronize, but keep the rest in the thread


If you wish to update the screen constantly, then use OnGuiUpdate as it gets called frequently. (every few milliseconds)
But it depends on what kind of method you use if what you do will be visible.
If your code is running in the main thread doing an infinite loop then the GUI won't visually update unless you force it to. (e.g: controlname.repaint() )
You can also use processMessages inside OnGuiUpdate , but that will enable the user to click on buttons as well, causing more headache than you need

_________________
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
View user's profile Send private message MSN Messenger
mgr.inz.Player
I post too much
Reputation: 217

Joined: 07 Nov 2008
Posts: 4438
Location: W kraju nad Wisla. UTC+01:00

PostPosted: Sun Aug 06, 2017 2:20 am    Post subject: Reply with quote

panraven wrote:
I think timer function should be lightweight anyway, there should be alternative to do heavy job like aobscan inside a timer function.

Run this script in main thread (execute in 'Lua engine' window)
Code:
createTimer().OnTimer = function () sleep(100) end

sleep in not heavy operation, but CE GUI will freeze for 0.1 second every second. Just start dragging any CE form to see this effect.

_________________
Back to top
View user's profile Send private message MSN Messenger
Dark Byte
Site Admin
Reputation: 457

Joined: 09 May 2003
Posts: 25252
Location: The netherlands

PostPosted: Sun Aug 06, 2017 2:49 am    Post subject: Reply with quote

You can also just have a thread that sleeps in a loop and every loop call a function (synchronized or not)
_________________
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
View user's profile Send private message MSN Messenger
panraven
Grandmaster Cheater
Reputation: 54

Joined: 01 Oct 2008
Posts: 938

PostPosted: Sun Aug 06, 2017 4:50 am    Post subject: Reply with quote

Thanks Dark Byte, the inMainThread/checkSynchonize in OnGuiUpdate work .

Code:

...
  ms.OnlyOneResult = true
  local updcnt = 0
  ms.OnGuiUpdate = function(m, naddr, nscanned, nresult)
    updcnt = updcnt + 1
    if updcnt % 10~= 0 then return end -- slower gui update
    MainForm.Caption = fmt ("%8d/%8d , so far %s",nscanned, naddr, nresult)
    if inMainThread() then checkSynchronize()end
  end

  ms.firstScan(soExactValue, vtByteArray, rtRounded, aob, '', 1, -1, '', fsmNotAligned, '', true, true, false, false)
  ms.WaitTillDone()
  r = ms.Result
...


It has GuiUpdate with or without async execution.

---

@mgr.inz.Player
sleep (100) is 'heavy' in term of time the timer wait?
I guess normally mixing sleep with timer is not appropriate .

Thank you help me understand the thread thing.

_________________
- Retarded.
Back to top
View user's profile Send private message
mgr.inz.Player
I post too much
Reputation: 217

Joined: 07 Nov 2008
Posts: 4438
Location: W kraju nad Wisla. UTC+01:00

PostPosted: Sat Aug 12, 2017 10:04 am    Post subject: Reply with quote

Quote:
I guess normally mixing sleep with timer is not appropriate

It is just an example to show you that you do not need 50%-100% CPU intense Lua command/function to see CE GUI freeze effect.


Even simple readInteger('$process') in OnTimer function, to check process existence, it adds CE GUI micro-freezing (can be visible when you make D3D animations with Lua in main CE thread)

Other example with bigger freeze time: getAutoAttachList().add('prey.exe')
Autoattaching is using TTimer object, on Windows 10 it is already problematic, there are 130 or more processes. Every 2 seconds CE GUI will freeze for 0.1-0.5 second.

If you want to create trainer with customized/animated GUI... animations won't be smooth.
I solved both problems (process existence and autoattach) with one native thread and global var isAttachedToProcess (other functions are checking this var).

Code:
function OpenProcess_CheckExistence(thread)
  thread.name = '"OpenProcess_CheckExistence"'

  while true do
    if readInteger(processName)==nil then
      isAttachedToProcess=false
      if openProcess(processName) then
        AddressList.disableAllWithoutExecute()
        isAttachedToProcess=true
        -- call to function, cut for better readability
        thread.synchronize( --call to function, cut for better readability )
      end
    end
    sleep(5000)
  end

end






PS: Well, current and future OSes will have more and more processes. I think I will report another suggestion on GitHub (autoattach in separate thread instead of TTimer).
PSS: I'm stopping this off-topic discussion. If you want to talk more about it, open new forum thread and invite me with a link on PM.

_________________
Back to top
View user's profile Send private message MSN Messenger
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Extensions All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites