Get all vehicle from vehicle pool

0xNull

Member
Joined
Jul 14, 2018
Messages
24
Reaction score
0
Hello. I'm trying to understand how you can get a pointer to each element in the transport pool.

I climbed the sites, I found this:

0xB6F980 - Pointer to the beginning of the transport pool (CVehicle)

CVehicle
Each transport as an object is equal to 2584 (0xA18) bytes and starts with 0xC502AA0.

0xB74494 - Contains a pointer. This index:
+0 = Contains a pointer to the first element in the CVehicle pool
+4 = Contains a pointer to the byte map showing which elements are currently used in the CVehicle pool
+8 = [dword] the maximum number of items in the CVehicle pool
+12 = [dword] the current number of items in the CVehicle pool
I just realized (using 0xB74494 + 8) - that the maximum CVehicle can be 710.

How can I get a pointer to, for example, the 5th or 10th element (from 710) of this pool?

Type, 0xB6F980 + 5 / 0xB6F980 + 10?

Help, please, I do not know where to write any more
 

monday

Expert
Joined
Jun 23, 2014
Messages
1,125
Reaction score
149
hi, I'm not sure if this will work because I didn't test it but you could give it a try:
[shcode=cpp]DWORD gtaVehBase = *(DWORD*)0xB74494;
DWORD byteMap = *(DWORD*)(gtaVehBase+4);
DWORD numberOfMaxVehs = *(DWORD*)(gtaVehBase+8);
DWORD numberOfActiveVehs = *(DWORD*)(gtaVehBase+12);

for(int i = 0; i < numberOfMaxVehs; i++)
{
    BYTE inUse = *(BYTE*)(byteMap + i);
    if(inUse > 0x00 && 0x80 > inUse)
    {                                                                    
        DWORD pVehStruct = (*(DWORD*)gtaVehBase) + i * 0xA18;                                
        DWORD pVehCoords = *(DWORD*)(pVehStruct+ 20);
        float x = *(float*)(pVehCoords + 48);
        float y = *(float*)(pVehCoords + 52);
        float z = *(float*)(pVehCoords + 56);
    }
}[/shcode]
 

monday

Expert
Joined
Jun 23, 2014
Messages
1,125
Reaction score
149
could you post the full code if that's not a problem so I could test/adjust it quickly?
 

0xNull

Member
Joined
Jul 14, 2018
Messages
24
Reaction score
0
Yes, this is C# :D

public void GetAllVehiclePointers()
{

int gtaVehBase = 0xB74494;
int byteMap = mem.ReadInt(gtaVehBase + 4);
int numberOfMaxVehs = mem.ReadInt(gtaVehBase + 8);
int numberOfActiveVehs = mem.ReadInt(gtaVehBase + 12);

for (int i = 0; i < numberOfMaxVehs; i++)
{
byte inUse = mem.ReadByte(byteMap + i);
if (inUse > 0x00 && 0x80 > inUse)
{
int pVehStruct = mem.ReadInt(gtaVehBase + i * 0xA18);
int pVehCoords = mem.ReadInt(pVehStruct + 20);
float x = mem.ReadFloat(pVehCoords + 48);
float y = mem.ReadFloat(pVehCoords + 52);
float z = mem.ReadFloat(pVehCoords + 56);

String x_string = x.ToString();

String y_string = y.ToString();

String z_string = z.ToString();
if (x != 0)
Console.WriteLine("X: " + x.ToString() + " Y: " + y.ToString() + " Z: " + z.ToString());

}
}
}
 

monday

Expert
Joined
Jun 23, 2014
Messages
1,125
Reaction score
149
If that code is not injected into gta_sa process then it will read memory of the process that actually runs it...

You would have to adapt that code with functions like these from:
http://www.codingvision.net/security/c-read-write-another-process-memory
 

0xNull

Member
Joined
Jul 14, 2018
Messages
24
Reaction score
0
code already injected into gta_sa, in other code block


Other code, for example:

public bool SetEngineOn(){
int num = mem.ReadInt(12196092);
mem.WriteByte(num + 1064, 16);
return true;
}

is working :(
 

monday

Expert
Joined
Jun 23, 2014
Messages
1,125
Reaction score
149
then my code/method is wrong, I thought you'll post the whole thing so I can test it quickly though...
 

0xNull

Member
Joined
Jul 14, 2018
Messages
24
Reaction score
0
monday said:
hi, I'm not sure if this will work because I didn't test it but you could give it a try:
[shcode=cpp]DWORD gtaVehBase = *(DWORD*)0xB74494;
DWORD byteMap = *(DWORD*)(gtaVehBase+4);
DWORD numberOfMaxVehs = *(DWORD*)(gtaVehBase+8);
DWORD numberOfActiveVehs = *(DWORD*)(gtaVehBase+12);

for(int i = 0; i < numberOfMaxVehs; i++)
{
    BYTE inUse = *(BYTE*)byteMap + i;
    if(inUse > 0x00 && 0x80 > inUse)
    {                                                                    
        DWORD pVehStruct = (*(DWORD*)gtaVehBase) + i * 0xA18;                                
        DWORD pVehCoords = *(DWORD*)(pVehStruct+ 20);
        float x = *(float*)(pVehCoords + 48);
        float y = *(float*)(pVehCoords + 52);
        float z = *(float*)(pVehCoords + 56);
    }
}[/shcode]

monday said:
then my code/method is wrong, I thought you'll post the whole thing so I can test it quickly though...

One minute..
 

monday

Expert
Joined
Jun 23, 2014
Messages
1,125
Reaction score
149
btw this part:
BYTE inUse = *(BYTE*)byteMap + i;

supposed to be:
BYTE inUse = *(BYTE*)(byteMap + i);
 

0xNull

Member
Joined
Jul 14, 2018
Messages
24
Reaction score
0
monday said:
hi, I'm not sure if this will work because I didn't test it but you could give it a try:
[shcode=cpp]DWORD gtaVehBase = *(DWORD*)0xB74494;
DWORD byteMap = *(DWORD*)(gtaVehBase+4);
DWORD numberOfMaxVehs = *(DWORD*)(gtaVehBase+8);
DWORD numberOfActiveVehs = *(DWORD*)(gtaVehBase+12);

for(int i = 0; i < numberOfMaxVehs; i++)
{
    BYTE inUse = *(BYTE*)byteMap + i;
    if(inUse > 0x00 && 0x80 > inUse)
    {                                                                    
        DWORD pVehStruct = (*(DWORD*)gtaVehBase) + i * 0xA18;                                
        DWORD pVehCoords = *(DWORD*)(pVehStruct+ 20);
        float x = *(float*)(pVehCoords + 48);
        float y = *(float*)(pVehCoords + 52);
        float z = *(float*)(pVehCoords + 56);
    }
}[/shcode]

monday said:
btw this part:
BYTE inUse = *(BYTE*)byteMap + i;

supposed to be:
BYTE inUse = *(BYTE*)(byteMap + i);

i uploaded simple version of my project https://drive.google.com/open?id=1zyjQBOObHMe7mcVQ_pQl6oKO3mTSr__J
 

monday

Expert
Joined
Jun 23, 2014
Messages
1,125
Reaction score
149
DWORD pVehStruct = (*(DWORD*)gtaVehBase) + i * 0xA18;
!=
int pVehStruct = mem.ReadInt(gtaVehBase + i * 0xA18);


ting is working :foreveralone_hurra:
Code:
namespace GTAPointerTest
{
    public class main_class
    {
        private ProcessMemoryReader mem = ProcessMemoryReader.Initialize();

        public void main_void()
        {
            mem.AttachToProcess("gta_sa");

            int gtaVehBase = mem.ReadInt(0xB74494);
            int byteMap = mem.ReadInt(gtaVehBase + 4);
            int numberOfMaxVehs = mem.ReadInt(gtaVehBase + 8);
            int numberOfActiveVehs = mem.ReadInt(gtaVehBase + 12);

            Console.WriteLine(string.Format("gtaVehBase={0:d}\nbyteMap={1:d}\nnumberOfMaxVehs={2:d}\nnumberOfActiveVehs={3:d}", gtaVehBase, byteMap, numberOfMaxVehs, numberOfActiveVehs));
            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();

            while (true)
            {

                for (int i = 1; i < numberOfMaxVehs; i++)
                {
                    byte inUse = mem.ReadByte(byteMap + i);

                    if (inUse > 0x00 && 0x80 > inUse)
                    {
                        int pVehStruct = mem.ReadInt(gtaVehBase) + i * 0xA18;
                        //Console.WriteLine(string.Format("inUse={0:d}\ni={1:d}\npVehStruct={2:d}\nmem.ReadInt(gtaVehBase)={3:d}\ni * 0xA18={4:d}", inUse, i, pVehStruct, mem.ReadInt(gtaVehBase), i * 0xA18));

                        int pVehCoords = mem.ReadInt(pVehStruct + 20);

                        float x = mem.ReadFloat(pVehCoords + 48);
                        float y = mem.ReadFloat(pVehCoords + 52);
                        float z = mem.ReadFloat(pVehCoords + 56);

                        String x_string = x.ToString();

                        String y_string = y.ToString();

                        String z_string = z.ToString();
                        if (x != 0)
                        {
                            Console.WriteLine("X: " + x.ToString() + " Y: " + y.ToString() + " Z: " + z.ToString());

                        }

                    }

                }
            }
        }
    }
}


btw having in mind that there's over 700 of these maybe it would be a good idea to add check to see if the number of active cars was already found in bytemap and break/start-again the loop, to improve performance

like
if(isUsed > && < isUsed){
found++;
//do stuff
if (found >= numberOfActiveVehs){
break;
}
}
 

0xNull

Member
Joined
Jul 14, 2018
Messages
24
Reaction score
0
monday said:
hi, I'm not sure if this will work because I didn't test it but you could give it a try:
[shcode=cpp]DWORD gtaVehBase = *(DWORD*)0xB74494;
DWORD byteMap = *(DWORD*)(gtaVehBase+4);
DWORD numberOfMaxVehs = *(DWORD*)(gtaVehBase+8);
DWORD numberOfActiveVehs = *(DWORD*)(gtaVehBase+12);

for(int i = 0; i < numberOfMaxVehs; i++)
{
    BYTE inUse = *(BYTE*)byteMap + i;
    if(inUse > 0x00 && 0x80 > inUse)
    {                                                                    
        DWORD pVehStruct = (*(DWORD*)gtaVehBase) + i * 0xA18;                                
        DWORD pVehCoords = *(DWORD*)(pVehStruct+ 20);
        float x = *(float*)(pVehCoords + 48);
        float y = *(float*)(pVehCoords + 52);
        float z = *(float*)(pVehCoords + 56);
    }
}[/shcode]

monday said:
DWORD pVehStruct = (*(DWORD*)gtaVehBase) + i * 0xA18;
!=
int pVehStruct = mem.ReadInt(gtaVehBase + i * 0xA18);


ting is working :foreveralone_hurra:
Code:
namespace GTAPointerTest
{
    public class main_class
    {
        private ProcessMemoryReader mem = ProcessMemoryReader.Initialize();

        public void main_void()
        {
            mem.AttachToProcess("gta_sa");

            int gtaVehBase = mem.ReadInt(0xB74494);
            int byteMap = mem.ReadInt(gtaVehBase + 4);
            int numberOfMaxVehs = mem.ReadInt(gtaVehBase + 8);
            int numberOfActiveVehs = mem.ReadInt(gtaVehBase + 12);

            Console.WriteLine(string.Format("gtaVehBase={0:d}\nbyteMap={1:d}\nnumberOfMaxVehs={2:d}\nnumberOfActiveVehs={3:d}", gtaVehBase, byteMap, numberOfMaxVehs, numberOfActiveVehs));
            Console.WriteLine("Press any key to continue...");
            Console.ReadKey();

            while (true)
            {

                for (int i = 1; i < numberOfMaxVehs; i++)
                {
                    byte inUse = mem.ReadByte(byteMap + i);

                    if (inUse > 0x00 && 0x80 > inUse)
                    {
                        int pVehStruct = mem.ReadInt(gtaVehBase) + i * 0xA18;
                        //Console.WriteLine(string.Format("inUse={0:d}\ni={1:d}\npVehStruct={2:d}\nmem.ReadInt(gtaVehBase)={3:d}\ni * 0xA18={4:d}", inUse, i, pVehStruct, mem.ReadInt(gtaVehBase), i * 0xA18));

                        int pVehCoords = mem.ReadInt(pVehStruct + 20);

                        float x = mem.ReadFloat(pVehCoords + 48);
                        float y = mem.ReadFloat(pVehCoords + 52);
                        float z = mem.ReadFloat(pVehCoords + 56);

                        String x_string = x.ToString();

                        String y_string = y.ToString();

                        String z_string = z.ToString();
                        if (x != 0)
                        {
                            Console.WriteLine("X: " + x.ToString() + " Y: " + y.ToString() + " Z: " + z.ToString());

                        }

                    }

                }
            }
        }
    }
}


btw having in mind that there's over 700 of these maybe it would be a good idea to add check to see if the number of active cars was already found in bytemap and break/start-again the loop, to improve performance

like
if(isUsed > && < isUsed){
   found++;
   //do stuff
   if (found >= numberOfActiveVehs){
   break;
   }
}






It really works! Thank you very much, you helped me a lot!
 

monday

Expert
Joined
Jun 23, 2014
Messages
1,125
Reaction score
149
nice project though. Btw because the code in quotes is the one before I edited it, make sure to change the following line if anyone is going to use it:
BYTE inUse = *(BYTE*)byteMap + i;

It should be:
BYTE inUse = *(BYTE*)(byteMap + i);
 
Top