Георгий |
Отправлено: 03.05.2004, 15:20 |
|
Почетный железнодорожник
Группа: Модератор
Сообщений: 874
|
задачка
есть комок вот с таким телом
CODE | 0x33, 0xC0, 0xE8, 0x09, 0x00, 0xB4, 0x09, 0xBA, 0x1F, 0x01, 0xCD, 0x21, 0xCD, 0x20, 0xBB, 0x1F,
0x01, 0xB9, 0x30, 0x00, 0x8B, 0x07, 0x83, 0xF0, 0x01, 0x89, 0x07, 0x43, 0xE2, 0xF6, 0xC3, 0x49,
0x64, 0x6D, 0x6D, 0x6E, 0x2D, 0x21, 0x51, 0x60, 0x65, 0x6E, 0x6F, 0x60, 0x6A, 0x20, 0x25, 0x49,
0x64, 0x6D, 0x6D, 0x6E, 0x2D, 0x21, 0x21, 0x65, 0x74, 0x63, 0x68, 0x6F, 0x60, 0x20, 0x25, 0x49,
0x64, 0x6D, 0x6D, 0x6E, 0x2D, 0x21, 0x21, 0x49, 0x60, 0x62, 0x6A, 0x64, 0x73, 0x20, 0x25 |
какой байт надо изменить, что бы вместо "Hello, Padonak!" выводилось "Hello, Hacker!"
PS. просьба к тем, кто знает откуда взялась задачка, не подсказывать остальным
Отредактировано Георгий — 03/05/2004, 16:28 |
|
exp |
Отправлено: 04.05.2004, 00:43 |
|
Мастер участка
Группа: Участник
Сообщений: 304
|
Тэээк...
Замечаем, что повторяется строчка
0x49, 0x64, 0x6D, 0x6D, 0x6E, 0x2D, 0x21 байты [32 ; 38] , [48 ; 54],
[64 ; 70]
Догадываемся, что нашли предложения, начинающихся со слова
"Hello, "
Тогда
0x49, h
0x64, e
0x6D, l
0x6D, l
0x6E, o
0x2D, ,
0x21,
0x51, p
0x60, a
0x65, d
0x6E, o
0x6F, n
0x60, a
0x6A, k
0x20, !
0x25 $
Эта строка выбрана за основу, т. к. в ней 1 последовательность подряд идущих одинаковых символов: "ll", тогда как в строках
0x49,0x64, 0x6D, 0x6D, 0x6E, 0x2D, 0x21, 0x21, 0x65, 0x74, 0x63, 0x68, 0x6F, 0x60, 0x20, 0x25, 0x49
и
0x49,0x64, 0x6D, 0x6D, 0x6E, 0x2D, 0x21, 0x21, 0x49, 0x60, 0x62, 0x6A, 0x64, 0x73, 0x20, 0x25
их две.
Далее так догадываемся о содержимом этих строк
0x49, h
0x64, e
0x6D, l
0x6D, l
0x6E, o
0x2D, ,
0x21,
0x21,
0x65, d
0x74, ?
0x63, ?
0x68, ?
0x6F, n
0x60, a
0x20, !
0x25 $
0x49, h
0x64, e
0x6D, l
0x6D, l
0x6E, o
0x2D, ,
0x21,
0x21,
0x49, h
0x60, a
0x62, ?
0x6A, k
0x64, ?
0x73, ?
0x20, !
0x25 $
Последняя строка более всего похожа на "Hello, Hacker!"
Теперь чтоб вывести строку нужно знать ее адрес
Строка 1 (та, которая предположительно выводится) начинается с 32-го байта 32(10) = 20(16) => ее адрес 0х20
Строка 2 начинается с 48-го байта 48(10) = 30(16) => ее адрес 0х30
Строка 3 (наша) начинается с 64-го байта 64(10) = 40(16) => ее адрес 0х40
//..................
Т. к. сегмент данных мы определили (начинается с 0х20), то до него идет сегмент кода. Вот он.
0x33, 0xC0, 0xE8, 0x09, 0x00, 0xB4, 0x09, 0xBA, 0x1F, 0x01, 0xCD, 0x21, 0xCD, 0x20, 0xBB, 0x1F,
0x01, 0xB9, 0x30, 0x00, 0x8B, 0x07, 0x83, 0xF0, 0x01, 0x89, 0x07, 0x43, 0xE2, 0xF6, 0xC3
Где-то здесь должен быть взят адрес строки 0х20. Он единственный (байт номер 14(10) = 0х0D) так вот его и меняем на 0х40
Ну что? верно?
А какая 2-я строка там на "d" начилась ?
|
|
Георгий |
Отправлено: 04.05.2004, 20:45 |
|
Почетный железнодорожник
Группа: Модератор
Сообщений: 874
|
exp
не, не угадал
теперь вместо 20го прерывания вызываем 40е
|
|
exp |
Отправлено: 04.05.2004, 23:50 |
|
Мастер участка
Группа: Участник
Сообщений: 304
|
Эге...
Значит байты 11-14 кодируют следующее:
int 21h
int 20h
значит до вызова int 21h ( 0xCD, 0x21 ) должен быть получен адрес этой строки....
А байты не с нуля ли нумеруются? если да то я ошибся на единицу и адрес строки "Hello, Padonak" не 0х20 а 0х1F, а адрес строки "Hello, Hacker!" не 0х40 а 0х3F
Находим байтик 0х1F в первой строчке и меняем его на 0х3F.
А теперь? Угадал?
... Прикольная задача.
|
|
Георгий |
Отправлено: 05.05.2004, 11:17 |
|
Почетный железнодорожник
Группа: Модератор
Сообщений: 874
|
она была взята из журнала хакер за апрель этого года.
я, кстати, сделал проще:
написал вот такую програмку:CODE | #include <fstream.h>
void main (void)
{
char orig_code[]={0x33, 0xC0, 0xE8, 0x09, 0x00, 0xB4, 0x09, 0xBA, 0x1F, 0x01, 0xCD, 0x21, 0xCD, 0x20, 0xBB, 0x1F,
0x01, 0xB9, 0x30, 0x00, 0x8B, 0x07, 0x83, 0xF0, 0x01, 0x89, 0x07, 0x43, 0xE2, 0xF6, 0xC3, 0x49,
0x64, 0x6D, 0x6D, 0x6E, 0x2D, 0x21, 0x51, 0x60, 0x65, 0x6E, 0x6F, 0x60, 0x6A, 0x20, 0x25, 0x49,
0x64, 0x6D, 0x6D, 0x6E, 0x2D, 0x21, 0x21, 0x65, 0x74, 0x63, 0x68, 0x6F, 0x60, 0x20, 0x25, 0x49,
0x64, 0x6D, 0x6D, 0x6E, 0x2D, 0x21, 0x21, 0x49, 0x60, 0x62, 0x6A, 0x64, 0x73, 0x20, 0x25};
char my_code[]={0x33, 0xC0, 0xE8, 0x09, 0x00, 0xB4, 0x09, 0xBA, 0x3F, 0x01, 0xCD, 0x21, 0xCD, 0x20, 0xBB, 0x1F,
0x01, 0xB9, 0x30, 0x00, 0x8B, 0x07, 0x83, 0xF0, 0x01, 0x89, 0x07, 0x43, 0xE2, 0xF6, 0xC3, 0x49,
0x64, 0x6D, 0x6D, 0x6E, 0x2D, 0x21, 0x51, 0x60, 0x65, 0x6E, 0x6F, 0x60, 0x6A, 0x20, 0x25, 0x49,
0x64, 0x6D, 0x6D, 0x6E, 0x2D, 0x21, 0x21, 0x65, 0x74, 0x63, 0x68, 0x6F, 0x60, 0x20, 0x25, 0x49,
0x64, 0x6D, 0x6D, 0x6E, 0x2D, 0x21, 0x21, 0x49, 0x60, 0x62, 0x6A, 0x64, 0x73, 0x20, 0x25};
char exp_code[]={0x33, 0xC0, 0xE8, 0x09, 0x00, 0xB4, 0x09, 0xBA, 0x1F, 0x01, 0xCD, 0x21, 0xCD, 0x40, 0xBB, 0x1F,
0x01, 0xB9, 0x30, 0x00, 0x8B, 0x07, 0x83, 0xF0, 0x01, 0x89, 0x07, 0x43, 0xE2, 0xF6, 0xC3, 0x49,
0x64, 0x6D, 0x6D, 0x6E, 0x2D, 0x21, 0x51, 0x60, 0x65, 0x6E, 0x6F, 0x60, 0x6A, 0x20, 0x25, 0x49,
0x64, 0x6D, 0x6D, 0x6E, 0x2D, 0x21, 0x21, 0x65, 0x74, 0x63, 0x68, 0x6F, 0x60, 0x20, 0x25, 0x49,
0x64, 0x6D, 0x6D, 0x6E, 0x2D, 0x21, 0x21, 0x49, 0x60, 0x62, 0x6A, 0x64, 0x73, 0x20, 0x25};
fstream f("c:\\c.com",ios::out|ios::binary);
f.write(exp_code,sizeof(exp_code));
f.close();
} |
и используя обыкновенный отладчик от bc3.1 нашёл нужный байт |
|
exp |
Отправлено: 05.05.2004, 23:10 |
|
Мастер участка
Группа: Участник
Сообщений: 304
|
Так значит правильно?
|
|
Георгий |
Отправлено: 06.05.2004, 01:12 |
|
Почетный железнодорожник
Группа: Модератор
Сообщений: 874
|
да, конечно правильно.
только одно уточнение — комок грузится по смещению 100h, поэтому настоящий адрес текстовой строки 13F, а не 3F но на байт это не оказывает ни какого влияния. |
|
eugene_sh |
Отправлено: 17.05.2004, 16:49 |
|
Не зарегистрирован
|
прикольная задачка. Я перевел в СОМ и с помощью отладчика нашел байт.
Но шифруется строка примитивно — инвертируется младший бит. Решил за
пару минут. IDA — Rulez!!!
2b|!2b — Шекспир (содрал не поомню где) |
|
|