Определить исходный язык из двоичного файла? - PullRequest
10 голосов
/ 10 ноября 2009

I ответил на другой вопрос о разработке для iPhone на языках, не являющихся Objective-C, и я сделал утверждение, что использование, скажем, C # для написания для iPhone неправильно для обозревателя Apple. Я в основном говорил об элементах пользовательского интерфейса, различающихся в библиотеках ObjC и C #, о которых идет речь, но комментатор высказал интересную мысль, которая привела меня к этому вопросу:

Можно ли определить язык, на котором написана программа, исключительно из ее двоичного файла? Если есть такие методы, что это такое?

Предположим для целей вопроса:

  • То, что с точки зрения взаимодействия (поведение консоли, любой внешний вид графического интерфейса и т. Д.), Они идентичны.
  • Эта производительность не является надежным показателем языка (не сравнивая, скажем, Java с C).
  • То, что у вас нет переводчика или чего-то другого между вами и языком - просто необработанный исполняемый двоичный файл.

Бонусные баллы, если вы не зависимы от языка.

Ответы [ 8 ]

14 голосов
/ 10 ноября 2009

Краткий ответ: ДА

Длинный ответ:

Если вы посмотрите на двоичный файл, вы можете найти имена библиотек, с которыми были связаны ссылки. Открытие cmd.exe в TextPad легко находит следующее с шестнадцатеричным смещением 0x270: msvcrt.dll, KERNEL32.dll, NTDLL.DLL , USER32.dll и т. Д. Msvcrt - это функции поддержки времени выполнения Microsoft C. KERNEL32, NTDLL и USER32.dll - это библиотеки для конкретных ОС, которые сообщают вам либо целевую платформу, либо платформу, на которой она была построена, в зависимости от того, насколько хорошо среда кросс-платформенной разработки разделяет их.

Если оставить в стороне эти ключи, большинству любого компилятора c / c ++ придется вставлять имена функций в двоичный файл, в таблице есть список всех функций (или точек входа), хранящихся в таблице. C ++ «искажает» имена функций для кодирования аргументов и их типов для поддержки перегруженных методов. Можно запутать имена функций, но они все еще будут существовать. Сигнатуры функций будут включать количество и типы аргументов, которые можно использовать для отслеживания системных или внутренних вызовов, используемых в программе. По смещению 0x4190 "SetThreadUILanguage", который можно искать, чтобы узнать много нового о среде разработки . Я нашел таблицу точек входа со смещением 0x1ED8A. Я мог легко увидеть имена, такие как printf, exit и scanf; вместе с __p__fmode, __p__commode и __initenv

Любой исполняемый файл для процессора x86 будет иметь сегмент данных, который будет содержать любой статический текст, который был включен в программу. Назад к cmd.exe (смещение 0x42C8) находится текст "S.o.f.t.w.a.r.e..P.o.l.i.c.i.e.s..M.i.c.r.o.s.o.f.t..W.i.n.d.o.w.s..S.y.s.t.e.m.". Строка занимает вдвое больше символов, чем обычно необходимо, потому что она была сохранена с использованием символов двойной ширины, вероятно, для интернационализации. Коды ошибок или сообщения являются основным источником здесь.

По смещению B1B0 - "p.u.s.h.d", за которым следуют mkdir, rmdir, chdir, md, rd и cd; Я оставил непечатные символы для удобства чтения. Это все аргументы команды для cmd.exe.

Для других программ мне иногда удавалось найти путь, по которому программа была скомпилирована.

Итак, да , можно определить исходный язык из двоичного файла.

7 голосов
/ 10 ноября 2009

Я не хакер компилятора (надеюсь, когда-нибудь), но я полагаю, что вы можете найти контрольные знаки в двоичном файле, которые бы указывали, какой компилятор его сгенерировал, и некоторые из используемых опций компилятора, такие как указан уровень оптимизации.

Строго говоря, однако, то, что вы спрашиваете, невозможно. Может быть, кто-то сел с ручкой и бумагой и разработал двоичные коды, соответствующие программе, которую он хотел написать, а затем напечатал это в шестнадцатеричном редакторе. По сути, они программировали на ассемблере без ассемблера. Точно так же вы никогда не сможете с уверенностью сказать, был ли собственный двоичный файл написан на прямом ассемблере или на языке C со встроенной сборкой.

Что касается сред виртуальных машин, таких как JVM и .NET, вы должны иметь возможность идентифицировать ВМ по байт-кодам в двоичном исполняемом файле, как я ожидаю. Однако, возможно, вы не сможете определить, какой был исходный язык, например C # по сравнению с Visual Basic, если у вас нет особых пристрастий компилятора.

1 голос
/ 15 марта 2013

как насчет этих инструментов:

PE Детектив

PEiD

оба являются идентификаторами PE. хорошо, они оба для окон, но это то, что было, когда я приземлился здесь

1 голос
/ 10 ноября 2009

Сначала запустите what на некоторых двоичных файлах и посмотрите на вывод. Идентификаторы CVS (и SVN) разбросаны по всему двоичному изображению. И большинство из них из библиотек.

Кроме того, часто есть «карта» для различных библиотечных функций. Это тоже большой намек.

Когда библиотеки связаны с исполняемым файлом, в двоичный файл часто входит карта с именами и смещениями. Это часть создания «кода, независимого от позиции». Вы не можете просто «жестко связать» различные объектные файлы вместе. Вам нужна карта, и вы должны выполнить некоторые поиски при загрузке двоичного файла в память.

Наконец, модуль запуска для C, C ++ (и я предполагаю, что C #) уникален для стандартного набора библиотек этого компилятора.

1 голос
/ 10 ноября 2009

Полагаю, вы могли бы, если вы разберете исходный код или, по крайней мере, вы знаете компилятор, поскольку, например, не все компиляторы будут использовать один и тот же код для printf, поэтому Objective-C и gnu C должны различаться здесь.

Вы исключили все языки байт-кода, поэтому эта проблема будет встречаться реже, чем ожидалось.

0 голосов
/ 10 ноября 2009

Команду 'strings' можно использовать, чтобы получить некоторые подсказки относительно того, какой язык использовался (например, я просто запустил ее на раздвоенном двоичном файле для написанного мною приложения C, и первые найденные записи это библиотеки, связанные исполняемый файл).

0 голосов
/ 10 ноября 2009

Нет, байт-код не зависит от языка. Различные компиляторы могут даже брать один и тот же исходный код и генерировать разные двоичные файлы. Вот почему вы не видите декомпиляторов общего назначения, которые будут работать с двоичными файлами.

0 голосов
/ 10 ноября 2009

Ну, C изначально преобразован в ASM, так что вы можете написать весь код на C в ASM.

...