我遇到了有关绕路的问题。众所周知,绕路只能在5个字节的空间内移动(即'jmp'调用和4个字节的地址)。因此,在类(方法)中是不可能有“钩子”函数的,因为您无法提供'this'指针,因为没有足够的空间(更彻底地解释问题请参见这里)。因此,我一整天都在构思解决方案,现在我想听听您对这个问题的看法,以便在不确定是否可能的情况下开始一个3-5天的项目。
最初,我有三个目标:我希望'hook'函数是类方法,我希望整个方法是面向对象的(没有静态函数或全局对象),并且最糟糕/最难的部分是完全动态的。这是我的(理论上的)解决方案;通过汇编,人们可以在运行时修改函数(任何绕路方法都是一个完美的例子)。因此,既然我可以动态地修改函数,那么我不应该也能够动态地创建它们吗?例如;我为要使用malloc/new分配的存储器分配了约30个字节。不会只需用与不同汇编运算符对应的二进制数字替换所有字节,然后直接调用地址(因为它将包含一个函数)吗?
注:我预先知道我要绕路的所有函数的返回值和所有参数,并且由于我正在使用GCC,thiscall约定与_cdecl基本相同。
这就是我的思路/即将实现的方法;我创建了一个'Function'类。该构造函数采用可变数量的参数(除第一个参数外,该参数描述目标函数的返回值)。
每个参数都是钩子将接收的参数的描述(大小和是否为指针)。因此,假设我想为
编辑:在示例中,
通过这种实现方式,我可以轻松地将类方法作为回调函数,但这需要大量的汇编代码(而且我甚至没有特别丰富的经验)。 最终,唯一非动态的东西将是我的回调类中的方法(这也需要前后回调)。
所以我想知道:这是可能的吗?需要多少工作量?我是否在自找麻烦?
编辑:如果我表述不够清晰,请见谅,但如果您想要更详细的解释,请随时提问!
编辑2:我还想知道是否可以在某个地方找到所有汇编操作符的十六进制值?列表会很有帮助!或者是否可能以某种方式“保存”asm(“”)代码到内存地址(我非常怀疑)。
最初,我有三个目标:我希望'hook'函数是类方法,我希望整个方法是面向对象的(没有静态函数或全局对象),并且最糟糕/最难的部分是完全动态的。这是我的(理论上的)解决方案;通过汇编,人们可以在运行时修改函数(任何绕路方法都是一个完美的例子)。因此,既然我可以动态地修改函数,那么我不应该也能够动态地创建它们吗?例如;我为要使用malloc/new分配的存储器分配了约30个字节。不会只需用与不同汇编运算符对应的二进制数字替换所有字节,然后直接调用地址(因为它将包含一个函数)吗?
注:我预先知道我要绕路的所有函数的返回值和所有参数,并且由于我正在使用GCC,thiscall约定与_cdecl基本相同。
这就是我的思路/即将实现的方法;我创建了一个'Function'类。该构造函数采用可变数量的参数(除第一个参数外,该参数描述目标函数的返回值)。
每个参数都是钩子将接收的参数的描述(大小和是否为指针)。因此,假设我想为
int * RandomClass::IntCheckNum(short arg1)
创建一个Function类。那么我只需像这样操作:Function func(Type(4, true), Type(4, true), Type(2, false))
。其中'Type'定义为Type(uint size, bool pointer)
。然后通过汇编,我可以动态地创建函数(注意:这全部使用_cdecl调用约定),因为我可以计算参数数量和总大小。编辑:在示例中,
Type(4, true)
是返回值(int*),第二个Type(4, true)
是RandomClass 'this'指针,Type(2, false)
描述第一个参数(short arg1)。通过这种实现方式,我可以轻松地将类方法作为回调函数,但这需要大量的汇编代码(而且我甚至没有特别丰富的经验)。 最终,唯一非动态的东西将是我的回调类中的方法(这也需要前后回调)。
所以我想知道:这是可能的吗?需要多少工作量?我是否在自找麻烦?
编辑:如果我表述不够清晰,请见谅,但如果您想要更详细的解释,请随时提问!
编辑2:我还想知道是否可以在某个地方找到所有汇编操作符的十六进制值?列表会很有帮助!或者是否可能以某种方式“保存”asm(“”)代码到内存地址(我非常怀疑)。
std::function
吗?还是我漏掉了什么? - Konrad Rudolph