Поиск целочисленных объявленных переменных в исполняемом файле ELF с использованием шестнадцатеричного редактора
Я хочу изменить значение объявленной целочисленной переменной в исполняемом файле, используя шестнадцатеричный редактор, только предположим, что я знаю, что в коде объявлена переменная типа int, и переменная такая:
значение int = 1337;
я хочу отредактировать исполняемый файл с помощью шестнадцатеричного редактора, поиск по значению 1337 и изменить его на что-то другое, я пробовал ghex в Ubuntu, но я не знаю, как его искать, я преобразовал его в шестнадцатеричный, но я не нашел его Спасибо заранее ребята.
1 ответ
Во-первых, вы бы использовали readelf
определить виртуальный адрес переменной (где она находится в памяти после загрузки программы). -s
покажет вам таблицу символов, и мы будем искать имя вашей переменной.
readelf -s a.out | grep value
Это выведет строку, которая выглядит следующим образом:
64: 000000000060102c 4 OBJECT GLOBAL DEFAULT 24 value
Итак, здесь 64-й символ в файле value
, Его адрес загрузки равен 0x60102c, а его размер составляет 4 байта. Теперь у нас есть виртуальный адрес, но он не говорит нам, где он находится в файле. Для этого нам нужно сделать три вещи:
- Выяснить, в каком разделе он находится,
- Выяснить смещение сечения этого значения
- Добавьте смещение раздела к смещению файла этого раздела, чтобы получить фактическое смещение файла вашего элемента ("адрес", который вы увидите в шестнадцатеричном редакторе, если откроете файл ELF).
Давайте работать readelf
снова. -S
перечислю разделы.
readelf -S a.out
Вот фрагмент вывода. Помните, что адрес нашей переменной по адресу 60102c
и мы ищем раздел, где 60102c
лежит между его Address
И его Address + Size
, Поскольку это переменная для чтения и записи, можно предположить, что она будет в .data
раздел.
Section Headers:
[Nr] Name Type Address Offset
Size EntSize Flags Link Info Align
...
[21] .dynamic DYNAMIC 0000000000600e28 00000e28
00000000000001d0 0000000000000010 WA 6 0 8
[22] .got PROGBITS 0000000000600ff8 00000ff8
0000000000000008 0000000000000008 WA 0 0 8
[23] .got.plt PROGBITS 0000000000601000 00001000
0000000000000028 0000000000000008 WA 0 0 8
[24] .data PROGBITS 0000000000601028 00001028
0000000000000008 0000000000000000 WA 0 0 4
[25] .bss NOBITS 0000000000601030 00001030
0000000000000008 0000000000000000 WA 0 0 4
[26] .comment PROGBITS 0000000000000000 00001030
000000000000002c 0000000000000001 MS 0 0 1
Конечно же, .data
живет в памяти 601028
в 601028+8 = 601030
, Вычитание value
адрес из этого раздела адрес, мы получаем:
60102c Address of `value`
- 601028 Start address of .data section
--------
4
Таким образом, value
находится по смещению 4 от начала .data
раздел. Теперь, где в файле находится .data
раздел? Вот что Offset
колонка говорит нам. .data
начинается со смещения файла 1028
, Зная это, мы можем найти смещение файла value
:
1028 File offset of .data section
+ 4 Offset of `value` in .data section
-------
102c File offset of `value`
У нас есть смещение файла, теперь давайте удостоверимся, что знаем, чего ожидать. Ваша переменная имеет значение 1337. В шестнадцатеричном формате это 0x539. Но нам нужно поднять порядок байтов (или "порядковый номер"). Системы Intel x86 имеют младший порядок. Это означает, что когда целое число больше одного байта хранится по адресу, байт с наименьшим значением (или "маленький" конец) значения находится по этому адресу, а остальные байты - по последующему (увеличивающийся адрес).
Таким образом, ваш 1337 будет сохранен (как 4-байтовый int
) в файле вот так:
39 05 00 00
В системе с прямым порядком байтов (например, Motorola 68k) значение будет отображаться в файле в обратном порядке:
00 00 05 39
Тем не менее, если вы откроете свой файл ELF в шестнадцатеричном редакторе и перейдете к смещению 102c, вы увидите свое значение:
ELF-файлы не имеют контрольной суммы или CRC, поэтому вы можете просто отредактировать это значение в своем шестнадцатеричном редакторе, и оно будет иметь новое значение при выполнении вашей программы!