反向设计一个虚拟方法,该方法仅在返回之前对EAX的低字节进行异或

Art*_*ire 4 c++ x86 assembly reverse-engineering

我需要帮助从反汇编逆向工程虚拟方法.该代码最初使用Microsoft的Visual C++编译.有问题的方法如下:

sub_92D110    proc near
xor al, al
retn
sub_92d110    endp
Run Code Online (Sandbox Code Playgroud)

这个方法在很多类之间引用,甚至在一个类的vtable内多次引用.我不确定它的作用; 这是否意味着该方法被内联,但调用仍然保持vtable保持其大小?

如果是这样,那该怎么xor al, al办?我是否误解了召唤大会或其他什么?

Mat*_*lia 11

这很可能是这样的:

bool someclass::somemethod() {
    return false;
} 
Run Code Online (Sandbox Code Playgroud)

说明

  • xor al,al将低字节eax设置为零.
  • 所有x86调用约定都eax用作寄存器大小整数值的"返回值"寄存器.
  • 这不能是一个返回int(如return 0;)的函数,因为它只清理低字节(并且没有x86调用约定eax用作输入参数,所以它不是一个奇怪的函数,它接受一个整数参数,将其低字节归零并返回它).
  • 这给我们留下了一个函数,它返回一个字节大小的值,设置为零,因此它可以返回一个char/ unsigned char(0)或一个bool(false); 我更倾向于认为它是第二种选择,因为在实践中它更经常出现(特别是在可能由派生类重新定义的方法的"空"基类实现中).
  • 它既不需要参数,也不是可变参数,它不会查看任何参数.VC++/x86上的C++方法使用__thiscall调用约定,除了放入this指针外ecx,它与__stdcall"常规"方法相同,__cdecl与变量函数相同; 现在,__stdcall是callee清理,这里没有清理可言,这意味着没有争论; 另一方面,即使在__cdecl函数中也没有被调用方法的清理,所以我们不能先验地排除这种可能性.话虽这么说,但我认为最后一种选择不太可能.

这个方法在很多类之间引用,甚至在一个类的vtable内多次引用.

这完全正常; VC++的链接器定期合并编译为相同机器代码的不相关函数(并且令人困惑地称之为"相同的COMDAT折叠").

鉴于此过程非常低(它主要查看为各种函数生成的字节并查看它们是否可以重复数据删除),理论上上述所有假设可能在一起 - 它可能是一种不带参数的方法返回bool false一个vtable槽和一个varargs方法,char在另一个槽中返回零.

  • 值得注意的是,VC++中不受限制的"COMDAT折叠"行为通常被认为是C++中的[非法](/sf/ask/1857361831/),因为它意味着指向不相关函数的指针可能比较相等.其他链接器(`gold`)已实现有限形式的COMDAT折叠,但不使用不安全行为[默认](/sf/ask/1061824711/ -instructions-comdat-folding)还提供"安全"版本,只有在无法观察时才折叠. (2认同)
  • [这个](/sf/answers/2034003331/)可能是@BeeOnRope所讨论的更好的参考,它也指向[此博客文章](https://blogs.msdn. microsoft.com/vcblog/2013/09/11/introducing-gw-compiler-switch/)建议COMDAT折叠仅在您没有获取功能的地址时应用.如果事实确实如此,则表明此优化*符合"as-if"规则的标准. (2认同)