我正在 IDA 中练习逆向工程,我在 Visual C++ 中创建了一个示例应用程序来练习使用类/结构,反编译器输出似乎不正确 - 我想知道是否可以解决这个问题以更接近正确反编译结果或者这是否仅仅是反编译器的限制。
#include <iostream>
#include "exstruct.cpp"
int main()
{
int x, y;
std::cin >> x;
std::cin >> y;
calculator c(x, y);
std::cout << c.multiply() << "\r\n";
}
我使用关闭优化的 Visual C++ 编译器进行编译,在定义函数和数据结构后,hex-rays 反编译器输出如下:
int __cdecl main(int argc, const char **argv, const char **envp)
{
char *newline; // ST04_4
int cout; // eax
Calculator calculator; // [esp+4h] [ebp-18h]
int x; // [esp+10h] [ebp-Ch]
int y; // [esp+14h] [ebp-8h]
std::basic_istream<char,std::char_traits<char>>::operator>>(std::cin, &x, calculator.x);
std::basic_istream<char,std::char_traits<char>>::operator>>(std::cin, &y, calculator.y);
Calculator_constructor(&calculator, x, y);
calculator.x = (int)new_line_string;
newline = (char *)Calculator_multiply(&calculator);
cout = std::basic_ostream<char,std::char_traits<char>>::operator<<(std::cout);
printf(cout, (int)newline);
return 0;
}
这一切看起来相当不错,直到它分配新的线串\r\n
到calculator.x
,然后乘到的结果newline
变量,这是错误的原因很明显。
我已经审查了程序集,这根本不是发生的事情。以下程序集的片段:
.text:00701088 lea ecx, [ebp+calculator] ; this
.text:0070108B call Calculator_constructor
.text:00701090 push offset new_line_string ; this
.text:00701095 lea ecx, [ebp+calculator] ; this
.text:00701098 call Calculator_multiply
.text:0070109D push eax
.text:0070109E mov ecx, ds:?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::basic_ostream<char,std::char_traits<char>> std::cout
.text:007010A4 call ds:??6?$basic_ostream@DU?$char_traits@D@std@@@std@@QAEAAV01@H@Z ; std::basic_ostream<char,std::char_traits<char>>::operator<<(int)
.text:007010AA push eax
.text:007010AB call printf
在我看来,反编译器很困惑,因为指向\r\n
文字的指针push
发生在multiply
调用之前,使它看起来像一个实际上不是的参数。
无论如何我可以解决这个问题吗?
完整的组装在这里。
exstruct.cpp
作为文本:
class calculator
{
public:
int x;
int y;
int z;
calculator(int x, int y)
{
this->x = x;
this->y = y;
this->z = x + y;
}
int multiply()
{
return this->x * this->y;
}
};
构造函数和乘法源和反编译源:
笔记:
- Hex-Rays 反编译器 v7.0.0.170914
- 我手动增加了函数的大小,
1C
因为它最初没有被检测newline
为一个字段 - 我手动将
\r\n
内存中的位置定义为字符串