C Строковые литералы не в машинном коде? - PullRequest
1 голос
/ 03 августа 2009

Мне нужно немного изменить строку в исполняемом файле, для которого у меня больше нет исходного кода. Это было написано в C.

Я замечаю, что строковые литералы C, похоже, вообще не появляются в списке машинного кода - во всяком случае, не в сыром ASCII, не в utf8 / 16/32 или чем-то подобном. Похоже, они закодированы, как часть 32-битных операционных кодов. Например, я знаю, что код имеет строку c: печать («Моя строка»); байтами 'm' 'y' '' 's' и т. д., но строка, кажется, вообще не появляется, даже в любом кодировке utf8 / 16/32 и даже при 1/2/3/4/5 / 6/7/8 байт между каждым символом (я проверил все эти комбинации).

Из того, что я понимаю, литералы могут быть в непосредственных кодах операций, и они могут иметь 8 бит для значения ASCII в не байтовой позиции с выравниванием. Кто-нибудь знает, какие коды операций я должен искать? На данный момент я все еще не могу найти ничего похожего на строки, даже если я сдвигаю весь файл по крупицам.

Ответы [ 7 ]

3 голосов
/ 03 августа 2009

Сомнительно, что простой оператор печати будет закодирован таким образом компилятором.

Мое предположение одно из следующих:

  1. EXE получает строку из другого места. (Еще один файл, другая DLL и т. Д.)

  2. Вы не достаточно усердны, чтобы найти строку. Я предполагаю, что вы использовали шестнадцатеричный редактор, который показывает ascii и восьмеричный код?

  3. Автор кода изо всех сил старался помешать вам делать то, что вы хотите.

Что вы действительно пытаетесь делать в любом случае?

2 голосов
/ 03 августа 2009

Хотя я не уверен, почему вы не можете найти строку,

Я уверен, что это будет опасная и очень сложная работа, просто обновить строку

2 голосов
/ 03 августа 2009

вместо того, чтобы сдвигать весь файл по крупицам или смотреть на кучу разных кодировок, почему бы вам просто не разобрать исполняемый файл? Программа не может просто делать загадочные вещи без кода, и вы можете прочитать код, разобрав его. Если данные хранятся в кодах операций, их будет сложно изменить, но я не могу себе представить, почему компилятор будет хранить строку таким образом.

1 голос
/ 03 августа 2009

Вероятный ответ на вопрос "использованный один раз в сравнении с более часто используемым" заключается в том, что используемые чаще всего хранятся в отдельном разделе, но использованные один раз строки хранятся с вкраплениями кода (например, после безусловной инструкции перехода / перехода). Почему вы не можете видеть строки с помощью шестнадцатеричного редактора - загадка; код операции «загрузить немедленную строку» был бы довольно необычным (это АДРЕС начала строки, который требуется передать в качестве аргумента функции), и в любом случае строка должна быть видимой. Строка, не сохраняемая на границе байта, будет крайне необычной.

Предложение: создайте небольшую тестовую программу с несколькими строками, которые использовались один раз, и несколькими строками, использованными более одного раза, и посмотрите на это с помощью (a) objdump (b) шестнадцатеричного редактора. Если у вашего компилятора есть опция отображения кода сборки, сгенерированного для каждой строки исходного кода, включите его. Повторите все вышеперечисленное для каждого уровня оптимизации, предлагаемого компилятором. Затем используйте знания, полученные на реальном файле.

Пожалуйста, учтите, что разглашение архитектуры машины и того, какой компилятор (это не государственная тайна, не так ли?) Может дать вам лучшее решение раньше и избежать возможного отрицательного ответа на ваш вопрос; -)

1 голос
/ 03 августа 2009

Используйте инструмент, такой как Dumpbin (поставляется с Visual Studio) или objdump (инструмент GNU, доступный на любой платформе).

Дамп содержимого разделов, названных .rodata и .text; строка, вероятно, там. Если вы не можете его найти, выполните поиск в других разделах данных и кода.

Если вы действительно не можете его найти, то исполняемый файл может быть зашифрован. Но так как вы написали это, это не очень вероятно. =)

[редактировать]

На мой взгляд, наиболее вероятная возможность состоит в том, что строка была помещена в раздел кода (вероятно, называется .text). Вы должны вывести его как данные и использовать инструмент, такой как grep шестнадцатеричного редактора, для поиска строки.

0 голосов
/ 03 августа 2009

Я проследил программу и обнаружил, что она хранит строки в разделе, в котором она использует DEFLATE при инициализации, это никогда не бывает просто:

Я не знаю, какой компилятор я использовал, я думаю, что это был компилятор watcom. Код более 10 лет.

0 голосов
/ 03 августа 2009

Я только что скомпилировал hello world в C на gcc, а затем прочитал exe в SciTE, и я вижу строку в бреде Попробуйте посмотреть на исполняемый файл в другом редакторе.

РЕДАКТИРОВАТЬ: Я просто попытался изменить найденную строку (добавив буквы в строку в середине слова), но это сломало exe. Итак, я не знаю, как вы собираетесь изменить строку.

...