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 


Bug? (Cannot display custom type as signed)

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
Zephiles
Advanced Cheater
Reputation: 0

Joined: 04 Feb 2016
Posts: 56

PostPosted: Tue Nov 22, 2016 12:15 pm    Post subject: Bug? (Cannot display custom type as signed) Reply with quote

This specific custom type will not display as a signed value. It will always display as unsigned, regardless of whether I try to change it or not:
Code:

alloc(TypeName,256)
alloc(ByteSize,4)
alloc(ConvertRoutine,1024)
alloc(ConvertBackRoutine,1024)

TypeName:
db '2 Byte Big Endian',0

ByteSize:
dd 2

//The convert routine should hold a routine that converts the data to an integer (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:
//jmp dllname.functionname
[64-bit]
//or manual:
//parameters: (64-bit)
//rcx=address of input
xor eax,eax
mov ax,[rcx] //eax now contains the bytes 'input' pointed to
xchg ah,al //convert to big endian

ret
[/64-bit]

[32-bit]
//jmp dllname.functionname
//or manual:
//parameters: (32-bit)
push ebp
mov ebp,esp
//[ebp+8]=input
//example:
mov eax,[ebp+8] //place the address that contains the bytes into eax
mov ax,[eax] //place the bytes into eax so it's handled as a normal 4 byte value
and eax,ffff //cleanup
xchg ah,al //convert to big endian

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:
//jmp dllname.functionname
//or manual:
[64-bit]
//parameters: (64-bit)
//ecx=input
//rdx=address of output
//example:
xchg ch,cl //convert the little endian input into a big endian input
mov [rdx],cx //place the integer the 4 bytes pointed to by rdx

ret
[/64-bit]

[32-bit]
//parameters: (32-bit)
push ebp
mov ebp,esp
//[ebp+8]=input
//[ebp+c]=address of output
//example:
push eax
push ebx
mov eax,[ebp+8] //load the value into eax
mov ebx,[ebp+c] //load the address into ebx

//convert the value to big endian
xchg ah,al

mov [ebx],ax //write the value into the address
pop ebx
pop eax

pop ebp
ret 8
[/32-bit]

A similar custom type, however, works perfectly fine with displaying as signed:
Code:

alloc(TypeName,256)
alloc(ByteSize,4)
alloc(ConvertRoutine,1024)
alloc(ConvertBackRoutine,1024)

TypeName:
db '4 Byte Big Endian',0

ByteSize:
dd 4

//The convert routine should hold a routine that converts the data to an integer (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:
//jmp dllname.functionname
[64-bit]
//or manual:
//parameters: (64-bit)
//rcx=address of input
xor eax,eax
mov eax,[rcx] //eax now contains the bytes 'input' pointed to
bswap eax //convert to big endian

ret
[/64-bit]

[32-bit]
//jmp dllname.functionname
//or manual:
//parameters: (32-bit)
push ebp
mov ebp,esp
//[ebp+8]=input
//example:
mov eax,[ebp+8] //place the address that contains the bytes into eax
mov eax,[eax] //place the bytes into eax so it's handled as a normal 4 byte value

bswap eax

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:
//jmp dllname.functionname
//or manual:
[64-bit]
//parameters: (64-bit)
//ecx=input
//rdx=address of output
//example:
bswap ecx //convert the little endian input into a big endian input
mov [rdx],ecx //place the integer the 4 bytes pointed to by rdx

ret
[/64-bit]

[32-bit]
//parameters: (32-bit)
push ebp
mov ebp,esp
//[ebp+8]=input
//[ebp+c]=address of output
//example:
push eax
push ebx
mov eax,[ebp+8] //load the value into eax
mov ebx,[ebp+c] //load the address into ebx

//convert the value to big endian
bswap eax

mov [ebx],eax //write the value into the address
pop ebx
pop eax

pop ebp
ret 8
[/32-bit]

Is this caused by some sort of bug in Cheat Engine, or is something missing from the first custom type?
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

Joined: 09 May 2003
Posts: 25294
Location: The netherlands

PostPosted: Tue Nov 22, 2016 12:59 pm    Post subject: Reply with quote

For two byte big endian to have sign support you need to copy the value of bit15 to bit 16 to 31 (sign extend)
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
Zephiles
Advanced Cheater
Reputation: 0

Joined: 04 Feb 2016
Posts: 56

PostPosted: Tue Nov 22, 2016 1:10 pm    Post subject: Reply with quote

Dark Byte wrote:
For two byte big endian to have sign support you need to copy the value of bit15 to bit 16 to 31 (sign extend)

Could you help me with this? Because I don't know how to code that.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 458

Joined: 09 May 2003
Posts: 25294
Location: The netherlands

PostPosted: Tue Nov 22, 2016 1:20 pm    Post subject: Reply with quote

I can not test it right now, but replace
Code:

mov [rdx],cx

with
Code:

movsx [rdx],cx

_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
Zephiles
Advanced Cheater
Reputation: 0

Joined: 04 Feb 2016
Posts: 56

PostPosted: Tue Nov 22, 2016 2:17 pm    Post subject: Reply with quote

Dark Byte wrote:
I can not test it right now, but replace
Code:

mov [rdx],cx

with
Code:

movsx [rdx],cx

This gives me a message saying that the line can't be compiled.


Last edited by Zephiles on Tue Nov 22, 2016 2:19 pm; edited 1 time in total
Back to top
View user's profile Send private message
panraven
Grandmaster Cheater
Reputation: 55

Joined: 01 Oct 2008
Posts: 942

PostPosted: Tue Nov 22, 2016 2:19 pm    Post subject: Reply with quote

May be
Code:

xchg  ah,al
movsx eax,ax // added


bye~

_________________
- Retarded.
Back to top
View user's profile Send private message
Zephiles
Advanced Cheater
Reputation: 0

Joined: 04 Feb 2016
Posts: 56

PostPosted: Tue Nov 22, 2016 2:23 pm    Post subject: Reply with quote

panraven wrote:
May be
Code:

xchg  ah,al
movsx eax,ax // added


bye~

Alright this seems to be working correctly. Thanks for the help!

Edit: I just realized that this forces the number to be displayed as a signed value. Is there a way to make it so that it only displays as a signed value if this option is selected for the address?
Back to top
View user's profile Send private message
mgr.inz.Player
I post too much
Reputation: 218

Joined: 07 Nov 2008
Posts: 4438
Location: W kraju nad Wisla. UTC+01:00

PostPosted: Sun Nov 27, 2016 10:17 am    Post subject: Reply with quote

Just to clear things up.

CE setting "show values as if they are signed" applies to address list entries and found list entries. It is a global setting.

Memory records (address list entries), whatever numeric type, have additional ShowAsSigned property (which overrides global setting).


Just added memory record do not override global ShowAsSigned. Now I just added new 4bytes address (memory record), highlighted it, copied and pasted it here as XML:
Code:
<?xml version="1.0" encoding="utf-8"?>
<CheatTable>
  <CheatEntries>
    <CheatEntry>
      <ID>0</ID>
      <Description>"No description"</Description>
      <VariableType>4 Bytes</VariableType>
      <Address/>
    </CheatEntry>
  </CheatEntries>
</CheatTable>


Above was created with global ShowAsSigned unchecked. Below with global ShowAsSigned checked.
Code:
<?xml version="1.0" encoding="utf-8"?>
<CheatTable>
  <CheatEntries>
    <CheatEntry>
      <ID>0</ID>
      <Description>"No description"</Description>
      <VariableType>4 Bytes</VariableType>
      <Address/>
    </CheatEntry>
  </CheatEntries>
</CheatTable>


It is the same, whatever global ShowAsSigned is set or not.


But if we right-click memory record and select "show as signed". We override global settings.
From now on, this memory record will not respect global setting and we can not revert back this override.
If override is set, it will be set forever. Of course we can edit CT file and remove ShowAsSigned node. Or remove and add again.

If we override it to show as signed, XML code is (new node ShowAsSigned set to 1):
Code:
<?xml version="1.0" encoding="utf-8"?>
<CheatTable>
  <CheatEntries>
    <CheatEntry>
      <ID>0</ID>
      <Description>"No description"</Description>
      <ShowAsSigned>1</ShowAsSigned>
      <VariableType>4 Bytes</VariableType>
      <Address/>
    </CheatEntry>
  </CheatEntries>
</CheatTable>


If we override it to show as unsigned, XML code is (node ShowAsSigned set to 0):
Code:
<?xml version="1.0" encoding="utf-8"?>
<CheatTable>
  <CheatEntries>
    <CheatEntry>
      <ID>0</ID>
      <Description>"No description"</Description>
      <ShowAsSigned>0</ShowAsSigned>
      <VariableType>4 Bytes</VariableType>
      <Address/>
    </CheatEntry>
  </CheatEntries>
</CheatTable>





The problem is with this context menu:


In above menu we can not be 100% sure what checked "show as signed" really means.
Maybe:
- it shows that global setting "show as signed" is checked and overriding is not set
- it shows that global setting "show as signed" is checked and overriding is set to show as signed
- it shows that global setting "show as signed" is not checked and overriding is set to show as signed

The same with unchecked "show as signed".
Maybe:
- it shows that global setting "show as signed" is not checked and overriding is not set
- it shows that global setting "show as signed" is not checked and overriding is set to show as unsigned
- it shows that global setting "show as signed" is checked and overriding is set to show as unsigned

To check if overriding is set (for certain memory record), we have to play with global setting: uncheck global setting, rightclick memory record, check global setting, rightclick memory record. Or copy and paste to notepad.












Anyway, I found out that there is a bug, and custom types are always showed as signed.
I created fake type which has "mov eax,FFFFFF85"

So memory record with this type should show:
- this "-123" when overriding is set to show signed, or when overriding is not set and global show as signed is checked.
- this "4294967173" when overriding is set to show unsigned, or when overriding is not set and global show as signed is unchecked.

Here I sent my pull request (patch) to fix this:
https://github.com/cheat-engine/cheat-engine/pull/127

_________________
Back to top
View user's profile Send private message MSN Messenger
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