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 


Trying to learn - Crashing Witcher 1

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
robboten
How do I cheat?
Reputation: 0

Joined: 08 Feb 2020
Posts: 3

PostPosted: Mon Feb 10, 2020 12:56 pm    Post subject: Trying to learn - Crashing Witcher 1 Reply with quote

Am trying to learn by watching tutorials and messing about. I can do basic things but still having trouble with code injection. For example I try to make a god mode or smt similar for Witcher 1. But as soon as I get into a fight with the script the game crashes. And I can't understand why. Super frustrating.

Could anyone help me to see what I am doing wrong?

It should be super simple, but it seems not.. I have tried different kinds of stuff between jne and jmp in newcode. Like removing the movss/mov altogether. Getting max health and mov into esi+48 (health) and some more. All with same result. I have confirmed the adresses several times. 'Wied' is part of a string I use to identify if the one hit is me or someone else. Health is a float.

Code:

[ENABLE]

aobscanmodule(bajs,witcher.EXE,F3 0F 11 46 48 74) // should be unique
alloc(newmem,$1000)

label(code)
label(return)

newmem:
cmp [esi+0000007c],'Wied'
jne code
movss [esi+48],xmm0
mov [esi+48],(float)200
jmp return

code:
  movss [esi+48],xmm0
  jmp return

bajs:
  jmp newmem
return:
registersymbol(bajs)

[DISABLE]

bajs:
  db F3 0F 11 46 48

unregistersymbol(bajs)
dealloc(newmem)


original code
Code:

"witcher.EXE"+37B197: 83 7E 0C 01              -  cmp dword ptr [esi+0C],01
"witcher.EXE"+37B19B: 74 0E                    -  je witcher.EXE+37B1AB
"witcher.EXE"+37B19D: 85 C0                    -  test eax,eax
"witcher.EXE"+37B19F: 74 0A                    -  je witcher.EXE+37B1AB
"witcher.EXE"+37B1A1: 83 F8 03                 -  cmp eax,03
"witcher.EXE"+37B1A4: 74 05                    -  je witcher.EXE+37B1AB
"witcher.EXE"+37B1A6: 83 F8 01                 -  cmp eax,01
"witcher.EXE"+37B1A9: 75 17                    -  jne witcher.EXE+37B1C2
"witcher.EXE"+37B1AB: 8B 4E 10                 -  mov ecx,[esi+10]
"witcher.EXE"+37B1AE: 85 C9                    -  test ecx,ecx
// ---------- INJECTING HERE ----------
"witcher.EXE"+37B1B0: F3 0F 11 46 48           -  movss [esi+48],xmm0
// ---------- DONE INJECTING  ----------
"witcher.EXE"+37B1B5: 74 0B                    -  je witcher.EXE+37B1C2
"witcher.EXE"+37B1B7: 8B 11                    -  mov edx,[ecx]
"witcher.EXE"+37B1B9: 50                       -  push eax
"witcher.EXE"+37B1BA: 8B 82 B8 00 00 00        -  mov eax,[edx+000000B8]
"witcher.EXE"+37B1C0: FF D0                    -  call eax
"witcher.EXE"+37B1C2: 5E                       -  pop esi
"witcher.EXE"+37B1C3: C2 08 00                 -  ret 0008
"witcher.EXE"+37B1C6: CC                       -  int 3
"witcher.EXE"+37B1C7: CC                       -  int 3
"witcher.EXE"+37B1C8: CC                       -  int 3


Thanks in advance!
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4697

PostPosted: Mon Feb 10, 2020 1:38 pm    Post subject: Reply with quote

jcc instructions like je and jne conditionally jump to somewhere else. They do this by reading from a special register called EFLAGS (RFLAGS on x64). This register stores information about results from other instructions among other things.

Instructions like cmp and test will set certain bits in EFLAGS to show what the "result" of the instruction is. e.g. cmp will set ZF in EFLAGS if the two operands are equivalent. Later on, instructions like je will check EFLAGS for these values to see if it should jump or not. In the case of je, it will jump if ZF=1 and not jump otherwise.

Some instructions don't modify EFLAGS at all, such as movss. Interleaving such instructions between instructions that set and read EFLAGS can make the code run slightly faster for reasons I won't get into. This is what's happening at the injection point:
Code:
test ecx,ecx
movss [esi+48],xmm0
je witcher.EXE+37B1C2
test sets EFLAGS, movss doesn't access it, and je reads from it.

The je instruction expects EFLAGS to have been set by the test instruction. Injecting code at the movss instruction will work fine only if EFLAGS is preserved across the code injection. The cmp instruction in your code injection destroys the values the test instruction sets, and so that je instruction doesn't do what it was suppose to do.

More specifically, it looks like that je instruction is testing for a null pointer, and your code injection is inadvertently saying it is null. That jump destination is probably some error handling mechanism to "gracefully" exit instead of triggering a segfault.

The easiest way to solve this would be to do the test instruction again when you exit:
Code:
newmem:
  cmp [esi+0000007c],'Wied'
  movss [esi+48],xmm0
  jne short code
  mov [esi+48],(float)200
code:
  test ecx,ecx
  jmp return

Or just inject a couple instructions earlier and change xmm0.

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
robboten
How do I cheat?
Reputation: 0

Joined: 08 Feb 2020
Posts: 3

PostPosted: Mon Feb 10, 2020 1:59 pm    Post subject: Reply with quote

Thanks a lot! That is very interesting! I looked at another code to see how they did it and I didn't understand why they used pushfd before the changed code. I looked it up but didn't understand about the eflags. I am guessing that is another way of working around it, is that right?

I started hacking the game because I was bored with the fights. Now hacking it is much more fun than playing it haha.

Thank you again!
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4697

PostPosted: Mon Feb 10, 2020 2:24 pm    Post subject: Reply with quote

Yes. pushfd (pushfq on x64) will store EFLAGS on the stack, and the corresponding pop instruction will restore it from the stack.

I didn't mention it because there's almost always a solution I'd consider to be better, but you should use your discretion.

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
robboten
How do I cheat?
Reputation: 0

Joined: 08 Feb 2020
Posts: 3

PostPosted: Mon Feb 10, 2020 2:43 pm    Post subject: Reply with quote

Ok, thanks for confirming anyway. Have tested your solution now and it works great! Now off for more exploring! Very Happy
Next up is one hit kill and some more. Am also trying to map out the structure for where the base pointer is pointing at. Tricky but fun!
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