Reverse Engineering Asked by user3238415 on January 27, 2021
I’m working on reversing a C++ application and I’ve come across a structure that contains a getter function that returns TypeDescriptor*
, I’ve read some articles on RTTI and reversing C++ but can’t find a structure that matches what I’m seeing.
It seems to be a compiler generated structure because of the TypeDescriptor
getter? I’m hoping someone can point me in the right direction. There’s multiple of these structures, they are in mostly contiguous but not completely as far as I can see.
Pseudo code for the struct looks like:
// These are all function pointers
class SomeClazz
{
// func1/func2 are pointers to the same function. It looks like a constructor.
void* func1(void* param1, void** param2);
void* func2(void* param1, void** param2);
// This function differs depending on the class. I believe this to be a implementation of a virtual function maybe?
virtual void handler();
// Returns a pointer to a RTTI TypeDescriptor depending on the class
TypeDescriptor* get_type_descriptor();
void get_something();
}
Here’s code in the func1/2
functions in case there’s a hint of what it is:
undefined ** FUN_00125860(longlong param_1,undefined **param_2)
{
undefined4 uVar1;
undefined4 uVar2;
undefined4 uVar3;
*param_2 = (undefined *)&Vftable_maybe_00589ef0;
uVar1 = *(undefined4 *)(param_1 + 0xc);
uVar2 = *(undefined4 *)(param_1 + 0x10);
uVar3 = *(undefined4 *)(param_1 + 0x14);
*(undefined4 *)(param_2 + 1) = *(undefined4 *)(param_1 + 8);
*(undefined4 *)((longlong)param_2 + 0xc) = uVar1;
*(undefined4 *)(param_2 + 2) = uVar2;
*(undefined4 *)((longlong)param_2 + 0x14) = uVar3;
return param_2;
}
Here’s get_type_descriptor
:
TypeDescriptor * class::get_type_descriptor(void)
{
return &class_<lambda_88a0d3301c644a20c1df3ad0c52a86e4>_RTTI_Type_Descriptor;
}
////////////
LEA RAX, [class_<lambda_88a0d3301c644a20c1df3ad0c52 ...]
RET
Here’s get_something
, not sure what the purpose is or what it’s doing:
LEA RAX, [RCX+0x8]
RET
Any help/suggestions would be great. Thanks.
This is a lambda expression. When the lambda expression has captures it is compiled into a implementation defined structure. In my case the lambda has captures, using MSVC the structure was _Func_Base
defined as:
#pragma warning(push)
#pragma warning(disable : 4265) // class has virtual functions, but destructor is not virtual (/Wall)
// CLASS TEMPLATE _Func_base
template <class _Rx, class... _Types>
class __declspec(novtable) _Func_base { // abstract base for implementation types
public:
virtual _Func_base* _Copy(void*) const = 0;
virtual _Func_base* _Move(void*) noexcept = 0;
virtual _Rx _Do_call(_Types&&...) = 0;
virtual const type_info& _Target_type() const noexcept = 0;
virtual void _Delete_this(bool) noexcept = 0;
#if _HAS_STATIC_RTTI
const void* _Target(const type_info& _Info) const noexcept {
return _Target_type() == _Info ? _Get() : nullptr;
}
#endif // _HAS_STATIC_RTTI
_Func_base() = default;
_Func_base(const _Func_base&) = delete;
_Func_base& operator=(const _Func_base&) = delete;
// dtor non-virtual due to _Delete_this()
private:
virtual const void* _Get() const noexcept = 0;
};
#pragma warning(pop)
Correct answer by user3238415 on January 27, 2021
IIRC the typeid
operator returns a pointer to a type info instance.
Overall the code looks like a lambda expression implementation; the “constructor” captures the context so that the “handler” (lambda body) can access the variables it needs from the outer scope.
Answered by Igor Skochinsky on January 27, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP