这个非虚函数反编译后是怎么回事?
Whats up with this non virtual function after it gets decompiled?
所以我决定尝试使用 Ghidra 反编译/反汇编一个简单的 c++ class,其中包含一个虚函数和一个非虚函数。然而;反编译让我有点困惑。下面是我的来源和我的反编译。我不明白的是为什么对非虚函数的调用包含参数,例如打印的字符串和这 3 个其他奇怪的参数。这些其他参数是什么?我只能假设其中一个是“This”指针?如果有,另外两个是什么?
编译于 visual studio 2k17 x64 版本无 pdb
来源
#include <iostream>
#include <stdio.h>
class Person
{
public:
Person(int val)
{
myval = val;
}
void PersonFunction()
{
printf("this is a person func/n");
}
virtual void PersonFunction2()
{
printf("this is a person func2/n");
}
protected:
int myval = 5;
};
int main(int argc, char** argv)
{
Person * person = new Person(10);
std::cout << "Hello World!\n";
person->PersonFunction();
person->PersonFunction2();
}
反编译
undefined8
FUN_140001080(undefined8 param_1,undefined8 param_2,undefined8 param_3,undefined8 param_4)
{
code **ppcVar1;
ppcVar1 = (code **)operator_new(0x10);
*ppcVar1 = (code *)Person::vftable;
*(undefined4 *)(ppcVar1 + 1) = 10;
FUN_1400010e0((longlong *)cout_exref);
FUN_140001010("this is a person func/n",param_2,param_3,param_4); #what is going on here.. why 3 params?
(**(code **)*ppcVar1)(ppcVar1); # this, i assume is the virtual function call passing in this ptr
return 0;
}
// furthermore inside FUN140001010
void FUN_140001010(undefined8 param_1,undefined8 param_2,undefined8 param_3,undefined8 param_4)
{
undefined8 uVar1;
undefined8 *puVar2;
undefined8 local_res10;
undefined8 local_res18;
undefined8 local_res20;
local_res10 = param_2;
local_res18 = param_3;
local_res20 = param_4;
uVar1 = __acrt_iob_func(1);
puVar2 = (undefined8 *)FUN_140001000();
__stdio_common_vfprintf(*puVar2,uVar1,param_1,0,&local_res10);
return;
}
谁能解释一下接受我的字符串和三个参数的函数是怎么回事?参数是什么?为什么要传递字符串?
所以看起来 MSVC++ 编译器刚刚优化并将 printf 直接内联到 main 中。
这就是 printf 在 vaargs 下的样子:
_Check_return_opt_
_CRT_STDIO_INLINE int __CRTDECL printf(
_In_z_ _Printf_format_string_ char const* const _Format,
...)
#if defined _NO_CRT_STDIO_INLINE
;
#else
{
int _Result;
va_list _ArgList;
__crt_va_start(_ArgList, _Format);
_Result = _vfprintf_l(stdout, _Format, NULL, _ArgList);
__crt_va_end(_ArgList);
return _Result;
}
#endif
_Check_return_opt_
_CRT_STDIO_INLINE int __CRTDECL _vfprintf_l(
_Inout_ FILE* const _Stream,
_In_z_ char const* const _Format,
_In_opt_ _locale_t const _Locale,
va_list _ArgList
)
#if defined _NO_CRT_STDIO_INLINE
;
#else
{
return __stdio_common_vfprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, _Stream, _Format, _Locale, _ArgList);
}
#endif
所以我决定尝试使用 Ghidra 反编译/反汇编一个简单的 c++ class,其中包含一个虚函数和一个非虚函数。然而;反编译让我有点困惑。下面是我的来源和我的反编译。我不明白的是为什么对非虚函数的调用包含参数,例如打印的字符串和这 3 个其他奇怪的参数。这些其他参数是什么?我只能假设其中一个是“This”指针?如果有,另外两个是什么?
编译于 visual studio 2k17 x64 版本无 pdb
来源
#include <iostream>
#include <stdio.h>
class Person
{
public:
Person(int val)
{
myval = val;
}
void PersonFunction()
{
printf("this is a person func/n");
}
virtual void PersonFunction2()
{
printf("this is a person func2/n");
}
protected:
int myval = 5;
};
int main(int argc, char** argv)
{
Person * person = new Person(10);
std::cout << "Hello World!\n";
person->PersonFunction();
person->PersonFunction2();
}
反编译
undefined8
FUN_140001080(undefined8 param_1,undefined8 param_2,undefined8 param_3,undefined8 param_4)
{
code **ppcVar1;
ppcVar1 = (code **)operator_new(0x10);
*ppcVar1 = (code *)Person::vftable;
*(undefined4 *)(ppcVar1 + 1) = 10;
FUN_1400010e0((longlong *)cout_exref);
FUN_140001010("this is a person func/n",param_2,param_3,param_4); #what is going on here.. why 3 params?
(**(code **)*ppcVar1)(ppcVar1); # this, i assume is the virtual function call passing in this ptr
return 0;
}
// furthermore inside FUN140001010
void FUN_140001010(undefined8 param_1,undefined8 param_2,undefined8 param_3,undefined8 param_4)
{
undefined8 uVar1;
undefined8 *puVar2;
undefined8 local_res10;
undefined8 local_res18;
undefined8 local_res20;
local_res10 = param_2;
local_res18 = param_3;
local_res20 = param_4;
uVar1 = __acrt_iob_func(1);
puVar2 = (undefined8 *)FUN_140001000();
__stdio_common_vfprintf(*puVar2,uVar1,param_1,0,&local_res10);
return;
}
谁能解释一下接受我的字符串和三个参数的函数是怎么回事?参数是什么?为什么要传递字符串?
所以看起来 MSVC++ 编译器刚刚优化并将 printf 直接内联到 main 中。 这就是 printf 在 vaargs 下的样子:
_Check_return_opt_
_CRT_STDIO_INLINE int __CRTDECL printf(
_In_z_ _Printf_format_string_ char const* const _Format,
...)
#if defined _NO_CRT_STDIO_INLINE
;
#else
{
int _Result;
va_list _ArgList;
__crt_va_start(_ArgList, _Format);
_Result = _vfprintf_l(stdout, _Format, NULL, _ArgList);
__crt_va_end(_ArgList);
return _Result;
}
#endif
_Check_return_opt_
_CRT_STDIO_INLINE int __CRTDECL _vfprintf_l(
_Inout_ FILE* const _Stream,
_In_z_ char const* const _Format,
_In_opt_ _locale_t const _Locale,
va_list _ArgList
)
#if defined _NO_CRT_STDIO_INLINE
;
#else
{
return __stdio_common_vfprintf(_CRT_INTERNAL_LOCAL_PRINTF_OPTIONS, _Stream, _Format, _Locale, _ArgList);
}
#endif