C ++ - 这些代码行是什么意思?

时间:2015-11-14 20:47:01

标签: c++

我正在查看一些源代码,但不明白发生了什么。以下是我从源代码中汇总的一些代码(来自各地的定义,我只包含了必要的内容):

#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;

具体来说,这些最后两行意味着什么呢? :

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

稍后在源代码中我看到了GET_PLAYER_NAME的用法,它看起来像这样:

char* player = GET_PLAYER_NAME(0);

GET_PLAYER_NAME是某种带整数参数的函数吗?

我真的对此感到困惑,并试图理解它,所以如果有人可以扩展其含义和语法,那将非常有帮助。谢谢!

3 个答案:

答案 0 :(得分:4)

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

表示在类型为GET_PLAYER_NAME_t的名称为opd_s的堆栈上创建结构变量,并使用字段Sub = Offsets::GET_PLAYER_NAME初始化它,即0x421974Toc = TOC,即{{ 1}}。

因此,有一个名为0x1C75288GET_PLAYER_NAME_t类型的结构,等于opd_s

{ 0x421974, 0x1C75288 }

它定义了函数指针char*(*GET_PLAYER_NAME)(uint PlayerID) = (char*(*)(uint))&GET_PLAYER_NAME_t; ,它指向前面声明的struct。

实际上GET_PLAYER_NAME(uint PlayerID)会调用带有操作码GET_PLAYER_NAME(0)0x421974的内容,我们无法知道它的作用,因为我们不知道它编译的架构(至少建筑的位数和字节顺序)。

当然它不是x86,在x86上的DEP阻止执行堆栈数据作为代码。

答案 1 :(得分:3)

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

这声明了一个名为GET_PLAYER_NAME_t的{​​{1}}类型的变量。这已初始化为opd_s,即{ Offsets::GET_PLAYER_NAME, TOC }数据成员为SubOffsets::GET_PLAYER_NAME数据成员为Toc

TOC

这声明了一个名为char*(*GET_PLAYER_NAME)(uint PlayerID) = ... 的变量。它的类型是:指向函数的指针,该函数将GET_PLAYER_NAME作为参数并返回`char *。

uint

这会将(char*(*)(uint))&GET_PLAYER_NAME_t; 的地址转换为指针......见上文。

这看起来非常可疑,因为作为结构的GET_PLAYER_NAME_t变量的内容将被解释为通过GET_PLAYER_NAME_t的函数调用中的第一条指令。

答案 2 :(得分:1)

这是通过prx模块在PS3上调用函数的方法。此代码在外部插件上运行,称为prx模块。可以认为它有点像DLL。您可以将游戏的可执行文件加载到IDA中,并获取要调用的函数的地址。所以在这种情况下,正在调用0x421974。由于我们实际上没有游戏的来源,你需要定义这样的功能:

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

opd结构只是一个特定于单元处理器的int数组。 在Xbox上它就是这样的:

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

它的全部功能就是在GTA5上调用0x421974 GET_PLAYER_NAME并从其客户索引中获取玩家名称。

处理器是powerpc。