 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
Punz1A4 Cheater
Reputation: 0
Joined: 10 Jun 2016 Posts: 25
|
Posted: Fri Jun 10, 2016 6:20 pm Post subject: Instant actions after enabling/disabling script |
|
|
So I was writing this simple script that moves a value into desired location. Although it works, it requires some additional actions (to disable the effects of script I have to use certain ability twice again) in game to do what I wanted to achieve.
My question is whether it is possible or not to:
a) move certain value (float 1 in this case) to an address ( [ecx+14] in this case) in the disable section (which would spare me some extra work I have to do in the game after disabling the script)
b) forcing the script to execute the code as soon as it's enabled (not when the process gets to the opcode's location after something in the game happens that requires this opcode to be used)
(Preferably in assembly cause as close as I ever got to lua was c++... which is still kinda far away in some cases)
Oh and here's the original script I wrote that as I said requires some additional actions in the game in order to work:
| Code: | [ENABLE]
aobscanmodule(time_stop,Dishonored.exe,F3 0F 11 41 14 D9)
alloc(newmem,$1000)
label(code)
label(return)
newmem:
code:
mov [ecx+14],(float)0.0 //stops the time
jmp return
time_stop:
jmp code
return:
registersymbol(time_stop)
[DISABLE]
time_stop:
db F3 0F 11 41 14
unregistersymbol(time_stop)
dealloc(newmem) |
If it makes any difference moving 0 to an address in [ecx+14] stops the time in the game while character can move and moving 1 makes everyting back to normal.
|
|
| Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4706
|
Posted: Fri Jun 10, 2016 7:12 pm Post subject: |
|
|
The register ecx is constantly changing as the game is running. Before the game gets to this instruction, it must assign the correct value to ecx usually via a hierarchy of pointers to structures with offsets. Moving some value randomly into [ecx+14] won't do what you want it to unless you move the right value into ecx first. So, either wait for the game do that for you, or do it yourself via a static pointer or registered symbol.
For example, to directly answer your first question:
| Code: | [ENABLE]
aobscanmodule(time_stop,Dishonored.exe,F3 0F 11 41 14 D9)
alloc(newmem,1024)
label(code)
label(return)
label(timeaddr)
registersymbol(timeaddr)
registersymbol(time_stop)
newmem:
code:
mov [timeaddr],ecx
mov [ecx+14],(float)0.0 //stops the time
jmp return
timeaddr:
dd 0
time_stop:
jmp code
return:
[DISABLE]
time_stop:
db F3 0F 11 41 14
{$lua}
writeFloat("[timeaddr]+14",1)
{$asm}
unregistersymbol(timeaddr)
unregistersymbol(time_stop)
dealloc(newmem) |
As for your second question, you can call whatever subroutine that code is in to run. Just make sure you call it with the same parameters that the game does. The stack and some registers will probably have to be set to a specific value in order for the game to not crash (let alone do what it's suppose to). Use createthread in order to create a thread that will execute the call.
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
| Back to top |
|
 |
Punz1A4 Cheater
Reputation: 0
Joined: 10 Jun 2016 Posts: 25
|
Posted: Sat Jun 11, 2016 2:13 pm Post subject: |
|
|
Okay so first off huge thanks ParkourPenguin for help
I managed to modify the example you have given to save the appropriate address at [ecx+14] after using ability one time in game.
| Code: | push eax
lea eax,[ecx+14]
mov [time_address],eax
pop eax |
As long as script is active, which makes time_address hold the address of ecx+14, I can toogle on and off the second script as many times as I want stopping and resuming time in the game with a hotkey
| Code: | [ENABLE]
globalalloc(_freeze,2048)
createthread(_freeze)
_freeze:
push eax
mov eax,[time_address]
mov [eax],(float)0 //stops time
pop eax
ret
[DISABLE]
{$lua}
writeFloat("[time_address]",1)
|
So basically everything works as I wanted it to, though since I'm still pretty new to that stuff could somebody explain that part a little more?
| Quote: | | As for your second question, you can call whatever subroutine that code is in to run. |
Subroutine meaning a part of the code in memory viewer consisting of few lines of opcodes? I looked around the opcode I was modifying in scripts above and there was indeed a chunk of code in memory viewer separated by a lot of "int 3" opcodes from both sides. Would I have to include all of that code between "int 3" stuff in order to force script to execute as soon as it's enabled? Asking cause it was about 100 lines of code... which is kinda a lot (if I attached it properly there should be a screenshot of the end of that chunk in memory viewer).
Also
| Quote: | | Just make sure you call it with the same parameters that the game does. The stack and some registers will probably have to be set to a specific value in order for the game to not crash (let alone do what it's suppose to). |
Those parameters are found via breakpoint right? But if so then at which point? The one where the line of code I wanted to edit is placed or the beginning of subroutine? Lastly how can you set stack values?
Sorry for the lengthy post but it's a bit confusing for a newbie.
| Description: |
|
| Filesize: |
168.69 KB |
| Viewed: |
2421 Time(s) |

|
|
|
| Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 152
Joined: 06 Jul 2014 Posts: 4706
|
Posted: Sat Jun 11, 2016 2:47 pm Post subject: |
|
|
A subroutine is generally synonymous with a function or a method in higher-level programming languages. It's more or less a sequence of instructions you call to run. It starts at a specific point and can end at any "ret" instruction inside of it. You don't need to copy and paste the entire thing; just figure out the address of the start of the subroutine and call that. For example, if it starts at the address Dishonored.GetStackOwnerClass+D3B80, then your code (if there was no parameters or other setup) would generally look something like this:
| Code: | alloc(derp,1024)
createthread(derp)
derp:
call Dishonored.GetStackOwnerClass+D3B80
ret |
However, as I said previously, you'll have to pass the same arguments to the subroutine that the game does. It looks like there's 6 of them from that ret instruction (stdcall, 24 bytes / 4 bytes = 6 arguments). Some registers might also need to be set properly beforehand depending on what the subroutine is doing (i.e. if it accesses a register w/o first assigning a value to it). You can step past the ret to see what instruction called the subroutine to run and see where the game gets the arguments from.
Since you stated you're a newbie, it would probably be best if you just put this on hold. Learn more about assembly (i.e. what the stack is) and come back to this later if you want.
Also, you can simplify that second script to this:
| Code: | {$lua}
[ENABLE]
writeFloat("[time_address]",0)
[DISABLE]
writeFloat("[time_address]",1) | The [ENABLE] and [DISABLE] tags will be recognized even when after a {$lua} tag.
_________________
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
|
|