我正在查看一些源代码,但不明白发生了什么。以下是我从源代码中汇总的一些代码(来自各地的定义,我只包含了必要的内容):
#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
是某种带整数参数的函数吗?
我真的对此感到困惑,并试图理解它,所以如果有人可以扩展其含义和语法,那将非常有帮助。谢谢!
答案 0 :(得分:4)
opd_s GET_PLAYER_NAME_t = { Offsets::GET_PLAYER_NAME, TOC };
表示在类型为GET_PLAYER_NAME_t
的名称为opd_s
的堆栈上创建结构变量,并使用字段Sub = Offsets::GET_PLAYER_NAME
初始化它,即0x421974
和Toc = TOC
,即{{ 1}}。
因此,有一个名为0x1C75288
且GET_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 }
数据成员为Sub
,Offsets::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。