Как научить IDA правильно разбирать делегаты lua_CFunction?
От: Albeoris  
Дата: 22.07.18 13:37
Оценка:
Доброго времени суток!

В процессе обратной разработки столкнулся с необходимостью получить информацию о СИшных функциях, зарегистрированных для 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);
    
      ...
    }


Возможно ли это? Существуют ли готовые решения?
Сейчас оказывается проще найти использования этой функции в скриптах и по именам параметров и последующему использованию предположить — что она принимает и возвращает, но это муторная ручная работа. Хочется автоматизировать.
"Хаос всегда побеждает порядок, поскольку лучше организован." (с) Терри Пратчетт
Отредактировано 22.07.2018 14:10 Albeoris . Предыдущая версия .
reverse engineering lua asm ida disassembly
Re: Как научить IDA правильно разбирать делегаты lua_CFunction?
От: IID Россия  
Дата: 03.08.18 00:43
Оценка:
Здравствуйте, Albeoris, Вы писали:

A>Теперь необходимо узнать количество и типы параметров и возвращаемых значений. И вот с этим возникают проблемы.


В LUA любая функция может принять и вернуть сколько угодно значений. Причём обе эти последовательности нетипизированы.
Сигнатуры у функций — всего лишь необязательный синтаксический сахар.
Лишние значения будут отброшены, недостающие будут считаться nil.

Подчеркну, что любое число значений функция может вернуть в зависимости от своей логики.
Например:
— в случае ошибки nil
— когда параметр 1 и он число — квадрат этого числа
— когда параметр строка — список слов этой строки
Кроме того функция может вернуть генератор, рассчитывая на повторный вход после yeld.
kalsarikännit
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.