Доброго времени суток!
В процессе обратной разработки столкнулся с необходимостью получить информацию о СИшных функциях, зарегистрированных для Lua'ых типов.
Если кто-нибудь занимался аналогичными задачами, можете посоветовать какие-нибудь плагины для IDA, или просто поделиться толковыми советами — как упростить себе жизнь?
Сейчас это выглядит так...
Собираем информацию о структуре классов и их членах, это не составляет проблем. В IDA регистрация выглядит следующим образом:
tolua_beginmodule(v1, "MyClass");
tolua_function(v1, (__int64)"setarray ", (__int64)sub_140423DE0);
tolua_function(v1, (__int64)"getarray ", (__int64)sub_140423E60);
tolua_endmodule(v1);
Теперь необходимо узнать количество и типы параметров и возвращаемых значений.
И вот с этим возникают проблемы.
Сигнатура метода-регистратора
известна:
define TOLUA_API __declspec(dllexport)
TOLUA_API void tolua_function (lua_State* L, const char* name, lua_CFunction func);
Определение делегата
тоже:
typedef int (*lua_CFunction) (lua_State *L);
Но вычленить из этого сигнатуру метода довольно проблематично:
int __fastcall sub_140423DE0(__int64 a1)
{
__int64 v1; // rbx@1
__int64 v2; // rax@1
__int64 v3; // rbx@1
__int64 v5; // [sp+0h] [bp-48h]@1
__int64 v6; // [sp+20h] [bp-28h]@1
__int64 v7; // [sp+28h] [bp-20h]@1
__int64 v8; // [sp+30h] [bp-18h]@1
v6 = -2i64;
v1 = a1;
v7 = 0i64;
sub_14012C2C0(&v7, a1);
LODWORD(v2) = sub_14012C290(v1);
v3 = v2;
sub_140425F50(v2); <<- нам сюда
sub_1400FD970(v3);
sub_14012C2E0(&v7);
return sub_14043C160((unsigned __int64)&v5 ^ v8);
}
Поскольку я ни разу не программист, то нужный мне, реальный коллбек нашёл путём сравнения этих сгенерированных компилятором стабин:
sub_140425F50(v2);
И после 15 минут медитации обнаружил, что в переменной &v47 со стека предположительно лежит первый параметр типа char *. Осталось найти их количество, типы остальных и возвращаемое значение.
Хочется чего-нибудь более автоматизированного, исключив ошибки из-за человеческого фактора. Всё-таки функции имеют вполне чёткую и однозначную сигнатуру, и хочется, чтобы IDA их отображала примерно так:
static int setarray (lua_State *L) {
NumArray *a = (NumArray *)lua_touserdata(L, 1);
int index = luaL_checkint(L, 2);
double value = luaL_checknumber(L, 3);
...
}
Возможно ли это? Существуют ли готовые решения?
Сейчас оказывается проще найти использования этой функции в скриптах и по именам параметров и последующему использованию предположить — что она принимает и возвращает, но это муторная ручная работа. Хочется автоматизировать.
"Хаос всегда побеждает порядок, поскольку лучше организован." (с) Терри Пратчетт