Anonymous
Во
s54820
А почему у тебя 4 в 32 строке?
s54820
Что вообще ты в этой строке хочешь сделать?
Anonymous
Хотя... Строка ж лежит в секции rodata, да? И если так, то ничерта я не поменяю в ней. Так?
Anonymous
Первый символ поменять. Потому, что адрес то в 4 байта
s54820
Вероятно, ты хочешь чего-то типа этого вместо строк 32-34:
uintptr_t *mov_offset = (uintptr_t *) (ptr_fun + 9);
const char *orig_string = (const char *) *mov_offset;
char *new_string = malloc(strlen(orig_string) + 1);
strcpy(new_string, orig_string);
new_string[0] = 'h';
*mov_offset = (uintptr_t) new_string;
(разумеется, #include <stdint.h>).
Anonymous
Ну т.е. я вытаскиваю адрес искомой строки из fun, а после по этому адресу меняю первый символ
s54820
Anonymous
Ну я не код патчу, а строку, а она лежит вне fun внутри билда
Anonymous
Но да, это скорее всего .rodata, в общем я затупил
Anonymous
Anonymous
Т.е. код, не rodata
s54820
Ну я не код патчу, а строку, а она лежит вне fun внутри билда
Чтобы подменить строку, у тебя есть ровно три варианта: либо патчить саму строку, либо патчить инструкцию в коде новым адресом строки, либо какой-нибудь самотрассировкой дойти до нужной инструкции и сэмулировать её — пропустить оригинальную и выполнить свой вариант (ну или дойти до вызова printf() и подменить аргумент в стеке).
Anonymous
Вот, я решил пропатчить саму строку
Anonymous
Подменять адрес пробовал, не вышло тоже
Anonymous
Anonymous
Anonymous
Оо, годная идея
s54820
Anonymous
Любишь fasm?
Anonymous
Я обычно на nasm'е, но тоже надо трайнуть, да. И вообще хорошенько тему с настройкой ld разобрать, дабы полностью управлять процессом сборки конечного экзэкутабельного файла)
Anonymous
Вообще меня радует, что можно обсудить подобные вопросы. А то в среднем люди почему то не шарят. Хотя может это только у меня так
Vladimir
Vladimir
патчить сгенерированный компилятором код - неблагодарное занятие
Vladimir
изменил ключи компиляции - и привет
Anonymous
Anonymous
смысл?
Полиморфизм всякий интересен
Anonymous
Vladimir
На какие?
ну оптимизацию поставил другую или тупо компилятор другой взял )
Anonymous
А есть что-то кроме gcc?
Anonymous
Рофл, сорь
Vladimir
Anonymous
Llvm же в чистом виде не для сей, а для своего абстрактного ассма
Vladimir
Vladimir
есть ещё icc
Vladimir
pcc
Anonymous
Интересно, насколько это все много весит
Vladimir
tiny cc
Anonymous
А вот это топовая тема, на досуге пытаюсь вкурить его исходники
Vladimir
я pcc как-то давно ковырял
Anonymous
А еще есть 8cc, но он не для продакшена, больше учебный
Anonymous
я pcc как-то давно ковырял
В любом случае, это пока что очень потно. Парсить древо лексем и по нему генерить асм - жоско уж очень
Vladimir
именно для этого и придуман llvm - чтобы именно генерить код и оптимизировать абстрактное дерево, и чтобы фронтенд и бекенд смог написать любой студент
Anonymous
Погоди. Код на Си -> массив лексем -> абстрактное лексическое древо -> llvm asm -> машинный код
Anonymous
Так же в общем случае
Vladimir
ну
Anonymous
И вот процесс трансляции лексического древа в llvm asm и есть тот самый потный момент
Vladimir
не
Anonymous
Си достаточно сложен для парсинга
Anonymous
Vladimir
из биткода llvm в машинный оптимизированный
Anonymous
Я хочу сказать, что это потно для понимания
Vladimir
да и вообще парсинг исходного текста одна из самых простых задач. в вот генерация кода - уже сложнее гораздо
Anonymous
Так а я о чем. О генерации кода по синтаксическому древу
Vladimir
так биткод llvm по сути и является распарсенным синтаксическим деревом. а ядро llvm его сначала оптимизирует, а уже потом переводит в машкод
Vladimir
так и любой байткод java, webasm и проч. он и декомпилируется легко
Anonymous
Да, знаю. Т.е. по твоему генерация байткода llvm это просто
Vladimir
llvm биткод не генерил, а парсеры писал
Anonymous
Хм. Хотя тут сложно сравнивать. Байткод явы весьма высокоуровневый, мэй би и llvm туда же
Vladimir
Vladimir
код должен быть строго структурированным
Vladimir
чтобы джитить проще было
Anonymous
Ну и в общем. Не хочет он писать в память, хоть тресни. Походу придется с линкером калдовать
Anonymous
ну да, там address вместо ptr_string, но не суть.
s54820
Anonymous
int fun() {
char* string = "Hello, World!";
printf("==> %s\n\n", string);
return 0;
}
int main() {
fun(); // Hello, World!
// вытаскеваем адрес строки из fun
int* address = memcpy((int*)malloc(4), (char*)(&fun) + 9, 4);
char* ptr = (char*)(*address);
// проверяем, в ту ли область ОЗУ мы попали
printf("%s%02X\n\n", "==> ptr_string: 0x", *address);
for (int i = 0; i < 13; i ++)
printf(" 0x%02X -> %c\n", ptr + i, *(ptr + i));
// все верно
// от ptr до ptr+13 - RW
VirtualProtect(ptr, 13, 0x04, NULL);
*ptr = '#'; // и записывать он упорно не хочет(
fun();
return 0;
}
Anonymous
==> Hello, World!
==> ptr_string: 0x403024
0x403024 -> H
0x403025 -> e
0x403026 -> l
0x403027 -> l
0x403028 -> o
0x403029 -> ,
0x40302A ->
0x40302B -> W
0x40302C -> o
0x40302D -> r
0x40302E -> l
0x40302F -> d
0x403030 -> !
Anonymous
и вот вывод, на *ptr = '#' программа завершается. Без ошибок
s54820
int fun() {
char* string = "Hello, World!";
printf("==> %s\n\n", string);
return 0;
}
int main() {
fun(); // Hello, World!
// вытаскеваем адрес строки из fun
int* address = memcpy((int*)malloc(4), (char*)(&fun) + 9, 4);
char* ptr = (char*)(*address);
// проверяем, в ту ли область ОЗУ мы попали
printf("%s%02X\n\n", "==> ptr_string: 0x", *address);
for (int i = 0; i < 13; i ++)
printf(" 0x%02X -> %c\n", ptr + i, *(ptr + i));
// все верно
// от ptr до ptr+13 - RW
VirtualProtect(ptr, 13, 0x04, NULL);
*ptr = '#'; // и записывать он упорно не хочет(
fun();
return 0;
}
А давно у нас последним параметром VirtualProtect() можно NULL класть? И проверять надо, что она тебе вернула.
Anonymous
блин, точняк.
Anonymous
изи, заработало. Вот только интересно, DWORD это какое-то тип винапишный?
s54820
int fun() {
char* string = "Hello, World!";
printf("==> %s\n\n", string);
return 0;
}
int main() {
fun(); // Hello, World!
// вытаскеваем адрес строки из fun
int* address = memcpy((int*)malloc(4), (char*)(&fun) + 9, 4);
char* ptr = (char*)(*address);
// проверяем, в ту ли область ОЗУ мы попали
printf("%s%02X\n\n", "==> ptr_string: 0x", *address);
for (int i = 0; i < 13; i ++)
printf(" 0x%02X -> %c\n", ptr + i, *(ptr + i));
// все верно
// от ptr до ptr+13 - RW
VirtualProtect(ptr, 13, 0x04, NULL);
*ptr = '#'; // и записывать он упорно не хочет(
fun();
return 0;
}
Ещё непонятно, зачем тебе там malloc() и memcpy(). И нестандартный #include <malloc.h>. И где void в аргументах у main() и fun(), если это Си?
s54820
Anonymous
видать порт mingw игнорит эти моменты
Anonymous
long же в два раза больше int`а? Или я туплю.