⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cheat engine.shp.svn-base

📁 这是一段游戏修改工具的源代码.ring3功能由dephi开发,驱动是C开发.希望对大家有帮助
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:

Code: 

00405000: 
jmp InjectHealthAddress  //jump to the codecave 
nop  //nops for the lost space 
nop 
returnHealthReader:  //this is the label that is used to return to the address (so you dont have to write down 00405007 when jumping back, just to make it easy....) 


injectHealthReader: 
push eax //save eax, not really needed here since eax gets changed anyhow, but it's a good habbit to save and restore registers 
lea eax,[esi+ecx*4] //this instruction places the result of esi+ecx*4 into eax 
mov [playerhealthaddress],eax 
pop eax //restore the register, again, not needed here, but good habbit to do 

originalhealthreadercode: //label defining the original code, can be used to jump into or just skip, not needed here 
mov eax,[esi+ecx*4]  //read health 
mov ecx,[esi+edx*4+4] //read something else, my gues, armor 

jmp returnHealthReader //jump back to the original game code, when done successfull, it wont crash... 
 


As you see to specify a exact address just type it in ended with a ':' . Everything you type in after that will get assembled on and after that address (the jump and nops in this case, and the definition of the returnHealthReader:, which is in it's own turn also a address specifier, but doesn't change the current address) 

This code introduces labels, they are basicly identifiers specifying a address where thay have been placed. 
you can't just use a label though, you'll first have to declare it using the label(labelname) function. I usually declare labels right after the part where I alloc memory. 

so, right after the alloc I have this code to get the code above working: 
Code: 

label(returnHealthReader) //tell the assembler than returnHealthReader is a valid identifier, so dont bug out 
label(originalhealthreadercode) //same as above 
 


now when you run the game the address of your health will get stored into the location of playerhealthaddress. 
You can already use this with cheat engine, because the auto assembler will tell you the address, but the allocation will change each time, so making a table for other people won't work, they'd have to fill in the address each time themselves. (I dont find that a problem but somehow some people do....) 



So, let's automate it a little further and use the knowledge of your healthaddress to make yourself invulnerable, but not your oponents. 
Just like the injection for the code that reads your health you can do the same for that that decreases health. 
And you can put it in the same script as the injection for the reader, as you saw in the alloc part where I already allocated space for the injection for the health decreaser (so you dont have to edit the address the other script allocated) 

so, write scriptcode that places a jump over the code that decreases your health, in this case "mov [esi+ecx*4],edx" which has bytecode 89 14 8e (3 bytes), too small, so find a instruction before or after thats also suitable, in this case there's a sub edx,eax just before this instruction, its bytecode is 29 c2 (2 bytes) so a perfect fit (5 bytes, so no need to nop), and even easier to make a code injection for (else I'd have to use a label between the 2 instructions to just skip the original line, but this sub edx,eax line is used to decrease as well, and doesn't change any of the locator addresses, and useless for the rest, so it doesn't hurt to skip it as well) 

so to inject your routine that checks if this is your health or not and if so, dont decrease do: 
Code: 

00421000: 
jmp injectHealthWriter 
returnHealthWriter: //just declare it here, it'll get address 00421005, so a jmp returnHealthWriter will get converted to jmp 00421005 


injectHealthWriter: 
//do a check if esi+ecx*4 matches the address stored in playerhealthaddress 
//if it matches, skip the original code, if it doesn't just execute it 

//save the registers we use, and before I forget, do not touch esp between saving and restoring the registers unless 
//it's to read something(like parameters), in which case you'll have to adjust the offset 
//also, dont change the registers that you use to find the address 
push eax 
push ebx 
mov eax,[playerhealthaddress] 
lea ebx,[esi+ecx*4] 
cmp eax,ebx 

je itstheplayer 

//not the player 
pop ebx //I think I could have doen this before the je, but better safe than sorry 
pop eax 
jmp originaldecreasehealthcode 


itstheplayer: 
pop ebx //restore the registers, keep in mind to restore the registers in reverse order 
pop eax 
jmp returnHealthWriter //dont execute the original code, return imeadiatly 

originaldecreasehealthcode: 
sub edx,eax 
mov [esi+ecx*4],edx 
jmp returnHealthWriter 
 


again, I used a few labels to make it easier for me 
but, that also means I'd have to declare them, else the assembler will complain it doesn't recognize them 
so: 
Code: 

label(returnHealthWriter) 
label(itstheplayer) 
label(originaldecreasehealthcode) 
 


and I prefer adding declarations at the top. 
















So, the complete auto assembler script would look like: 
Code: 

alloc(injectHealthReader,1024) //creates a identifier called injecthealthreader that points to a block of 1024 bytes 
alloc(injectHealthWriter,1024) //2nd code cave to handle the code of the decrease health code, for easy management 
alloc(playerhealthaddress,4) //this will hold the address of health, a 4 byte value (pointer, in 64 bit this'll have to be 8 bytes) 
label(returnHealthReader) //tell the assembler than returnHealthReader is a valid identifier, so dont bug out 
label(originalhealthreadercode) //same as above 
label(returnHealthWriter) 
label(itstheplayer) 
label(originaldecreasehealthcode) 


//---------------------------------------- 
//              Healthreader 
//---------------------------------------- 
00405000: 
jmp InjectHealthAddress  //jump to the codecave 
nop  //nops for the lost space 
nop 
returnHealthReader:  //this is the label that is used to return to the address (so you dont have to write down 00405007 when jumping back, just to make it easy....) 


injectHealthReader: 
push eax //save eax, not really needed here since eax gets changed anyhow, but it's a good habbit to save and restore registers 
lea eax,[esi+ecx*4] //this instruction places the result of esi+ecx*4 into eax 
mov [playerhealthaddress],eax 
pop eax //restore the register, again, not needed here, but good habbit to do 

originalhealthreadercode: //label defining the original code, can be used to jump into or just skip, not needed here 
mov eax,[esi+ecx*4]  //read health 
mov ecx,[esi+edx*4+4] //read something else, my gues, armor 

jmp returnHealthReader //jump back to the original game code, when done successfull, it wont crash... 



//---------------------------------------- 
//           Health decreaser 
//---------------------------------------- 



00421000: 
jmp injectHealthWriter  //overwrite the original code with a jump. 
returnHealthWriter: //just declare it here, it'll get address 00421005, so a jmp returnHealthWriter will get converted to jmp 00421005 


injectHealthWriter: 
//do a check if esi+ecx*4 matches the address stored in playerhealthaddress 
//if it matches, skip the original code, if it doesn't just execute it 

//save the registers we use, and before I forget, do not touch esp between saving and restoring the registers unless 
//it's to read something(like parameters), in which case you'll have to adjust the offset 
//also, dont change the registers that you use to find the address 
push eax 
push ebx 
mov eax,[playerhealthaddress] 
lea ebx,[esi+ecx*4] 
cmp eax,ebx 

je itstheplayer 

//not the player 
pop ebx //I think I could have doen this before the je, but better safe than sorry 
pop eax 
jmp originaldecreasehealthcode 


itstheplayer: 
pop ebx //restore the registers, keep in mind to restore the registers in reverse order 
pop eax 
jmp returnHealthWriter //dont execute the original code, return imeadiatly 

originaldecreasehealthcode: 
sub edx,eax 
mov [esi+ecx*4],edx 
jmp returnHealthWriter 


 


Please be aware that I havn't tested this in ce yet, I've been writing this in notepad on a pc that doesnt have ce installed, so there may be a few syntax errors, and some of the code I've written can surely be optimised, but I hope you get the general idea. 

Also, there's a bug in ce 5.0 where you can't use small identiers that can apear in the name of another identifier. (e.g weirdmemlocxxx and memloc can't be used at the same time, because memloc fits in weirdmemlocxxx) 
But if you use normal names for identifiers this wont couse a problem, and I recommend identifiers of more than 4 characters, else it may happen you get the name of a assembler instruction and accidentally overwrite that when used. 

_____________________
 
The other method of using code injection is finding if there are differences between the player data and opponent data. 
Lets say that if it's the player [esi+ecx*4+14] contains a 1 otherwhise a 0. you can then do a check if that is set or not, if so, skip, otherwhise, decrease health 

Code: 

alloc(injectHealthWriter,1024) //2nd code cave to handle the code of the decrease health code, for easy management 
label(returnHealthWriter) 
label(itstheplayer) 
label(originaldecreasehealthcode) 


//---------------------------------------- 
//           Health decreaser 
//---------------------------------------- 



00421000: 
jmp injectHealthWriter  //overwrite the original code with a jump. 
returnHealthWriter: //just declare it here, it'll get address 00421005, so a jmp returnHealthWriter will get converted to jmp 00421005 


injectHealthWriter: 
push eax 
mov eax,[esi+ecx*4+14] 
cmp eax,1 
je itstheplayer 

//not the player 
pop eax 
jmp originaldecreasehealthcode 


itstheplayer: 
pop eax //restore the register 
jmp returnHealthWriter //dont execute the original code, return imeadiatly 

originaldecreasehealthcode: 
sub edx,eax 
mov [esi+ecx*4],edx 
jmp returnHealthWriter 
 
 
 
----- SHM ---- page 28 ---- 
Originally posted by Smidge204

When searching for a value in memory using the scan, here are a few pointers to find the value quickly: 

1) If the value is known, but the format is not (ie: Byte, 2 Bytes, 4 Bytes...) search for the smallest type that will hold the data. 

For example, if the value you want is 60, search for bytes. If the value is 1224, search for 2 Byte values, etc. The i

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -