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

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


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

Распаковка eXPressor 1.5.0.1, Protection stub.

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

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

Автор: HoBleen <DragoonFly@rambler.ru>

Распаковка eXPressor 1.5.0.1, Protection stub.

Инструменты.


OllyDbg 1.10 и плагины к ней: Olly advanced 1.26 (или просто протапченный отладчик), PhantOm 0.60, OllyScript v0.93.
ImpRec
PETools или дампер в виде плагина к OllyDbg.

Жертва.


Распаковывать будем сам пакер Expressor версии 1.5.0.1.

Антиотладка.


Для начала настроим наш отладчик. В Олли адвансед помечаем все чекбоксы, отвечающие за исправление багов. В фантоме выставляем галки "Hide from PEB", "LoadDriver", "hook GetTickCount", "hook RDTSC" и "Custom handler exceptions". Первые две опции защищают олю от обнаружения, RDTSC и GetTickCount - от антитрейса, а вот последняя нужна для обхода фишки Guard Access Flag (Описывается далее).

Поехали!


Итак, грузим нашу цель в отладчик. Видим такой ЕР:


004E5000 > 68 92545300      PUSH eXPresso.00535492
004E5005   C3               RETN
004E5006   35 3FC90973      XOR EAX,7309C93F
004E500B   82B1 BC72D820 4A XOR BYTE PTR DS:[ECX+20D872BC],4A
004E5012   F0:2E:58         LOCK POP EAX                        
004E5015   3B45 92          CMP EAX,DWORD PTR SS:[EBP-6E]
004E5018   F1               INT1


Попробуем дойти до ОЕР. Запускаем программу, останавливаемся на каком-то исключении:


00B145F0   8908             MOV DWORD PTR DS:[EAX],ECX ; <-- EAX = 0
00B145F2   E8 03000000      CALL 00B145FA
00B145F7   EB 02            JMP SHORT 00B145FB


Жмём Shift + F9. После этого пакер распаковывает секции программы, настраивает импорт программы, посылает кучу debug string отладчику =) Встаём на еще одном исключении:


00B189F5   8138 EEFEEEFE    CMP DWORD PTR DS:[EAX],FEEEFEEE ; <-- EAX = 0
00B189FB  ^75 F4            JNZ SHORT 00B189F1
00B189FD   FE4D FF          DEC BYTE PTR SS:[EBP-1]
00B18A00  ^75 EF            JNZ SHORT 00B189F1
00B18A02   64:8F05 00000000 POP DWORD PTR FS:[0]
00B18A09   C745 F8 01000000 MOV DWORD PTR SS:[EBP-8],1
00B18A10   C3               RETN
00B18A11   837D F8 00       CMP DWORD PTR SS:[EBP-8],0
00B18A15   75 20            JNZ SHORT 00B18A37
00B18A17   8B45 10          MOV EAX,DWORD PTR SS:[EBP+10]
00B18A1A   EB 01            JMP SHORT 00B18A1D
00B18A1C  -E9 C780B800      JMP 016A0AE8


Пока оно нас не интересует. Отпускаем программу еще раз и видим окно с просьбой зарегистрироваться. Обычно протекторы выдают подобные сообщения недалеко от ОЕР'а. Попробуем поставить брекпоинт на обращение к секции кода. нажимаем на ОК, проходимся по exception'ам и... прога запустилась. Значит прот предвидел наши действия и сбросил атрибуты секции кода. Ну что же, перезапускаем программу, идём по исключениям до месаджбокса и ставим брекпоинт на функцию VirtualProtect. Причем не на первый байт функции, т.к. протектор проверяет вызываемые функции на наличие перехвата 0ССh, а на второй (или еще дальше - как угодно). Прерываемся на ней и смотрим в стек.


0012F704   00A7375B   <-- ESP
0012F708   00401000   |lpAddress = VA of code section
0012F70C   0007E25D   |dwSize = size of code section
0412F710   00000010   |flNewProtect
0012F714   0012FD70   |lpflOldProtect   


Первый же вызов наш - в стеке лежит адрес секции кода, на которую прот хочет поставить атрибуты защиты, чтобы сбросить наш брекпоинт. Выходим из функции. После этого протектор не будет проверять защиту страниц, поэтому можно смело ставить memory breakpoint on access. Проходим десяток исключений и оказываемся точно на ОЕР.


0045417D   55               PUSH EBP
0045417E   8BEC             MOV EBP,ESP
00454180   6A FF            PUSH -1
00454182   68 48694800      PUSH eXPresso.00486948
00454187   68 D0954500      PUSH eXPresso.004595D0
0045418C   64:A1 00000000   MOV EAX,DWORD PTR FS:[0]
00454192   50               PUSH EAX
00454193   64:8925 00000000 MOV DWORD PTR FS:[0],ESP
0045419A   83EC 58          SUB ESP,58
0045419D   53               PUSH EBX
0045419E   56               PUSH ESI
0045419F   57               PUSH EDI
004541A0   8965 E8          MOV DWORD PTR SS:[EBP-18],ESP
004541A3   FF15 40024800    CALL DWORD PTR DS:[480240]


Охрана, встаёт охрана!


Если бы опция "Custom handler exceptions" не была включена, то прервались бы в таком интересном месте (функция-пустышка):


01500000   C3               RETN			; <=== Здесь
01500001   0000             ADD BYTE PTR DS:[EAX],AL
01500003   0000             ADD BYTE PTR DS:[EAX],AL


И оля сообщает об остановке на мемори брекпоинте. Но мы же ничего не ставили на такой адрес! Если запустить программу по F9, то выскочит окошко с едким замечанием о том, что мы используем отладчик. Попробуем разобраться. Прокрутим окно кода чуть выше адреса возврата из этой пустышки и увидим следующий код:


00C18847   55               PUSH EBP
00C18848   8BEC             MOV EBP,ESP
00C1884A   83EC 10          SUB ESP,10
00C1884D   8365 F8 00       AND DWORD PTR SS:[EBP-8],0
00C18851   53               PUSH EBX
00C18852   56               PUSH ESI
00C18853   EB 01            JMP SHORT 00C18856
00C18855   A3 B8001000      MOV DWORD PTR DS:[1000B8],EAX
00C1885A   006A 40          ADD BYTE PTR DS:[EDX+40],CH
00C1885D   50               PUSH EAX
00C1885E   50               PUSH EAX
00C1885F   A1 4410C100      MOV EAX,DWORD PTR DS:[C11044]
00C18864   6A 00            PUSH 0
00C18866   FF50 10          CALL DWORD PTR DS:[EAX+10]               ; kernel32.VirtualAlloc
00C18869   8BF0             MOV ESI,EAX
00C1886B   85F6             TEST ESI,ESI
00C1886D   8975 F4          MOV DWORD PTR SS:[EBP-C],ESI
00C18870   0F84 91000000    JE 00C18907
00C18876   EB 01            JMP SHORT 00C18879
00C18878   A0 8B45F4C6      MOV AL,BYTE PTR DS:[C6F4458B]
00C1887D   00C3             ADD BL,AL
00C1887F   8945 F0          MOV DWORD PTR SS:[EBP-10],EAX
00C18882   BB 40010000      MOV EBX,140
00C18887   EB 01            JMP SHORT 00C1888A
00C18889   A0 E8A9FBFF      MOV AL,BYTE PTR DS:[FFFBA9E8]
00C1888E   FF85 C075036A    INC DWORD PTR SS:[EBP+6A0375C0]
00C18894   015B EB          ADD DWORD PTR DS:[EBX-15],EBX
00C18897   01A2 8D45FC50    ADD DWORD PTR DS:[EDX+50FC458D],ESP
00C1889D   A1 4410C100      MOV EAX,DWORD PTR DS:[C11044]
00C188A2   53               PUSH EBX		;NewProtect, ebx = 00000140 = PAGE_EXECUTE_READWRITE | PAGE_GUARD
00C188A3   6A 10            PUSH 10
00C188A5   56               PUSH ESI
00C188A6   FF50 0C          CALL DWORD PTR DS:[EAX+C]                ; kernel32.VirtualProtect
00C188A9   68 DA88C100      PUSH 0C188DA
00C188AE   EB 01            JMP SHORT 00C188B1
00C188B0   8864FF 35        MOV BYTE PTR DS:[EDI+EDI*8+35],AH
00C188B4   0000             ADD BYTE PTR DS:[EAX],AL
00C188B6   0000             ADD BYTE PTR DS:[EAX],AL
00C188B8   64:8925 00000000 MOV DWORD PTR FS:[0],ESP
00C188BF   FF55 F0          CALL DWORD PTR SS:[EBP-10]
00C188C2   EB 01            JMP SHORT 00C188C5
00C188C4   A2 648F0500      MOV BYTE PTR DS:[58F64],AL
00C188C9   0000             ADD BYTE PTR DS:[EAX],AL
00C188CB   00C7             ADD BH,AL
00C188CD   45               INC EBP
00C188CE   F8               CLC
00C188CF   0100             ADD DWORD PTR DS:[EAX],EAX
00C188D1   0000             ADD BYTE PTR DS:[EAX],AL
00C188D3   C3               RETN


Вот в чём дело! Протектор запрашивает память и ставит на неё особый атрибут - GUARD. В MSDN об этом флаге написано вот что: "Any attempt to access a guard page causes the system to raise a STATUS_GUARD_PAGE exception and turn off the guard page status." А ольга сама использует этот флаг для своих брекпоинтов на память. И если возникает подобное исключение, то она думает, что возникла попытка доступа на контролируемую страницу и не даёт возникнуть исключению. Если исключения не возникает, то выполнение продолжается возникновением сообщения о замеченном отладчике. Иначе обработчик исключения подменяет значение регистра EIP на своё, и выполнение кода проходит дальше.
Вот код обработчика:


00C188DA   8B45 10          MOV EAX,DWORD PTR SS:[EBP+10]	; <== обработчик
00C188DD   C780 B8000000 EA>MOV DWORD PTR DS:[EAX+B8],0C188EA
00C188E7   33C0             XOR EAX,EAX
00C188E9   C3               RETN

00C188EA   64:8F05 00000000 POP DWORD PTR FS:[0] ; <== сюда передается управление, если возникло исключение
00C188F1   83C4 04          ADD ESP,4
00C188F4   A1 4410C100      MOV EAX,DWORD PTR DS:[C11044]
00C188F9   68 00800000      PUSH 8000
00C188FE   6A 00            PUSH 0


Так что если отказаться от обработки исключений плагином фантомом, то можно предложить такой метод обхода антидебага: когда отладчик тормозится на этом исключении, мы заменяем значение регистра EIP на 0C188EA (Эмулируем работу обработчика исключений;) ). Тогда все будет так, как будто программа запущена без оли.


Не пойман - не вор.



Но дампить еще рано. Внимательно посмотрим на код, заметим тучу странных call'ов.


00401643   56               PUSH ESI
00401644   E8 D0E92B01      CALL 016C0019   		;<==== Вот это.
00401649   FB               STI
0040164A   894424 68        MOV DWORD PTR SS:[ESP+68],EAX
0040164E   8B8424 B4020000  MOV EAX,DWORD PTR SS:[ESP+2B4]


А внутри у нас вот что:


016C0019   FF0424           INC DWORD PTR SS:[ESP]	; т.е. возврат не на 00401649, а на 0040164A
016C001C   68 00006C01      PUSH 16C0000
016C0021   C3               RETN


Следуем по адресу вот сюда:


016C0000   8BFF             MOV EDI,EDI
016C0002   55               PUSH EBP
016C0003   8BEC             MOV EBP,ESP
016C0005   51               PUSH ECX
016C0006   51               PUSH ECX
016C0007   8D45 F8          LEA EAX,DWORD PTR SS:[EBP-8]
016C000A   50               PUSH EAX
016C000B   FF75 08          PUSH DWORD PTR SS:[EBP+8]
016C000E   68 A20C817C      PUSH 7C810CA2
016C0013   68 210C817C      PUSH kernel32.GetFileSizeEx
016C0018   C3               RETN


Ага, GetFileSizeEx! Экспрессо украл у нас вызов АПИ и создал переходник в выделенном участке памяти. Заметьте, inc по адресу 016C0019 увеличивает на 1 адрес возврата, т.к. украденная команда (jmp [addr]) на 1 больше текущей (call relative).
Таблица импорта тоже изрядно обработана:


00480000  83 78 DC 77 A0 0B 66 01 23 C1 DE 77 E7 EB DC 77  ѓxЬw f#БЮwзлЬw
00480010  B0 0B 67 01 BB D5 DE 77 4A CF DD 77 C0 0B 68 01  °g»ХЮwJПЭwАh
00480020  D0 0B 69 01 E0 0B 6A 01 F0 6B DC 77 00 00 00 00  РiаjрkЬw....
00480030  C9 91 5C 5D FC 02 5D 5D DD 15 5D 5D 2E BD 5B 5D  Й‘]ь]]Э]].Ѕ[]
00480040  A5 45 5F 5D 00 00 00 00 C0 09 48 01 D0 09 49 01  ҐE_]....А.HР.I
00480050  E0 09 4A 01 F0 09 4B 01 00 0A 4C 01 FC 8A F1 77  а.Jр.K..LьЉсw
00480060  10 0A 4D 01 FB 5E F1 77 20 0A 4E 01 6F C0 F1 77  .Mы^сw .NoАсw
00480070  F8 6C F2 77 FD C7 F3 77 30 0A 4F 01 40 0A 50 01  шlтwэЗуw0.O@.P
00480080  50 0A 51 01 60 0A 52 01 F3 AD F1 77 ED D9 F1 77  P.Q`.Rу­сwнЩсw
00480090  99 8B F1 77 FA 8D F1 77 2A 7D F1 77 70 0A 53 01  ™‹сwъЌсw*}сwp.S
004800A0  29 94 F1 77 F1 DD F1 77 80 0A 54 01 3A 7C F1 77  )”сwсЭсwЂ.T:|сw
004800B0  90 0A 55 01 A0 0A 56 01 B0 0A 57 01 97 5D F1 77  ђ.U .V°.W—]сw
004800C0  C0 0A 58 01 6C EC F1 77 E1 68 F2 77 D0 0A 59 01  А.XlмсwбhтwР.Y
004800D0  E0 0A 5A 01 F0 81 F1 77 4F 53 F4 77 F0 0A 5B 01  а.ZрЃсwOSфwр.[
004800E0  00 0B 5C 01 10 0B 5D 01 90 5B F1 77 20 0B 5E 01  .]ђ[сw ^
004800F0  30 0B 5F 01 43 70 F1 77 B2 6F F1 77 40 0B 60 01  0_CpсwІoсw@`



Много dword'ов указывают на выделенную область памяти. Вот один из них:


01660BA0   B8 01000000      MOV EAX,1
01660BA5   FFA0 AB0B6601    JMP DWORD PTR DS:[EAX+1660BAB] ;[1660BAC] = 77DC761Bh
01660BAB   EB 1B            JMP SHORT 01660BC8
01660BAD  ^76 DC            JBE SHORT 01660B8B
01660BAF   77 00            JA SHORT 01660BB1


Через одну команду осуществляется прыжок на первоначальную АПИ. Восстанавливает таблицу скрипт (его код приведён в конце статьи).
После того, как он отработал, у нас останется еще 2 нераспознаных вызова. Эти функции прот эмулирует уже получше:


00B73AE9   55               PUSH EBP
00B73AEA   8BEC             MOV EBP,ESP
00B73AEC   EB 01            JMP SHORT 00B73AEF

00B73AEF   68 0D3BB700      PUSH 0B73B0D
00B73AF4   64:FF35 00000000 PUSH DWORD PTR FS:[0]
00B73AFB   EB 01            JMP SHORT 00B73AFE

00B73AFE   64:8925 00000000 MOV DWORD PTR FS:[0],ESP
00B73B05   33C0             XOR EAX,EAX
00B73B07   66:8F00          POP WORD PTR DS:[EAX]  ; Антитрейс
00B73B0A   6A 00            PUSH 0
00B73B0C   C3               RETN

00B73B0D   8B4D 10          MOV ECX,DWORD PTR SS:[EBP+10]
00B73B10   C781 B8000000 1D>MOV DWORD PTR DS:[ECX+B8],0B73B1D
00B73B1A   33C0             XOR EAX,EAX
00B73B1C   C3               RETN

00B73B1D   64:8F05 00000000 POP DWORD PTR FS:[0]
00B73B24   83C4 04          ADD ESP,4
00B73B27   FF75 08          PUSH DWORD PTR SS:[EBP+8]
00B73B2A   A1 4410B700      MOV EAX,DWORD PTR DS:[B71044]
00B73B2F   FF50 34          CALL DWORD PTR DS:[EAX+34] ; <== вызов АПИ
00B73B32   5D               POP EBP
00B73B33   C2 0400          RETN 4


Их заменяем руками. После этого вся таблица окажется восстановленной.
Теперь можно заняться украденными call'ами. Для их восстановления лучше проследить за их созданием. Оно следует сразу же после того самого исключения с константой FEEEFEEE. Перезапускаем программу, останавливаемся на этом исключении, ставим breakpoint на GetModuleHandleA. Выйдя из этой функции, мы окажемся в цикле создания этих call'ов. Потрейсим чуть-чуть и увидим такой код:


00C23E9F   68 F13EC200      PUSH 0C23EF1
00C23EA4   EB 01            JMP SHORT 00C23EA7

00C23EA7   C745 E0 089AC200 MOV DWORD PTR SS:[EBP-20],0C29A08
00C23EAE   FF65 E0          JMP DWORD PTR SS:[EBP-20]		;GetProcAddressByHash
...
00C23EF1   8945 D8          MOV DWORD PTR SS:[EBP-28],EAX	;Возврат сюда
00C23EF4   837D D8 00       CMP DWORD PTR SS:[EBP-28],0
00C23EF8   75 07            JNZ SHORT 00C23F01
;
;Пропущен код создания переходника
;
00B140E9   8B45 E4          MOV EAX,DWORD PTR SS:[EBP-1C]            
00B140EC   C600 E8          MOV BYTE PTR DS:[EAX],0E8		; Первый байт опкода команды call
00B140EF   8B45 E4          MOV EAX,DWORD PTR SS:[EBP-1C]	      
00B140F2   40               INC EAX				       
00B140F3   8945 EC          MOV DWORD PTR SS:[EBP-14],EAX		
00B140F6   50               PUSH EAX					 
00B140F7   E8 03000000      CALL 00B140FF				 
00B140FC   01EB             ADD EBX,EBP					 
.......									 
00B14109   58               POP EAX                                  	 
00B1410A   8B45 E4          MOV EAX,DWORD PTR SS:[EBP-1C]		 
00B1410D   83C0 05          ADD EAX,5					 
00B14110   8B4D F8          MOV ECX,DWORD PTR SS:[EBP-8]		 
00B14113   2BC8             SUB ECX,EAX					
00B14115   8B45 EC          MOV EAX,DWORD PTR SS:[EBP-14]	       
00B14118   8908             MOV DWORD PTR DS:[EAX],ECX		; Аргумент команды call
00B1411A   EB 01            JMP SHORT 00B1411D


Находясь по адресу 00C23EF1 в eax будет адрес API, а по адресу 00B14118 записывается подменённая команда. Теперь надо писать скрипт для восстановления украденного call'а. Лучше не создавать новую таблицу с адресами API-функций, а искать этот адрес в оригинальной IAT. Поэтому сначала нужно очистить импорт от переходников, а после - запускать скрипт (его код - в конце статьи). Запускать его надо, находясь на GetModuleHandleA.
Смотрим на код - все вроде на месте. Делаем дамп, запускаем ImpRec, указываем местонахождение IAT - RVA = 80000, Size = 6AC. Для совместимости с другими версиями Windows заменяем функцию RestoreLastError на SetLastError, а Shell32!SHCreateDirectory на Shell32!#165. После этого можно сохранять дамп. Убираем директорию TLS за ненадобностью.

Попробуем запустить наш дамп. Экспрессо работает, даже успешно пакует, но вываливается с ошибкой по адресу 00ae416f (выделенная память!), если нажать кнопку "About". Грузим в отладчик, останавливаемся на этом исключении. Видим такую картину:


00406173   A1 641E4A00      MOV EAX,DWORD PTR DS:[4A1E64]	; [004A1E64]=00AE416F
00406178   85C0             TEST EAX,EAX
0040617A   0F84 BD000000    JE Dumped_.0040623D
00406180   8D9424 90000000  LEA EDX,DWORD PTR SS:[ESP+90]
00406187   6A 00            PUSH 0
00406189   52               PUSH EDX
0040618A   FFD0             CALL EAX				; Вот отсюда мы улетели в никуда
0040618C   83C4 08          ADD ESP,8
0040618F   8D4C24 1C        LEA ECX,DWORD PTR SS:[ESP+1C]


Хмм... Странный адрес для хранения адреса API - 4A1E64, он находится в секции данных. Посмотрим что там у нас в оригинальной программе.


00B5416F   55               PUSH EBP     ; Вызов этой функции.
00B54170   8BEC             MOV EBP,ESP
00B54172   81EC 1C020000    SUB ESP,21C
00B54178   56               PUSH ESI
00B54179   57               PUSH EDI
00B5417A   50               PUSH EAX
00B5417B   E8 03000000      CALL 00B54183
00B54180   01EB             ADD EBX,EBP
00B54182   0A8B 04248B00    OR CL,BYTE PTR DS:[EBX+8B2404]
00B54188   000424           ADD BYTE PTR SS:[ESP],AL
00B5418B   C3               RETN
00B5418C  -E9 58A14410      JMP 10F9E2E9
...
00B541B5   59               POP ECX
00B541B6   50               PUSH EAX				     ; "GetVolumeInformationA"
00B541B7   57               PUSH EDI				
00B541B8   FF16             CALL DWORD PTR DS:[ESI]                  ; kernel32.GetProcAddress
00B541BA   8BF0             MOV ESI,EAX
...
00B541EA   E8 475C0000      CALL 00B59E36
00B541EF   59               POP ECX
00B541F0   50               PUSH EAX
00B541F1   FFD6             CALL ESI		; kernel32.GetVolumeInformationA
00B541F3   85C0             TEST EAX,EAX
...
00B5420C   59               POP ECX
00B5420D   50               PUSH EAX
00B5420E   8D85 ECFEFFFF    LEA EAX,DWORD PTR SS:[EBP-114]
00B54214   50               PUSH EAX				   
00B54215   FF16             CALL DWORD PTR DS:[ESI]                  ; USER32.wsprintfA
00B54217   83C4 0C          ADD ESP,0C
00B5421A   EB 01            JMP SHORT 00B5421D

00B5421D   8DBD ECFEFFFF    LEA EDI,DWORD PTR SS:[EBP-114]
00B54223   83C9 FF          OR ECX,FFFFFFFF
00B54226   33C0             XOR EAX,EAX
00B54228   F2:AE            REPNE SCAS BYTE PTR ES:[EDI]
00B5422A   F7D1             NOT ECX
00B5422C   2BF9             SUB EDI,ECX
00B5422E   8BC1             MOV EAX,ECX
00B54230   8BF7             MOV ESI,EDI
00B54232   8B7D 08          MOV EDI,DWORD PTR SS:[EBP+8]
00B54235   C1E9 02          SHR ECX,2
00B54238   F3:A5            REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS>
00B5423A   8BC8             MOV ECX,EAX
00B5423C   83E1 03          AND ECX,3
00B5423F   F3:A4            REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[>
00B54241   EB 01            JMP SHORT 00B54244
00B54243   F76A 01          IMUL DWORD PTR DS:[EDX+1]
00B54246   58               POP EAX
00B54247   EB 02            JMP SHORT 00B5424B
00B54249   33C0             XOR EAX,EAX
00B5424B   5F               POP EDI                                  ; 0012DE6C
00B5424C   5E               POP ESI
00B5424D   C9               LEAVE
00B5424E   C3               RETN


Заглянем в спавку нашего пакера-протектора.


DLL_CPP_EXP BOOL __stdcall SetMachineID(LPSTR MachineID);

Description: Stub calls this for retrieving HardwareID.


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

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




Скрипт для восстановления IAT.


//Script restores iat for eXPressor 1.5.0.1
//by HoBleen
//
//Run it when code section is already unpacked

var base
var end
var cur
var addr
var tmp


//place of IAT
mov base, 480000
mov end, 4806A8
mov cur, base

next:
add cur,4
cmp cur, end
ja end_p
cmp [cur], 0
jne ok_
jmp next

ok_:
//now check if it is our call
mov addr, [cur]
mov tmp, [addr]
cmp tmp, 01B8
jne next

//yes, our call
add addr, 0C
mov tmp, [addr]
mov [cur], tmp
log cur

jmp next

end_p:
msg "IAT has been restored!"
ret


Скритп для восстановления call'ов.


//Script restores stolen calls for eXPressor 1.5.0.1
//by HoBleen
//
//Run it from GetModuleHandleA (in IAT creation)

var api_addr
var write_addr
var end_addr
var api
var iat
var tmp
var base
var end
var cur
var addr

mov base, 480000
mov end, 4806A8

mov cur, base



rtr
sti
mov api_addr, eip
and api_addr, 0FFFF0000
mov write_addr, api_addr
mov tmp, api_addr
mov end_addr, api_addr

or  api_addr, 3EF1
or  write_addr, 411A
or  end_addr, 412B
mov iat, 4E5000

bp end_addr
bp api_addr
bp write_addr
run

next:

cmp eip, api_addr
jne exit
mov api, eax //save real api address
run
mov tmp, eax
dec tmp
mov [tmp], #FF15#
add tmp, 2

//search API in IAT
//from base to end
mov addr, base

next_search:
cmp [addr], api
je ok
add addr, 4
cmp addr, end
ja error
jmp next_search

ok:
mov [tmp], addr
run
jmp next

error:
eval "Cannot find api! ADDR = {api}"
msg $RESULT
log api

bc end_addr
bc api_addr
bc write_addr
ret

exit:
msg "All ok!"
bc api_addr
bc write_addr
bc end_addr
ret




Обсуждение статьи: Распаковка eXPressor 1.5.0.1, Protection stub. >>>


Комментарии к статье: Распаковка eXPressor 1.5.0.1, Protection stub.

deepred 09.07.2007 22:16:27
Спасибо за статью. Статья хорошая, а самое главное понятно и доходчиво написана. Респект и уважуха!!!!!!! ;)
---
pavka 12.08.2007 10:45:19
там все можно делать много проще..
/*
//////////////////////////////////////////////////
Назначение скрипта eXePressor Unpacker 1.5.01
OS : XP SP2 Олька любая патченая Фантом, Адвансед
Note : Дополнительная информация
/////////////////////////////////////////////////
*/
var oep
var mh
var cb
var csz
var mbase
var em
var iat
var E8
var func
var iat_start
ask "Введите начало IAT"
cmp $RESULT, 0
je quit
mov iat_start,$RESULT

GMI eip,CODEBASE
mov cb,$RESULT
GMI eip,CODESIZE
mov csz,$RESULT
GMI eip,ENTRY
mov oep,$RESULT
BC oep

gpa "GetProcAddress","kernel32.dll"
find $RESULT,#5F5BC9C2#
bp $RESULT 3
erun
bc eip
rtu
find eip,#595985C0#
cmp $RESULT,0
je quit
mov [$RESULT 4],#9090# // убираем переходники в иат
run
mov [eip],#CC# // обходим проверку на дебаг
mov mh,[esp 8]
bp mh
run
bc eip
add mh,10
bp mh
run
bc eip
add eip,7
rtr
sti
find eip,#586A01585E5B5FC9C3#
cmp $RESULT,0
je quit
mov oep,$RESULT 8
bp oep
GMEMI eip, MEMORYBASE
mov mbase,$RESULT
find mbase,#8945D8837DD800750733C0#
mov em,$RESULT
bp em
find em,#C600E88B45E4#
mov E8,$RESULT
bp E8
mov mbase,E8 2C
bp mbase
loop:
erun
cmp eip,em
jne oepfind
mov iat,eax
find iat_start,iat
mov func,$RESULT
erun
sti
mov [eax],#FF15# // для делфи FF25
erun
inc eax
add eip,2
mov [eax],func

jmp loop

oepfind:
bc eip
sti
BPRM cb, csz
run
BPMC
bc E8
bc em
bc mbase
CMT eip,"OEP"
CMT eip,"OEP"
eval "eXePressor Unpacked! Iat fixed, emul api remove!IAT Start: {iat_start}"
msg $RESULT
ret
quit:
ret


---

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



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


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