| 
			
				|  | Cheat Engine The Official Site of Cheat Engine
 
 
 |  
 
	
		| View previous topic :: View next topic |  
		| Author | Message |  
		| MechaCrab How do I cheat?
 
 ![]() Reputation: 0 
 Joined: 30 Dec 2015
 Posts: 5
 
 
 | 
			
				|  Posted: Thu Dec 31, 2015 12:49 am    Post subject: FF7 Auto-Assembler Help |   |  
				| 
 |  
				| Hey guys, hoping you could help.  Had a quick question. So I'm trying to create a multiplier for experience and AP points, and I'm able to find the addresses for the values easy enough through memory viewer. I've been able to cobble a usable multiplier code using your tutorials, however I'm having a problem when I try to toggle the script off, as the game crashes whenever I do. The code in question currently multiplies any experience gained in battle by a factor of two. This is what I've got so far: 
 
  	  | Code: |  	  | [ENABLE] //code from here to '[DISABLE]' will be used to enable the cheat
 alloc(newmem,2048)
 label(returnhere)
 label(originalcode)
 label(exit)
 
 newmem: //this is allocated memory, you have read,write,execute access
 shl ecx,1
 sub ecx,[FF7_EN.exe+59E2C0]//place your code here
 
 originalcode:
 mov [FF7_EN.exe+59E2C0],ecx
 
 exit:
 jmp returnhere
 
 "FF7_EN.exe"+3154B:
 jmp newmem
 nop
 returnhere:
 
 
 
 
 [DISABLE]
 //code from here till the end of the code will be used to disable the cheat
 dealloc(newmem)
 "FF7_EN.exe"+3154B:
 mov [FF7_EN.exe+59E2C0],ecx
 //Alt: db 89 0D C0 E2 99 00
 | 
 
 If anybody could help me figure out what's wrong, it would be very much appreciated, as I'm clueless.
 |  |  
		| Back to top |  |  
		|  |  
		| ParkourPenguin I post too much
 
  Reputation: 152 
 Joined: 06 Jul 2014
 Posts: 4706
 
 
 | 
			
				|  Posted: Thu Dec 31, 2015 10:24 am    Post subject: |   |  
				| 
 |  
				| I'm not sure either; although, I might be missing something obvious. 
 A few questions:
 What's with that sub ecx,[...]? Why have it there?
 I'm guessing FF7_EN.exe+59E2C0 is the address of your experience?
 Could you post the ASM around the instruction "FF7_EN.exe"+3154B? Either an image or copying the instructions would work. To do so, right click in CE's disassembler, select "Go to address", paste that address in, go up a few instructions, select a few via shift-click, right click on them, select "Copy to clipboard -> Bytes+Opcodes", and post that here.
 _________________
 
 I don't know where I'm going, but I'll figure it out when I get there. |  |  
		| Back to top |  |  
		|  |  
		| MechaCrab How do I cheat?
 
 ![]() Reputation: 0 
 Joined: 30 Dec 2015
 Posts: 5
 
 
 | 
			
				|  Posted: Thu Dec 31, 2015 12:53 pm    Post subject: |   |  
				| 
 |  
				|  	  | ParkourPenguin wrote: |  	  | I'm not sure either; although, I might be missing something obvious. 
 A few questions:
 What's with that sub ecx,[...]? Why have it there?
 I'm guessing FF7_EN.exe+59E2C0 is the address of your experience?
 Could you post the ASM around the instruction "FF7_EN.exe"+3154B? Either an image or copying the instructions would work. To do so, right click in CE's disassembler, select "Go to address", paste that address in, go up a few instructions, select a few via shift-click, right click on them, select "Copy to clipboard -> Bytes+Opcodes", and post that here.
 | 
 
 
  	  | Code: |  	  | FF7_EN.exe+3153F - 8B 0D C0E29900        - mov ecx,[FF7_EN.exe+59E2C0] FF7_EN.exe+31545 - 03 88 38B19A00        - add ecx,[eax+FF7_EN.exe+5AB138]
 FF7_EN.exe+3154B - 89 0D C0E29900        - mov [FF7_EN.exe+59E2C0],ecx
 FF7_EN.exe+31551 - 8B 55 FC              - mov edx,[ebp-04]
 FF7_EN.exe+31554 - 83 C2 04              - add edx,04
 
 EAX=000001A0
 EBX=7FFDE000
 ECX=0000001B
 EDX=00000010
 ESI=01053B58
 EDI=00F6F2D0
 ESP=001950E0
 EBP=00195120
 EIP=00431551
 | 
 
 Here we go, I hope this is what you needed. These are the instructions which write to the address of the post-battle results screen for experience received. Another set of instructions also write to this address, which I will show below:
 
 
  	  | Code: |  	  | FF7_EN.exe+1C6F9F - 83 EC 08              - sub esp,08 FF7_EN.exe+1C6FA2 - C7 45 F8 00000000     - mov [ebp-08],00000000
 FF7_EN.exe+1C6FA9 - C7 05 C0E29900 00000000 - mov [FF7_EN.exe+59E2C0],00000000
 FF7_EN.exe+1C6FB3 - C7 05 C4E29900 00000000 - mov [FF7_EN.exe+59E2C4],00000000
 FF7_EN.exe+1C6FBD - C7 05 C8E29900 00000000 - mov [FF7_EN.exe+59E2C8],00000000
 
 EAX=00000020
 EBX=7FFDE000
 ECX=00000000
 EDX=00000020
 ESI=01053B58
 EDI=00F6F2D0
 ESP=001950D0
 EBP=001950D8
 EIP=005C6FB3
 | 
 
 This set of instructions is executed after all monsters on-screen are defeated, during the "victory pose", and takes place before the first code I listed. I wasn't sure whether to include this or not, as I'm not sure what these instructions do exactly, but I thought it couldn't hurt to post as well.
 
 As for the "sub" command in my code, it was my solution to how this game calculates experience in battle. A normal shl, while working fine on just one enemy, gave me more than double experience when I encountered multiple enemies. This is because the game begins calculating experience the moment a monster is defeated, since a player may "run" from a battle before the entire fight is concluded. The equation thus becomes (Base + Earned Exp) = EXP earned after battle, where if two monsters of 20exp each are defeated, it would look like:
 (0+20) = 20
 (20+20) = 40
 40 = Exp
 
 My shl code by itself created the equation ((Base + Earned)x2) = 2base +2earned, which gave me much higher exp than I was asking for. The experience resulted from my new equation:
 ((0+20)x2) = 40
 ((40+20)x2) = 120
 120 = Exp
 
 Thus the need to subtract the base, or ((Base + Earned)x2) - Base = Base +2earned, which was what I needed, "Base" being [FF7_EN.exe+59E2C0].
 
 Thank you for answering my post, and I hope that you can help me in solving this last hurdle.
 
 
 EDIT: Whoa, hold on. So I double checked, and the experience code toggle works just fine. The problem is actually in my AP and GIL modifiers, which I modeled on the EXP modifier. It's very strange, because what appears to be happening is when I disable these scripts, it puts the original code back into place, BUT for some reason changes several bits of instruction immediately after, which I assume result in the crash. I'll try to list a before/after for both of the problem scripts.
 
 2x AP:
 
  	  | Code: |  	  | [ENABLE] //code from here to '[DISABLE]' will be used to enable the cheat
 alloc(newmem,1024)
 label(returnhere)
 label(originalcode)
 label(exit)
 
 newmem: //this is allocated memory, you have read,write,execute access
 shl eax,1
 sub eax,[FF7_EN.exe+59E2C4]//place your code here
 
 originalcode:
 mov [FF7_EN.exe+59E2C4],eax
 
 exit:
 jmp returnhere
 
 "FF7_EN.exe"+3157D:
 jmp newmem
 returnhere:
 
 
 
 
 [DISABLE]
 //code from here till the end of the code will be used to disable the cheat
 dealloc(newmem)
 "FF7_EN.exe"+3157D:
 mov [FF7_EN.exe+59E2C4],eax
 //Alt: db A3 C4 E2 99 00
 | 
 
 Before Injection:
 
  	  | Code: |  	  | FF7_EN.exe+31576 - A1 C4E29900           - mov eax,[FF7_EN.exe+59E2C4] FF7_EN.exe+3157B - 03 C2                 - add eax,edx
 FF7_EN.exe+3157D - A3 C4E29900           - mov [FF7_EN.exe+59E2C4],eax
 FF7_EN.exe+31582 - 8B 4D FC              - mov ecx,[ebp-04]
 FF7_EN.exe+31585 - 83 C1 04              - add ecx,04
 
 EAX=00000003
 EBX=7FFDE000
 ECX=009A900C
 EDX=00000003
 ESI=010C3B58
 EDI=00F6F2D0
 ESP=001950E0
 EBP=00195120
 EIP=00431582
 | 
 
 After injection:
 
  	  | Code: |  	  | FF7_EN.exe+31576 - A1 C4E29900           - mov eax,[FF7_EN.exe+59E2C4] FF7_EN.exe+3157B - 03 C2                 - add eax,edx
 FF7_EN.exe+3157D - E9 7EEAE4FF           - jmp 00280000
 FF7_EN.exe+31582 - 00 4D FC              - add [ebp-04],cl
 FF7_EN.exe+31585 - 83 C1 04              - add ecx,04
 
 | 
 
 After Disabling:
 
  	  | Code: |  	  | FF7_EN.exe+31576 - A1 C4E29900           - mov eax,[FF7_EN.exe+59E2C4] FF7_EN.exe+3157B - 03 C2                 - add eax,edx
 FF7_EN.exe+3157D - 89 05 C4E29900        - mov [FF7_EN.exe+59E2C4],eax
 FF7_EN.exe+31583 - 4D                    - dec ebp
 FF7_EN.exe+31584 - FC                    - cld
 FF7_EN.exe+31585 - 83 C1 04              - add ecx,04
 | 
 
 2x GIL:
 
  	  | Code: |  	  | [ENABLE] //code from here to '[DISABLE]' will be used to enable the cheat
 alloc(newmem,2048)
 label(returnhere)
 label(originalcode)
 label(exit)
 
 newmem: //this is allocated memory, you have read,write,execute access
 shl eax,1
 sub eax,[FF7_EN.exe+59E2C8]//place your code here
 
 originalcode:
 mov [FF7_EN.exe+59E2C8],eax
 
 exit:
 jmp returnhere
 
 "FF7_EN.exe"+31565:
 jmp newmem
 returnhere:
 
 
 
 
 [DISABLE]
 //code from here till the end of the code will be used to disable the cheat
 dealloc(newmem)
 "FF7_EN.exe"+31565:
 mov [FF7_EN.exe+59E2C8],eax
 //Alt: db A3 C8 E2 99 00
 | 
 
 Before Injection:
 
  	  | Code: |  	  | FF7_EN.exe+3155A - A1 C8E29900           - mov eax,[FF7_EN.exe+59E2C8] FF7_EN.exe+3155F - 03 82 34B19A00        - add eax,[edx+FF7_EN.exe+5AB134]
 FF7_EN.exe+31565 - A3 C8E29900           - mov [FF7_EN.exe+59E2C8],eax
 FF7_EN.exe+3156A - 8B 4D DC              - mov ecx,[ebp-24]
 FF7_EN.exe+3156D - 33 D2                 - xor edx,edx
 
 EAX=0000001E
 EBX=7FFDE000
 ECX=0000001B
 EDX=000001A0
 ESI=01173B58
 EDI=00F6F2D0
 ESP=001950E0
 EBP=00195120
 EIP=0043156A
 | 
 
 (This second set of instructions is exclusive to GIL, and also happens at the same time. This script I did not modify, but I will include it in case it proves meaningful.)
 
  	  | Code: |  	  | FF7_EN.exe+3167C - 0FAF D1               - imul edx,ecx
 FF7_EN.exe+3167F - C1 FA 04              - sar edx,04
 FF7_EN.exe+31682 - 89 15 C8E29900        - mov [FF7_EN.exe+59E2C8],edx
 FF7_EN.exe+31688 - E8 E6AA2900           - call FF7_EN.exe+2CC173
 FF7_EN.exe+3168D - C7 45 FC 00000000     - mov [ebp-04],00000000
 
 EAX=00000010
 EBX=7FFDE000
 ECX=00000010
 EDX=0000001E
 ESI=01173B58
 EDI=00F6F2D0
 ESP=001950E0
 EBP=00195120
 EIP=00431688
 | 
 
 After Injection:
 
  	  | Code: |  	  | FF7_EN.exe+3155A - A1 C8E29900           - mov eax,[FF7_EN.exe+59E2C8] FF7_EN.exe+3155F - 03 82 34B19A00        - add eax,[edx+FF7_EN.exe+5AB134]
 FF7_EN.exe+31565 - E9 96EAEDFF           - jmp 00310000
 FF7_EN.exe+3156A - 8B 4D DC              - mov ecx,[ebp-24]
 FF7_EN.exe+3156D - 33 D2                 - xor edx,edx
 
 FF7_EN.exe+3167C - 0FAF D1               - imul edx,ecx
 FF7_EN.exe+3167F - C1 FA 04              - sar edx,04
 FF7_EN.exe+31682 - 89 15 C8E29900        - mov [FF7_EN.exe+59E2C8],edx
 FF7_EN.exe+31688 - E8 E6AA2900           - call FF7_EN.exe+2CC173
 FF7_EN.exe+3168D - C7 45 FC 00000000     - mov [ebp-04],00000000
 | 
 
 After Disabling:
 
  	  | Code: |  	  | FF7_EN.exe+3155A - A1 C8E29900           - mov eax,[FF7_EN.exe+59E2C8] FF7_EN.exe+3155F - 03 82 34B19A00        - add eax,[edx+FF7_EN.exe+5AB134]
 FF7_EN.exe+31565 - 89 05 C8E29900        - mov [FF7_EN.exe+59E2C8],eax
 FF7_EN.exe+3156B - 4D                    - dec ebp
 FF7_EN.exe+3156C - DC 33                 - fdiv qword ptr [ebx]
 FF7_EN.exe+3156E - D2 66 8B              - shl byte ptr [esi-75],cl
 FF7_EN.exe+31571 - 91                    - xchg eax,ecx
 FF7_EN.exe+31572 - 9E                    - sahf
 | 
 
 I hope you'll be able to help me, as right now I'm completely baffled.
 
 Last edited by MechaCrab on Thu Dec 31, 2015 2:08 pm; edited 1 time in total
 |  |  
		| Back to top |  |  
		|  |  
		| ParkourPenguin I post too much
 
  Reputation: 152 
 Joined: 06 Jul 2014
 Posts: 4706
 
 
 | 
			
				|  Posted: Thu Dec 31, 2015 1:58 pm    Post subject: |   |  
				| 
 |  
				| Yup, I have no idea why it's crashing when you disable the script. Everything seems fine. It might be a bug in how CE parses module names in instructions, but I doubt it. You can try putting FF7_EN.exe in quotes to make it more explicit. You should look at your allocated memory to find out if CE assembled your code correctly.
 
 The best way to find out what's wrong is to debug it yourself.
 
 Set a breakpoint (Debug -> Toggle Breakpoint) at the instruction FF7_EN.exe+31545 (the one before where you're writing the jump to). This will stop the game when that instruction is run.
 
 If you do something in-game to trigger the breakpoint (i.e. kill a monster) before enabling the script, you should be able to step through (Debug -> Step) the next couple instructions just fine. You can continue running (Debug -> Run) when you're past the instruction FF7_EN.exe+31551.
 
 Now enable the script, and do something in-game to trigger the breakpoint. This time, you should see a jmp at FF7_EN.exe+3154B. Step into that, and you should see your code. Compare that with what you have written down. If it logically makes sense (i.e. sub ecx,[FF7_EN.exe+59E2C0] may be interpreted as sub ecx, [0099E2C0]), then you're good, and can continue stepping though it until after you reach the jmp back to the instruction FF7_EN.exe+31551. If everything seems fine, then continue running.
 
 Now disable the script. I'm assuming it doesn't immediately crash upon disabling the script. Look at the instructions around FF7_EN.exe+3154B again. If everything looks the same as it was before enabling the script, then it should run just fine and nothing should crash.
 _________________
 
 I don't know where I'm going, but I'll figure it out when I get there. |  |  
		| Back to top |  |  
		|  |  
		| MechaCrab How do I cheat?
 
 ![]() Reputation: 0 
 Joined: 30 Dec 2015
 Posts: 5
 
 
 | 
			
				|  Posted: Thu Dec 31, 2015 2:41 pm    Post subject: |   |  
				| 
 |  
				| Unfortunately, when I try to establish breakpoints at  FF7_EN.exe+3155F (for GIL) and  FF7_EN.exe+3157D (for AP), selected one at a time of course, I am unable to successfully run it after I step through, as the game crashes once I click back to the window. 
 Sorry, I'm quite new at this so I might be doing it wrong, since I assume, being unaltered by my script, the game should continue to run after I've used the Step function past a certain extent.
 |  |  
		| Back to top |  |  
		|  |  
		| ParkourPenguin I post too much
 
  Reputation: 152 
 Joined: 06 Jul 2014
 Posts: 4706
 
 
 | 
			
				|  Posted: Thu Dec 31, 2015 3:08 pm    Post subject: |   |  
				| 
 |  
				| Nevermind my previous post, that was written without me having seen your edit. 
 The problem is that there are different ways of translating the mnemonics humans understand (i.e. mov) into the bytes computers understand. More specifically, even though the mnemonic of that instruction is the exact same, CE isn't translating that into bytes the same way as was originally done by the game. It's putting one more byte than is needed, and as such, is overriding part of the next instruction. This subsequently throws numerous instructions after that out of alignment, which will almost certainly crash the game.
 
 To solve this, just write the bytes directly back to that memory address with db. You can probably trust that it'll be the same whenever you restart the process since it's loaded at 0x00400000, so you can do that directly. If it fails or you just want to be save, globalalloc some backup region of memory and use readmem to backup the bytes into there when enabling scripts. Then just use readmem again when disabling the script to read from the backup.
 
 Here's an example of doing it directly with your 2x AP Script:
 
  	  | Code: |  	  | [ENABLE] //code from here to '[DISABLE]' will be used to enable the cheat
 alloc(newmem,1024)
 label(returnhere)
 label(originalcode)
 label(exit)
 
 newmem: //this is allocated memory, you have read,write,execute access
 shl eax,1
 sub eax,[FF7_EN.exe+59E2C4]//place your code here
 
 originalcode:
 mov [FF7_EN.exe+59E2C4],eax
 
 exit:
 jmp returnhere
 
 "FF7_EN.exe"+3157D:
 jmp newmem
 returnhere:
 
 
 
 
 [DISABLE]
 //code from here till the end of the code will be used to disable the cheat
 dealloc(newmem)
 "FF7_EN.exe"+3157D:
 db A3 C4 E2 99 00
 //Alt (Doesn't work; will crash the game): mov [FF7_EN.exe+59E2C4],eax
 | 
 _________________
 
 I don't know where I'm going, but I'll figure it out when I get there. |  |  
		| Back to top |  |  
		|  |  
		| MechaCrab How do I cheat?
 
 ![]() Reputation: 0 
 Joined: 30 Dec 2015
 Posts: 5
 
 
 | 
			
				|  Posted: Thu Dec 31, 2015 3:45 pm    Post subject: |   |  
				| 
 |  
				| Thank you! Your first solution worked, and I've tested it with all my scripts. I would have had no idea that was what was causing the problem. I had thought that the mnemonic instructions were always 1:1, and was baffled on why the code wasn't disabling to the proper place, but I guess it isn't always 100% translated correctly as you said. 
 So what exactly does the db do? Is it just the memory address in bytes instead of assembly language?
 
 Regardless, thank you again very much for helping me. I've learned a lot from my first script.
 
 Edit: Sorry, this is a bit embarrassing, but I would like to give you a positive review for your help. Trouble is I have no idea how to do that on this site.
 |  |  
		| Back to top |  |  
		|  |  
		| ParkourPenguin I post too much
 
  Reputation: 152 
 Joined: 06 Jul 2014
 Posts: 4706
 
 
 | 
			
				|  Posted: Thu Dec 31, 2015 4:08 pm    Post subject: |   |  
				| 
 |  
				| db ("declare bytes") is a pseudo-instruction that directly writes some bytes to an address. Normally, ASM code is parsed and translated into bytes that are then written to an address, but you can bypass that step and write the bytes yourself if you want to. It's very useful in this case. 
 A thumbs up icon appears next to a user's reputation when you are signed into an account that has 15 or more posts. But you should also read the FAQ if you haven't already.
 _________________
 
 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
 
 |  |