Coding

 Reply to this postStart new topic

memory things

badboy
post Jun 8 2012, 05:50 PM
Post #1


Trained Member

Posts: 76
From: Nederland, NL
Joined: 1-May 12



As you might have noticed I am trying to learn some things about memory. And I have some questions:

In the get all actors example, the actors are just numbers. Are they? And if so, what are cars for kind of number?

And let's say I am creating an actor outside a thread, in a dll. If I create a ped, is it just an int? Will there be any conflicts with other peds? How is it done in viligant justice, as pure memory or is it a directly injected script?

And my final question, 0xB6F5F0 is the player pointer, what about other peds how to get their struct (without cleo)? And there was a link to the source code of an old version of cleo, does anyone have it?
Go to the top of the page
 
+Quote Post
Deji
post Jun 9 2012, 12:20 AM
Post #2


Coding like a Rockstar!

Group Icon

Posts: 1,468
From: ???
Joined: 28-May 09



CLEO source: http://sannybuilder.com/dev/cleo.txt

Everything in a computer is numbers. The values in vara are always numbers, even ped handles. No exception to the rule. Knowing that, we could just go through every number that possible with 4 bytes and we wouldn't just end up having every ped handle possible, but every other kind of handle, every possible float, every penguin... But of course going through all those numbers will take a lot of processing time.

On a more helpful note, the handles for peds, vehicles and objects are actually the address with some math applied. But as I said before, I dont have IDA and my memory would make a really bad IDB. I think the address is simply bit shifted 8 bits I think. It makes the number smaller by losing some of the bits. But doesnt lose so much that there is risk of collision. You should be able to find the function that makes this conversion in the IDB. Opcodes that use handles convert it the other way. CLEO uses that func to get the address of entities.

And if you create a ped in a dll... Well, you dont create a ped. There is no C++ command to create a ped tongue.gif Sarcasm aside peds in SA are the visual representation of data (yeah, yeah im getting to it...). Ped creation is simply creating a class (aka struct called CPed... Its a standard for class names to begin with C). You already know what structs are (my fone battery is on 6% and im rambling, grr). After creating the CPed class we get a pointer to it which we then use as a reference to the ped. Yes, just a number, but an important one smile.gif


--------------------
Go to the top of the page
 
+Quote Post
badboy
post Jun 10 2012, 11:52 AM
Post #3


Trained Member

Posts: 76
From: Nederland, NL
Joined: 1-May 12



About the numbers of peds, I see some similarities:
CODE
Hex:
01 00
01 03
01 04
01 05
01 06
01 07
01 08
01 09
01 0A
02 0D
01 12

Output:
1
769
1025
1281
1537
1793
2049
2305
2561
3330
4609


[quote]You should be able to find the function that makes this conversion in the IDB.[/qoute]
How to find functions?

I've created a script to convert the handling of a car into a boat when it hits the water. But I don't know what the size is of the addresses, 4 crashed the game and 8 didn't work. The game doesn't crash but starts a new regular game (maybe I've hit something intresting?). What values should I use?

EDIT:
No more page stretching

This post has been edited by badboy: Jun 12 2012, 02:43 PM
Go to the top of the page
 
+Quote Post
Deji
post Jun 10 2012, 01:08 PM
Post #4


Coding like a Rockstar!

Group Icon

Posts: 1,468
From: ???
Joined: 28-May 09



Floats are 4 bytes.

Press Ctrl+L in IDA to open up the functions window and Alt+T to start a search. Enter "atHandle" and you should find the function.


--------------------
Go to the top of the page
 
+Quote Post
badboy
post Jun 12 2012, 01:31 PM
Post #5


Trained Member

Posts: 76
From: Nederland, NL
Joined: 1-May 12



Doesn't exist, and after looking over link2012's post: can I download a good version of SA idb somewhere?
Go to the top of the page
 
+Quote Post
Albreht
post Jun 12 2012, 01:34 PM
Post #6


Trained Newbie

Posts: 21
Joined: 19-February 12



CODE
TransmissionData_nDriveType  - Front  = 70, Rear   = 82, 4WD      = 52
TransmissionData_nEngineType - Petrol = 80, Diesel = 68, Electric = 69


and this is my script.
i hope this would help smile.gif

CODE
03C0: 0@ = actor $PLAYER_ACTOR car
0A97: 31@ = car 0@ struct
31@ += 0x384
//fMass
0A8D: 30@ = read_memory 31@ size 4 virtual_protect 0
30@ += 0x4
0A8C: write_memory 30@ size 4 value 1700.0 virtual_protect 0
Go to the top of the page
 
+Quote Post
LINK/2012
post Jun 12 2012, 02:26 PM
Post #7


I will kill you

Posts: 126
Joined: 13-May 11



QUOTE (badboy @ Jun 12 2012, 10:31 AM) *
Doesn't exist, and after looking over link2012's post: can I download a good version of SA idb somewhere?

http://public.sannybuilder.com/gtasa_exe_idb/
Here you have a III and SA idb, good to start your work.

(I think you already have this?)


This post has been edited by LINK2012: Jun 12 2012, 02:26 PM
Go to the top of the page
 
+Quote Post
Deji
post Jun 12 2012, 06:45 PM
Post #8


Coding like a Rockstar!

Group Icon

Posts: 1,468
From: ???
Joined: 28-May 09



Use the 'Last modified' link to get the latest version.


--------------------
Go to the top of the page
 
+Quote Post
badboy
post Jun 12 2012, 07:02 PM
Post #9


Trained Member

Posts: 76
From: Nederland, NL
Joined: 1-May 12



Thanks, I found it now biggrin.gif
Go to the top of the page
 
+Quote Post
badboy
post Jun 18 2012, 07:53 PM
Post #10


Trained Member

Posts: 76
From: Nederland, NL
Joined: 1-May 12



I'm trying to make a small asi file and I want to know if this will work. And I've got some questions. Is "CPed +0x46F" BYTE, WORD or DWORD? My code is wrong if it's not DWORD.

CODE
// DWORD * CPed = (DWORD*)0xB6F5F0;

bool IsStanding(DWORD * CPed)
{
    CPed += 0x46F;

    if (*CPed == 128)
        return true;
    else
        return false;
}


Would this work (as a check), and what is CPed for the player? Is it 0xB6F5F0 or 0xB7CD98. And how come the memory addresses are always the same. Shouldn't they be different on each runtime?
Go to the top of the page
 
+Quote Post
Wesser
post Jun 18 2012, 09:16 PM
Post #11


The Assistant

Posts: 84
From: Matera, IT
Joined: 16-June 11



CPed + 0x46C is a 4-byte flag. To check if the player is in stand position, do (untested):

CODE
bool IsPedStanding = (*(unsigned int *)(CPed + 0x46C) & 0x80000000) != 0;

0xB6F5F0 points to a CCamera member which contains a direct pointer to player's CPed. 0xB7CD98 is a array of 2 CPlayer, whose first member contains a direct pointer to player's CPed, use this instead. Note that I said these static memory addresses contain a dynamic pointer, the needed one.

This post has been edited by Wesser: Jun 19 2012, 04:55 PM
Go to the top of the page
 
+Quote Post
LINK/2012
post Jun 21 2012, 05:13 PM
Post #12


I will kill you

Posts: 126
Joined: 13-May 11



This will not work properly because a DWORD pointer + 1 is equal to moving the pointer 4 bytes ahead.
Pointer += 10 is basically Pointer += sizeof(*Pointer) * 10

What you can do is cast it to a byte during the addition.

Properly function
CODE
bool IsStanding(DWORD* CPed)
{
    (BYTE*)CPed += 0x46F; // Now moved right 0x46F ahead.
    return (*CPed & 0x80000000) != 0;
}


Properly Wesser's version:
CODE
bool IsPedStanding = (*(unsigned int *)((BYTE*)CPed + 0x46C) & 0x80000000) != 0;


This post has been edited by LINK2012: Jun 21 2012, 05:14 PM
Go to the top of the page
 
+Quote Post
Wesser
post Jun 22 2012, 03:35 PM
Post #13


The Assistant

Posts: 84
From: Matera, IT
Joined: 16-June 11



I was uncertain when posting but Visual Studio's ASM listing gave the same answer. wink.gif
Go to the top of the page
 
+Quote Post
badboy
post Jun 24 2012, 01:06 PM
Post #14


Trained Member

Posts: 76
From: Nederland, NL
Joined: 1-May 12



Thanks for all the help. I can't test if it works because I haven't finished my code. Anyway, I want to keep running my code. And I need to hook a function (or is there another way?). I've searched but I can only find function hooks which use Detours 1.5, but that one is outdated and visual studio keeps giving me error's when compiling. Later versions of detours don't have the function that I need to use. Does anyone have an example of a hook, or know relatively easy articles about it?
Go to the top of the page
 
+Quote Post
LINK/2012
post Jun 24 2012, 09:05 PM
Post #15


I will kill you

Posts: 126
Joined: 13-May 11



Are you trying to hook a function from a attached dll or a fully separated process?

What you should do is unprotect the memory region, insert a jmp or call to the hook in the region to hook, and then restore the old region protection.
If is not clear yet, you can take a look at the source of: http://www.gtaforums.com/index.php?showtopic=514465
Is a very simple code, very easy to understand. (Note that I did the hooks code entirely in ASM, but it's is not necessary, is relative);

Don't know if is the samething for separated process because GTA acessing other process memory will cause a exception, right?

This post has been edited by LINK2012: Jun 24 2012, 09:24 PM
Go to the top of the page
 
+Quote Post
Deji
post Jun 25 2012, 06:47 PM
Post #16


Coding like a Rockstar!

Group Icon

Posts: 1,468
From: ???
Joined: 28-May 09



In IDA, you will find calls like this:
CODE
call sub_421000


The call bytecode is E8, and the function address will be 0x421000. Thid means the assembled code looks like this in hex:
CODE
E8 00 10 42 00


So if we get the address of the start of the call function, we just have to add 1 byte to the address and we have a pointer to the function address, 0x421000. All we have to do is unprotect those 4 bytes, write our own function address and call the function address we wrote over in our function. Protecting again is entirely optional.


--------------------
Go to the top of the page
 
+Quote Post
badboy
post Jun 26 2012, 11:19 AM
Post #17


Trained Member

Posts: 76
From: Nederland, NL
Joined: 1-May 12



I've tried this:
I need my hook te be executed at every new frame, so I chose _RpWorldRender (0x74F570) is this a good function to hook? Next thing I unprotected the memory. Using this address "void* pAddress = (void*)_RpWorldRender;". How to add 1 to this? Do I need to add one here already? And now I'm stuck at the next part. Do I need to replace it with a jump to my function (+1?) and the rest just 0's? And at the end of my function I need to insert my code and then the rest of the original function?


This post has been edited by badboy: Jun 27 2012, 06:15 PM
Go to the top of the page
 
+Quote Post
badboy
post Jun 27 2012, 08:23 PM
Post #18


Trained Member

Posts: 76
From: Nederland, NL
Joined: 1-May 12



Deleted (again)

This post has been edited by badboy: Jul 2 2012, 04:25 PM
Go to the top of the page
 
+Quote Post
badboy
post Jul 2 2012, 04:45 PM
Post #19


Trained Member

Posts: 76
From: Nederland, NL
Joined: 1-May 12



Here is my latest attempt (triple post yeey), I've came to the conclusion that I was wrong again. I wanted to replace the whole func, but as you told me that's not what I should have done. Anyway I did things the easy way this time and copy paste link2012 code (the hook thing). Everything went fine, but when I start the game (when finished loading) I got a game crash. It's not that I really modded any thing, I just replaced a call with a call to my hook and in my hook I placed a call to the original func. And now I'm 100% sure that the call is the problem. Can anyone help me out?

Code (shorter is better I suppose):
CODE
#include "stdafx.h"
#include "Hooks.h"
#include "Injector.h"

void* getPlayerCoords;

DEFINE_HOOKER( hook )
{
    ASM
    {
        call getPlayerCoords
    }
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        getPlayerCoords = (void*)0x0056E010;
        MAKE_CALL(0x00423F26, &hook);
        break;
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}


I've also edited LINK2012's code a bit, I added a call func (maybe that's where everything went wrong?).
@LINK2012 I hope you don't mind me posting your code, just say it and I'll remove it.

Injector.h
CODE
extern void WriteMemory(void* Address, void* value, size_t size, bool vp = false);

extern BYTE jmp_Jz;
extern BYTE call; // Mine
extern WORD ja_Jz;

#define MEM_ADDRESS(mem) (void*)(mem)

#define MAKE_JMP(at, dest)    {\
    WriteMemory(MEM_ADDRESS(at), &jmp_Jz, 1u, true);\
    WriteMemory(MEM_ADDRESS(at+1), (DWORD)((BYTE*)dest - (at+1+4)), true);\
                            }
// Mine
#define MAKE_CALL(at, dest)
    WriteMemory(MEM_ADDRESS(at), &call, 1u, true);\
    WriteMemory(MEM_ADDRESS(at+1), (DWORD)((BYTE*)dest - (at+1+4)), true);\
                            }

#define MAKE_JA(at, dest)    {\
    WriteMemory(MEM_ADDRESS(at), &ja_Jz, 2u, true);\
    WriteMemory(MEM_ADDRESS(at+2), (DWORD)((BYTE*)dest - (at+2+4)), true);\
                            }

inline void UnprotectMemory(void* Address, int size, DWORD* oldProtect)
{
    if(!VirtualProtect(Address, size, PAGE_EXECUTE_READWRITE, oldProtect)) MessageBoxA(NULL, "FAIL1", "FAIL1", NULL);
}

inline void ProtectMemory(void* Address, int size, DWORD Protect)
{
    DWORD buf;
    if(!VirtualProtect(Address, size, Protect, &buf)) MessageBoxA(NULL, "FAIL1", "FAIL1", NULL);
}

inline void WriteMemory(void* Address, DWORD value, bool vp)
{
    WriteMemory(Address, &value, 4, vp);
}


injector.ccp
CODE
#include "stdafx.h"
#include "Injector.h"

BYTE jmp_Jz = 0xE9;
BYTE call = 0xE8; // Mine
WORD ja_Jz  = 0x870F;


void WriteMemory(void* Address, void* value, size_t size, bool vp)
{
    DWORD oldProtect;
    if(vp) UnprotectMemory(Address, size, &oldProtect);

    memcpy(Address, value, size);

    if(vp) VirtualProtect(Address, size, oldProtect, &oldProtect);
}
Go to the top of the page
 
+Quote Post
LINK/2012
post Jul 2 2012, 05:19 PM
Post #20


I will kill you

Posts: 126
Joined: 13-May 11



The MAKE_CALL macro is fine, is not the problem, the problem is the second call...

The original call:
CODE
push    0FFFFFFFFh    ; playerIndex
push    ecx        ; outPoint
call    _getPlayerCoords


The problem is, when you do a call another thing goes to the stack, that is the current ip, so the ret know where it must go...

_getPlayerCoords expects that the stack is as follow when called:
CODE
[esp+0] = return code pointer (pushed by the CALL instruction in 0x423F26)
[esp+4] = pointer to a RwV3D struct to return the results
[esp+8] = player index


But, in your call to _getPlayerCoords, the stack will be like this:
CODE
[esp+0] = return code pointer (pushed by the CALL instruction in your hook)
[esp+4] = return code pointer (pushed by the CALL instruction in 0x423F26)
[esp+8] = pointer to a RwV3D struct to return the results
[esp+12] = player index


Now you can see what's wrong right?
To fix the problem, you can use a jmp instead of a call in your hook, jmps don't push anything.


CODE
DEFINE_HOOKER( hook )
{
    ASM
    {
        mov eax, 0x56E010 //
        jmp eax           // absolute jump, so we don't have to do calculations of relative address...
    }
}


Another way to do a absolute jmp
CODE
DEFINE_HOOKER( hook )
{
    ASM
    {
        push 0x56E010
        ret
    }
}


Yes, we pushed a new return point to the return instruction laugh.gif


QUOTE
@LINK2012 I hope you don't mind me posting your code, just say it and I'll remove it.

No problem.

This post has been edited by LINK2012: Jul 2 2012, 05:19 PM
Go to the top of the page
 
+Quote Post
Reply to this postStart new topic

2 User(s) are reading this topic (2 Guests and 0 Anonymous Users)
0 Members: