View previous topic :: View next topic |
Author |
Message |
lebara How do I cheat? Reputation: 0
Joined: 16 Jan 2020 Posts: 2
|
Posted: Thu Jan 16, 2020 1:14 pm Post subject: Value of type double not reading correctly? |
|
|
I'm having an issue with trying to use ReadProcessMemory in C++ to get the value of a value with the type double.
This value increases with 1 each second, but I can't get the value to show up correctly in my program.
Both CheatEngine and ReClass show the "correct" value for the double which I'm trying to read, e.g. 82.059770787135
But when I try to read this value I always get a huge number like:
4636002375915651072 or 4.636e+18 (this is the same value as for the type "8 Bytes" in CheatEngine. So I don't get a nice decimal number I can work with.
This value does increase each time, but not with the same margin, so
doing something like 4636002375915651072 - 4636002375915650988 (= 82) wouldn't work.
I can read any other address just fine, it's just this double that's giving me trouble.
Any tips on what I could be doing wrong?
Description: |
Image of the value in CE/RC |
|
Filesize: |
64.92 KB |
Viewed: |
1674 Time(s) |
|
|
|
Back to top |
|
|
DanyDollaro Master Cheater Reputation: 3
Joined: 01 Aug 2019 Posts: 334
|
Posted: Fri Jan 17, 2020 8:16 am Post subject: |
|
|
You're doing it right, the value 4636002375915651072 if read as double equals 89.5562.
You should be able to resolve by casting the value that is shown on the screen, an example [C++]:
Code: | #include <iostream>
int main()
{
double a;
*(__int64*)&a = 4636002375915651072;
// you can use this too:
// *reinterpret_cast<__int64*>(&a) = 4636002375915651072;
std::cout << a;
} |
(or changing the type of buffer you are using as a double)
|
|
Back to top |
|
|
ParkourPenguin I post too much Reputation: 138
Joined: 06 Jul 2014 Posts: 4275
|
Posted: Fri Jan 17, 2020 11:27 am Post subject: |
|
|
That's undefined behaviour in C++. You can get around that by disabling strict aliasing in the compiler options, but that would have other side effects. The "correct" way to do it would be to use memcpy (or bit_cast if using C++20):
Code: | #include <limits>
#include <cstdint>
#include <cstdio>
#include <cstring>
int main()
{
static_assert(std::numeric_limits<double>::is_iec559, "Not IEEE-754 compliant");
double a;
uint64_t b = 4636002375915651072;
std::memcpy(&a, &b, sizeof(a));
std::printf("64-bit: %.16llX\ndouble: %f\n", b, a);
return 0;
}
|
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
|
lebara How do I cheat? Reputation: 0
Joined: 16 Jan 2020 Posts: 2
|
Posted: Mon Jan 20, 2020 4:49 am Post subject: |
|
|
DanyDollaro wrote: | You're doing it right, the value 4636002375915651072 if read as double equals 89.5562.
You should be able to resolve by casting the value that is shown on the screen, an example [C++]:
Code: | #include <iostream>
int main()
{
double a;
*(__int64*)&a = 4636002375915651072;
// you can use this too:
// *reinterpret_cast<__int64*>(&a) = 4636002375915651072;
std::cout << a;
} |
(or changing the type of buffer you are using as a double) |
Yes, that worked, thank you!
|
|
Back to top |
|
|
mgr.inz.Player I post too much Reputation: 218
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Mon Jan 20, 2020 5:10 am Post subject: |
|
|
You can also use unions:
Code: | #include <stdio.h>
#include <string.h>
union buffer {
double d;
unsigned long long i;
};
int main( ) {
union buffer buf;
buf.i = 4636002375915651072ULL;
printf("%f\n",buf.d);
return 0;
} |
Code: | >usingunion.exe
89.556223 |
Or Pascal absolute keyword:
Code: | program Project1;
{$mode objfpc}{$H+}
uses SysUtils;
var
i: QWord;
d: double absolute i;
begin
i:=4636002375915651072;
WriteLn(Format('%g',[d]));
ReadLn;
end. |
Code: | >Project1.exe
89,556223468622193 |
_________________
|
|
Back to top |
|
|
DanyDollaro Master Cheater Reputation: 3
Joined: 01 Aug 2019 Posts: 334
|
Posted: Mon Jan 20, 2020 1:21 pm Post subject: |
|
|
Seeing the answer of mgr.inz.Player I got a better solution than the cast :
Code: | #include <iostream>
int main()
{
__int64 a = 4636002375915651072;
double& b = (double&)a; // Ok yes, I said "a better solution than the cast"
// but this cast will only have to be done once
std::cout << a << '\n' << b;
} |
consists in passing an int64 type variable via reference (&) to a double type variable (making a cast anyway), however in this case both the variable 'a' and 'b' point to the same address so you will not have to perform a cast each time to re-convert the value.
Another example:
Code: | #include <iostream>
int main()
{
__int64 a = 4636002375915651072;
double& b = (double&)a;
std::cout << "Integer Version (a): " << a << '\n' << "Double Version (b): " << b << "\n\n";
// Changing the value of variable a also
// changes the value of variable b
a = 10;
std::cout << b << std::endl;
a = 123;
std::cout << b << std::endl;
} |
(The method is very similar to that of the "union")
|
|
Back to top |
|
|
|