Сей раз ЛК выпустила на свет шесть крякми, два из которых были написаны на человеческом языке С. Приступим к анализу. Линк, архив, семпл из статьи.
SHADOW
В описании к заданию написано:
Оке, все чисто. Cмотрим импорт:
На данном этапе, не копая дизасм листинг (он кст небольшой, см смещение 00402310), можно понять логику работы приложения:
Очевидно, нам необходимо выцепить драйвер. Загружаем r3 отладчик архетипа «Оля», ставим бряк на CreateServiceA, DeviceIoControl и клацаем F9 (антиотладка отсутствует). Сразу же срабатывает точка останова на CreateServiceA, вот так выглядит стек:
Замечаем путь к нашему драйверу, копируем его куда-нибудь. Клацаем F9, ловим еще одну остановку на этой же функции:
Вам может показаться, что это один и тот же драйвер, однако присмотритесь внимательнее: названия чуть-чуть отличаются. Его тоже сохраним. Клацаем F9, перед нами появляется консолька с просьбой ввести некие данные:
Вводим рандом, отправляем. Сразу же срабатывает бряк на DeviceIoControl:
Здесь мы можем лицезреть нашу связку меил : сериал, которая передается третьим и пятым параметром соответственно. Четвертый и шестой аргумент — размер буферов (с учетом нуля). Трассируем в отладчике до ret, затем еще до одного. В результате увидим такую картину:
Иными словами, если DeviceIoControl вернул ненулевое значение — крякми решен. Что ж, перейдем к изучению первого драйвера. DriverEntry:
Обработчик DeviceIoControl:
Заветная Validate:
Обратить эту функцию не составит труда. Однако давайте вспомним, что у нас существует и второй драйвер, про который мы пока ничего не знаем. Его DriverEntry:
Интересное кино! Выглядит как самый настоящий драйвер-фильтр. Глянем обработчик:
Что мы здесь видим:
Таким образом, учтя все проверки, можно набросать что-то типа этого:
Функция GetMD5 самая стандартная, взятая отсюда. Компилируем, запускаем:
Solved. На этом прощаюсь.
SHADOW
В описании к заданию написано:
«Ollydbg не спасет Вас, исследователи! Игра будет вестись в темных уголках ядра операционной системы. Хватит ли Вам смелости узнать потаенные места виртуальной реальности? Shadow ждет вас, найдите его!»Намек ясен. Делаем пару прогонов анализаторами нашего образца:
Убрано под спойлер
Оке, все чисто. Cмотрим импорт:
Убрано под спойлер
На данном этапе, не копая дизасм листинг (он кст небольшой, см смещение 00402310), можно понять логику работы приложения:
- Подгружается драйвер (CreateService)
- Ему передаются некие параметры (DeviceIoControl)
- Драйвер что-то делает
- ???
Очевидно, нам необходимо выцепить драйвер. Загружаем r3 отладчик архетипа «Оля», ставим бряк на CreateServiceA, DeviceIoControl и клацаем F9 (антиотладка отсутствует). Сразу же срабатывает точка останова на CreateServiceA, вот так выглядит стек:
Убрано под спойлер
Замечаем путь к нашему драйверу, копируем его куда-нибудь. Клацаем F9, ловим еще одну остановку на этой же функции:
Убрано под спойлер
Вам может показаться, что это один и тот же драйвер, однако присмотритесь внимательнее: названия чуть-чуть отличаются. Его тоже сохраним. Клацаем F9, перед нами появляется консолька с просьбой ввести некие данные:
Убрано под спойлер
Вводим рандом, отправляем. Сразу же срабатывает бряк на DeviceIoControl:
Убрано под спойлер
Здесь мы можем лицезреть нашу связку меил : сериал, которая передается третьим и пятым параметром соответственно. Четвертый и шестой аргумент — размер буферов (с учетом нуля). Трассируем в отладчике до ret, затем еще до одного. В результате увидим такую картину:
Убрано под спойлер
Иными словами, если DeviceIoControl вернул ненулевое значение — крякми решен. Что ж, перейдем к изучению первого драйвера. DriverEntry:
Убрано под спойлер
Обработчик DeviceIoControl:
Убрано под спойлер
Заветная Validate:
Убрано под спойлер
Обратить эту функцию не составит труда. Однако давайте вспомним, что у нас существует и второй драйвер, про который мы пока ничего не знаем. Его DriverEntry:
Убрано под спойлер
Интересное кино! Выглядит как самый настоящий драйвер-фильтр. Глянем обработчик:
Убрано под спойлер
Что мы здесь видим:
- Функция ValidateStr отвечает за дополнительную валидацию наших первичных данных: допускаются только символы A..Z + a..z + 0..9 + '.' + '@'. Я бы оторвал руки человеку, который добавил такую проверку — лично мой меил не проходит ее, в нем содержится символ '-'
- Функция ModifyMail изменяет наш меил следующим образом:
Убрано под спойлер
- IofCallDriver передает управление основному драйверу с уже измененными данными
Таким образом, учтя все проверки, можно набросать что-то типа этого:
Убрано под спойлер
#include "main.h"
char mail[257];
char hashes[32][33];
void main()
{
for (;;)
{
printf_s("Enter your name (1 chars min and 256 chars max, only A..Z + a..z + '.' + '@'):\n");
fgets(mail, 257, stdin);
int ln = strlen(mail) - 1;
if (mail[ln] == '\n')
mail[ln] = '\x00';
else ln++;
if (ln < 1)
continue;
for (int i = 0; i < ln; i++)
{
if ((mail[i] < '0' || mail[i] > '9') && mail[i] != '.' && mail[i] != '@')
{
if (i & 1)
mail[i] &= 0xDF;
else
mail[i] |= 0x20;
}
} //change chars case
GetMD5(mail, ln, mail);
for (int i = 0; i < 32; i++)
{
if (mail[i] < '0' || mail[i] > '9')
{
mail[i] &= 0xDF;
GetMD5(mail, 32, hashes[i]);
mail[i] |= 0x20;
}
else
GetMD5(mail, 32, hashes[i]);
}
for (int i = 0; i < 32; i++)
mail[i] = hashes[i][i];
printf("%s\n", mail);
}
}
Функция GetMD5 самая стандартная, взятая отсюда. Компилируем, запускаем:
Убрано под спойлер
Solved. На этом прощаюсь.
potan
А пробовали ломать что-нибудь, написанное на Haskell? Он такой код создает, что ни один человек на ассемблере руками не напишет.
unc1e Автор
Нет, не пробовал. Проблема зачастую не в коде, а в его количестве. Сколько метров (наверняка именно в этих единицах) весит хелловорлд?
potan
Функция main из helloworld:
.data
.align 8
.align 1
.globl __stginit_Main
__stginit_Main:
.data
.align 8
.align 1
sK5_closure:
.quad sK5_info
.quad 0
.quad 0
.quad 0
.section .rodata
.align 8
.align 1
cKc_str:
.byte 72
.byte 101
.byte 108
.byte 108
.byte 111
.byte 44
.byte 32
.byte 87
.byte 111
.byte 114
.byte 108
.byte 100
.byte 0
.text
.align 8
.long SKg_srt-(sK5_info)+0
.long 0
.quad 0
.quad 4294967318
sK5_info:
.LcKd:
leaq -16(%rbp),%rax
cmpq %r15,%rax
jb .LcKe
.LcKf:
movq %r13,%rcx
movq %rbx,%rdx
subq $8,%rsp
subq $32,%rsp
xorl %eax,%eax
call newCAF
addq $40,%rsp
testq %rax,%rax
je .LcKb
.LcKa:
movq $stg_bh_upd_frame_info,-16(%rbp)
movq %rax,-8(%rbp)
movl $cKc_str,%r14d
movl $ghczmprim_GHCziCString_unpackCStringzh_closure,%ebx
addq $-16,%rbp
jmp stg_ap_n_fast
.LcKb:
jmp *(%rbx)
.LcKe:
jmp *-16(%r13)
.data
.align 8
.align 1
sK4_closure:
.quad sK4_info
.quad 0
.quad 0
.quad 0
.text
.align 8
.long SKg_srt-(sK4_info)+8
.long 0
.quad 0
.quad 12884901910
sK4_info:
.LcKt:
leaq -16(%rbp),%rax
cmpq %r15,%rax
jb .LcKu
.LcKv:
movq %r13,%rcx
movq %rbx,%rdx
subq $8,%rsp
subq $32,%rsp
xorl %eax,%eax
call newCAF
addq $40,%rsp
testq %rax,%rax
je .LcKs
.LcKr:
movq $stg_bh_upd_frame_info,-16(%rbp)
movq %rax,-8(%rbp)
movl $base_GHCziShow_zdfShowChar_closure,%r14d
movl $base_GHCziShow_zdfShowZMZN_closure,%ebx
addq $-16,%rbp
jmp stg_ap_p_fast
.LcKs:
jmp *(%rbx)
.LcKu:
jmp *-16(%r13)
.data
.align 8
.align 1
.globl Main_main_closure
Main_main_closure:
.quad Main_main_info
.quad 0
.quad 0
.quad 0
.text
.align 8
.long SKg_srt-(Main_main_info)+24
.long 0
.quad 0
.quad 30064771094
.globl Main_main_info
Main_main_info:
.LcKH:
leaq -16(%rbp),%rax
cmpq %r15,%rax
jb .LcKI
.LcKJ:
movq %r13,%rcx
movq %rbx,%rdx
subq $8,%rsp
subq $32,%rsp
xorl %eax,%eax
call newCAF
addq $40,%rsp
testq %rax,%rax
je .LcKG
.LcKF:
movq $stg_bh_upd_frame_info,-16(%rbp)
movq %rax,-8(%rbp)
movl $sK5_closure,%esi
movl $sK4_closure,%r14d
movl $base_SystemziIO_print_closure,%ebx
addq $-16,%rbp
jmp stg_ap_pp_fast
.LcKG:
jmp *(%rbx)
.LcKI:
jmp *-16(%r13)
.data
.align 8
.align 1
.globl ZCMain_main_closure
ZCMain_main_closure:
.quad ZCMain_main_info
.quad 0
.quad 0
.quad 0
.text
.align 8
.long SKg_srt-(ZCMain_main_info)+48
.long 0
.quad 0
.quad 12884901910
.globl ZCMain_main_info
ZCMain_main_info:
.LcKV:
leaq -16(%rbp),%rax
cmpq %r15,%rax
jb .LcKW
.LcKX:
movq %r13,%rcx
movq %rbx,%rdx
subq $8,%rsp
subq $32,%rsp
xorl %eax,%eax
call newCAF
addq $40,%rsp
testq %rax,%rax
je .LcKU
.LcKT:
movq $stg_bh_upd_frame_info,-16(%rbp)
movq %rax,-8(%rbp)
movl $Main_main_closure,%r14d
movl $base_GHCziTopHandler_runMainIO_closure,%ebx
addq $-16,%rbp
jmp stg_ap_p_fast
.LcKU:
jmp *(%rbx)
.LcKW:
jmp *-16(%r13)
.section .data
.align 8
.align 1
SKg_srt:
.quad ghczmprim_GHCziCString_unpackCStringzh_closure
.quad base_GHCziShow_zdfShowZMZN_closure
.quad base_GHCziShow_zdfShowChar_closure
.quad base_SystemziIO_print_closure
.quad sK4_closure
.quad sK5_closure
.quad base_GHCziTopHandler_runMainIO_closure
.quad Main_main_closure
.ident «GHC 7.10.3»
ReakTiVe-007
unc1e Автор
Это довольно цивильный код)) Правда, неинтеловский формат режет глаза + оверхед директив