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

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


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


Crack ASProtect 2.3 SKE Inline patch




Массу крэкерских инструментов, видеоуроков и статей вы сможете найти на видеокурсе от нашего сайта. Подробнее здесь.

Inline Patch for InLineMe ASProtect 2.3 SKE



Автор: ev1l^4 [tPORt]



[Intro]


Работа ASProtect начинается с полиморфного декриптора, затем он выделяет память и распаковывает туда виртуальную dll, вся основная работа происходит там, проверка CRC и тд. Мы разберём полиморфный декриптор, перепишем его и сделаем криптор! Так мы пройдём первую часть, затем перехватывая некоторые места в выделенной памяти восстановим CRC и доберёмся до места, с которого можно произвести пропатчивание программы.



[Polymorph Decryptor]


Полиморфный самодифицирующийся декриптор состоит из 4 частей, одна часть декриптует код и следующую часть декриптора, таким образом декриптовка начинается с последнего блока декриптуемых данных. Полиморф - это код затрудняющий анализ, который добавляется среди обычного кода и не влияет на его работу, но при этом каждый раз он разный. Но так как мы имеем дело с полиморфным декриптором в протекторе, то значит используется генератор полиморфного декриптора. Декрипторы и данные расположены так:

1 - декриптор

2 - декриптор (закриптованный, раскриптовывается первой частью)

3 - декриптор (закриптованный, раскриптовывается первой и второй частью)

4 - декриптор (закриптованный, раскриптовывается первой, второй и третьей частью)

5 - Код выделяющий память для виртуальной dll ASProtect и осуществляющий дальнейшую работу в выделенную память.


В качестве примера возьмём InLineMe ASProtect 2.3.exe, который лежит в архиве со статьёй.

 00401000      68 01704000   PUSH 407001
 00401005      E8 01000000   CALL 0040100B
 0040100A      C3            RETN
 0040100B      C3            RETN
 - стандартное начало ASProtect, а.
 
00407001 60 PUSHAD 00407002 E8 03000000 CALL 0040700A 00407007 E9 EB045D45 JMP 459D74F7 0040700C 55 PUSH EBP 0040700D C3 RETN 0040700E E8 01000000 CALL 00407014 00407013 EB 5D JMP SHORT 00407072 - начало, подготовка к работе
00407014 5D POP EBP 00407015 BB EDFFFFFF MOV EBX, -13 0040701A 03DD ADD EBX, EBP 0040701C 81EB 00700000 SUB EBX, 7000 - получение дельта смещения равному ImageBase


[I Polymorph Decryptor]



 004070F7    5A              POP EDX - получаем дельта смещение
 004070F8    8BF9            MOV EDI, ECX - полиморфная команда
 004070FA    81C2 52080000   ADD EDX, 852 - получение последнего блока (назовём его началом декриптуемых данных, её адрес в данном примере 0040793C)
 00407100    66:81D1 0E60    ADC CX, 600E - полиморфная команда
 00407105    B8 3CE83E35     MOV EAX, 353EE83C  
 0040710A    81E8 52E63E35   SUB EAX, 353EE652 - получение количества раскриптуемых блоков
 00407110    66:81C1 E662    ADD CX, 62E6 - полиморфная команда
 00407115    FF32            PUSH DWORD PTR [EDX] - сохранение первого блока в стек
 00407117    8AF8            MOV BH, AL - полиморфная команда
 00407119    5E              POP ESI - сохраняем декриптуемые данные в регистр ESI
 0040711A    8BFB            MOV EDI, EBX - полиморфная команда
 0040711C    81C6 6774AB30   ADD ESI, 30AB7467 - декриптуем (действие 1)
 00407122    66:B9 B188      MOV CX, 88B1 - полиморфная команда
 00407126    81C6 14222225   ADD ESI, 25222214 - декриптуем (действие 2)
 0040712C    0F89 08000000   JNS 0040713A - полиморфная команда
 00407132    0F87 02000000   JA 0040713A - полиморфная команда
 00407138    50              PUSH EAX - полиморфная команда
 00407139    5B              POP EBX - полиморфная команда
 0040713A    81F6 BDCA6225   XOR ESI, 2562CABD - декриптуем (действие 3)
 00407140    8AFC            MOV BH, AH - полиморфная команда
 00407142    56              PUSH ESI - заносим в стек декриптуемые данные
 
00407143 E8 09000000 CALL 00407151 00407148 5D POP EBP 00407149 D2A3 A0591EFF SHL BYTE PTR [EBX+FF1E59A0], CL 0040714F CC INT3 00407150 15 516681F7 ADC EAX, F7816651 00407151 51 PUSH ECX 00407152 66:81F7 938B XOR DI, 8B93 00407157 59 POP ECX 00407158 5B POP EBX - обфускация
00407159 8F02 POP DWORD PTR [EDX] - сохранение из стека раскриптованных данных 0040715B 66:81D7 0123 ADC DI, 2301 - полиморфная команда 00407160 83EA 04 SUB EDX, 4 - уменьшение на 1 блок 00407163 83E8 01 SUB EAX, 1 - уменьшение счётчика на 1 00407166 0F85 14000000 JNZ 00407180 - если счётчик закончился, то идём к следующему декриптору 0040716C BF 2CD1244F MOV EDI, 4F24D12C - полиморфная команда 00407171 E9 22000000 JMP 00407198 - переход на начало второго декриптора 00407180 66:B9 6578 MOV CX, 7865 - полиморфная команда 00407184 E9 8CFFFFFF JMP 00407115 - переход на начало первого декриптора


[II Polymorph Decryptor]


 00407198    E8 06000000     CALL 004071A3 - $+Bh
 0040719D    26:67:14 BD     ADC AL, 0BD - обфускация
 004071A1    B2 03           MOV DL, 3 - обфускация
 004071A3    66:81F6 ACE7    XOR SI, 0E7AC - полиморфная команда
 004071A8    58              POP EAX - получаем дельта смещение
 004071A9    0FBFD6          MOVSX EDX, SI - полиморфная команда
 004071AC    81C0 9F070000   ADD EAX, 79F - получаем начало декриптуемых данных
 004071B2    80EE F3         SUB DH, 0F3 - полиморфная команда
 004071B5    68 BE010000     PUSH 1BE - полиморфная команда
 004071BA    0FBFF8          MOVSX EDI, AX - полиморфная команда
 004071BD    59              POP ECX - полиморфная команда
 
004071BE FF30 PUSH DWORD PTR [EAX] - заносим в стек декриптуемые данные. eax==0040793C 004071C0 66:81E2 E393 AND DX, 93E3 - полиморфная команда 004071C5 5B POP EBX - получаем в регистр EBX декриптуемые данные 004071C6 BE 3F8B982E MOV ESI, 2E988B3F - полиморфная команда
004071CB 81EB 13C4E662 SUB EBX, 62E6C413 - декриптуем (действие 1) 004071D1 81CF D1F5F402 OR EDI, 2F4F5D1 - полиморфная команда 004071D7 81F3 5076B165 XOR EBX, 65B17650 - декриптуем (действие 2) 004071DD 81EB 49F07B30 SUB EBX, 307BF049 - декриптуем (действие 3) 004071E3 8918 MOV DWORD PTR [EAX], EBX - сохраняем обратно декриптованные данные 004071E5 66:8BF7 MOV SI, DI - полиморфная команда 004071E8 83E8 03 SUB EAX, 3 004071EB 48 DEC EAX - подготавливаем следующий блок 004071EC E9 09000000 JMP 004071FA 004071F1 7D 72 JGE SHORT 00407265 004071F3 C3 RETN 004071F4 40 INC EAX 004071F5 79 BE JNS SHORT 004071B5 004071F7 1F POP DS 004071F8 6C INSB 004071F9 35 81E90100 XOR EAX, 1E981 - обфускация
004071FA 81E9 01000000 SUB ECX, 1 - уменьшаем счётчик на 1 00407200 0F85 1C000000 JNZ 00407222 - если счётчик закончился, то идём к третьему декриптору 00407206 56 PUSH ESI - полиморфная команда 00407207 53 PUSH EBX - полиморфная команда 00407208 66:BF 6E05 MOV DI, 56E - полиморфная команда 0040720C 5E POP ESI - полиморфная команда 0040720D 5A POP EDX - полиморфная команда 0040720E E9 35000000 JMP 00407248 - идём к третьему декриптору 00407213 2B88 21460734 SUB ECX, DWORD PTR [EAX+34074621] 00407219 5D POP EBP 0040721A D2A3 A0591EFF SHL BYTE PTR [EBX+FF1E59A0], CL 00407220 CC INT3 00407221 15 E90D0000 ADC EAX, 0DE9 - обфускация
00407222 E9 0D000000 JMP 00407234 00407227 91 XCHG EAX, ECX 00407228 F6F7 DIV BH 0040722A 64:CD 82 INT 82 0040722D 93 XCHG EAX, EBX 0040722E D0C9 ROR CL, 1 00407230 CE INTO 00407231 EF OUT DX, EAX 00407232 FC CLD 00407233 85E9 TEST ECX, EBP - обфускация
00407234 E9 85FFFFFF JMP 004071BE - идём на начало второго декриптора


[III Polymorph Decryptor]



 00407248    66:81C3 FF9B    ADD BX, 9BFF
 0040724D    E8 11000000     CALL 00407263
 00407252    15 2A1BB891     ADC EAX, 91B81B2A
 00407257    F6F7            DIV BH
 00407259    64:CD 82        INT 82
 0040725C    93              XCHG EAX, EBX
 0040725D    D0C9            ROR CL, 1
 0040725F    CE              INTO
 00407260    EF              OUT DX, EAX
 00407261    FC              CLD
 00407262    855F E9         TEST DWORD PTR [EDI-17], EBX
 - обфускация
 
00407263 5F POP EDI - получаем дельта смещение 00407264 E9 0C000000 JMP 00407275 - полиморфная команда 00407269 94 XCHG EAX, ESP - обфускация 0040726A 3D 32830039 CMP EAX, 39008332 - обфускация 0040726F 7E DF JLE SHORT 00407250 - обфускация 00407271 2C F5 SUB AL, 0F5 - обфускация 00407273 8AFB MOV BH, BL - обфускация 00407275 81C7 EA060000 ADD EDI, 6EA - получаем адрес начала декриптовки (0040793C) 0040727B 66:81D1 C40A ADC CX, 0AC4 - полиморфная команда 00407280 2BD2 SUB EDX, EDX - очищаем регистр EDX для введения счётчика 00407282 E9 05000000 JMP 0040728C - полиморфная команда 00407287 A9 2ECF5C65 TEST EAX, 655CCF2E - обфускация 0040728C 8B0417 MOV EAX, DWORD PTR [EDI+EDX] - получаем первые декриптуемые данные в регистр EAX 0040728F 8AEF MOV CH, BH - полиморфная команда 00407291 81C0 881F8C4C ADD EAX, 4C8C1F88 - декриптуем (действие 1) 00407297 81E8 210D7534 SUB EAX, 34750D21 - декриптуем (действие 2) 0040729D B9 DBB8DA56 MOV ECX, 56DAB8DB - полиморфная команда 004072A2 81F0 46D55C08 XOR EAX, 85CD546 - декриптуем (действие 3) 004072A8 66:81DE 4200 SBB SI, 42 - полиморфная команда 004072AD 50 PUSH EAX - заносим в стек декриптованные данные 004072AE 68 8EDEDA47 PUSH 47DADE8E - полиморфная команда 004072B3 59 POP ECX - полиморфная команда 004072B4 8F0417 POP DWORD PTR [EDI+EDX] - сохраняем декриптованные данные на место криптованных 004072B7 66:BE F96B MOV SI, 6BF9 - полиморфная команда 004072BB 68 EC5A4829 PUSH 29485AEC - полиморфная команда 004072C0 66:81C3 6D1F ADD BX, 1F6D - полиморфная команда 004072C5 5E POP ESI - полиморфная команда 004072C6 83EA 02 SUB EDX, 2 - уменьшаем блок 004072C9 E8 06000000 CALL 004072D4
004072CE C687 B4DD5223 5>MOV BYTE PTR [EDI+2352DDB4], 5B - обфускация
004072D4 5B POP EBX - полиморфная команда 004072D5 4A DEC EDX - уменьшаем блок 004072D6 4A DEC EDX - уменьшаем блок
004072D7 E8 0D000000 CALL 004072E9
004072DC 1176 77 ADC DWORD PTR [ESI+77], ESI 004072DF E4 4D IN AL, 4D 004072E1 0213 ADD DL, BYTE PTR [EBX] 004072E3 50 PUSH EAX 004072E4 49 DEC ECX 004072E5 4E DEC ESI 004072E6 6F OUTSD 004072E7 7C 05 JL SHORT 004072EE - обфускация
004072E9 5B POP EBX - полиморфная команда 004072EA 81FA B8F9FFFF CMP EDX, -648 - если счётчик равен -648h 004072F0 0F85 96FFFFFF JNZ 0040728C - то и идём к четвёртому декриптору 004072F6 8BCF MOV ECX, EDI - полиморфная команда (начало 4-ого декриптора)


[VI Polymorph Decryptor]



 004072F8    E9 0A000000     JMP 00407307 - полиморфная команда
 004072FD    EA DB7851B6 B72>JMP FAR 24B7:B65178DB - обфускация
 00407304    8D42 53         LEA EAX, DWORD PTR [EDX+53] - обфускация
 00407307    E8 05000000     CALL 0040731
 
0040730C 898E AFBC45B5 MOV DWORD PTR [ESI+B545BCAF], ECX - обфускация
00407311 B5 BC MOV CH, 0BC - полиморфная команда 00407313 5E POP ESI - получаем дельта смещение 00407314 0FBFC1 MOVSX EAX, CX - полиморфная команда 00407317 81C6 2F060000 ADD ESI, 62F - получаем начало декриптуемых данных (0040793C-1) 0040731D E9 14000000 JMP 00407336 - полиморфная команда 00407322 EC IN AL, DX - обфускация 00407323 B5 4A MOV CH, 4A - обфускация 00407325 BB D8311697 MOV EBX, 971631D8 - обфускация 0040732A 846D A2 TEST BYTE PTR [EBP-5E], CH - обфускация 0040732D 33F0 XOR ESI, EAX - обфускация 0040732F 69EE 8F1C25FA IMUL EBP, ESI, FA251C8F - обфускация 00407335 AB STOSD - обфускация 00407336 33FF XOR EDI, EDI - обнуляем регистр для счётчика 00407338 E8 0C000000 CALL 00407349 - полиморфная команда 0040733D B4 DD MOV AH, 0DD - обфускация 0040733F 52 PUSH EDX - обфускация 00407340 2320 AND ESP, DWORD PTR [EAX] - обфускация 00407342 D99E 7F4C95AA FSTP DWORD PTR [ESI+AA954C7F] - обфускация 00407348 9B WAIT - обфускация 00407349 66:8BC6 MOV AX, SI - полиморфная команда 0040734C 5B POP EBX - полиморфная команда 0040734D 8B143E MOV EDX, DWORD PTR [ESI+EDI] - получаем в регистр EDX первый блок от начала-1 декриптуемых данных 00407350 66:8BCA MOV CX, DX - полиморфная команда 00407353 81F2 F4CF4A53 XOR EDX, 534ACFF4 - декриптуем (действие 1) 00407359 E9 10000000 JMP 0040736E - полиморфная команда
0040735E 68 81266714 PUSH 14672681 00407363 BD B20380B9 MOV EBP, B98003B2 00407368 FE ??? 00407369 5F POP EDI 0040736A AC LODSB 0040736B 75 0A JNZ SHORT 00407377 0040736D 7B 81 JPO SHORT 004072F0 - обфускация
0040736E 81EA 1D13EF0C SUB EDX, 0CEF131D - декриптуем (действие 2) 00407374 68 D65D321E PUSH 1E325DD6 - полиморфная команда 00407379 66:81D9 B01B SBB CX, 1BB0 - полиморфная команда 0040737E 59 POP ECX - полиморфная команда 0040737F 81EA 92290C7F SUB EDX, 7F0C2992 - декриптуем (действие 3) 00407385 81D8 74115B23 SBB EAX, 235B1174 - полиморфная команда 0040738B 52 PUSH EDX - заносим в стек декриптованные данные 0040738C 8BDE MOV EBX, ESI - полиморфная команда 0040738E 8F043E POP DWORD PTR [ESI+EDI] - сохраняем декриптованные данные на место криптованных 00407391 81CB 5B17DF38 OR EBX, 38DF175B - полиморфная команда 00407397 66:81C0 A4BF ADD AX, 0BFA4 - полиморфная команда 0040739C 81EF C258721E SUB EDI, 1E7258C2 - уменьшаем счётчик
004073A2 0F81 2A000000 JNO 004073D2 - полиморфная команда
004073A8 E8 11000000 CALL 004073BE 004073AD C51A LDS EBX, FWORD PTR [EDX] 004073AF 4B DEC EBX 004073B0 2841 E6 SUB BYTE PTR [ECX-1A], AL 004073B3 27 DAA 004073B4 D4 7D AAM 7D 004073B6 ^ 72 C3 JB SHORT 0040737B 004073B8 40 INC EAX 004073B9 ^ 79 BE JNS SHORT 00407379 004073BB 1F POP DS 004073BC 6C INSB - обфускация
004073BE E8 0D000000 CALL 004073D0 004073C3 B1 96 MOV CL, 96 004073C5 17 POP SS 004073C6 04 ED ADD AL, 0ED 004073C8 22B3 70E96E0F AND DH, BYTE PTR [EBX+F6EE970] 004073CE 9C PUSHFD 004073CF A5 MOVSD 004073D0 5B POP EBX 004073D1 58 POP EAX - обфускация
004073D2 81C7 BE58721E ADD EDI, 1E7258BE - выравниваем счётчик 004073D8 8BCF MOV ECX, EDI - полиморфная команда 004073DA 81FF D4FAFFFF CMP EDI, -52C - если равно 004073E0 0F85 12000000 JNZ 004073F8 - то не срабатывает и идём к раскриптованному коду
004073E6 80D0 CC ADC AL, 0CC - полиморфная команда 004073E9 E9 25000000 JMP 00407413 - идём к раскриптованному коду
004073F8 50 PUSH EAX - полиморфная команда 004073F9 52 PUSH EDX - полиморфная команда 004073FA 5B POP EBX - полиморфная команда 004073FB 59 POP ECX - полиморфная команда 004073FC ^ E9 4CFFFFFF JMP 0040734D - идём на начало четвёртого декриптора


[Code of the unpacking ASProtect]


 004074BA    6A 40           PUSH 40
 004074BC    68 00100000     PUSH 1000
 004074C1    FFB5 08040000   PUSH DWORD PTR [EBP+408]
 004074C7    6A 00           PUSH 0
 004074C9    FF95 F0030000   CALL DWORD PTR [EBP+3F0] ; kernel32.VirtualAlloc
 004074CF    8985 CC010000   MOV DWORD PTR [EBP+1CC], EAX ; 008E0000  
 - выделение памяти для данных распаковки и сохранение адреса в зарезервированную память
 
004074E1 50 PUSH EAX ; 008E0000 004074E2 53 PUSH EBX ; 004089E8 004074E3 E8 04010000 CALL 004075EC - распаковка кода в выделенную память
004074E8 6A 40 PUSH 40 004074EA 68 00100000 PUSH 1000 004074EF FFB5 08040000 PUSH DWORD PTR [EBP+408] 004074F5 6A 00 PUSH 0 004074F7 FF95 F0030000 CALL DWORD PTR [EBP+3F0]; kernel32.VirtualAlloc 004074FD 8985 31040000 MOV DWORD PTR [EBP+431], EAX ; 00940000 - выделение памяти для распаковщика ASProtect, виртуальной dll ASProtect и сохранение адреса в зарезервированную память
004075AA 8985 C7010000 MOV DWORD PTR [EBP+1C7], EAX - сохранение адреса для перехода в выделенную память
004075D0 68 00800000 PUSH 8000 004075D5 6A 00 PUSH 0 004075D7 56 PUSH ESI ; 008E0000 004075D8 FF95 F4030000 CALL DWORD PTR [EBP+3F4] ; kernel32.VirtualFree - освобождение выделенной памяти
004075DE 68 00009900 PUSH 990000 004075E3 C3 RETN - переход в выделенную память для дальнейшей распаковки ASProtect
009900B6 6A 04 PUSH 4 009900B8 68 00100000 PUSH 1000 009900BD 68 46050000 PUSH 546 009900C2 6A 00 PUSH 0 009900C4 FF95 79294400 CALL DWORD PTR [EBP+442979] ; kernel32.VirtualAlloc 009900CA 8985 75294400 MOV DWORD PTR [EBP+442975], EAX ; 008E0000 - выделение памяти под следующий распаковщик и сохранение адреса
009900D6 50 PUSH EAX ; 008E0000 009900D7 53 PUSH EBX ; 00990101 009900D8 E8 74050000 CALL 00990651 - распаковка из выделенной памяти в следующую
009900F3 68 00800000 PUSH 8000 009900F8 6A 00 PUSH 0 009900FA 50 PUSH EAX ; 008E0000 009900FB FF95 7D294400 CALL DWORD PTR [EBP+44297D] ; kernel32.VirtualFree - освобождение выделенной памяти
00990101 8D85 512C4400 LEA EAX, DWORD PTR [EBP+442C51] 00990107 50 PUSH EAX ; 0099030D 00990108 C3 RETN - переход в следующий распаковщик
00990339 6A 04 PUSH 4 0099033B 68 00100000 PUSH 1000 00990340 50 PUSH EAX 00990341 6A 00 PUSH 0 00990343 FF95 79294400 CALL DWORD PTR [EBP+442979] ; kernel32.VirtualAlloc 00990349 8985 75294400 MOV DWORD PTR [EBP+442975], EAX ; 008E0000 - выделение памяти под код для распаковки ASProtect и сохранение адреса
00990358 50 PUSH EAX ; 008E0000 00990359 53 PUSH EBX ; 00941000 0099035A E8 F2020000 CALL 00990651 - распаковка dll ASProtect из одной выделенной памяти в другую
009903D7 68 00800000 PUSH 8000 009903DC 6A 00 PUSH 0 009903DE 50 PUSH EAX ; 008E0000 009903DF FF95 7D294400 CALL DWORD PTR [EBP+44297D] ; kernel32.VirtualFree - освобождение выделенной памяти
009905BB 8985 112F4400 MOV DWORD PTR [EBP+442F11], EAX ; (0097F5A0) - сохранение адреса точки входа виртуальной dll ASProtect

009905C1 61 POPAD 009905C2 75 08 JNZ SHORT 009905CC 009905C4 B8 01000000 MOV EAX, 1 009905C9 C2 0C00 RETN 0C 009905CC 68 A0F59700 PUSH 97F5A0 009905D1 C3 RETN - переход на точку входа dll ASProtect
0097F5A0 55 PUSH EBP ; InLineMe.00407418 0097F5A1 8BEC MOV EBP, ESP 0097F5A3 83C4 B4 ADD ESP, -4C 0097F5A6 B8 88F29700 MOV EAX, 97F288 0097F5AB E8 D867FCFF CALL 00945D88 - процедура инициализации Delphi 0097F5B0 E8 0B40FCFF CALL 009435C0 - точка входа ASProtect
00943690 E8 F7FEFFFF CALL 0094358C 0094358C BF 9C149800 MOV EDI, 98149C 00943591 8B1D B4149800 MOV EBX, DWORD PTR [9814B4] 00943597 8B2D B0149800 MOV EBP, DWORD PTR [9814B0] 0094359D FF77 1C PUSH DWORD PTR [EDI+1C] 009435A0 FF77 20 PUSH DWORD PTR [EDI+20] 009435A3 8B37 MOV ESI, DWORD PTR [EDI] 009435A5 B9 0B000000 MOV ECX, 0B 009435AA F3:A5 REP MOVSD 009435AC 5F POP EDI ; 00943695 009435AD 5E POP ESI ; 00943695 009435AE 31C0 XOR EAX, EAX 009435B0 8705 30109800 XCHG DWORD PTR [981030], EAX 009435B6 F7D8 NEG EAX 009435B8 19C0 SBB EAX, EAX 009435BA 40 INC EAX 009435BB C9 LEAVE 009435BC C2 0C00 RETN 0C - переход в начало цикла VM ASProtect


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


 0097E3B8     55              PUSH EBP
 0097E3B9     8BEC            MOV EBP, ESP
 0097E3BB     83C4 F4         ADD ESP, -0C
 - начало распаковщика первых байт цикла VM
 
0097E610 E8 73FBFFFF CALL 0097E188 - процедура начала цикла VM, нам сюда 0097E615 E8 AA4BFCFF CALL 009431C4 0097E61A 8B45 FC MOV EAX, DWORD PTR [EBP-4] 0097E61D E8 F245FCFF CALL 00942C14 0097E622 E8 71E8FFFF CALL 0097CE98 0097E627 5F POP EDI 0097E628 5E POP ESI 0097E629 5B POP EBX 0097E62A 8BE5 MOV ESP, EBP 0097E62C 5D POP EBP 0097E62D C3 RETN
0097E188 68 00000000 PUSH 0 0097E18D 68 88E19700 PUSH 97E188 0097E192 68 CCEFA300 PUSH 0A3EFCC 0097E197 E8 ACB0FFFF CALL 00979248 - начало цикла VM, нам сюда
00979248 60 PUSHAD 00979249 89E0 MOV EAX, ESP 0097924B 9C PUSHFD 0097924C 5A POP EDX 0097924D 55 PUSH EBP 0097924E 89E5 MOV EBP, ESP 00979250 83C5 24 ADD EBP, 24 00979253 31C9 XOR ECX, ECX 00979255 64:8B09 MOV ECX, DWORD PTR FS:[ECX] 00979258 81EC B80B0000 SUB ESP, 0BB8 0097925E FF75 08 PUSH DWORD PTR [EBP+8] 00979261 FF75 0C PUSH DWORD PTR [EBP+C] 00979264 52 PUSH EDX 00979265 51 PUSH ECX 00979266 50 PUSH EAX 00979267 FF75 04 PUSH DWORD PTR [EBP+4] 0097926A E8 F5FEFFFF CALL 00979164 - заходим сюда - начало VM
00979229 E8 8AFDFFFF CALL 00978FB8 0097922E 5F POP EDI 0097922F 5E POP ESI 00979230 5B POP EBX 00979231 8BE5 MOV ESP, EBP 00979233 5D POP EBP 00979234 C2 1800 RETN 18 - в конце процедуры CALL 00979164, нам нужна последняя процедура
0097900B FF75 F8 PUSH DWORD PTR [EBP-8] 0097900E 9D POPFD 0097900F 8B65 F4 MOV ESP, DWORD PTR [EBP-C]\ 00979012 61 POPAD 00979013 C3 RETN

- после работы VM происходит переход на какое-либо действие, нам это место нужно для перехвата входа в процедуру MapViewOfFile, которая выделяет место под запакованный файл ASProtect,ом и сохраняет его там для проверки CRC, нам нужно поменять там изменённые данные на оригинальные, чтобы CRC посчиталось идентично оригиналу. Также это место можно найти по сигнатуре 9D 8B 65 ?? 61 C3, искать с начала выделенной памяти, нам нужно то, которое попадается второй раз.


Чтобы перехватить переход в процедуру MapViewOfFile, нам нужно узнать в какой раз будит переход на эту API, для этого мы перехватим это место и сделаем счётчик.


Ставим железный брейк на выполнение по адресу 0097900E(в моём случае такой), запускаем и выделяем память используя плагин HideOD, у меня выделился адрес 1BA0000

 0097900E     68 0000BA01     PUSH 1BA0000
 00979013     C3              RETN
 - переход в выделенную память
 
01BA0000 9D POPFD 01BA0001 8B65 F4 MOV ESP, DWORD PTR [EBP-C] 01BA0004 61 POPAD 01BA0005 FF05 4000BA01 INC DWORD PTR [1BA0040] - увеличиваем счётчик 01BA000B C3 RETN

- последние 6 байт, увеличение счётчика и возвращение, куда шёл переход. Убираем железный брейк и ставим брейк на API MapViewOfFile, запускаем. У меня по адресу [1BA0040] было 2Dh(45d).

 01BB0000     68 0000BB01     PUSH 1BB0000
 01BB0005     68 D3D39700     PUSH 97D3D3
 01BB000A     68 1888A300     PUSH 0A38818
 01BB000F     E8 3492DCFE     CALL 00979248
  

- после выполнения MapViewOfFile, возвращение идёт на начало VM.


; Следующий адрес будит нужен для пропатчивания программы. Искать будим просто, поставим брейк на запись в секцию кода, после того как распакуется код, поставим брейк на доступ к секции кода, т.к. будут проверка кода, если он пропатчен раньше проверки CRC, то произойдёт ошибка, мы просто пропатчим код после этой проверки.

 0094C0E6     881C3E          MOV BYTE PTR [ESI+EDI], BL
 0094C0E9     FF45 F0         INC DWORD PTR [EBP-10]
 0094C0EC     FF4D EC         DEC DWORD PTR [EBP-14]
 0094C0EF     75 95           JNZ SHORT 0094C086
  

- первое прерывание, брейк на запись, убираем брейк, пропускаем цикл и снова ставим брейк на запись и жмём shift+f9 до тех пор, пока не попадем в такое место:


 0094266B     F3:A5           REP MOVSD
 0094266D     89C1            MOV ECX, EAX
 0094266F     83E1 03         AND ECX, 3
 00942672     F3:A4           REP MOVSB
 00942674     5F              POP EDI                                  ; 0012FF3C
 00942675     5E              POP ESI                                  ; 0012FF3C
 00942676     C3              RETN
  

- запись распакованного кода в секцию кода, далее ставим брейк на доступ к секции кода и запускаем


 0094FB5C     033A            ADD EDI, DWORD PTR [EDX]
 0094FB5E     03CF            ADD ECX, EDI
 0094FB60     8BF9            MOV EDI, ECX
 0094FB62     C1E7 03         SHL EDI, 3
 0094FB65     C1E9 1D         SHR ECX, 1D
 0094FB68     0BF9            OR EDI, ECX
  

- получаем хэш от секции кода, снимаем брейк и трейсим вниз, выходим из процедуры


 00950318     8BD7            MOV EDX, EDI
 0095031A     8BC6            MOV EAX, ESI
 0095031C     8B08            MOV ECX, DWORD PTR [EAX]
 0095031E     FF51 14         CALL DWORD PTR [ECX+14]
 00950321     83C7 40         ADD EDI, 40
 00950324     83EB 40         SUB EBX, 40
 00950327     83FB 40         CMP EBX, 40
 0095032A     7D EC           JGE SHORT 00950318
 0095032C     8B0424          MOV EAX, DWORD PTR [ESP]
 - выходим из цикла получения хеша
 
0097DF06 83C4 30 ADD ESP, 30 0097DF09 5D POP EBP 0097DF0A 5F POP EDI 0097DF0B 5E POP ESI 0097DF0C 5B POP EBX 0097DF0D C3 RETN - трейсим до сюда
0040100C EB 14 JMP SHORT 00401022

- меняем в секции кода два байта, для обхода мессаги, которую нужно кильнуть и запускаем

; Инлайнми запустился успешно, нет мессаги. Проверив, а доступен ли адрес 0097DF06 после выполнения API MapViewOfFile, мы видим, он доступен. Анализ окончен!


[Example of the use ASPPCAD]


Для обхода полиморфного декриптора я написал простой криптор/декриптор, который приложен к статье. Сейчас он заточен под InLineMe ASProtect 2.3.exe, если вам нужно будит использовать его в другой программе, то все нужные команды и адреса использования вынесены в Cryptor_and_Decryptor.asm, разобраться как ASPPCAD работает думаю сможете самостоятельно, я лишь покажу пример использования.


Нам нужно место, которое рядом с готовым переходом в выделенную память, ставим брейк на VirtualAlloc и ищем, как найдём убираем брейк c VirtualAlloc, мне понравилось это:

004075C2 53 PUSH EBX

но, т.к. оно закриптовано и раскриптовывается поблочно, нам нужно узнать адрес блока, рядом с этим местом, ставим железный брейк на доступ 1 или 2 байта, перезапускаем, прервались:

00407115 FF32 PUSH DWORD PTR [EDX] ; 004075C0

  • адрес узнали, делаем рестарт программы


Попробуем сначала декриптор, копируем 16 байт по адресу 004075C0 - EC 9B 41 85 E9 21 55 88 E6 D4 03 95 31 2E 33 9D и ещё 8 байт в начале и в конце, получаем

EC 02 4C F7 BD 06 83 EA EC 9B 41 85 E9 21 55 88 E6 D4 03 95 31 2E 33 9D 51 9C 0E FF EC 21 55 9C

- декриптуем байты и получаем 16 декриптованных байт, как видим 8 по бокам исчезли, но они нам и не нужны, они нужны были лишь для правильной декриптовки, т.к. блоки взаимосвязаны.


0000536A006A006A01578B5E0803DF53 - получили из ASPPCAD

00 00 53 6A 00 6A 00 6A 01 57 8B 5E 08 03 DF 53 - из OllyDbg

- идентичны, за исключением пробелов :)


Криптовка делается аналогично, естественно доходим до раскриптованного кода, а уже потом криптуем. По адресу 004075C2 пишем свои байты, по адресу 004075C0 копируем 16 байт и 8 по бокам, потом криптуем в ASPPCAD и получаем 16 байт, которые нужно сохранить по адресу 004075C0, когда код не раскриптован, изменится столько байт, сколько меняли, в нашем случаи будит 5.



[Inline patching InLineMe - ASProtect 2.3 SKE]


Инлайн патч расположим в последней секции .adata, для этого увеличим у неё RawSize, поставим 300h. Добавим 300 байт физически, с помощью HexAssistant или другого хекс редактора способного добавлять байты. Открываем в HexAssistant, идём вниз используя клавишу End, нажимаем Insert Block и вводим 300h, добавляемые байты 00 и кликаем OK.


Попробуем запустить приложение, выскакивает сообщение о повреждённом файле, но впереди мы исправим это недоразумение. Адрес секции .adata==00459000, поэтому по адресу 004075C2 пишем переход JMP 00459000, но предварительно запишем по адресу 00459000 код возвращающий на место эти байты, прежде дойдите до раскриптованного кода, для быстрого прохода до раскриптованного кода используйте брейк на API VirtualAlloc.


Я делаю так, пишу записать 0:


 00459000    C705 C2754000 0>MOV DWORD PTR [4075C2], 0
 0045900A    C605 C2754000 0>MOV BYTE PTR [4075C2], 0
  

потом в окне помощи подглядываю байты, которые расположены в настоящий момент:

DS:[004075C2]=6A006A53

DS:[004075C2]=53 ('S')

и добавляю константы, получаю:


 00459000    C705 C2754000 5>MOV DWORD PTR [4075C2], 6A006A53
 0045900A    C605 C2754000 5>MOV BYTE PTR [4075C2], 53
  

- сохраняем код в файл, затем пишем переход по адресу 004075C2 в секцию .adata и криптуем, как было рассказано в прошлой главе, получаем EC9B87339E6E8F88E6D40395312E339D - эти байты нужно сохранить по адресу 004075C0, пока ещё не раскриптован код, поэтому перезапускаем и вписываем, изменилось 5 байт, как раз те, что и заменили, сохраняем их.


 00459000    C705 C2754000 5>MOV DWORD PTR [4075C2], 6A006A53
 0045900A    C605 C2754000 5>MOV BYTE PTR [4075C2], 53
 00459011    90              NOP
 - байты восстановились, продолжаем
 
004074FD 8985 31040000 MOV DWORD PTR [EBP+431], EAX

- здесь сохраняется адрес dll ASProtect и работы с ним, сохраним его в секции .adata


009900F3 68 00800000 PUSH 8000

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


 $+500F3  >  68 00800000     PUSH 8000
 
00459011 50 PUSH EAX 00459012 8B85 31040000 MOV EAX, DWORD PTR [EBP+431] 00459018 A3 00904500 MOV DWORD PTR [459000], EAX - сохраняем регистр EAX, т.к. мы его используем, сохраняем в нашу память выделенный адрес
0045901D C780 F3000500 6>MOV DWORD PTR [EAX+500F3], 45903668 00459027 66:C780 F700050>MOV WORD PTR [EAX+500F7], 0C300 00459030 58 POP EAX ; 00990000 00459031 - E9 8CE5FAFF JMP 004075C2 ; InLineMe.004075C2 - сохраняем адрес возвращения, востанавливаем значение в регистре EAX и продолжаем работу кода, с перехваченного места
$+505C1 > 61 POPAD - смещение
009905C1 61 POPAD 009905C2 75 08 JNZ SHORT 009905CC 009905C4 B8 00C30000 MOV EAX, 0C300 009905C9 C2 0C00 RETN 0C 009905CC 68 A0F59700 PUSH 97F5A0 009905D1 C3 RETN - следующее место, которое будим перехватывать
00459036 50 PUSH EAX 00459037 A1 00904500 MOV EAX, DWORD PTR [459000] 0045903C C780 F3000500 6>MOV DWORD PTR [EAX+500F3], 800068 00459046 66:C780 F700050>MOV WORD PTR [EAX+500F7], 6A00 0045904F C780 C1050500 6>MOV DWORD PTR [EAX+505C1], 45907368 00459059 66:C780 C105050>MOV WORD PTR [EAX+505C5], 0C300 00459062 05 F3000500 ADD EAX, 500F3 00459067 A3 6E904500 MOV DWORD PTR [45906E], EAX 0045906C 58 POP EAX 0045906D 68 00000000 PUSH 0 00459072 C3 RETN

- сохраняем код, востанавливаем байты, перехватываем новое место, пишем переход (делаем также, как в ASProtect,е)



 $+3900E  >  9D              POPFD
 - смещение
 
0097900E 9D POPFD 0097900F 8B65 F4 MOV ESP, DWORD PTR [EBP-C] 00979012 61 POPAD 00979013 C3 RETN - следующее место, которое будим перехватывать
00459073 50 PUSH EAX 00459074 A1 00904500 MOV EAX, DWORD PTR [459000] 00459079 C780 C1050500 6>MOV DWORD PTR [EAX+505C1], B8087561 00459083 66:C780 C105050>MOV WORD PTR [EAX+505C1], 7561 0045908C C780 0E900300 6>MOV DWORD PTR [EAX+3900E], 4590A668 00459096 66:C780 1290030>MOV WORD PTR [EAX+39012], 0C300 0045909F 05 C1050500 ADD EAX, 505C1 004590A4 ^ EB C1 JMP SHORT 00459067 00459067 A3 6E904500 MOV DWORD PTR [45906E], EAX 0045906C 58 POP EAX 0045906D 68 C1059900 PUSH 9905C1 00459072 C3 RETN

- востанавливаем байты, перехватываем новое место и переходим к выполнению кода протектора


Следующий наш код будит работать так:

1. Будет сравнение, не 45(2Dh) ли раз проходим, если нет, то идём как обычно, если да, то отрабатываем:


 004590BB    9D              POPFD
 004590BC    8B65 F4         MOV ESP, DWORD PTR [EBP-C]
 004590BF    61              POPAD
  

2. Меняем параметр у API MapViewOfFile, записываем в параметр AccessMode 1(FILE_MAP_COPY) на место 4(FILE_MAP_READ), чтобы был доступ на запись:


 004590C0    C74424 0C 01000>MOV DWORD PTR [ESP+C], 1
  

3. Перехватываем другое место:


 $+39248  >  60              PUSHAD
 00979248    60              PUSHAD
 00979249    89E0            MOV EAX, ESP
 0097924B    9C              PUSHFD
 0097924C    5A              POP EDX
 0097924D    55              PUSH EBP
 0097924E    89E5            MOV EBP, ESP
 - находится просто, начало VM:
 01BB0000    68 0000BB01     PUSH 1BB0000
 01BB0005    68 D3D39700     PUSH 97D3D3
 01BB000A    68 1888A300     PUSH 0A38818
 01BB000F    E8 3492DCFE     CALL 00979248
 - процедура, 00979248    60              PUSHAD
 
004590C8 50 PUSH EAX 004590C9 A1 00904500 MOV EAX, DWORD PTR [459000] 004590CE C780 0E900300 9>MOV DWORD PTR [EAX+3900E], F4658B9D 004590D8 66:C780 1290030>MOV WORD PTR [EAX+39012], 0C361 004590E1 C780 48920300 6>MOV DWORD PTR [EAX+39248], 4590F668 004590EB 66:C780 4C92030>MOV WORD PTR [EAX+3924C], 0C300 004590F4 58 POP EAX ; 01BB0014 004590F5 C3 RETN - востанавливаем байты, перехватываем новое место, возвращаем значение в регистр EAX и идём на выполнение MapViewOfFile, полный код: 004590A6 FE05 75904500 INC BYTE PTR [459075] - место, с 00 004590AC 803D 75904500 2>CMP BYTE PTR [459075], 2D 004590B3 74 06 JE SHORT 004590BB 004590B5 9D POPFD 004590B6 8B65 F4 MOV ESP, DWORD PTR [EBP-C] 004590B9 61 POPAD 004590BA C3 RETN 004590BB 9D POPFD 004590BC 8B65 F4 MOV ESP, DWORD PTR [EBP-C] 004590BF 61 POPAD 004590C0 C74424 0C 01000>MOV DWORD PTR [ESP+C], 1 004590C8 50 PUSH EAX 004590C9 A1 00904500 MOV EAX, DWORD PTR [459000] 004590CE C780 0E900300 9>MOV DWORD PTR [EAX+3900E], F4658B9D 004590D8 66:C780 1290030>MOV WORD PTR [EAX+39012], 0C361 004590E1 C780 48920300 6>MOV DWORD PTR [EAX+39248], 4590F668 004590EB 66:C780 4C92030>MOV WORD PTR [EAX+3924C], 0C300 004590F4 58 POP EAX ; 01BB0014 004590F5 C3 RETN

- сравниваем, если наше, то выполняем оригинальные байты, меняем параметр, возвращаем код и перехватываем новое место


В следующем коде нам нужно востановить изменённые байты, для этого сравниваем их чем-то, нам главное узнать смещения, я сравнивал dup,ом ;)


 +----------------+----------+----------+
 |   RAW Offset   | New Byte | Old Byte |
 +----------------+----------+----------+
 |    000002B1    |    03    |    00    |
 |    000013C2    |    87    |    41    |
 |    000013C3    |    33    |    85    |
 |    000013C4    |    9E    |    E9    |
 |    000013C5    |    6E    |    21    |
 |    000013C6    |    8F    |    55    |
 +----------------+----------+----------+
  

Адрес с выделенной памятью API MapViewOfFile возвращает в регистр EAX, поэтому смещение сразу будим добавлять к нему



 $+3DF06  >  83C4 30         ADD ESP, 30
 0097DF06    83C4 30         ADD ESP, 30
 0097DF09    5D              POP EBP                                  ; 01BC0000
 0097DF0A    5F              POP EDI                                  ; 01BC0000
 0097DF0B    5E              POP ESI                                  ; 01BC0000
 0097DF0C    5B              POP EBX                                  ; 01BC0000
 0097DF0D    C3              RETN
  

- следующий адрес, который будим перехватывать и с него же патчить код программы


 004590F6    C680 B1020000 0>MOV BYTE PTR [EAX+2B1], 0 - востанавливаем изменнёные байты
 004590FD    C780 C2130000 4>MOV DWORD PTR [EAX+13C2], 21E98541 - востанавливаем изменнёные байты
 00459107    C680 C6130000 5>MOV BYTE PTR [EAX+13C6], 55 - востанавливаем изменнёные байты
 0045910E    50              PUSH EAX
 0045910F    A1 00904500     MOV EAX, DWORD PTR [459000]
 00459114    C780 48920300 6>MOV DWORD PTR [EAX+39248], 9CE08960
 0045911E    66:C780 4C92030>MOV WORD PTR [EAX+3924C], 555A
 00459127    C780 06DF0300 6>MOV DWORD PTR [EAX+3DF06], 45914468
 00459131    66:C780 0ADF030>MOV WORD PTR [EAX+3DF0A], 0C300
 0045913A    05 48920300     ADD EAX, 39248
 0045913F  ^ E9 23FFFFFF     JMP 00459067
 00459067    A3 6E904500     MOV DWORD PTR [45906E], EAX
 0045906C    58              POP EAX
 0045906D    68 00000000     PUSH 0
 00459072    C3              RETN
  

- востанавливаем изменённые данные в выделенной памяти по смещениям, чтобы CRC посчиталось идентично оригиналу, возвращаем изменённые байты в перехваченном месте, перехватываем новое место с которого можно произвести пропатчивание программы, добавляем смещение к базе и получаем перехваченный адрес на который перейдём


 00459144    50              PUSH EAX
 00459145    A1 00904500     MOV EAX, DWORD PTR [459000]
 0045914A    C780 06DF0300 8>MOV DWORD PTR [EAX+3DF06], 5D30C483
 00459154    66:C780 0ADF030>MOV WORD PTR [EAX+3DF0A], 5E5F
 0045915D    66:C705 0C10400>MOV WORD PTR [40100C], 14EB
 00459166    05 06DF0300     ADD EAX, 3DF06
 0045916B  ^ E9 F7FEFFFF     JMP 00459067
 00459067    A3 6E904500     MOV DWORD PTR [45906E], EAX
 0045906C    58              POP EAX
 0045906D    68 00000000     PUSH 0
 00459072    C3              RETN
  

- возвращаем изменённые данные в перехваченном месте и пропатчиваем программу!




[Outro]


Мы рассмотрели полиморфный декриптор и сделали самый красивый обход этого места, немного пробежались по распаковке виртуальной dll ASProtect,а и по самому телу протектора, некоторые места были мало рассмотрены, но для создания инлайн патча, как видите, этого вполне хватает.




[Greets to]


Red_Bar0n, M!H@N, x0man and all tPORt members…



[Thank to]


void for review.



Скачать статью "Crack ASProtect 2.3 SKE Inline patch" в авторском оформление + файлы.
пароль архива на картинке



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


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