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 


How to find the memory adderss of an array

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking
View previous topic :: View next topic  
Author Message
5tapl3r
Newbie cheater
Reputation: 0

Joined: 31 Dec 2013
Posts: 15

PostPosted: Thu Jan 02, 2014 12:49 pm    Post subject: How to find the memory adderss of an array Reply with quote

Hi everyone, I made a very simple program in order to test something:

Code:

#include <iostream>
#include <windows.h>
#include <vector>

using namespace std;

int main()
{
    vector<int> test;
    test.push_back(1);
    test.push_back(1);
    test.push_back(2);
    test.push_back(3);
    test.push_back(5);
    test.push_back(8);
    test.push_back(13);
    test.push_back(21);
    test.push_back(34);
    test.push_back(55);
    test.push_back(89);
    test.push_back(144);
    test.push_back(233);
    test.push_back(377);
    test.push_back(610);
    test.push_back(987);
    int i = 16;
    while(1)
    {
        test.push_back(test[i-2] + test[i-1]);
        for (int j = 0; j < i; j++)
        {
            cout << test[j] << "\n";
        }
        i++;
        cout << "********************" << "\n\n\n";
        Sleep(3000);
    }
    return 0;
}


As you can see, the vector "test" updates every 3 seconds. Since "test" is never the same size, it is futile to look for the memory address of each value. What I'm looking for is the memory address of "test" so that I can get my other program to ReadProcessMemory( test_address ); and get all the values in the vector, even when it updates itself.

Is it possible?
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Thu Jan 02, 2014 2:25 pm    Post subject: Reply with quote

Yes, it is possible to get the address.
For your specific example here is something you can do via debugging:

  1. Compile the given code into an application.
  2. Open the application in a debugger such as Cheat Engine or OllyDbg


In this case, I am using OllyDbg and I compiled the application in release mode to get rid of the debugging checks and such.

We land up at the OEP here:
Code:

011227B9 > $ E8 43040000    CALL ConsoleA.__security_init_cookie <-- OEP
011227BE   .^E9 91FEFFFF    JMP ConsoleA.__tmainCRTStartup


Given that this is a C++ application (we can tell based on __tmainCRTStartup) we look for a call to exit.

In OllyDbg you do this by right-clicking in the CPU window and choosing 'Search For -> Name (label) in Current Model'.

In the new window locate:
MSVCR120.exit

The name of the owning module will differ based on your compiler version and so on.

Right-click this, choose 'Find references to import'.
Select the first one from the list.

Next, scroll up and locate the first call before the call to exit. This will be the true entry point of the application:
Code:

0112273A   . FF35 FC401201  PUSH DWORD PTR DS:[envp]
01122740   . FF35 F8401201  PUSH DWORD PTR DS:[argv]
01122746   . FF35 F4401201  PUSH DWORD PTR DS:[argc]
0112274C   . E8 4FEBFFFF    CALL ConsoleA.main               <- Our application entry.
01122751   . 83C4 0C        ADD ESP,0xC
01122754   . A3 EC401201    MOV DWORD PTR DS:[mainret],EAX
01122759   . 833D F0401201 >CMP DWORD PTR DS:[managedapp],0x0
01122760   . 75 36          JNZ SHORT ConsoleA.01122798
01122762   . 50             PUSH EAX                                 ; /status
01122763   . FF15 74301201  CALL DWORD PTR DS:[<&MSVCR120.exit>]     ; \exit


Double click the call to follow into its code. Now we can see the actual applications code that we made:
Code:
011212A0 > $ 55             PUSH EBP
011212A1   . 8BEC           MOV EBP,ESP
011212A3   . 83E4 F8        AND ESP,0xFFFFFFF8
011212A6   . 6A FF          PUSH -0x1
011212A8   . 68 682D1201    PUSH ConsoleA.01122D68
011212AD   . 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
011212B3   . 50             PUSH EAX
011212B4   . 83EC 68        SUB ESP,0x68
011212B7   . A1 00401201    MOV EAX,DWORD PTR DS:[__security_cookie]
011212BC   . 33C4           XOR EAX,ESP
011212BE   . 894424 60      MOV DWORD PTR SS:[ESP+0x60],EAX
011212C2   . 53             PUSH EBX
011212C3   . 56             PUSH ESI
011212C4   . 57             PUSH EDI
011212C5   . A1 00401201    MOV EAX,DWORD PTR DS:[__security_cookie]
011212CA   . 33C4           XOR EAX,ESP
011212CC   . 50             PUSH EAX
011212CD   . 8D4424 78      LEA EAX,DWORD PTR SS:[ESP+0x78]
011212D1   . 64:A3 00000000 MOV DWORD PTR FS:[0],EAX
011212D7   . 0F57C0         XORPS XMM0,XMM0
011212DA   . C74424 6C 0000>MOV DWORD PTR SS:[ESP+0x6C],0x0
011212E2     66             DB 66                                                                    ;  CHAR 'f'
011212E3     0F             DB 0F
011212E4   . D6             SALC
011212E5   . 44             INC ESP
011212E6   . 24 64          AND AL,0x64
011212E8   . C74424 64 0000>MOV DWORD PTR SS:[ESP+0x64],0x0
011212F0   . C74424 68 0000>MOV DWORD PTR SS:[ESP+0x68],0x0
011212F8   . C74424 6C 0000>MOV DWORD PTR SS:[ESP+0x6C],0x0
01121300   . 51             PUSH ECX
01121301   . 8D4C24 68      LEA ECX,DWORD PTR SS:[ESP+0x68]
01121305   . C78424 8400000>MOV DWORD PTR SS:[ESP+0x84],0x0
01121310   . E8 FB090000    CALL ConsoleA.std::vector<int,std::allocator<int> >::_Reserve


This chunk contains the initialization of the vector. Each reserve call is for the number you gave in the code:
Code:
test.push_back(1);


You will see lines before each call too like this:
Code:

011213B3   . C74424 54 0200>MOV DWORD PTR SS:[ESP+0x54],0x2

0112142C   . C74424 28 0300>MOV DWORD PTR SS:[ESP+0x28],0x3

011214A5   . C74424 48 0500>MOV DWORD PTR SS:[ESP+0x48],0x5

0112151E   . C74424 30 0800>MOV DWORD PTR SS:[ESP+0x30],0x8


Which are the numbers you asked to initialize the vector with.

The calls with:
Code:
0011138C   . 51             PUSH ECX
0011138D   . 8D4C24 68      LEA ECX,DWORD PTR SS:[ESP+0x68]
00111391   . E8 7A090000    CALL ConsoleA.std::vector<int,std::allocator<int> >::_Reserve


ECX after the LEA is what holds the base pointer of the vector object.

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
5tapl3r
Newbie cheater
Reputation: 0

Joined: 31 Dec 2013
Posts: 15

PostPosted: Thu Jan 02, 2014 3:23 pm    Post subject: Reply with quote

Thank you for the answer, I wish I knew enough to make a better use of it...
So I downloaded OllyDbg to follow what you did step-by-step, but I quickly got stuck at the OEP part. I guess OEP stands for original entry point? I don't really know where I'm supposed to find these lines:

Code:
011227B9 > $ E8 43040000    CALL ConsoleA.__security_init_cookie <-- OEP
 011227BE   .^E9 91FEFFFF    JMP ConsoleA.__tmainCRTStartup


Given that I'm stuck so early in your explanation, I'm not sure I would even understand the rest of what you did.

Is it possible to do what I'm trying to do in Cheat engine only? Do you have any other suggestions? I feel really bad since I realize your explanation was great, but I just suck too much to understand it Sad
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 205

Joined: 25 Jan 2006
Posts: 8587
Location: 127.0.0.1

PostPosted: Fri Jan 03, 2014 12:50 am    Post subject: Reply with quote

You are on the right track.

Just keep following my post. Where you landed when the application is first started in OllyDBG is called the OEP (original entry point). Granted it is not always the correct OEP if the file is packed, protected, or similar. (Olly can also hit a breakpoint earlier before the OEP, hit an exception, or similar causing it to land somewhere invalid first too.)

You can do some of this with Cheat Engine but its a bit more work and more involved.

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
justa_dude
Grandmaster Cheater
Reputation: 23

Joined: 29 Jun 2010
Posts: 893

PostPosted: Fri Jan 03, 2014 2:22 am    Post subject: Re: How to find the memory adderss of an array Reply with quote

5tapl3r wrote:
Since "test" is never the same size, it is futile to look for the memory address of each value.

It's been many years since I've gone deep on the STL, but most implementations I've seen just double the size of the internal array when the vector reaches capacity. So, you don't have to get very far into your sequence before the memory becomes relatively stable.

5tapl3r wrote:
What I'm looking for is the memory address of "test" so that I can get my other program to ReadProcessMemory( test_address ); and get all the values in the vector, even when it updates itself.

Is it possible?


Try doing an aob search for the values. You should be able to get the vector's internal array pretty easily, though again you'll perhaps have to refresh your address periodically as the vector grows in size. Just remember that the numbers are all going to be stored little endian.
Back to top
View user's profile Send private message
5tapl3r
Newbie cheater
Reputation: 0

Joined: 31 Dec 2013
Posts: 15

PostPosted: Fri Jan 03, 2014 10:16 am    Post subject: Reply with quote

I've never done any array of byte search and I'm not sure what I should write in the search box.

The vector should look like this at first:

test = [1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987]

then after 3 seconds:

test = [1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597]

another 3 seconds:

test = [1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584]

etc...

So I have plenty of known values to look for, I just don't know how to do array of byte search and there doesn't seem to be any tutorial...
Back to top
View user's profile Send private message
justa_dude
Grandmaster Cheater
Reputation: 23

Joined: 29 Jun 2010
Posts: 893

PostPosted: Fri Jan 03, 2014 7:12 pm    Post subject: Reply with quote

5tapl3r wrote:
I've never done any array of byte search and I'm not sure what I should write in the search box.

Assuming your C compiler uses 4-byte ints, you probably want to search for something like "01 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00" etc. Again, just remember that everything is little endian, so e.g. 987 = 0x3db = db 03 00 00, and that you may have to refresh your search periodically as the array grows (although I wouldn't be shocked if the first capacity increase doesn't happen until you have 1k or so elements).

Helpfile included with Cheat Engine (help-> CE Help wrote:
Array of byte
Same as text, but uses a array of byte instead of characters, and supports wildcards.
input:
xx xx xx xx ...
xx ?? xx xx
xx ** xx xx

An array of byte (AoB) scan can be useful when you know that prior to the address you need is always a specific occurrence of bytes. (like: 66 66 66 10 10, and 4 bytes after that is your health which is stored as 1 byte. Scanning for 1 byte will take a lot longer than scanning for this string of bytes. Scanning for this string will probably only result 1 address, where as scanning for 1 byte will return thousands of addresses the first time)
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking 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