Difference between revisions of "Help File:Money type"

From Cheat Engine
Jump to navigation Jump to search
(Created page with '<hr><div align="left"><font face="Arial" color="#010101" class="Arial2"> The following custom type script will handle values that need to be divided by 100 to get to the corre…')
 
 
(2 intermediate revisions by the same user not shown)
Line 1: Line 1:
<hr><div align="left"><font face="Arial"  color="#010101"  class="Arial2">
+
[[Category:Help]]
The following custom type script will handle values that need to be divided by 100 to get to the  
+
== Money type (divided by 100) ==
correct value</font></div><div align="left"><font face="Arial"  color="#010101"  class="Arial2">
+
 
This type is used by some games like civilization 5 where the money and research technology is  
+
The following custom type script will handle values that need to be divided by 100 to get to the correct value
stored using this floating point type.</font></div><div align="left"><font face="Arial"  color="#010101"  class="Arial2"><br></font></div><div align="left"><font face="Arial"  color="#010101"  class="Arial2">
+
This type is used by some games like civilization 5 where the money and research technology is stored using this floating point type.
example:</font></div><div align="left"><font face="Arial"  color="#010101"  class="Arial2">
+
 
100.35 gold would be stored in memory as 10013</font></div><div align="left"><font face="Arial"  color="#010101"  class="Arial2">
+
 
103.89 gold would be stored in memory as 10389</font></div><div align="left"><font face="Arial"  color="#010101"  class="Arial2"><br></font></div><div align="left"><font face="Arial"  color="#010101"  class="Arial2">
+
Example:
with this script you'd be able to scan for 100 and 103 respectively, and if you wanted to change  
+
 
the value to 700 you'd just change the value to 700 instead of 70000</font></div><div align="left"><font face="Arial"  color="#010101"  class="Arial2"><br></font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2"><br></font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
100.35 gold would be stored in memory as 10013
alloc(TypeName,256)</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
 
alloc(ByteSize,4)</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
103.89 gold would be stored in memory as 10389
alloc(ConvertRoutine,1024)</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
 
alloc(ConvertBackRoutine,1024)</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2"><br></font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
 
TypeName:</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
with this script you'd be able to scan for 100 and 103 respectively, and if you wanted to change the value to 700 you'd just change the value to 700 instead of 70000
db 'Civ 5 Float',0</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2"><br></font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
 
ByteSize:</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
 
dd 4</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2"><br></font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  alloc(TypeName,256)
//The convert routine should hold a routine that converts the data to an  
+
  alloc(ByteSize,4)
nteger (in eax)</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  alloc(ConvertRoutine,1024)
//function declared as: stdcall int ConvertRoutine(unsigned char  
+
  alloc(ConvertBackRoutine,1024)
*input);</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2"><br></font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
 
//Note: Keep in mind that this routine can be called by multiple threads  
+
  TypeName:
at the same time.</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2"><br></font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  db 'Civ 5 Float',0
ConvertRoutine:</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
 
[32-bit]</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  ByteSize:
push ebp</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  dd 4
mov ebp,esp</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
 
push ecx</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  // The convert routine should hold a routine that converts the data to an nteger (in eax)
mov ecx,[ebp+8]</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  // function declared as: stdcall int ConvertRoutine(unsigned char *input);
[/32-bit]</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2"><br></font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
 
//at this point ecx contains the address where the bytes are stored</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  // Note: Keep in mind that this routine can be called by multiple threads at the same time.
//save the used registers</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
 
push edx //fun fact about ce's assembler, because push ebx does not  
+
  ConvertRoutine:
exist in 64-bit it becomes the 64-bit push rdx automatically</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  [32-bit]
push ebx</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2"><br></font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  push ebp
//put the bytes into the eax register</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  mov ebp,esp
mov eax,[ecx] //second fun fact, addressing with 32-bit registers  
+
  push ecx
doesn't work in 64-bit, it becomes a 64-bit automatically (most of the  
+
  mov ecx,[ebp+8]
time)</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2"><br></font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  [/32-bit]
xor edx,edx</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
 
mov ebx,#100</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  // at this point ecx contains the address where the bytes are stored
div ebx //divide eax by 100 and put the result in eax (and leftover in  
+
  // save the used registers
edx)</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2"><br></font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  push edx // fun fact about ce's assembler, because push ebx does not exist in 64-bit it becomes the 64-bit push rdx automatically
pop ebx</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  push ebx
pop edx</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
 
//and now exit the routine</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  // put the bytes into the eax register
[64-bit]</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  mov eax,[ecx] // second fun fact, addressing with 32-bit registers doesn't work in 64-bit, it becomes a 64-bit automatically (most of the time)
ret</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
 
[/64-bit]</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  xor edx,edx
[32-bit]</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  mov ebx,#100
pop ecx</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  div ebx // divide eax by 100 and put the result in eax (and leftover in edx)
pop ebp</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
 
ret 4</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  pop ebx
[/32-bit]</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2"><br></font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  pop edx
//The convert back routine should hold a routine that converts the given  
+
  // and now exit the routine
integer back to a row of bytes (e.g when the user wats to write a new  
+
  [64-bit]
value)</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  ret
//function declared as: stdcall void ConvertBackRoutine(int i, unsigned  
+
  [/64-bit]
char *output);</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  [32-bit]
ConvertBackRoutine:</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  pop ecx
[32-bit]</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  pop ebp
push ebp</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  ret 4
mov ebp,esp</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  [/32-bit]
push edx //save the registers</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
 
push ecx</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  // The convert back routine should hold a routine that converts the given integer back to a row of bytes (e.g when the user wats to write a new value)
mov edx,[ebp+0c]</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  // function declared as: stdcall void ConvertBackRoutine(int i, unsigned char *output);
mov ecx,[ebp+08]</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  ConvertBackRoutine:
[/32-bit]</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2"><br></font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  [32-bit]
//at this point edx contains the address to write the value to</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  push ebp
//and ecx contains the value</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  mov ebp,esp
push eax</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  push edx // save the registers
push edx</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  push ecx
push ecx</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2"><br></font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  mov edx,[ebp+0c]
mov eax,ecx //eax gets the given value</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  mov ecx,[ebp+08]
xor edx,edx //clear edx</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  [/32-bit]
mov ecx,#100</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
 
mul ecx //multiply eax and put the results into edx:eax (edx is ignored  
+
  // at this point edx contains the address to write the value to
for this routine)</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2"><br></font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  // and ecx contains the value
pop ecx</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  push eax
pop edx</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  push edx
mov [edx],eax</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  push ecx
pop eax</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2"><br></font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
 
[64-bit]</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  mov eax,ecx // eax gets the given value
//everything is back to what it was, so exit</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  xor edx,edx // clear edx
ret</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  mov ecx,#100
[/64-bit]</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2"><br></font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  mul ecx // multiply eax and put the results into edx:eax (edx is ignored for this routine)
[32-bit]</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
 
//cleanup first</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  pop ecx
pop ecx</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  pop edx
pop edx</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  mov [edx],eax
pop ebp</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
  pop eax
ret 8</font></div><div align="left"><font face="Courier New"  color="#010101"  class="CourierNew2">
+
 
[/32-bit] </font></div>
+
  [64-bit]
 +
  // everything is back to what it was, so exit
 +
  ret
 +
  [/64-bit]
 +
 
 +
  [32-bit]
 +
  // cleanup first
 +
  pop ecx
 +
  pop edx
 +
  pop ebp
 +
  ret 8
 +
  [/32-bit]
 +
 
 +
== Links ==
 +
* [[Cheat Engine:Help File|Help File]]
 +
 
 +
* [[Help_File:Value_types|Back]]
 +
 
 +
* [[Help_File:old_flash_(div_8)|Next]]

Latest revision as of 12:08, 19 March 2017

Money type (divided by 100)[edit]

The following custom type script will handle values that need to be divided by 100 to get to the correct value This type is used by some games like civilization 5 where the money and research technology is stored using this floating point type.


Example:

100.35 gold would be stored in memory as 10013

103.89 gold would be stored in memory as 10389


with this script you'd be able to scan for 100 and 103 respectively, and if you wanted to change the value to 700 you'd just change the value to 700 instead of 70000


 alloc(TypeName,256)
 alloc(ByteSize,4)
 alloc(ConvertRoutine,1024)
 alloc(ConvertBackRoutine,1024)
 
 TypeName:
 db 'Civ 5 Float',0
 
 ByteSize:
 dd 4
 
 // The convert routine should hold a routine that converts the data to an nteger (in eax)
 // function declared as: stdcall int ConvertRoutine(unsigned char *input);
 
 // Note: Keep in mind that this routine can be called by multiple threads at the same time.
 
 ConvertRoutine:
 [32-bit]
 push ebp
 mov ebp,esp
 push ecx
 mov ecx,[ebp+8]
 [/32-bit]
 
 // at this point ecx contains the address where the bytes are stored
 // save the used registers
 push edx // fun fact about ce's assembler, because push ebx does not exist in 64-bit it becomes the 64-bit push rdx automatically
 push ebx
 
 // put the bytes into the eax register
 mov eax,[ecx] // second fun fact, addressing with 32-bit registers doesn't work in 64-bit, it becomes a 64-bit automatically (most of the time)
 
 xor edx,edx
 mov ebx,#100
 div ebx // divide eax by 100 and put the result in eax (and leftover in edx)
 
 pop ebx
 pop edx
 // and now exit the routine
 [64-bit]
 ret
 [/64-bit]
 [32-bit]
 pop ecx
 pop ebp
 ret 4
 [/32-bit]
 
 // The convert back routine should hold a routine that converts the given integer back to a row of bytes (e.g when the user wats to write a new value)
 // function declared as: stdcall void ConvertBackRoutine(int i, unsigned char *output);
 ConvertBackRoutine:
 [32-bit]
 push ebp
 mov ebp,esp
 push edx // save the registers
 push ecx
 mov edx,[ebp+0c]
 mov ecx,[ebp+08]
 [/32-bit]
 
 // at this point edx contains the address to write the value to
 // and ecx contains the value
 push eax
 push edx
 push ecx
 
 mov eax,ecx // eax gets the given value
 xor edx,edx // clear edx
 mov ecx,#100
 mul ecx // multiply eax and put the results into edx:eax (edx is ignored for this routine)
 
 pop ecx
 pop edx
 mov [edx],eax
 pop eax
 
 [64-bit]
 // everything is back to what it was, so exit
 ret
 [/64-bit]
 
 [32-bit]
 // cleanup first
 pop ecx
 pop edx
 pop ebp
 ret 8
 [/32-bit]

Links[edit]