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 


Thread problem: it never exits :)

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
OtisInf
Cheater
Reputation: 0

Joined: 22 Sep 2015
Posts: 25
Location: The Netherlands

PostPosted: Fri Apr 01, 2016 12:06 pm    Post subject: Thread problem: it never exits :) Reply with quote

Hi,

I'm busy working on an AOB based timestop CT for Assassin's Creed Syndicate. This means I can't overwrite any code in the ACS.exe process, as that will make the process crash. I have to set two bytes at two different locations. These locations are known, I have the index-based addresses, these are:

Code:

[ENABLE]
[ACS.exe+70C2A08]+2F8:
db 01
[[ACS.exe+7151690]+98]+8A8:
db 01
[DISABLE]
[ACS.exe+70C2A08]+2F8:
db 0
[[ACS.exe+7151690]+98]+8A8:
db 0


But this is rigid, and I want to scan for these offsets with AOBscan and set them with a thread.

My code is below. This sets the first flag (on [ACS.exe+70C2A08]+2F8), but the problem is with the disable: the thread apparently never exists. pStopFlag is set to 0 when I disable the cheat with the key, so [disable] is called, but pThreadEnded is always 0. Also the flag set by the cheat stays '1'.

The general idea is that the [Enable] starts a thread, the thread sets the flags (currently 1 is implemented), and busy waits with a thread sleep in a loop till a byte is set to 1 (pStopFlag). If that's the case, the 2 flags (currently 1 is implemented) have to be set to 0 again, so that's the code after the sleep loop. I don't know any other way to do that, than this, and IMHO this should work OK. I have two pointers in the CT for debug, pStopFlag and pThreadEnded, and when I enable, both will flip to 0, when I disable, only pStopFlag flips to 1, pThreadEnded stays 0. The flag of the cheat also stays 1. When I move the code for setting pThreadEnded above the loop, its value is set, so the debug pointers and the actual set code works fine. Conclusion: the thread never ends! Wink

It's a 64bit game, hence the calculation of the offset Smile

What do I do wrong?

Thanks in advance!

// Enable script, which performs the AOB scan
Code:

[ENABLE]
aobscanmodule(MenuSystemEnable_AOB, ACS.exe, 40534883EC??488BD9E8????????488B0D????????4885C974??E8????????488B0D????????)
label(MenuSystemEnable)
registersymbol(MenuSystemEnable)
MenuSystemEnable_AOB:
MenuSystemEnable:

[DISABLE]
unregistersymbol(MenuSystemEnable)


The actual cheat script, which is a child of the above code in the CT:
Code:

[ENABLE]
globalalloc(timestop, 128)
createthread(timestop)
label(positive)
label(calculateRealAddress)
label(pMenuSystemData)
label(waitForDisable)
label(pStopFlag)
label(pThreadEnded)
registersymbol(calculateRealAddress)
registersymbol(pMenuSystemData)
registersymbol(waitForDisable)
registersymbol(pStopFlag)
registersymbol(pThreadEnded)

timestop:
  push rsi
  push rdi
  push eax
  push rbx
  mov rsi,MenuSystemEnable+0
  mov rax,11            // offset in AOB block for DWord to read
  mov rbx,pMenuSystemData
  call calculateRealAddress
  // switch on menu camera system
  mov byte ptr [rdi+2F8],01
  //push rdi
waitForDisable:
  push #500
  call sleep
  cmp byte [pStopFlag],01
  jne waitForDisable
  // reset flags to 0
  lea rdi,[pMenuSystemData]
//  pop rdi
  mov byte ptr [rdi+2F8],0
  mov rbx,pThreadEnded
  mov byte ptr [rbx],1
  pop rbx
  pop eax
  pop rdi
  pop rsi
  ret

//[[ACS.exe+7151690]+98]+8A8:
//db 01

pMenuSystemData:
dq 0

pStopFlag:
db 0

pThreadEnded:
db 0

// in:
//    - rsi: Source of AOB scanned block
//    - eax: offset in AOB block for dword to read
//    - rbx: address of label to write the calculated pointer to. Used in disable.
//
// out:
//    - rdi: address of start of block to index into.
calculateRealAddress:
  push ecx
  xor rdi,rdi
  add rsi,eax        // rsi now points to DWord to read
  cmp dword [rsi],80000000 // test if the most significant bit is set
  jb short positive
  mov rdi,ffffffff00000000 // it's set so sign extend
positive:
  mov ecx,[rsi] // this will clear the upper bits of rcx leaving the unsigned value at [rsi+eax] in rcx
  add rdi,ecx
  add rsi,edi
  add rsi,4         // offset to dword already added to rsi. add 4 as we read a dword, this is now the offset after the Dword in the AOB scanned block
  mov [rbx],rsi
  mov rdi,[rsi]
  pop ecx
  ret

[DISABLE]
pStopFlag:
db 1

unregistersymbol(calculateRealAddress)
unregistersymbol(pMenuSystemData)
unregistersymbol(waitForDisable)
unregistersymbol(pStopFlag)
unregistersymbol(pThreadEnded)

//[ACS.exe+70C2A08]+2F8:
//db 0
//[[ACS.exe+7151690]+98]+8A8:
//db 0
Back to top
View user's profile Send private message
++METHOS
I post too much
Reputation: 92

Joined: 29 Oct 2010
Posts: 4197

PostPosted: Fri Apr 01, 2016 3:33 pm    Post subject: Reply with quote

Just curious, so I took a look at this game. I managed to get the script working for a while, but the game eventually crashed. I don't know if that was due to the protection, because of the injection points that I used, or maybe just a bug in the game itself. I only tested it once before deleting the game. Anyway, this was done with the latest version of SE plugin and CE 6.5.


ACS.CT
 Description:
Test Script

Download
 Filename:  ACS.CT
 Filesize:  4 KB
 Downloaded:  457 Time(s)

Back to top
View user's profile Send private message
OtisInf
Cheater
Reputation: 0

Joined: 22 Sep 2015
Posts: 25
Location: The Netherlands

PostPosted: Fri Apr 01, 2016 4:18 pm    Post subject: Reply with quote

whoa that looks totally different to my code Smile

I think the crashes are caused by a race condition between the engine's threads: I think the 2 bytes set are mutexes to make systems start / stop actions, as they control different threads (if you debug the calls to the different flags) and switching the 8A8 indexed one to 1 switches off the camera completely, switching 2F8 to 1 enables the camera system (as the UI/menu uses it) on, so what is needed is achieved: complete standstill with a moving camera Wink. But likely some other subsystem runs off the tracks as multithreading is hard, and Ubisoft's PC programmers didn't anticipate this scenario I think. (aka: another flag has likely to be set somewhere, but which one is unclear)

I was thinking about first doing the 8A8 indexed one and then the 2F8 one, as doing it the other way around is less ideal (as the game crashed on me a couple of times indeed that way too). But I see you did it the other way around so it's not that. :/

Anyway, I appreciate your help on this! Smile Do you mind if I ask a couple of questions regarding this?

Do you know what it could be that makes the thread I create not exit? Your code, is that usable to obtain the actual addresses? I see you use stealthedit, which I haven't seen before, is there documentation on that somewhere? Any url is fine Smile

Thanks again Smile

Tomorrow I'll try to use a keyhandler as a threadloop (similar to what sunbeam used in his ACS table), which is even more overhead to set just 1 byte haha but at least it will let me enable/disable it without problems.
Back to top
View user's profile Send private message
++METHOS
I post too much
Reputation: 92

Joined: 29 Oct 2010
Posts: 4197

PostPosted: Fri Apr 01, 2016 4:56 pm    Post subject: Reply with quote

OtisInf wrote:
Do you know what it could be that makes the thread I create not exit?
-Did you check out these other topics:

http://forum.cheatengine.org/viewtopic.php?t=575644
http://forum.cheatengine.org/viewtopic.php?t=588178

OtisInf wrote:
Your code, is that usable to obtain the actual addresses?
-Yes.

OtisInf wrote:
I see you use stealthedit, which I haven't seen before, is there documentation on that somewhere?
-There are a few topics that discuss this here on CEF, but not many. The release thread is in the beta testing sub-forum. If you're not part of that group, you can download it here:

http://cheatengine.org/temp/stealthedit2.4.zip
Back to top
View user's profile Send private message
OtisInf
Cheater
Reputation: 0

Joined: 22 Sep 2015
Posts: 25
Location: The Netherlands

PostPosted: Sat Apr 02, 2016 1:38 am    Post subject: Reply with quote

++METHOS wrote:
OtisInf wrote:
Do you know what it could be that makes the thread I create not exit?
-Did you check out these other topics:

http://forum.cheatengine.org/viewtopic.php?t=575644
http://forum.cheatengine.org/viewtopic.php?t=588178

I did, but didn't find a solution, as my problem isn't to kill a thread but to make it end properly: it now hangs on the sleep it seems. But I went back to the first thread, and realized what was wrong Smile -> I used the 32bit way of calling sleep (by pushing the # of milliseconds onto the stack), while I should have been using the 64bit way of calling sleep, which is using rcx instead of the stack. I didn't realize calling sleep had two different usages.

So that's solved Smile

Quote:

OtisInf wrote:
Your code, is that usable to obtain the actual addresses?
-Yes.

Neat! Will keep this in mind!

Quote:

OtisInf wrote:
I see you use stealthedit, which I haven't seen before, is there documentation on that somewhere?
-There are a few topics that discuss this here on CEF, but not many. The release thread is in the beta testing sub-forum. If you're not part of that group, you can download it here:

http://cheatengine.org/temp/stealthedit2.4.zip

Ah thanks for the heads up. Nice CE gets stealth edits so a complex thread setup is no longer needed Wink

Thanks for the help!
Back to top
View user's profile Send private message
++METHOS
I post too much
Reputation: 92

Joined: 29 Oct 2010
Posts: 4197

PostPosted: Sat Apr 02, 2016 9:35 am    Post subject: Reply with quote

OtisInf wrote:
I didn't realize calling sleep had two different usages.
-Ah...yes. To be honest, I didn't even look at your script. Sorry.

OtisInf wrote:
so a complex thread setup is no longer needed
-I wouldn't necessarily say that...only because SE may not work effectively on all targets. However, in cases that it does, you can inject and manipulate to your heart's content. Very Happy
Back to top
View user's profile Send private message
OtisInf
Cheater
Reputation: 0

Joined: 22 Sep 2015
Posts: 25
Location: The Netherlands

PostPosted: Sat Apr 02, 2016 10:41 am    Post subject: Reply with quote

++METHOS wrote:
OtisInf wrote:
I didn't realize calling sleep had two different usages.
-Ah...yes. To be honest, I didn't even look at your script. Sorry.

No worries, I figured it out. Smile
Quote:

OtisInf wrote:
so a complex thread setup is no longer needed
-I wouldn't necessarily say that...only because SE may not work effectively on all targets. However, in cases that it does, you can inject and manipulate to your heart's content. Very Happy

that would be great indeed.

I wrote the script now with AOB scans, a thread which neatly exists, all constants are scanned from the code, so should be future proof Wink See: http://forum.cheatengine.org/viewtopic.php?t=588771

Cheers!
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine 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