Категория > Новости > Фундаментальные основы хакерства. Как идентифицировать структуры и объекты в чужой программе - «Новости»
Фундаментальные основы хакерства. Как идентифицировать структуры и объекты в чужой программе - «Новости»14-10-2020, 00:02. Автор: Ядвига |
|
странице автора. Обращаю твое внимание на одну деталь: с текущей статьи я перехожу на Visual Studio 2019. Последняя версия датируется 17 сентября и имеет номер 16.7.5. Чтобы избежать возможных несостыковок, советую тебе тоже обновить «Студию». Идентификация структурСтруктуры очень популярны среди программистов. Позволяя объединить под одной крышей родственные данные, они делают листинг программы более наглядным и упрощают его понимание. Соответственно, идентификация структур при дизассемблировании облегчает анализ кода. К великому сожалению исследователей, структуры как таковые существуют только в исходном тексте программы и практически полностью «перемалываются» при ее компиляции, становясь неотличимыми от обычных, никак не связанных друг с другом переменных. Мастер создания приложения в VS’19 Рассмотрим пример, демонстрирующий уничтожение структур на стадии компиляции: #include <stdio.h>#include <string.h>struct zzz{ char s0[16]; int a; float f;};void func(struct zzz y)// Понятное дело, передачи структуры РїРѕ значению лучше избегать,// РЅРѕ здесь это сделано умышленно для демонстрации скрытого создания// локальной переменной{ printf("%s %x %fn", &y.s0[0], y.a, y.f);}int main(){ struct zzz y; strcpy_s(&y.s0[0], 14, "Hello,Sailor!"); // Для копирования строки y.a = 0x666;// используется безопасная версия функции y.f = (float)6.6;// Чтобы подавить возражение компилятора, func(y);// указываем целевой тип}Результат компиляции этого кода с помощью Visual Studio 2019 для платформы x64 должен выглядеть так: main proc near; Члены структуры неотличимы РѕС‚ обычных локальных переменныхvar_48 = xmmword ptr -48hvar_38 = qword ptr -38hDst = byte ptr -28hvar_18 = qword ptr -18hvar_10 = qword ptr -10h sub rsp, 68h mov rax, cs:__security_cookie xor rax, rsp mov [rsp+68h+var_10], rax ; Подготовка параметров для вызова функции lea r8, Src; "Hello,Sailor!" mov edx, 0Eh; SizeInBytes lea rcx, [rsp+68h+Dst] ; Dst ; Вызов функции для копирования строки РёР· сегмента данных РІ локальную ; переменную call cs:__imp_strcpy_sСледующая команда копирует одно вещественное число, находящееся в младших 32 битах источника, — константу movss xmm1, cs:__real@40d33333 ; Помещаем указатель РЅР° строку РІ регистр RDX lea rdx, [rsp+68h+var_48]Далее с использованием инструкции Следующая команда копирует строго двойное слово из памяти в регистр (у нас это movsd xmm3, cs:__real@401a666660000000 ; Помещаем значение 0x666 РІ 32-битный регистр mov r8d, 666h ; Р?Р· переменной (СЃРј. метку --1) копируем РґРІРѕР№РЅРѕРµ слово РІ регистр movsd xmm2, [rsp+68h+var_18]Далее учетверенное слово (64 бит) копируется из регистра movq r9, xmm3Инструкция shufps xmm2, xmm2, 0E1h ; Копирование нижней 32-битной части источника РІ приемник movss xmm2, xmm1 ; Копирует 128 Р±РёС‚ РёР· регистра РІ переменную movaps [rsp+68h+var_48], xmm0 ; Р’ соответствии СЃ маской перемешивает содержимое регистра (СЃРј. выше) shufps xmm2, xmm2, 0E1h ; Две следующие инструкции помещают значение регистра РІ переменные, ; находящиеся РІ памяти movsd [rsp+68h+var_18], xmm2 movsd [rsp+68h+var_38], xmm2 ; Р’СЃРµ параметры находятся РЅР° СЃРІРѕРёС… местах, вызываем функцию printf call printf xor eax, eax mov rcx, [rsp+68h+var_10] xor rcx, rsp; StackCookie call __security_check_cookie add rsp, 68h retnmain endpКомпилятор сгенерировал довольно витиеватый код со множеством команд из расширения SSE. При этом он встроил функцию А теперь заменим структуру последовательным объявлением тех же самых переменных и рассмотрим пример, демонстрирующий сходство структур с обычными локальными переменными. IDA PRO int main(){ char s0[16]; int a; float f; strcpy_s(&s0[0], 14, "Hello,Sailor!"); a = 0x666; f = (float)6.6; printf("%s %x %fn", &s0[0], a, f);}И сравним результат компиляции с предыдущим: DstБез вызова дополнительных функций и передачи параметров дизассемблерный листинг заметно сократился. Остальной код остался идентичным предыдущему листингу. Перейти обратно к новости |