Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 12 ноября!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | FAQ | Форум | Скачать | Видеокурс
Новичку | Ссылки | Программирование | Интервью | Архив | Связь

Медосмотр AsProtect 2.0

Обсудить статью на форуме

Хорошая подборка видеоуроков, инструментов крэкера, книг и статей - здесь.

Автор: BiT-H@ck <bit-hack@mail.ru>

Здрасьте, здрасьте, это опять я. Недавно мне один чел подсунул прогу запротекченную аспирином, по словам Mario 555 это был аспирин 1.3/2.0 этого года, со всеми опциями защиты. Я потерял надежду, т.к. я в этом аспирине “не в зуб ногой”. Но я решил попробовать распаковать его не со всеми опциями (без VM), да ещё и не на делфи:) (насколько, надеюсь, всем известно, солод очень любит делфи, после защиты проги на делфи аспирином, аспирин сложнее снять в несколько раз, чем, если бы запротектить например С). Так, значит я протекчю С, без VM:), аспирином 2.0. Протектить буду calc из вын ХР. Запротектили? Теперь будем снимать:). Ещё я хочу предупредить, что способы, описаны здесь далеки от совершенства (как смог, так анпакнул).

<ОЕР find, import recover and many other…>
Грузим прогу в олли, видим:

 01001000	6801F00101	PUSH 0101F001
 01001005	E801000000	CALL 0100100B
 0100100A	C3			RETN
 0100100B	C3			RETN
 

Где-то я это видел? Не подскажет где? А, вспомнил, примерно в 30% всех прог, которые я поломал… Отрубаем все игноры и топчем до посинения 20 раз по Ctrl+F9. Тормознулись, теперь ставим брейк на секцию кода проги. И продолжаем топтать по Ctrl+F9 до остановки на ОЕР. О, ОЕР:

 01012475	6A70			PUSH 70
 01012477	68E0150001	PUSH 010015E0
 0101247C	E847030000	CALL 010127C8
 01012481	33DB			XOR EBX, EBX
 01012483	53			PUSH EBX
 01012484	8B3D20100001	MOV EDI, DWORD PTR DS:[1001020]
 

Так, теперь берём ImpRec, вводим всё, что надо, получаем чистую IAT, ни одной испорченной функции!!! Теперь берём любой дампер и дампим. Ок, привинчиваем импорт. Всё, распаковка завершена, до свиданья:) Запускаем дамп иииии…. И “тишина”. Ничего не произошло. Странно, а я посчитать хотел. Будем лечить.

<Dump recover>
Грузим дамп в олю и, пока, не наблюдаем ничего странного. Трейсим. И натыкаемся на вот “это”:

 010124E1	6A 02		PUSH 2
 010124E3	E8			DB E8
 010124E4	1C			DB 1C
 010124E5	DBC7		FCMOVNB ST, ST(7)
 010124E7	FFD2			CALL EDX
 010124E9	59			POP ECX
 010124EA	830D10500101	OR DWORD PTR DS:[1015010], FFFFFFFF
 

И чего только инженеры intel не придумают! Я об FCMOVNB не слышал отроду, да ещё и мелкомягкие это юзают. Брр, ужас. Или не юзают… Странно это как-то: сначала “левые” байты, а после них такая команда. Смотрим, как у нас в запакованном ехе, а у нас там:

 010124E1	6A02			PUSH 2
 010124E3	E81CDBC7FF	CALL 00C90004
 010124E8	D25983		RCR BYTE PTR DS:[ECX-7D], CL
 010124EB	0D10500101	OR EAX, 1015010
 


Оп-па аспр что-то спёр из нашей проги. Воров надо наказывать! Заходим в запакованном ехе в спёртую функцию, а там:

 00C90004	FF0424		INC DWORD PTR SS:[ESP] ;Увеличили адрес возврата на 1
 00C90007	68 0000C800	PUSH 0C80000 
 00C9000C	C3			RETN ; Перешли на 0C80000
 

Ок, трейсим через ret и оказываемся тут:

 00C80000	8BFF			MOV EDI, EDI
 00C80002	55			PUSH EBP
 00C80003	8BEC			MOV EBP, ESP
 00C80005	8B4508		MOV EAX, DWORD PTR SS:[EBP+8]
 00C80008	A3 BC17C577	MOV DWORD PTR DS:[77C517BC], EAX
 00C8000D	5D			 POP EBP
 00C8000E	C3			RETN
 

Это какая-то системная функция (не знаю, как это идентифицировать, я посмотрел в оригинале, что вызывается api функция). Сейчас наша цель её идентифицировать. Выделяем всю функцию, binary copy, Ctrl+M, выделяем память после нашего ехешника, ctrl+B, paste, enter. Ага, функция из msvcrt.dll, лежащая по адресу 77C2537C. Теперь заходим в executable modules, выделяем msvcrt.dll, view names. Теперь ищем функцию, которая находится по адресу 77C2537C. Это функция __set_app_type. Теперь ищем таблицу импорта.

 010124F8	FF1508120001	CALL DWORD PTR DS:[<&msvcrt.__p__fmode>]
 

Это, значит, что она примерно лежит по адресу 01001208. Идём туда.

 01001208	DBF1C077	DD msvcrt.__p__fmode
 0100120C	7C53C277	DD msvcrt.__set_app_type
 01001210	DD9CC177	DD msvcrt.??3@YAXPAX@Z
 

Здесь ищем адрес, который указывает на __set_app_type. А, вот он, по адресу 0100120C:) Ну и пишем, начиная с адреса 010124E3 call [0100120C], но просто так написать нельзя! Надо предварительно занопить место под функцию. Такая функция занимает 6 байт, Ctrl+E и пишем 6 раз 90. Ок, теперь пишем то, что хотели - call [0100120C]. Сохраняем, запускаем, облом:( Грузим сохраненный ехешник в олю и продолжаем дебажить. Трейсим, трейсим и доходим до такого места:

 010125BC	50			PUSH EAX
 010125BD	E842DAC9FF	CALL 00CB0004
 010125C2	83F645		XOR ESI, 45
 

Ах ты с*ка, ещё и отсюда спёр! Ок, смотрим оригинал (функцию):

 00CB0004	FF0424		INC DWORD PTR SS:[ESP]
 00CB0007	E9F4FFFEFF	JMP 00CA0000
 

Оооо, я ща умру. Переходим по джампу и видим:

 00CA0000	6A 18		PUSH 18
 00CA0002	68 982C817C	PUSH 7C812C98
 00CA0007	68 FA1E807C	PUSH 7C801EFA
 00CA000C	68 CB24807C	PUSH 7C8024CB
 00CA0011	C3			RETN
 

Идём через RETN и попадаем сюда:

 7C8024CB	68F399837C	PUSH 7C8399F3
 7C8024D0	64A100000000	MOV EAX, DWORD PTR FS:[0]
 7C8024D6	50			PUSH EAX
 

Хе, посередине какой-то функции из kernel32.dll. Выходим из неё.

 7C801EEE	6A18			PUSH 18
 7C801EF0	68982C817C		PUSH 7C812C98
 7C801EF5	E8D1050000		CALL 7C8024CB
 7C801EFA	64A118000000	MOV EAX, DWORD PTR FS:[18] ;сюда попали
 7C801F00	8B4030		MOV EAX, DWORD PTR DS:[EAX+30]
 7C801F03	8B7010		MOV ESI, DWORD PTR DS:[EAX+10]
 

Смотрим, что за функция у нас по адресу 7C801EEE. GetStartupInfoA. Прописываем её за место переходника. Сохраняем, запускаем. Опять облом. Продолжаем трейсить, до такого места:

 01001F51	B8EE280101	MOV EAX, 010128EE
 01001F56	E8F5060100	CALL 01012650 ; заходим
 
 01012650	E9ABD9D0FF	JMP 00D20000
 01012655	2840E3		SUB BYTE PTR DS:[EAX-1D], AL
 01012658	B1AD			MOV CL, 0AD
 0101265A	61			POPAD
 0101265B	D2490A		ROR BYTE PTR DS:[ECX+A], CL
 0101265E	E4AF			IN AL, 0AF
 01012660	BB0C7F10E2		MOV EBX, E2107F0C
 01012665	732D			JNB SHORT 01012694
 01012667	C3			RETN
 01012668	EC			IN AL, DX
 01012669	773C			JA SHORT 010126A7
 0101266B	310DE34CCCFF	XOR DWORD PTR DS:[FFCC4CE3], ECX
 

Чё ржёте? Нормальная функция:) Тут уже аспирин начал наглеть и спёр целую функцию! Идём в оригинал (запакованную прогу) и смотрим на адрес 00D20000.

 00D20000	68FFFFFFFF		PUSH -1
 00D20005	50			PUSH EAX
 00D20006	C1C01F		ROL EAX, 1F
 00D20009	F2			PREFIX REPNE
 00D2000A	EB01			JMP SHORT 00D2000D
 00D2000C	69B8C2404200EB	IMUL EDI, DWORD PTR DS:[EAX+4240C2], 20C>
 00D20016	B800000000		MOV EAX, 0
 00D2001B	648B00		MOV EAX, DWORD PTR FS:[EAX]
 00D2001E	50			PUSH EAX
 00D2001F	B81E104A00		MOV EAX, 4A101E
 00D20024	C1D0AB		RCL EAX, 0AB
 00D20027	8B44240C		MOV EAX, DWORD PTR SS:[ESP+C]
 00D2002B	64892500000000	MOV DWORD PTR FS:[0], ESP
 00D20032	55			PUSH EBP
 00D20033	8F44240C		POP DWORD PTR SS:[ESP+C]
 00D20037	64EB02		JMP SHORT 00D2003C
 00D2003A	CD20			INT 20
 00D2003C	81C51E4469E6	ADD EBP, E669441E
 00D20042	13ED			ADC EBP, EBP
 00D20044	8D6C0C0C		LEA EBP, DWORD PTR SS:[ESP+ECX+C]
 00D20048	F2			PREFIX REPNE
 00D20049	EB01			JMP SHORT 00D2004C
 00D2004B	F02BE9		LOCK SUB EBP, ECX
 00D2004E	50			PUSH EAX
 00D2004F	C3			RETN
 

Метоморф с полиморфом – отличное сочетание:) В последнее время я полюбил это сочетание, даже начал понимать, что да как… Трейсим, попутно отделяя зёрна от плевел.

 00D20000	68FFFFFFFF		PUSH -1
 00D20005	50			PUSH EAX
 

Это оригинал, продолжаем.

 00D20016	B800000000	MOV EAX, 0
 00D2001B	648B00	MOV EAX, DWORD PTR FS:[EAX]
 

А это у нас mov eax, fs:[0], продолжаем.

 00D2001E	50	PUSH EAX
 

Оригинал.

 00D20027	8B44240C		MOV EAX, DWORD PTR SS:[ESP+C]
 00D2002B	64892500000000	MOV DWORD PTR FS:[0], ESP
 

Оригинал.

 00D20032	55		PUSH EBP
 00D20033	8F44240C	POP DWORD PTR SS:[ESP+C]
 

Это mov [esp+0C], ebp, продолжаем.

 00D20044	8D6C0C0C	LEA EBP, DWORD PTR SS:[ESP+ECX+C]
 00D2004C	2BE9		SUB EBP, ECX
 

Это у нас будет LEA EBP, DWORD PTR SS:[ESP+C]

 00D2004E	50	PUSH EAX
 00D2004F	C3	RETN
 

Оригинал. Фуф, всё, теперь вставляем это на место переходника.

 01012650	6AFF			PUSH -1
 01012652	50			PUSH EAX
 01012653	64A100000000	MOV EAX, DWORD PTR FS:[0]
 01012659	50			PUSH EAX
 0101265A	8B44240C		MOV EAX, DWORD PTR SS:[ESP+C]
 0101265E	648925000000	MOV DWORD PTR FS:[0], ESP
 01012665	896C240C		MOV DWORD PTR SS:[ESP+C], EBP
 01012669	8D6C240C		LEA EBP, DWORD PTR SS:[ESP+C]
 0101266D	50			PUSH EAX
 0101266E	C3			RETN
 

Вот это у меня получилось. Сохраняем, запускаем, работает! Запускаем под отладчиком, закрываем, опять глюк:( Будем править:) Смотрим, где глюк, по адресу 00BB0004. В оригинале ставим бряк по этому адресу и отпускаем прогу на волю. Тормознулись. Смотрим в стек адрес возврата, у меня 0100439D. Идём по этому адресу и видим:

 01004392	FF35 044F0101		PUSH DWORD PTR DS:[1014F04]
 01004398	E8 67BCBAFF		CALL 00BB0004
 0100439D	AE				SCAS BYTE PTR ES:[EDI]
 

Ок, ещё одну функцию спёр. Начинаем трейсить код с целью узнать, что это за функция. Вот до куда я дотрейсил:

 00BA0000	8BFF		MOV EDI, EDI
 00BA0002	55		PUSH EBP
 00BA0003	8BEC		MOV EBP, ESP
 00BA0005	6A00		PUSH 0
 00BA0007	FF750C	PUSH DWORD PTR SS:[EBP+C]
 00BA000A	FF7508	PUSH DWORD PTR SS:[EBP+8]
 00BA000D	684225807C	PUSH 7C802542
 00BA0012	685025807C	PUSH kernel32.WaitForSingleObjectEx
 00BA0017	C3		RETN
 

Ага, значит WaitForSingleObjectEx. Исправляем call. Сохраняем, запускаем, закрываем, всё ОК. А теперь надо всё же выполнить цель, ради которой мы ломали. Запускам полученный исправленный дамп и считаем 2+2 жмём enter иииии… УРА, это ровно 4!!! Может, я когда-нибудь это буду считать в уме…

<Приветы to:>
All my command, cracklab, а особенно Alex(особеннее), Mario555 (а ему ещё особенее:), WELL, Bad_Guy. И to: dragon_gor, NUCLEuS и всем, кого я забыл…



Обсуждение статьи: Медосмотр AsProtect 2.0 >>>


Материалы находятся на сайте https://exelab.ru



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS