Search code examples
c++assemblyreverse-engineering

How to get the "raw" ptr of a lambda *capture* function


I want to make a C++ assembly hooking using lambda captures but for this i need to get the pointer of a lambda capture function.

something like this:

int val0 = 42;
auto lambdaCap = new auto([&]() -> int { return val0++; });
uint64_t pLambdaFn = static_cast<uint64_t>(&decltype(*lambdaCap)::operator()); // need this

I understand than a lambda function capture seems like an instance of class with a functor, but i want get the static address of lambda::operator(). In memory "lambdaCap" is just a ptr to the variables members used in the lambda.

Thanks


Solution

  • &decltype(*lambdaCap)::operator()) is not valid because decltype(*lambdaCap) is actually an lvalue reference to the closure type.

    Instead, std::remove_pointer_t<decltype(lambdaCap)> would give you the closure type itself. So you can write &std::remove_pointer_t<decltype(lambdaCap)>::operator() to get the pointer-to-member-function corresponding to the closure type's function call operator.

    However, this expression has type int (T::*)(), which cannot be converted into an integer type. You can store it as-is, and call it using a pointer to an instance of the closure type (such as lambdaCap itself) but you can't convert it to uint64_t. There is no way to convert a pointer-to-nonstatic-member to an integer type, whether with static_cast or reinterpret_cast or any other cast.