My "loop through memory" doesnt recognise value to find and it's very slow

Pages: 12
Yeah, thanks U both for clarification. Now when memcmp(p, &valToFind, sizeof(valToFind)) comparing bytes from p to valToFind there is a problem. My double is
theoretically equal double readed from memory, but in memory there's One byte diff (aob from game -> 00 00 00 33 33 73 51 40, valToFind aob -> 01 00 00 33 33 73 51 40) almost every time first byte isnt good

Is it good idea to check valToFind aob, and force this first byte to 00?
Last edited on
circle back to where someone explained that floating point is hard to compare.
you can skip that byte, rather than force zero...

memcmp( ((char*)p)+1, &((char*)valToFind)+1, sizeof(valToFind)-1)
check the +1s etc but roughly like that.
Is the actual address of found "double" value is p variable? What should I do to pass it into mem.write function? Isnt "address" sth like int?


memcmp( ((char*)p)+1, &((char*)valToFind)+1, sizeof(valToFind)-1)


Cannot case from type 'double' to pointer type 'char *'

So I did it like this:

char* xptr = (char*)(&valToFind);

if ( memcmp (((char *) p) +1, &xptr +1, sizeof (valToFind) -1) == 0 ) {

Is it good too?
And what address should I pass to mem.write function?
Last edited on
yea you got the idea, just have to cast whatever things to byte blocks (char *).

you should keep what you had for mem.write. It presumably writes the correct block over the old value. All the memcmp does is skip one byte, which you said was not matching. This may not be correct thing to do, but you can test the heck out of it to see if it works as you need it to.
Last edited on
mem.write(start, d_Y);

Isnt it write only start address / entire memory block? If I remember correctly I got crashed with this
what are you trying to write, and where? are you over-writing ONE double? Then the number of bytes you need to change are "sizeof(double)", and where is &variable or some pointer location etc that you got from where you found what to change. And what you change it to appears to be a constant. Look at what the .write() takes as parameters -- there may be a variety of overloads for it, with varying parameters -- and put those things into it so that it writes what you want where you want it. I looked but never found a 'memory' object so I don't know what the parameter options are... but it should be really simple once you check what you feed it.
Start no longer points to the value you want to change.
1
2
3
4
5
6
7
8
9
10
11
12
13
    valToFind = d_Y + playerHeight;
    len = end - start;
    for(start; start < end; start += oneMb){
        unsigned long bsize = len > oneMb ? oneMb : len;
        unsigned char *ptr = mem.getPointer(start,bsize);
        for ( offset = 0 ; offset < bsize ; offset += sizeof(double) ) {
            if ( memcmp(&ptr[offset], &valToFind, sizeof(valToFind)) == 0 ) {
                mem.write(start+offset, d_Y);
                std::cout << "Value found at: " << std::hex << "0x" << std::uppercase << (start+offset) << std::endl;
            }
       }
        delete [] ptr;
    }

^ I will check it

1
2
3
4
    template <typename T>
    void write(QWORD dwAddress, T value){
        WriteProcessMemory(hProcess, (LPVOID)dwAddress, &value, sizeof(T), 0);
    }


I want to replace found double values with choosen values (valToFind variable). So I have to write my double to address where the value is found.

write function need address. Is it possible to get address of wanted double from this memory block? (this address should be equal to double variable address in targeted program)

Like, find double valToFind variable and overwrite it with d_Y variable
Last edited on
Double recognision dont work, even with this flag. Address when this value is got found, Tried to do sth like this:

if ( memcmp (((char *) p) +1, &xptr +1, sizeof (valToFind) -1) == 0 ) {

and got sth like this:

if ( memcmp(&ptr[offset]+1, &valToFind+1, sizeof(valToFind)-1) == 0 ) {

but with this every address is falsely correct..


btw, when I said only first byte is incorrect, I checked it this way: calculated d_Y + playerHeight in Windows Calculator (got "identical" number), pasted it as value in address to find, and just checked it's bytes in "Browse this memory region" in CE.






Last edited on
> if ( memcmp(&ptr[offset]+1, &valToFind+1, sizeof(valToFind)-1) == 0 ) {
&valToFind+1 isn't the 2nd byte inside the variable valToFind, it's sizeof(valToFind) bytes away.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    valToFind = d_Y + playerHeight;
    unsigned char *valPtr = reinterpret_cast<unsigned char *>(&valToFind);
    len = end - start;
    for(start; start < end; start += oneMb){
        unsigned long bsize = len > oneMb ? oneMb : len;
        unsigned char *ptr = mem.getPointer(start,bsize);
        for ( offset = 0 ; offset < bsize ; offset += sizeof(double) ) {
            if ( memcmp(&ptr[offset]+1, valPtr+1, sizeof(valToFind)-1) == 0 ) {
                mem.write(start+offset, d_Y);
                std::cout << "Value found at: " << std::hex << "0x" << std::uppercase << (start+offset) << std::endl;
            }
       }
        delete [] ptr;
    }

Still it cant recognise value what I want to find :(

Maybe sth with this?
btw, when I said only first byte is incorrect, I checked it this way: calculated d_Y + playerHeight in Windows Calculator (got "identical" number), pasted it as value in address to find, and just checked it's bytes in "Browse this memory region" in CE.


Or how can I check (printable way) my calculated double aob?

byte* array = (byte*)&valToFind;

got weird char with this when tried to print it in any way
Last edited on
Perhaps you should post your actual latest code.

Posting random lines and "it doesn't work" isn't helping us figure out what you're doing wrong.
Oh wait, I was sleepy af when testing it, or it just didnt work (working now). I will test it few more times for sure.

Yeah, working now BUT, due to it's "inaccuracy" (probably cuz of this one byte?) got multiple values, and sometimes got crash (in target app). Which way will be better to improve accuracy of this? Fixing this one byte or save those addresses where value got found and rescan it (with changed value)? With this rescan I can do sth, but with this byte I need some help (^ post)



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <iostream>
#include <chrono>
#include <iomanip>
#include "memory.h"
#include <cstring>
#include <vector>
#include <fstream>
#include <cstdlib>
#include <stdlib.h>

Memory mem;

typedef uint64_t QWORD;


QWORD start = 0xC0000000; //0xD2000000
QWORD end = start + 0x26A85000; //0x26A85000;

const double playerHeight = 1.7999999523163;
double d_Y = 0;
double findValue = 0;
double valToFind = 0;

int main()
{

    std::cout << "Your height value? ";
    std::cin >> d_Y;

    auto t1 = std::chrono::high_resolution_clock::now();

    valToFind = d_Y + playerHeight;

    unsigned long len = end - start;
    unsigned long oneMb = 1024 * 1024;

    unsigned char *valPtr = reinterpret_cast<unsigned char *>(&valToFind);

    std::cout << std::hex << (static_cast<char*>(static_cast<void*>(&valToFind))) << std::endl;

    for(start; start < end; start += oneMb){
        unsigned long bsize = len > oneMb ? oneMb : len;
        unsigned char *ptr = mem.getPointer(start,bsize);
        for ( int offset = 0 ; offset < bsize ; offset += sizeof(double) ) {
            //if(start+offset == 0xDDFB28D8) std::cout << "GOT ADDRESS, NO VALUE YET" << std::endl;
            if ( memcmp(&ptr[offset]+1, valPtr+1, sizeof(valToFind)-1) == 0 ) {
                mem.write(start+offset, d_Y);
                std::cout << "Value found at: " << std::hex << "0x" << std::uppercase << (start+offset) << std::endl;
            }
       }
        delete [] ptr;
    }
    auto t2 = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::seconds>( t2 - t1 ).count();
    std::cout << std::endl << std::dec << duration;

    std::getchar();
    std::getchar();
    return 0;
}


1
2
3
4
5
6
unsigned char* Memory::getPointer(QWORD address, long Value)
{
    unsigned char *buff = new unsigned char[1024*1024];
    ReadProcessMemory(hProcess, (LPVOID)address, buff,Value,0);
    return buff;
}
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
    for(start; start < end; start += oneMb){
        unsigned long bsize = len > oneMb ? oneMb : len;
        unsigned char *ptr = mem.getPointer(start,bsize);
        for ( int offset = 0 ; offset < bsize ; offset += sizeof(double) ) {
            //if(start+offset == 0xDDFB28D8) std::cout << "GOT ADDRESS, NO VALUE YET" << std::endl;
            double *d = reinterpret_cast<double*>(&ptr[offset]);
            if ( closeEnough(*d,valToFind) ) {
                mem.write(start+offset, d_Y);
                std::cout << "Value found at: " << std::hex << "0x" << std::uppercase << (start+offset) << std::endl;
            }
       }
        delete [] ptr;
    }

    
// return true if target is within some tolerance of the reference
// http://c-faq.com/fp/fpequal.html
bool closeEnough(double target, double reference) {
  double lowerBound = reference - reference / 10;  // might need attention for negative values.
  double upperBound = reference + reference / 10;
  // remove differences that are out of the ball park
  if ( target < lowerBound || target > upperBound )
    return false;
  // both are similar, but read the FAQ
  // If you start looking for numbers massively different to 
  // 1e0 to 1E3, then the tolerance will need attention
  return fabs(target - reference) < 0.001;
}

Thank you for activity in entire post,

return fabs(target - reference) < 0.0000001;

with this tolerance no crash and probably best time (~7seconds).

I will mark it as solved in one day, maybe someone have an idea how to speed it up little bit more :D

I have lost track of what this is about entirely or where you are with it.
the only thing doing ANYTHING that costs you cycles is that get pointer and delete pair in the loop. IF there is some way to factor that out of the loop, then it would go faster. If there is not, its about as good as it gets: the rest of it is simple math. Or if you can rework the loops so the inner one does a larger chunk each time, so that you have less memory management calls.. eg change onemb to 10mb or whatever it would have some effect I believe.

a long time ago on older compilers I was able to beat fabs() with a cast to integer and & the bit. I don't know if that would be worthwhile or not. Its not portable across endians and its one of those awkward things you should not have to do anymore. This would not even be a real blip: its not where the time is being spent.

apart from that, you can kick off a group of the inner loops as threads for each outer loop, (or can you? Again, I have lost track of what you needed and am just looking at the last code posted up) depending on how many cores your CPU has. That would give you as much as 4 times faster if you can do it.

Oh: one more.
val to find is fixed, right? Then 19 and 20 should be static doubles. That would prevent you re-running the code on a different val to find, but it would cut some time.
if you don't want to do that, 19 and 20 look like 10% to me. would *1.1 and *.9 be better?
22-27 can probably be combined to a meta return statement with no condition, but I dunno if it would be faster, you can try it.

TLDR: can you thread it?
Last edited on
Topic archived. No new replies allowed.
Pages: 12