简体   繁体   中英

C++ - What do these lines of code mean?

I'm looking at some source code and don't understand what is going on. Here is some code I've put together from that source code (definitions came from all over the place and I've included only what's necessary):

#define TOC 0x1C75288

typedef unsigned int uint32_t;
typedef unsigned int uint;

struct opd_s
{
    uint32_t Sub;
    uint32_t Toc;
};

namespace Offsets{
    enum Address{
      GET_PLAYER_NAME = 0x421974
    };
}

opd_s GET_PLAYER_NAME_t = { Offsets::GET_PLAYER_NAME, TOC };
char*(*GET_PLAYER_NAME)(uint PlayerID) = (char*(*)(uint))&GET_PLAYER_NAME_t;

Specifically, what do these last 2 lines mean and do? :

opd_s GET_PLAYER_NAME_t = { Offsets::GET_PLAYER_NAME, TOC };
char*(*GET_PLAYER_NAME)(uint PlayerID) = (char*(*)(uint))&GET_PLAYER_NAME_t;

Later in the source code I see a usage of GET_PLAYER_NAME and it looks like this:

char* player = GET_PLAYER_NAME(0);

So is GET_PLAYER_NAME some sort of a function that takes an argument of an integer?

I'm just really confused about this and am trying to understand it, so if someone could exaplain the meaning and syntax, that would be extremely helpful. Thanks!

opd_s GET_PLAYER_NAME_t = { Offsets::GET_PLAYER_NAME, TOC };

means create struct variable on stack with name GET_PLAYER_NAME_t of type opd_s and initialize it with fields Sub = Offsets::GET_PLAYER_NAME , ie 0x421974 and Toc = TOC , ie 0x1C75288 .

So, there is a struct named GET_PLAYER_NAME_t with opd_s type, which is equal to { 0x421974, 0x1C75288 } .

char*(*GET_PLAYER_NAME)(uint PlayerID) = (char*(*)(uint))&GET_PLAYER_NAME_t;

It defines function pointer GET_PLAYER_NAME(uint PlayerID) which is pointed to former declared struct.

Actually GET_PLAYER_NAME(0) calls something with op-codes 0x421974 , 0x1C75288 , which we cannot know what it does, because we don't know the architecture it is compiled for (at least bitness and endianness of the architecture).

Surely it's not x86, DEP on x86 blocks executing stack data as code.

opd_s GET_PLAYER_NAME_t = { Offsets::GET_PLAYER_NAME, TOC };

This declares a variable named GET_PLAYER_NAME_t of type opd_s . This is initialized to { Offsets::GET_PLAYER_NAME, TOC } ie the Sub data member will be Offsets::GET_PLAYER_NAME and the Toc data member will be TOC .

char*(*GET_PLAYER_NAME)(uint PlayerID) = ...

This declares a variable named GET_PLAYER_NAME . Its type is: pointer to a function taking an uint as argument and returning `char *.

(char*(*)(uint))&GET_PLAYER_NAME_t;

This casts the adress of GET_PLAYER_NAME_t to a pointer ... see above.

This looks very suspicious as the contents of the GET_PLAYER_NAME_t variable which is a struct will be interpreted as the first instruction(s) in a function call via GET_PLAYER_NAME .

This is how functions are called on PS3 via a prx module. This code runs on an external plugin know as a prx module. Think of it kind of like a DLL. You can load the game's executable into IDA and get the address of the function you want to call. So in this case, 0x421974 is being called. Since we don't actually have the game's source, you need to define the function like this:

char*(*GET_PLAYER_NAME)(uint PlayerID) = (char*(*)(uint))&GET_PLAYER_NAME_t;

The opd structure is just an int array which is specific to the cell processor. On Xbox it would just be like this:

char*(*GET_PLAYER_NAME)(uint PlayerID) = (char*(*)(uint))0x421974;

Pretty much all it does is call 0x421974 which is GET_PLAYER_NAME on GTA5 and gets a players name from their client index.

The processor is powerpc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM