RCE.SU - реверсинг, кодинг, выделенные сервера, ICQ, proxy
Black ReMoS Night

Исследование Advanced Direct Remailer

Найти столь замечательный продукт можно на www.massmail.ru.

Это творение зашито не менее замечательным продуктом ASProtect'ом.

Теперь о главном! Сегодня мы займемся, исследованием, а затем написанием патча, который будучи встроен в защищенную прогу будет выполнять за нас всю черную работу, а затем в нужный момент поправит регистрацию в ADR!

По идее начать стоило-бы с того как ASProtect определяет наличие отладчика(кстати SoftIce), но я небуду этого делать потому, что по этому поводу написано очень много статей. Как говорится читайте исследуйте и разбирайтесь с этим сами:)

И помните главное: Что привычка получать всегда все в готовом виде, плохая привычка!

И так начнем!

Запускаем программу и видим в Nag'е, что это незарегистрированная копия и работать будет только 15 дней. Выбираем в меню опцию Справка->Регистрация... жмем на нее и получаем окошко в котором нас просят ввести Регистрационный код. Хмм... А этот где взять! Непорядок надо сделать так, чтобы неспрашивала.... приступим.
Вводим вместо номера, что-нибудь, к примеру 12345678. Затем, в Вашем любимом отладчике ставим бряк на hmemcpy:
bpx hmemcpy
Жмем ОК!И сразу попадаем в отладчик! Далее выполняем команду bc*. И жмем F12 пока не попадем в модуль adr, на инструкцию RET. Если попали прекрасно, еще немножко потопчим F12 пока снова не окажимя на инструкции RET в модуле adr.

Затем жмем F8 и.... Вы должны увидеть похожий код:
....
004306EB : LEA EDX, [ESP+08]
004306EF : PUSH EDX
004306F0 : CALL 004302A0 (1)
.....

Дойдя до (1) нужно нажать F8, чтобы зайти в неё. Потрясируйте код до тех пор пока не дойдете до этого:

....
004302DD : PUSH ECX
004302DE : CALL 00430220(2)
.....

Дойдя до (2) нужно нажать F8, чтобы зайти в неё. И теперь трасируйте до тех пор пока не остановитесь на инструкции:

....
00430283 : JNZ 0043028C (3)
00430285 : XOR EAX, EAX
....
0043028C : LEA EAX, [EBX-09]
....

Здесь собственно все старо как мир: Если мы допустим очищение регистра EAX, то программа будет считать себя незарегистрированной и с радостью нам об этом сообщит. Попробуем выполнить переход по этому адресу ...и... программа нас поздравит, что регистрационный код прокатил и после нажатия на OK мы снова попадем в этот код на переход (3), если же конечно вы поставили на него бряк, т.е
bpx 00430283
:)
Когда вы выполните переход по адресу (3) во второй раз в меню у вас исчезнет пункт Регистрация. Вроде бы на первый взгляд все правильно и должно работать, если не два НО!

  1. Программа запакована и вам так просто не удастся произвести необходимые изменения.
  2. Если вы после такой регистрации выберите пункт Настройка, то получите облом и программа аварийно завершится!

Со вторым мы разберемся чуть позже, уверяю вас там нет ничего сложного! А сейчас перейдем к основной части тобишь пункту 1. Сразу определимся, что я попробуя вам разъяснить каким образом я построил свой патч. Также опишу основные на мой взгляд точки останова и код, который необходимый знать чтобы построить этот самый патч.

Для начала уберем все точки останова ранее поставленные bc*. И поставим бряк на область памяти, т.е bpm 00430283 rwx. Жмем F5. И попадаем сюда:

....
00F5266B : REP MOVSD
00F5266D : MOV ECX, EAX
00F5266F : AND ECX, BYTE +03
....
Потрасируем далее по F10 до RET, и затем выйдем из этой функции. Мы окажемся здесь:

....
00F5444D : CALL 00F52658
00F54452 : RET (мы оказались здесь)
00F54453 : NOP
00F54454 : AND ECX, FF
....

Незнаю, что видите вы, а вижу что вместо RET можно вставить JMP на ту часть патча, которая будет ответственна за корректировку самой регистрации!

Отступление: В этой статье я привожу первый вариант своего патча, он конечно несовсем хорошо выглядит, но это я делаю специально для того, чтобы Вы дорогой читатель смогли уловить ход моей мысли на момент исследования этого продукта. Ибо я не ставлю своей конечной целью взлом. У меня одна единственная цель попытаться донести до вас методику взлома типичных вариантов защит.

Приведу этот участок патча:

.004C0CCE: 90 nop
.004C0CCF: 90 nop
.004C0CD0: C7055837F60045CABCDF mov d,[000F63758],0DFBCCA45
.004C0CDA: C7058C37F60045CABCDF mov d,[000F6378C],0DFBCCA45
.004C0CE4: C605E5FFF50074 mov b,[000F5FFE5],074 ;"t"
.004C0CEB: C605060D4C00ED mov b,[0004C0D06],0ED ;"э"
.004C0CF2: EB1A jmps .0004C0D0E -------- (1)
.004C0CF4: EB1D jmps .0004C0D13 -------- (2)
....
.004C0CFE: 803D8402430007 cmp b,[000430284],007 ;""
.004C0D05: 74C7 je .0004C0CCE -------- (3)
.004C0D07: C605E5FFF500EB mov b,[000F5FFE5],0EB ;"ы"
.004C0D0E: E94537A900 jmp 000AE2458
.004C0D13: 90 nop
.004C0D14: 803D6035F60000 cmp b,[000F63560],000 ;" "
.004C0D1B: 74F1 je .0004C0D0E -------- (4)
.004C0D1D: C60583024300EB mov b,[000430283],0EB ;"ы"
.004C0D24: C6050C5B420085 mov b,[000425B0C],085 ;"Е"
.004C0D2B: EBE1 jmps .0004C0D0E -------- (3)

Ассемблеровщиков прошу меня сильно не ругать так основная часть этого кода писалась прям в отладчике и поэтому приходилось оставлять немного свободного места для будущих команд!:) Кому не нравится мой код может написать свой ибо все адреса я приведу. Значит, что делает этот патч:

  1. Сначала мы ждем по адресу 000430284 байт 07 это уменя такая своеобразная проверка на распакованность основного кода программы. Если она уже распакованна, то идем по адресу 0004C0CCE.
  2. Если же она еще не распакована то патчим код распаковщика по адресу 000F5FFE5, т.е ставим безусловный переход (Там происходит проверка на целостность кода! Если этого не сделать то ASProtect выдаст сообщение, что вайл поврежден и завершит свою работу!)
  3. Код по адресу 004C0CCE выполнится в том случае, если код основной программы уже распакован. Прежде всего в адреса 000F63758 и 000F6378C нужно занести правильное значение контрольной суммы кода (Это контрольная сумма кода используется при расшифровки точки входа в программу)
  4. Затем нужно востановить исходное значение по адресу 000F5FFE5, т.е поставить первоначальный условный переход(Код по этому адресу больше вызываться небудет, но дальшее ASProtect будет расчитывать контрольную сумму очередного участка кода и этот код будет туда включен:). Кстати эта контрольная сумма расшифровывает точку входа в процедуру расшифровки основной точки входа! Вроде все правильно сказал :) если конечно, что не забыл!).
  5. А заключительная часть этого патча распологается по адресу 004C0D14. Дело в том, что ASProtect проверяет еще и целостность кода основной программы на исправления. После отработки этой проверки по адресу 00F63560 окажется какое-то значение:) И соответственно после этого мы можем смело патчить основную программу, что собственно и пытается сделать эта часть патча.

Теперь необходимо уточнить еще один нюанс! Помните я говорил, что если вы попробуете выполнить пункт Настройка в программе, то получите облом? Наверное, помните так вот в программе происходит еще одна проверка. Это происходит по адресу 00425B0B, если вы невыполните переход расположенный по этому адресу, то программа аварийно завершится! В своем патче я заменил байт по адресу 00425B0C - 84 на 85(думаю ничего страшного не произойдет если я сделал именно так).

Да патч, который запатчит регистрацию у нас есть, но ведь его еще надо как-то вызывать! Вот этим мы сейчас и займемся, помните адресс 00F5266D и инструкции после команды REP MOVSD. Там как рас 5 байт которые можно заменить на JMP в наш второй патч, а замененые команды выполнить внутри нашего патча.

Вот листинг:

.004C0CAA: 90 nop
.004C0CAB: 90 nop
.004C0CAC: 90 nop
.004C0CAD: 90 nop
.004C0CAE: C7055244F500E9A7C856 mov d,[000F54452],056C8A7E9 ------(1)
.004C0CB8: C7055644F500FF90C390 mov d,[000F54456],090C390FF -------(2)
.004C0CC2: 89C1 mov ecx,eax
.004C0CC4: 83E103 and ecx,003 ;""
.004C0CC7: E9A619A900 jmp 000AE0672

Команды (1) и (2) вставляют по адресу 000F54452 JMP на наш патч регистрации программы. Далее выполняются замененые команды и происходит возвращение в код распаковщика. Где-то примерно половину работы по созданию нашего патча мы сделали! Теперь если Вы после загрузки программы в ваш отладчик поставите бряк на адрес 00F5266D, т.е
bpx 00F5266D
и нажмете F5, вы остановитесь на первой команде по этому адресу, затем введите команду:
a

017f:00F5266D jmp 004C0CAA

Т.е другими словами вы переписали эти две команды стоящие ниже на JMP который перейдет на наш патч. Нажмите F5 и вы снова остановитесь по адресу 00F5266D, теперь если вы все сделали правильно и если я ничего не забыл программа должна запуститься зарегистрированной, естественно перед тем как жать F5 еще раз снимите все ранее установленные бряки bc*. 8-)

Я небуду спрашивать заработало это или нет потому, что я проделывал это несколько раз, последний раз в момент написания этой статьи и у меня все работало на УРА!; а перейду сразу к заключительно части статьи!

Если вы попробуете найти команды расположенные по адресу 00F5266D, то вы потерпите неудачу потому, что в экзешнике их нет, ведь это еще код распаковщика, следовательно теперь нам нужно найти место которое распаковывает эти команды в память.

Перезапускаем программу в отладчике снимаем все бряки и Ставим бряк на область памяти по адресу 00F5266D, т.е bpm 00F5266D rwx и жмем F5 пока вы неувидете следующие команды по адресу 00F673C7:

....
00F673C7 : F3A5 REP MOVSD
00F673C9 : 8BC8 MOV ECX, EAX
00F673CB : 83E103 AND ECX, BYTE +03
00F673CE : F3A4 REP MOVSB
....

Следователь по адресу 00F673C9 мы можем вставить JMP на наш патч по адресу 004C0DB1, который в свою очередь поставит JMP по адресу 00F5266D.

Вот соответствующий код в патче:

.004C0DB1: 90 nop
.004C0DB2: 8BC8 mov ecx,eax
.004C0DB4: 83E103 and ecx,003 ;""
.004C0DB7: C7056D26F500E938E656 mov d,[000F5266D],056E638E9
.004C0DC1: C6057126F500FF mov b,[000F52671],0FF ;"_"
.004C0DC8: E90166AA00 jmp 000AF53CE

Этот код выполняет замененые нами две команды и по адресу 00F5266D ставит JMP на наш патч регистрации, а затем возвращается в код распаковщика.

Далее перезапускаем программу в отладчике снимаем все бряки и ставим бряк на область памяти с адресом 00F673C7, т.е bpm 00F673C7 и жмем F5 пока не увидем похожий код:

....
00F670ED : 8B8575294400MOV EAX, [EBP+00442975]
00F670F3 : 6800800000 PUSH DWORD 8000
00F670F8 : 6A00 PUSH BYTE +00
....

По адресу 00F670F3 мы можем поставить JMP на наш патч который расположен по адресу 004C0D95, вот его код:

.004C0D95: 90 nop
.004C0D96: 6800800000 push 000008000 ;" А "
.004C0D9B: C705C973F600E9E39955 mov d,[000F673C9],05599E3E9
.004C0DA5: C605CD73F600FF mov b,[000F673CD],0FF ;"_"
.004C0DAC: E94763AA00 jmp 000AF50F8

Перезапускаем программу в отладчике снимаем все бряки и ставим бряк на область памяти с адресом 00F670ED, т.е bpm 00F670ED и жмем F5 пока не остановимся в следующем коде:

....
004B012A : F3A5 REP MOVSD (вы остановились здесь)
004B012C : 83C328 ADD EBX, BYTE +28
....
004B013E : 52PUSH EDX
004B013F : 8B18 MOV EBX, [EDX]
004B0141 : 03DA ADD EBX, EDX
004B0143 : 8B85E0EE4500 MOV EAX, [EBP+0045EEE0]
....

По адресу 004B013E можно также поставить JMP на очередной код в нашем патче, он выглядет так:

.004C0D79: 90 nop
.004C0D7A: 52 push edx
.004C0D7B: 8B18 mov ebx,[eax]
.004C0D7D: 03DA add ebx,edx
.004C0D7F: C705F370F600E99D9C55 mov d,[000F670F3],0559C9DE9
.004C0D89: C605F770F600FF mov b,[000F670F7],0FF ;"_"
.004C0D90: E9AEF3FEFF jmp .0004B0143 -------- (5)

Этот код ничего замысловатого так же не делает, он просто выполняет замененые команды и по адресу 00F670F3 ставит JMP на другую часть нашего патча расположенного по адресу 004C0D95. Могу вас обрадовать, что мы уже почти подобрались к началу пограммы, а точнее к тому куску кода, который имеется в запакованной программе.

Опять перезапускаем программу в отладчике снимаем все бряки и ставим бряк на область памяти с адресом 004B012A, т.е bpm 004B012A, жмем F5 один раз и останавливаемся в следующем коде:

....
004B067E : JMP 004B069F(вы остановились здесь)
....

Потрасируем немного программу по F8, пока недойдем до следующего кода:

....
004B06BD : 0F85B1FFFFFFFF JNZ NEAR 004B0674
004B06C3 : E92AFEFFFF JMP 004B04F2
....

Соответственно по адресу 004B06C3 мы можем вставить прыжок на нашу следующую часть патча, код его выглядит так:

.004C0D62: 90 nop
.004C0D63: C7053E014B00E9360C01 mov d,[0004B013E],0010C36E9
.004C0D6D: C60542014B0000 mov b,[0004B0142],000 ;" "
.004C0D74: E979F7FEFF jmp .0004B04F2 -------- (4)

Он сначала по адресу 004B013E вставит переход на адресс 004C0D79,а затем еще выполнит замененую нами команду: jmp 004B04F2.

Ну а теперь наконец самое главное! Вы наверное уже очень устали? А как я устал описывать все это :) Ну да ладно, продолжим. Снимаем все бряки и перезапускаем прогу под отладчиком, останавливаемся в самом начале, т.е здесь:

004B0001 : PUSHA (вы остановились здесь)
004B0002 : CALL 004B0022 (обязательно заходим в этот call, т.е жмем F8)
....
Потрасируем программу пока недойдем до следующих строк:

....
004B0016 : AD LODSD
004B0017 : 3578563412 XOR EAX, 12345678 (оригинально придуман ключ!:))
004B001C : AB STOSD
....

Записываем последовательно сть байт 3578563412 (*) на бумажку потому, что ее мы и будем искать в файле adr.exe. После чего вместо (*) мы должны будем вставить JMP на следующий код нашего патча:

.004C0D3A: 90 nop
.004C0D3B: 90 nop
.004C0D3C: 3578563412 xor eax,012345678 ;"4Vx"
.004C0D41: 803DC3064B00E9 cmp b,[0004B06C3],0E9 ;"щ"
.004C0D48: 7405 je .0004C0D4F -------- (1)
.004C0D4A: E9CDF2FEFF jmp .0004B001C -------- (2)
.004C0D4F: C705C3064B00E99A0601 mov d,[0004B06C3],001069AE9
.004C0D59: C605C7064B0000 mov b,[0004B06C7],000 ;" "
.004C0D60: EBE8
jmps .0004C0D4A -------- (3)

Единственное на что нужно обратить внимание это то, что в патче по адресу 004C0D41 я делаю проверку для того чтобы точно знать, когда расшифруется код по адресу 004B06C3, а затем уже ставлю переход на свой очередной код патча(который описан выше), т.е на адрес 004C0D62.

Ну и наконец открываем Hex-редактор, например Hiew, переходим в режим дизассемблирования, переходим на адрес .004B0017 и заменяем написанные там 5 байт на следующие: E91E0D0100.

В заключение привожу полный текст патча который необходимо поместить в конец исследуемого нами файла (там есть необходимое для нас место забитое к стати 00):

.004C0CAA: 90 nop
.004C0CAB: 90
nop
.004C0CAC: 90
nop
.004C0CAD: 90
nop
.004C0CAE: C7055244F500E9A7C856
mov d,[000F54452],056C8A7E9 ;
.004C0CB8: C7055644F500FF90C390
mov d,[000F54456],090C390FF ;
.004C0CC2: 89C1
mov ecx,eax
.004C0CC4: 83E103
and ecx,003 ;""
.004C0CC7: E9A619A900
jmp 000AE0672

.004C0CCE: 90 nop
.004C0CCF: 90
nop
.004C0CD0: C7055837F60045CABCDF
mov d,[000F63758],0DFBCCA45 ;
.004C0CDA: C7058C37F60045CABCDF
mov d,[000F6378C],0DFBCCA45 ;
.004C0CE4: C605E5FFF50074
mov b,[000F5FFE5],074 ;"t"
.004C0CEB: C605060D4C00ED
mov b,[0004C0D06],0ED ;"э"
.004C0CF2: EB1A
jmps .0004C0D0E -------- (1)
.004C0CF4: EB1D
jmps .0004C0D13 -------- (2)
.004C0CFE: 803D8402430007
cmp b,[000430284],007 ;""
.004C0D05: 74C7
je .0004C0CCE -------- (1)
.004C0D07: C605E5FFF500EB
mov b,[000F5FFE5],0EB ;"ы"
.004C0D0E: E94537A900
jmp 000AE2458

.004C0D13: 90 nop
.004C0D14: 803D6035F60000
cmp b,[000F63560],000 ;" "
.004C0D1B: 74F1
je .0004C0D0E -------- (2)
.004C0D1D: C60583024300EB
mov b,[000430283],0EB ;"ы"
.004C0D24: C6050C5B420085
mov b,[000425B0C],085 ;"Е"
.004C0D2B: EBE1
jmps .0004C0D0E -------- (3)

.004C0D3A: 90 nop
.004C0D3B: 90
nop
.004C0D3C: 3578563412
xor eax,012345678 ;"4Vx"
.004C0D41: 803DC3064B00E9
cmp b,[0004B06C3],0E9 ;"щ"
.004C0D48: 7405
je .0004C0D4F -------- (4)
.004C0D4A: E9CDF2FEFF
jmp .0004B001C -------- (5)
.004C0D4F: C705C3064B00E99A0601
mov d,[0004B06C3],001069AE9 ;
.004C0D59: C605C7064B0000
mov b,[0004B06C7],000 ;" "
.004C0D60: EBE8
jmps .0004C0D4A -------- (1)

.004C0D62: 90 nop
.004C0D63: C7053E014B00E9360C01
mov d,[0004B013E],0010C36E9 ;
.004C0D6D: C60542014B0000
mov b,[0004B0142],000 ;" "
.004C0D74: E979F7FEFF
jmp .0004B04F2 -------- (2)

.004C0D79: 90 nop
.004C0D7A: 52
push edx
.004C0D7B: 8B18
mov ebx,[eax]
.004C0D7D: 03DA
add ebx,edx
.004C0D7F: C705F370F600E99D9C55
mov d,[000F670F3],0559C9DE9 ;
.004C0D89: C605F770F600FF
mov b,[000F670F7],0FF ;"_"
.004C0D90: E9AEF3FEFF
jmp .0004B0143 -------- (3)

.004C0D95: 90 nop
.004C0D96: 6800800000
push 000008000 ;" А "
.004C0D9B: C705C973F600E9E39955
mov d,[000F673C9],05599E3E9 ;
.004C0DA5: C605CD73F600FF
mov b,[000F673CD],0FF ;"_"
.004C0DAC: E94763AA00
jmp 000AF50F8

.004C0DB1: 90 nop
.004C0DB2: 8BC8
mov ecx,eax
.004C0DB4: 83E103
and ecx,003 ;""
.004C0DB7: C7056D26F500E938E656
mov d,[000F5266D],056E638E9 ;
.004C0DC1: C6057126F500FF
mov b,[000F52671],0FF ;"_"
.004C0DC8: E90166AA00
jmp 000AF53CE

Конечно это самая малость того, что я накопал исследуя этот замечательный протектор ASProtect. Примерно, где-то процентов 25 я уже здесь описал. А всего же я раскопал примерно процентов 50 его кода. Но за гранью остались такие замечательные вещи как метод распаковки кода, сам алгоритм распаковки использующийся в ASProtect и конечноже API ASProtect'а именно API я и думаю заняться в свободное время, так-что кто знает может мы еще встретимся дорогой читатель! Засим разрешите откланяться!

Все вопросы и отзовы можно писать сюда на remos@euro.ru.

(с) 2001 Black ReMoS Night.


<= Вернуться к статьям