Категория > Новости > Фундаментальные основы хакерства. Как идентифицировать структуры и объекты в чужой программе - «Новости»
Фундаментальные основы хакерства. Как идентифицировать структуры и объекты в чужой программе - «Новости»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 -48h
var_38 = qword ptr -38h
Dst = byte ptr -28h
var_18 = qword ptr -18h
var_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
retn
main 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 Без вызова дополнительных функций и передачи параметров дизассемблерный листинг заметно сократился. Остальной код остался идентичным предыдущему листингу. Перейти обратно к новости |