В стадии разработки находится проект "Декомпилятор С++", представляющий плагин к IDA. Расписывать не буду, что он может делать, а что нет. Приведу промежуточный результат автоматического декомпилирования произвольной функции. Вариант IDA: Код (Text): .text:006738D0 SearchTreeWithoutDirchange proc near ; CODE XREF: j_SearchTreeWithoutDirchangej .text:006738D0 .text:006738D0 var_22C = byte ptr -22Ch .text:006738D0 var_1EC = dword ptr -1ECh .text:006738D0 var_1E8 = dword ptr -1E8h .text:006738D0 var_1E4 = dword ptr -1E4h .text:006738D0 var_1E0 = dword ptr -1E0h .text:006738D0 var_1DC = dword ptr -1DCh .text:006738D0 var_1D8 = dword ptr -1D8h .text:006738D0 var_1D4 = dword ptr -1D4h .text:006738D0 var_1D0 = dword ptr -1D0h .text:006738D0 var_1CC = dword ptr -1CCh .text:006738D0 var_1C8 = dword ptr -1C8h .text:006738D0 var_1C4 = dword ptr -1C4h .text:006738D0 var_1C0 = dword ptr -1C0h .text:006738D0 var_1BC = dword ptr -1BCh .text:006738D0 var_1B8 = byte ptr -1B8h .text:006738D0 var_1A4 = dword ptr -1A4h .text:006738D0 var_1A0 = dword ptr -1A0h .text:006738D0 var_19C = dword ptr -19Ch .text:006738D0 var_198 = byte ptr -198h .text:006738D0 var_184 = dword ptr -184h .text:006738D0 var_180 = byte ptr -180h .text:006738D0 var_16C = byte ptr -16Ch .text:006738D0 var_158 = dword ptr -158h .text:006738D0 var_154 = dword ptr -154h .text:006738D0 var_150 = byte ptr -150h .text:006738D0 var_13C = byte ptr -13Ch .text:006738D0 var_128 = dword ptr -128h .text:006738D0 var_124 = _finddata_t ptr -124h .text:006738D0 arg_0 = dword ptr 8 .text:006738D0 arg_4 = byte ptr 0Ch .text:006738D0 arg_18 = dword ptr 20h .text:006738D0 .text:006738D0 push ebp .text:006738D1 mov ebp, esp .text:006738D3 push 0FFFFFFFFh .text:006738D5 push offset unknown_libname_1682 ; Microsoft VisualC 2-8/net runtime .text:006738DA mov eax, large fs:0 .text:006738E0 push eax .text:006738E1 mov large fs:0, esp .text:006738E8 sub esp, 220h .text:006738EE push ebx .text:006738EF push esi .text:006738F0 push edi .text:006738F1 lea edi, [ebp+var_22C] .text:006738F7 mov ecx, 88h .text:006738FC mov eax, 0CCCCCCCCh .text:00673901 rep stosd .text:00673903 mov dword ptr [ebp+var_124.name+0FCh], 0 .text:0067390A mov esi, esp .text:0067390C lea eax, [ebp+var_124] .text:00673912 push eax ; struct _finddata_t * .text:00673913 mov edi, esp .text:00673915 lea ecx, [ebp+var_150] .text:0067391B push ecx .text:0067391C mov edx, [ebp+arg_0] .text:0067391F mov eax, [edx] .text:00673921 mov ecx, [ebp+arg_0] .text:00673924 call dword ptr [eax+28h] .text:00673927 cmp edi, esp .text:00673929 call __chkesp .text:0067392E mov [ebp+var_1C0], eax .text:00673934 mov ecx, [ebp+var_1C0] .text:0067393A mov [ebp+var_1C4], ecx .text:00673940 mov [ebp+var_124.name+0FCh], 1 .text:00673944 mov ecx, [ebp+var_1C4] .text:0067394A call j_zSTRING__operator_char_const__ .text:0067394F push eax ; char * .text:00673950 call ds:__imp___findfirst .text:00673956 add esp, 8 .text:00673959 cmp esi, esp .text:0067395B call __chkesp .text:00673960 mov [ebp+var_128], eax .text:00673966 mov [ebp+var_124.name+0FCh], 0 .text:0067396A lea ecx, [ebp+var_150] .text:00673970 call j_zSTRING___zSTRING .text:00673975 cmp [ebp+var_128], 0FFFFFFFFh .text:0067397C jz short loc_6739BB .text:0067397E mov esi, esp .text:00673980 mov edx, [ebp+var_128] .text:00673986 push edx ; __int32 .text:00673987 call ds:__imp___findclose .text:0067398D add esp, 4 .text:00673990 cmp esi, esp .text:00673992 call __chkesp .text:00673997 mov [ebp+var_154], 1 .text:006739A1 mov dword ptr [ebp+var_124.name+0FCh], 0FFFFFFFFh .text:006739A8 lea ecx, [ebp+arg_4] .text:006739AB call j_zSTRING___zSTRING .text:006739B0 mov eax, [ebp+var_154] .text:006739B6 jmp loc_673C4D .text:006739BB ; --------------------------------------------------------------------------- .text:006739BB .text:006739BB loc_6739BB: ; CODE XREF: SearchTreeWithoutDirchange+ACj .text:006739BB cmp [ebp+arg_18], 0 .text:006739BF jnz short loc_6739E5 .text:006739C1 mov [ebp+var_158], 0 .text:006739CB mov dword ptr [ebp+var_124.name+0FCh], 0FFFFFFFFh .text:006739D2 lea ecx, [ebp+arg_4] .text:006739D5 call j_zSTRING___zSTRING .text:006739DA mov eax, [ebp+var_158] .text:006739E0 jmp loc_673C4D .text:006739E5 ; --------------------------------------------------------------------------- .text:006739E5 .text:006739E5 loc_6739E5: ; CODE XREF: SearchTreeWithoutDirchange+EFj .text:006739E5 push offset a__4 ; "*.*" .text:006739EA mov esi, esp .text:006739EC lea eax, [ebp+var_16C] .text:006739F2 push eax .text:006739F3 mov ecx, [ebp+arg_0] .text:006739F6 mov edx, [ecx] .text:006739F8 mov ecx, [ebp+arg_0] .text:006739FB call dword ptr [edx+38h] .text:006739FE cmp esi, esp .text:00673A00 call __chkesp .text:00673A05 mov [ebp+var_1C8], eax .text:00673A0B mov eax, [ebp+var_1C8] .text:00673A11 mov [ebp+var_1CC], eax .text:00673A17 mov [ebp+var_124.name+0FCh], 2 .text:00673A1B mov ecx, [ebp+var_1CC] .text:00673A21 push ecx .text:00673A22 lea edx, [ebp+arg_4] .text:00673A25 push edx .text:00673A26 lea eax, [ebp+var_180] .text:00673A2C push eax .text:00673A2D call sub_40870B .text:00673A32 add esp, 0Ch .text:00673A35 mov [ebp+var_1D0], eax .text:00673A3B mov ecx, [ebp+var_1D0] .text:00673A41 mov [ebp+var_1D4], ecx .text:00673A47 mov [ebp+var_124.name+0FCh], 3 .text:00673A4B mov edx, [ebp+var_1D4] .text:00673A51 push edx .text:00673A52 lea eax, [ebp+var_13C] .text:00673A58 push eax .text:00673A59 call sub_40FD58 .text:00673A5E add esp, 0Ch .text:00673A61 mov [ebp+var_124.name+0FCh], 6 .text:00673A65 lea ecx, [ebp+var_180] .text:00673A6B call j_zSTRING___zSTRING .text:00673A70 mov [ebp+var_124.name+0FCh], 5 .text:00673A74 lea ecx, [ebp+var_16C] .text:00673A7A call j_zSTRING___zSTRING .text:00673A7F mov esi, esp .text:00673A81 lea ecx, [ebp+var_124] .text:00673A87 push ecx ; struct _finddata_t * .text:00673A88 lea ecx, [ebp+var_13C] .text:00673A8E call j_zSTRING__operator_char_const__ .text:00673A93 push eax ; char * .text:00673A94 call ds:__imp___findfirst .text:00673A9A add esp, 8 .text:00673A9D cmp esi, esp .text:00673A9F call __chkesp .text:00673AA4 mov [ebp+var_128], eax .text:00673AAA cmp [ebp+var_128], 0FFFFFFFFh .text:00673AB1 jz loc_673C1F .text:00673AB7 .text:00673AB7 loc_673AB7: ; CODE XREF: SearchTreeWithoutDirchange+330j .text:00673AB7 mov edx, [ebp+var_124.attrib] .text:00673ABD and edx, 10h .text:00673AC0 test edx, edx .text:00673AC2 jz short loc_673AD0 .text:00673AC4 movsx eax, byte ptr [ebp+var_124.time_access+4] .text:00673ACB cmp eax, 2Eh .text:00673ACE jnz short loc_673AD5 .text:00673AD0 .text:00673AD0 loc_673AD0: ; CODE XREF: SearchTreeWithoutDirchange+1F2j .text:00673AD0 jmp loc_673BDE .text:00673AD5 ; --------------------------------------------------------------------------- .text:00673AD5 .text:00673AD5 loc_673AD5: ; CODE XREF: SearchTreeWithoutDirchange+1FEj .text:00673AD5 sub esp, 14h .text:00673AD8 mov ecx, esp .text:00673ADA mov [ebp+var_184], esp .text:00673AE0 lea edx, [ebp+var_124.time_access+4] .text:00673AE6 push edx .text:00673AE7 call sub_40F8B7 .text:00673AEC mov [ebp+var_1D8], eax .text:00673AF2 lea eax, [ebp+var_198] .text:00673AF8 push eax .text:00673AF9 mov ecx, [ebp+arg_0] .text:00673AFC mov edx, [ecx] .text:00673AFE mov ecx, [ebp+arg_0] .text:00673B01 call dword ptr [edx+0F0h] .text:00673B07 mov [ebp+var_1DC], eax .text:00673B0D lea ecx, [ebp+var_198] .text:00673B13 call j_zSTRING___zSTRING .text:00673B18 mov eax, [ebp+arg_18] .text:00673B1B push eax .text:00673B1C sub esp, 14h .text:00673B1F mov ecx, esp .text:00673B21 mov [ebp+var_19C], esp .text:00673B27 lea edx, [ebp+arg_4] .text:00673B2A push edx .text:00673B2B call sub_401DCF .text:00673B30 mov [ebp+var_1E0], eax .text:00673B36 mov eax, [ebp+arg_0] .text:00673B39 push eax .text:00673B3A call j_SearchTreeWithoutDirchange .text:00673B3F add esp, 1Ch .text:00673B42 mov [ebp+var_1E4], eax .text:00673B48 cmp [ebp+var_1E4], 0 .text:00673B4F jz short loc_673B9D .text:00673B51 mov esi, esp .text:00673B53 mov ecx, [ebp+var_128] .text:00673B59 push ecx ; __int32 .text:00673B5A call ds:__imp___findclose .text:00673B60 add esp, 4 .text:00673B63 cmp esi, esp .text:00673B65 call __chkesp .text:00673B6A mov [ebp+var_1A0], 1 .text:00673B74 mov [ebp+var_124.name+0FCh], 0 .text:00673B78 lea ecx, [ebp+var_13C] .text:00673B7E call j_zSTRING___zSTRING .text:00673B83 mov dword ptr [ebp+var_124.name+0FCh], 0FFFFFFFFh .text:00673B8A lea ecx, [ebp+arg_4] .text:00673B8D call j_zSTRING___zSTRING .text:00673B92 mov eax, [ebp+var_1A0] .text:00673B98 jmp loc_673C4D .text:00673B9D ; --------------------------------------------------------------------------- .text:00673B9D .text:00673B9D loc_673B9D: ; CODE XREF: SearchTreeWithoutDirchange+27Fj .text:00673B9D sub esp, 14h .text:00673BA0 mov ecx, esp .text:00673BA2 mov [ebp+var_1A4], esp .text:00673BA8 push offset a__ ; ".." .text:00673BAD call sub_40F8B7 .text:00673BB2 mov [ebp+var_1E8], eax .text:00673BB8 lea edx, [ebp+var_1B8] .text:00673BBE push edx .text:00673BBF mov eax, [ebp+arg_0] .text:00673BC2 mov edx, [eax] .text:00673BC4 mov ecx, [ebp+arg_0] .text:00673BC7 call dword ptr [edx+0F0h] .text:00673BCD mov [ebp+var_1EC], eax .text:00673BD3 lea ecx, [ebp+var_1B8] .text:00673BD9 call j_zSTRING___zSTRING .text:00673BDE .text:00673BDE loc_673BDE: ; CODE XREF: SearchTreeWithoutDirchange:loc_673AD0j .text:00673BDE mov esi, esp .text:00673BE0 lea eax, [ebp+var_124] .text:00673BE6 push eax ; struct _finddata_t * .text:00673BE7 mov ecx, [ebp+var_128] .text:00673BED push ecx ; __int32 .text:00673BEE call ds:__imp___findnext .text:00673BF4 add esp, 8 .text:00673BF7 cmp esi, esp .text:00673BF9 call __chkesp .text:00673BFE test eax, eax .text:00673C00 jz loc_673AB7 .text:00673C06 mov esi, esp .text:00673C08 mov edx, [ebp+var_128] .text:00673C0E push edx ; __int32 .text:00673C0F call ds:__imp___findclose .text:00673C15 add esp, 4 .text:00673C18 cmp esi, esp .text:00673C1A call __chkesp .text:00673C1F .text:00673C1F loc_673C1F: ; CODE XREF: SearchTreeWithoutDirchange+1E1j .text:00673C1F mov [ebp+var_1BC], 0 .text:00673C29 mov [ebp+var_124.name+0FCh], 0 .text:00673C2D lea ecx, [ebp+var_13C] .text:00673C33 call j_zSTRING___zSTRING .text:00673C38 mov dword ptr [ebp+var_124.name+0FCh], 0FFFFFFFFh .text:00673C3F lea ecx, [ebp+arg_4] .text:00673C42 call j_zSTRING___zSTRING .text:00673C47 mov eax, [ebp+var_1BC] .text:00673C4D .text:00673C4D loc_673C4D: ; CODE XREF: SearchTreeWithoutDirchange+E6j .text:00673C4D ; SearchTreeWithoutDirchange+110j ... .text:00673C4D mov ecx, dword ptr [ebp+var_124.name+0F4h] .text:00673C50 mov large fs:0, ecx .text:00673C57 pop edi .text:00673C58 pop esi .text:00673C59 pop ebx .text:00673C5A add esp, 22Ch .text:00673C60 cmp ebp, esp .text:00673C62 call __chkesp .text:00673C67 mov esp, ebp .text:00673C69 pop ebp .text:00673C6A retn .text:00673C6A SearchTreeWithoutDirchange endp Результат после четвертого прохода декомпилятора: Код (Text): int SearchTreeWithoutDirchange(zFILE_FILE& file, zSTRING root, int bEntry) { memset(var22C, -858993460, 0x88); var150 = file.GetFullPath(); var1C0 = var150; var1C4 = var1C0; handle = __findfirst(var1C4.operator char const *(), &data_t); var150.~zSTRING(); if(handle != -1) __findclose(handle); var154 = 1; root.~zSTRING(); return var154; if(!bEntry) var158 = 0; root.~zSTRING(); return var158; var16C = file.GetDir(); var1C8 = var16C; var1CC = var1C8; var180 = operator+(root, var1CC); var1D0 = var180; var1D4 = var1D0; path = operator+(var1D4, "*.*"); var180.~zSTRING(); var16C.~zSTRING(); handle = __findfirst(path.operator char const *(), &data_t); if(handle != -1) do if(!(data_t.attrib & 0x10) || (data_t.name[0] == 0x2E)) continue; var184 = esp; var198 = file.DirStepInto(var1D8 = esp->zSTRING(data_t.name)); var1DC = var198; var198.~zSTRING(); var19C = esp; var1E4 = SearchTreeWithoutDirchange(file, var1E0 = esp->zSTRING(root), bEntry); if(var1E4) __findclose(handle); var1A0 = 1; path.~zSTRING(); root.~zSTRING(); return var1A0; var1A4 = esp; var1B8 = file.DirStepInto(var1E8 = esp->zSTRING("..")); var1EC = var1B8; var1B8.~zSTRING(); while(!__findnext(handle, &data_t)); __findclose(handle); var1BC = 0; path.~zSTRING(); root.~zSTRING(); return var1BC; } Ограничения на сегодняшний день: - Присутствие полной дебаг информации в любом виде и формате. - Декомпилируются только файлы, созданные VisualStudio. Следующие этапы разработки: 1. Адаптация декомпилятора к минимальной дебаг информации. 2. Адаптация декомпилятора к полному отсутствию дебаг информации. 3. Интерактивный интерфейс с IDA. Если кого-то заинтересовал этот проект и у него есть желание, свободное время и способности, то добро пожаловать в команду для реализации этапа 3.
Vam Хмммм... очень серьезное ограничение: и где такие файлы только берут? ЗЫ Хотя, если вспомнить, здесь в одном из топиков по-поводу отучения программы обновления игрушки выложен файл со следами дебужной информации.
Кто-то здесь декомпилятор постал (как отдельная програма, а не плагин для Иды). Года 2-3 назад. Кто нибудь помнит?
Это пока - разработка ещё не закончена. Почему так - попробую пояснить: когда есть полная дебаг информация, то для её типов создаются структуры, заполняются ей и участвуют в дальнейшей обработке (большего всё равно взять неоткуда). Когда её нет или она неполная (дебаг информация) создаются те же структуры, частично заполняются, а остальное заполнение производится по ходу разбора декомпилятором программы, т.н. восстановление типов данных. Как юмор принимается, хотя на сегодняшний день фигурные скобки заменяют отступы. На сегодняшний день я бы не назвал HexRays декомпилятором С++, просто декомпилятором в произвольный код, более читаемый, чем ассемблер - да, но не более того. Пока у него отсутствуют практически все конструкции языка С++. Декомпиляторов в С++ не существует, и всё, что раньше сделано, дает лишь минимальное приближение к требуемому.
Vam А вот интересно, как можно при полном отсутствии дебужной информации разрулить вызовы виртуальных методов для динамически созданных классов? Честно скажу, что даже руками, владея приличным опытом, это сделать нелегко...
Нелегко, но возможно. Я надеюсь, вам известно, как осуществляется вызов любого виртуального метода (хотя, надо различать виртуальные методы и виртуальные функции). Здесь вопрос был поставлен именно о виртуальной функции. Так вот, любой класс с виртуальностью будет иметь конструктор или деструктор (неважно какой), в нем производится инициализация указателя на таблицу виртуальных функций, присутствующую в бинарном коде - а далее дело техники.
Vam Не, я о другом: взять хотя бы приведенный пример, в котором выполнен вызов Код (Text): .text:00673924 call dword ptr [eax+28h] , что декомпилировалось в конструкцию: Код (Text): var150 = file.GetFullPath(); Это прошло, поскольку был известен тип аргумента Код (Text): zFILE_FILE& file Теперь предположим, что в качестве аргумента передается указатель на экземпляр класса, созданный динамически х.з. когда и в каком месте. Пока я это место не распознаю, я не буду знать, экземпляр какого класса был создан.
Это конечно так, взять и декомпилировать автоматом любую произвольную функцию полностью не получится. На это есть система откатов, отложенных декомпиляций и сквозного отслеживания типов переменных. В любом случае сначала будет декомпилирован полностью конструктор и (или) деструктор класса, затем его виртуальные функции (если есть), а только потом программа вернется к отложенным декомпиляциям с вызовом виртуальных функций.
Из приведенного асма видно, что используются исключения. Значит по ehfuncinfo->unwindtable можно идентифицировать деструкторы объектов. Если включено RTTI, можно вытащить имена полиморфных классов (имена бросаемых исключений в любом случае). Границы try определяются по var_124.name+0FCh, а catch по ehfuncinfo->tryblocktable->catchsym. Сделай /Fa тестовому сорцу, что бы понять детали. И на openrce была статья. Методы? в С++?
Vam, очень амбициозный проект. Пара вопросов: - ты смотрел какой код выдаёт VS2005 в режиме release, c полной оптимизацией? Ессно без debug info. Восстановить то что было inlined просто невозможно, т.к. части метода просто не присутствуют в конечном коде из-за оптимизации. - ну а код с STL? Эти методы компилер просто генерирует на лету. Eg: std::vector<MyFunkyStruct>::push_back() - его просто нету в исходнике. Что ты будешь создавать тут? И как это называть? В С++ virtual function и virtual method Это одно и то же. Member function и есть method.
J0E Это всё программой анализуруется, try и catch блоки восстанавливаются, правда пока не сделан анализ RTTI, но с полной дебаг инфой он и не нужен, а в дальнейшем и он будет реализован. а так же Я использую терминологию по дебаг информации от Microsoft. Виртуальная функция - функция класса (метод), вызываемая через виртуальную таблицу, указатель на которую сохранятся в классе, а тело функции в коде программы. Виртуальный метод - интерфейсная функция (метод) класса, производного от IUnknown, вызываемая через глобальную таблицу из другого программного модуля системы. s0larian Полностью с этим согласен. Я и не говорил, что созданные программой исходники будут на 100% соответствовать оригиналу, это сделать невозможно. Понятно и другое, чем больше отладочной информации мы имеем, тем больший % приближения к оригиналу можно получиить. Насчет inline - да, отдельных инлайн функций при отсутствующей дебаг инфе не будет, это в принципе не так и важно, главное, чтобы исходный код, сгенеренный программой был бы рабочим (пригодным для последующей компиляции). На все остальное планируется интерактивность, например, если пользоватеель выделил кусок кода и сказал, что это будет такая-то инлайн функция, то программа все преобразования в пределах проекта должна выполнить автоматически. Опять же всё зависит от уровня наличия дебаг инфы, в лучшем случае получим почти полный аналог исходника, в худшем - только тело конкретной функции без шаблонных аргументов, но вполне рабочее. Хотя для STL библиотек стандарта С++ планируется доп. анализ на шаблонность.
С точки зрения компилера, который генерирует код для вызова "basePtr->Method();" оба примера одинаковы: вызов виртуального метода. По поводу твоего подхода: 0. с полной дебаг информацией 1. c минимальной дебаг информации 2. c полным отсутствием дебаг информации. Мне кажется, что для 1. тебе придётся многое обобщить, и выбросить много кода, т.к. он не применим. Ну а для 2 - ещё раз всё переписать. Может надо было начинать с 2 и иметь итерактивность - человек скажет что вот эти похожие куски - путь это будет inline xxx::get_something(), а это вообще template был в оригинале. Если это хоть в какой-то мере заработает, то наличие debug info просто автоматизирует процесс. Кста, IDA была написана именно так. Енто, чем больше я над этим думаю, тем больше мне кажется что путь должен быть вот каким: - анализ asm: создатие types, structs - создать basic low level C эквивалентный asm - создать C++ эквивалентный С
На С++, да, выглядит одинаково, но я делаю не компилятор, а декомпилятор - а на ассемблере в реализации этих двух конструкций большие различия. Сейчас работа идет параллельно по п. 0 и 1 и первые четыре прохода программы (до приведенных результатов) работают. Выбрасывать ничего не приходится, а наоборот, нужно добавлять. Например, для п. 1 сделана поблочная обработка регистровых локальных переменных, которая для п.0 просто не нужна ввиду отсутствия оных (используются только локальные стековые переменные). Переписывать опять же не придется, всё ранее написанное будет работать, нужно будет только добавить в основном механизм распознавания типов данных, он в принципе уже написан, только требуется доработка некоторых моментов при декомпиляции конкретного кода. Интерактивность может быть двух видов: 1. Программа сделала сама всё что могла, а затем предлагает интерактивность - правь то, где я ошиблась или не смогла точно дать представление. 2. Сколько могу делаю (имеется в виду программа), затем спрашиваю, затем опять делаю и т.д. Но в во втором случае человек должен дать точный ответ, который он может и не знать, поэтому я с интерактивностью придерживаюсь варианта 1. А наиболее точно восстановить исходник программа может только по дебаг инфе, вот поэтому с него я и начал. Вернее было не совсем так (немного истории): проекту уже полгода, начало реализации было сделано по п.1, т.к. программа, которую необходимо было разобрать имела минимум дебаг инфы (номера строк С кода и имена глобальных переменных, включая и имена функций). При анализе и восстановлении типов переменных (особенно составных - указатели, ссылки, массивы, классы и др.) потребовалась разработка структур хранения типов со свойствами, от IDAшных представлений я сразу отказался, т.к. у них мала информативность, создавать с нуля свои - это долго (т.к. это процесс эволюционный, по ходу развития программы), поэтому я остановился на структурах хранения типов от Microsoft, в них есть все необходимые свойства типов и используются они в дебаг инфе (каждый, наверное, проходил отладку своих программ, и видел в окнах свойств переменных VS, всё, что требуется), а функционал для них написать не сложно. Поэтому работа по п.1 была приостановлена и началась работа по п.0 с разбора и загрузки всех типов дебаг инфы (вернее, только современных) от Microsoft. Насчет IDA не согласен (использую её начиная с версии 3.8), в первых версиях интерактивности практически не было, и только с появлением GUI (v 4.0) она стала развиваться. Оспаривать эти этапы я не буду, может быть они и похожи на мои (мало информации в этих трех строках), а кратко скажу какие четыре прохода пока выполняет программа по каждой из функций (полностью раскрывать алгоритм пока не имеет смысла): 1. Анализ asm кода с трассировкой стека, регистров, локальных и глобальных переменных. Результат: приблизительное определения границ выражений языка С в ассемблере. 2. Построение блоков, эквивалентных конструкциям языка С. 3. Повторяется п.1 но применительно к каждому созданному блоку, появляются первые типы данных. Создаются эквиваленты С++ представлений. 4. Компиляция эквивалентов в код С++ конструкций, уточнение и преобразование типов данных. В дальнейшем предполагается сделать ещё как минимум два прохода: оптимизация С конструкций (приведение к нормально читаемому виду) и создание листинга исходников. Причем с каждого из проходов может быть выполнен откат назад для разрешения конфликтных ситуаций или декомпиляция данной функции может быть отложена для разрешения критической ситуации и продолжена позже.
Интерактивности пока нет никакой, вся информация делится по типам и выводится только в три места: дебаг окно VS, окно сообщений IDA и текстовые файлы. Для реализации интерактивности мне как раз и требуется в помощь специалист в этом деле (знание IDA, умение работать с SDK (создание плагов) и владение BorlandBuilder) для ускорения работы. База для интерактивности уже сразу заложена в проект, например, если юзер поправил какой-то тип в структуре, то программа передекомпилирует только зависимые функции (возможно и не полностью) для отражения результата в исходниках. Начать можно с простой задачки - на навигационной панели IDA сделать раскраску декомпилированных успешно файлов в зеленый цвет, а отложенных декомпиляций в желтый.