ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2
Antichat снова доступен.
Форум Antichat (Античат) возвращается и снова открыт для пользователей. Здесь обсуждаются безопасность, программирование, технологии и многое другое. Сообщество снова собирается вместе.
Новый адрес: forum.antichat.xyz
Вернуться   Форум АНТИЧАТ > ИНФО > Статьи > Авторские статьи
   
Ответ
 
Опции темы Поиск в этой теме Опции просмотра

Распаковка PESpin 0.7
  #1  
Старый 10.12.2006, 16:55
Аватар для taha
taha
Постоянный
Регистрация: 20.08.2006
Сообщений: 327
Провел на форуме:
2472378

Репутация: 1077
По умолчанию Распаковка PESpin 0.7

Распаковка PESpin 0.7

Содержание
Введени
Инструменты
Поиск OEP
Восстановление импорта
Умный в гору не пойдёт
Заключение

Введение

Сегодня я покажу как вручную распаковать протектор PESpin. Итак, подопытную программу вы можете скачать тут: http://www.tuts4you.com/blogs/download.php?view.338 Что такое? Там же тутор есть. - скажет читатель. Да есть и кое-где мы будем на него опираться. Просто я расскажу больше чем в туторе. Вы в этом убедитесь. Эта статья посвящена скорее тому, как обойти злобный протектор.

Инструменты
Ollydbg + plugins(OllyScript,OllyDump,CmdBar)
Imp Rec
И всё!!!

Поиск OEP
Грузим прогу в Olly. Давайте просто запустим программу, F9. Она тормозится на каком то исключении, нам первые исключения не интересны. Идём дальше.

Код:
004001C9   FFFF             ???                                      ; Unknown command
004001CB   FFFF             ???                                      ; Unknown command
004001CD   FFFF             ???                                      ; Unknown command
004001CF   FFFF             ???                                      ; Unknown command
004001D1   FFFF             ???                                      ; Unknown command
004001D3   FFFF             ???                                      ; Unknown command
004001D5   FFFF             ???                                      ; Unknown command
004001D7   FFFF             ???                                      ; Unknown command
Код:
00407F17   2BDB             SUB EBX,EBX
00407F19   64:8F03          POP DWORD PTR FS:[EBX]
00407F1C   58               POP EAX
00407F1D   5D               POP EBP
И программа запущена.
Скорее всего OEP будет идти после последнего или предпоследнего исключения (чаще после последнего).
Ставим бряк на esp-4.Через CmdBar, набрав hr esp-4. Или можно, пройдя pushad, выбрать в окне регистров esp, нажать на правую и выбрать Follow in dump.
В окне дампа, выделяем первые четыре байта, на правую Breakpoint > Hardware, on access > Dword.
F9, и идём до последнего исключения, ещё Shift-F9.
Ctrl-A - и Олька анализирует код.

Код:
00407087   61               POPAD
00407088   6A 00            PUSH 0 ; <----- Мы тут
0040708A   EB 01            JMP SHORT packed.0040708D
0040708C   E3 68            JECXZ SHORT packed.004070F6
0040708E   97               XCHG EAX,EDI
0040708F   70 40            JO SHORT packed.004070D1
00407091   00E9             ADD CL,CH
Дальше трейсим по F8. После прыжка попадаем на пару байт ниже.

Код:
0040708D   68 97704000      PUSH packed.00407097
00407092  -E9 7DA0FFFF      JMP packed.00401114
Мда странно. Зачем такие переходы? Лан идём дальше.

Код:
00401114   .-E9 04EF4600    JMP 0087001D
00401119     FF             DB FF
0040111A   $-E9 6BEF4600    JMP 0087008A
0040111F     FF             DB FF
Хм ничего не напоминает? Мне да!! Переходы на импортируемые функции. Но нефакт.
Дальше.

0087001D EB 01 JMP SHORT 00870020

Код:
00870020   8BFF             MOV EDI,EDI                              ; packed.00407B1D
00870022   55               PUSH EBP
00870023   8BEC             MOV EBP,ESP
00870025   837D 08 00       CMP DWORD PTR SS:[EBP+8],0
00870029   EB 07            JMP SHORT 00870032
Идём до прыжка, и f8.

00870032 ^EB F8 JMP SHORT 0087002C
Дальше.

0087002C -E9 01B5F97B JMP kernel32.7C80B532

Ещё =).

7C80B532 74 18 JE SHORT kernel32.7C80B54C

Мы в kernel32, а если взглянуть ниже иожно увидеть вызов GetModuleHandleW.

Посмотрим на пару байт выше.

Код:
7C80B529 > 8BFF             MOV EDI,EDI
7C80B52B   55               PUSH EBP
7C80B52C   8BEC             MOV EBP,ESP
7C80B52E   837D 08 00       CMP DWORD PTR SS:[EBP+8],0
Помоему я где то это уже видел. Смотри 00870020. Хех он что, у API байты ворует? Откуда всё началось?

Код:
00407088   6A 00            PUSH 0 ;
0040708A   EB 01            JMP SHORT packed.0040708D
Протектор возвращяет на место значения раегостров (popad). А дальше судя по всему идёт API. OEP? Надо проверить нашу догадку. Трейсим дальше.

Скажем, не далеко от вызова GetModuleHendleA, мы попадаем в USER32, посмотрев ниже, мы видим:

Код:
77D4891B   6A 02            PUSH 2
77D4891D   FF75 18          PUSH DWORD PTR SS:[EBP+18]
77D48920   FF75 14          PUSH DWORD PTR SS:[EBP+14]
77D48923   FF75 10          PUSH DWORD PTR SS:[EBP+10]
77D48926   50               PUSH EAX
77D48927   56               PUSH ESI
77D48928   E8 69DFFFFF      CALL USER32.DialogBoxIndirectParamAorW
Это скорее всего DialogBoxParamA. Из чего можно сделать вывод, что 00407088 - это искомый OEP. Удаляем бряк с esp.

Ну и снимаем дамп естественно, через OllyDump.

Т.к. до OEP, в процессе исследования, придётся доходить часто, напишем скрипт:

go_to_OEP.txt
Код:
	var real_OEP
	mov real_OEP,00407088	// найденый OEP
	var ex_OEP
	mov ex_OEP,00407F17	// последнее исключение
ff:
	eoe fOEP
	esto
fOEP:
	cmp eip,ex_OEP
	jne ff
	bp real_OEP
	esto
	bc real_OEP
	cmt eip," <------------- OEP"
	an real_OEP
	ret
ex_OEP - это то самое исключение, после которого идёт OEP. Сначала мы идём до последнего исключения. Это делается для того, что бы нам ничего не мешало в процессе прохода до OEP. Вобщем после того как доходим до последнего исключения, ставим бряк на OEP и esto (Shift-F9). Мы на OEP. Согласитесь, использовать скрипт очень удобно, он экономит время.

Восстановление импорта
Да, будет нелегко, но мы справимся.
Итак, перезапускаем программу, вызываем наш скрипт go_to_oep.
Т.к. протектор прыгает на пару байт дальше адреса функции, ImpRec нам не поможет. Придётся делать список функций, что бы составиь файл для ImpRec. Есть несколько способов решения данной проблемы.
Первый:
Нужно поставтить бряки на все вызовы функций (я имею ввиду на jump'ы начиная с 0040110E). И запустить программу (F9), дальше, когда сработают бряки, идти до функций и подниматься на пару байт вверх. F10 > Search for >Name in all modules.
Опять F10 > Sort by > Address (Это упростит поиск). Ищем полученный адрес.
Например:

Первый раз бряк сработает тут ( GetModuleHandleA, но мы этого пока не знаем =) )
00401114 .-E9 04EF4600 JMP 0087001D

F8 пока не попадём сюда:
7C80B532 74 18 JE SHORT kernel32.7C80B54C

Вверх на пару байт. Как мы знаем функция начинается c
7C80B529 > 8BFF MOV EDI,EDI

Следовательно в окне All names ищем 7C80B529.
7C80B529 .text Export GetModuleHandleA

И так с каждой функцией.

Втрой:
Мы всё ещё на OEP.
Откроем окно memory map (Alt-M), и посмотрим как в памяти рапсоложенна наша прога.

Код:
00400000   00001000   packed                PE header     Imag   RWE       RWE
00401000   00001000   packed     .petite    code          Imag   RWE       RWE
00402000   00001000   packed     .petite    data          Imag   RWE       RWE
00403000   00001000   packed     .petite                  Imag   RWE       RWE
00404000   00002000   packed     .rsrc      resources     Imag   RWE       RWE
00406000   00003000   packed     .petite    SFX,imports   Imag   RWE       RWE
00410000   00103000                                       Map    R         R
00520000   00129000                                       Map    R E       R E
00820000   00003000                                       Map    R         R
00830000   00008000                                       Priv   RW        RW
00840000   00001000                                       Priv   RW        RW
00850000   00001000                                       Priv   RW        RW
00860000   00004000                                       Priv   RW        RW
00870000   00001000                                       Priv   RWE       RWE
5D5B0000   00001000   COMCTL32              PE header     Imag   R         RWE
5D5B1000   00070000   COMCTL32   .text      code,imports  Imag   R         RWE
Мы знаем, что в процессе работы она гуляет по всем байтам до 5D5B0000.
Вернёмся назад.
Мы знаем, что код программы и протетора выполняется от 00400000 до 5DB0000. Давайте задаим параметры трассировки Debug > Set condition (Ctrl-T).
В первом и во втором полях EIP is outside the range пишем 00400000 и 5DB0000 соответственно. Ставим галочку напротив EIP is outside the range, OK.
Ctrl-F11 и мы тут:
7C80B532 74 18 JE SHORT kernel32.7C80B54C
Ну дальше опять поднимаемся на пару байт вверх. Ищем адрес функции в Name in all Modules.

И когда мы закончим у нас будет вот такой список:
Код:
KERNEL32----------------

40110E
All names, item 17785
 Address=7C81CAA2 kernel32
 Section=.text
 Type=Export  (Known)
 Name=ExitProcess

401114
All names, item 5136
 Address=7C80B529 kernel32
 Section=.text
 Type=Export  (Known)
 Name=GetModuleHandleA

USER32----------------


40111A
Names in USER32, item 15
 Address=77D3B4B1
 Section=.text
 Type=Export  (Known)
 Name=BeginPaint

401120
All names, item 1707
 Address=77D488E1 USER32
 Section=.text
 Type=Export  (Known)
 Name=DialogBoxParamA

401126
All names, item 9904
 Address=77D46CC9 USER32
 Section=.text
 Type=Export  (Known)
 Name=EndDialog

40112C
All names, item 9704
 Address=77D3B4C5 USER32
 Section=.text
 Type=Export  (Known)
 Name=EndPaint

401132
All names, item 9901
 Address=77D467A8 USER32
 Section=.text
 Type=Export  (Known)
 Name=LoadBitmapA

401138
Names in USER32, item 825
 Address=77D3E2AE
 Section=.text
 Type=Export  (Known)
 Name=SendMessageA


GDI32----------------

40113E
All names, item 12302
 Address=77F16DC0 GDI32
 Section=.text
 Type=Export  (Known)
 Name=BitBlt

401144
All names, item 12283
 Address=77F15E10 GDI32
 Section=.text
 Type=Export  (Known)
 Name=CreateCompatibleDC

40114A
All names, item 12301
 Address=77F16CA6 GDI32
 Section=.text
 Type=Export  (Known)
 Name=DeleteDC
	
401150
All names, item 12300
 Address=77F16A3B GDI32
 Section=.text
 Type=Export  (Known)
 Name=DeleteObject

401156
All names, item 12279
 Address=77F159A0 GDI32
 Section=.text
 Type=Export  (Known)
 Name=SelectObject
Дальше нам нужно составить файл импорта для ImpRec.

paced.txt
Код:
Target: C:\packed.exe
OEP: 00007088	IATRVA: 0000306C	IATSize: 00000100

FThunk: 00003070	NbFunc: 00000006
1	00003070	user32.dll	000E	BeginPaint
1	00003074	user32.dll	009F	DialogBoxParamA
1	00003078	user32.dll	00C7	EndDialog
1	0000307C	user32.dll	00C9	EndPaint
1	00003080	user32.dll	01B6	LoadBitmapA
1	00003084	user32.dll	023C	SendMessageA

FThunk: 0000308C	NbFunc: 00000002
1	0000308C	kernel32.dll	00B0	ExitProcess
1	00003090	kernel32.dll	016F	GetModuleHandleA

FThunk: 00003098	NbFunc: 00000005
1	00003098	gdi32.dll	0013	BitBlt
1	0000309C	gdi32.dll	002E	CreateCompatibleDC
1	000030A0	gdi32.dll	008D	DeleteDC
1	000030A4	gdi32.dll	0090	DeleteObject
1	000030A8	gdi32.dll	020F	SelectObject
Открывеам ImpRec вибираем процесс и жмём на Load tree, выбираем packed.txt. Fix'ируем на dumped.exe.

Запускаем наш dumped_.exe. Что такое? он не работает =(. Ну естественно надо ещё jump'ы подправить.

Открываем dumped_.exe. Ctrl-G > 0040110E. Мда гора мусора.
Код:
0040110E     E9             DB E9
0040110F     ED             DB ED
00401110     EE             DB EE
00401111     46             DB 46                                    ;  CHAR 'F'
00401112     00             DB 00
Ctrl-B,галочка с keep size убрана, пишем FF25, Ok. Появился jump.
Код:
0040110E     FF25 EE4600FF  JMP DWORD PTR DS:[FF0046EE]
Теперь откопируем его столько раз, сколько у нас функций.
Теперь исправляем адреса. Адреса функций храняться в .mackt. У меня это адрес 00409000. Там лежат адреса наших функций. Так вот исправляем наши джампы.
Вместо FF0046EE будет адрес адреса функции. Вот:
Код:
0040110E    -FF25 A2CA817C  JMP DWORD PTR DS:[kernel32.ExitProcess]
Все jump должны остаться на своиз местах, нльзя менять местами функции.
Как мне разобраться что есть что в окне дампа .mackt? - спросит читатель. Действительно трудно, но вспомнить адреса апи вам поможет плагин APIFinder.

Умный в гору не пойдёт
Как всё геморойно! Скажет чиатель и будет прав. Я тоже не люблю возиться с импортом. Главное найти OEP, а там.... Но этот протектор ворует байты у API, что очень затрудняет взлом. И тут вступаю в дело я =)).
А что если написать скрипт который сам восстановит IAT. Приступим.
Итак код прохода до OEP есть.
Вернёмся в packed.exe.
Что делать дальше? Идея очень проста. Поставим бряки на все джампы.
Код:
	var y // первый jump
	mov y,0040110E
f_IAT:
	bp y
	add y,6
	cmp y,0040115C
	jne f_IAT
	eob f_bpx
	run
Дальше по мере срабатывания бряков, мы будим их удалять. Когда сработает бряк, мы будем к примеру тут:
00401114 .-E9 04EF4600 JMP 0087001D
Введём переменную, в которую будем сохранять адрес jmp.
var otcuda
Проходим jmp'ы:
sto
sto
И мы тут:
00870020 8BFF MOV EDI,EDI ; packed.00407B1D
Нужно посчитать растояние до перехода к переходу на переход к функции =). Тобишь до сюда:
00870029 EB 07 JMP SHORT 00870032
Мы же должны знать сколько байт спёр протектор.
Код:
	findop eip,#EB07#
	mov count,$RESULT
	sub count,eip
Конечно перед этим вводим переменную count. Дальше идём до этого jump'а:
Код:
sol_byte:
	sti
	cmp eip,$RESULT
	jne sol_byte
Проходим джампы:
Код:
	sto
	sto
	sto
И мы в kernel32, ну или где там будем. Вычисляем адрес начала функции:
Код:
	mov x,eip
	sub x,count
и сохраняем его в какю-нибудь не нужную программе область. Я выбрал 0040115F.
Пишем туда адрес функции и снимаем бряк с джампа.
Код:
	mov [cuda],x	
	bc otcuda
Теперь на место старого пишем новый.
Код:
	mov [otcuda],25FF
	add otcuda,2
	mov [otcuda],cuda
Увеличиваем cuda на 4. И:
Код:
	run
	jmp f_bpx
Вот скрипт:
Код:
	var real_OEP
	mov real_OEP,00407088	// найденый OEP

	var ex_OEP
	mov ex_OEP,00407F17	// последнее исключение
ff:
	eoe fOEP
	esto
fOEP:
	cmp eip,ex_OEP
	jne ff
	bp real_OEP
	esto
	bc real_OEP
	cmt eip," <------------- OEP"
	an real_OEP

	var count
	var x
	var y
	mov y,0040110E
	var otcuda
	var cuda
	mov cuda,0040115F

f_IAT:
	bp y
	add y,6
	cmp y,0040115C
	jne f_IAT
	eob f_bpx
	run
f_bpx:	
	mov otcuda,eip
	sto
	sto
	findop eip,#EB07#
	mov count,$RESULT
	sub count,eip

sol_byte:
	sti
	cmp eip,$RESULT
	jne sol_byte

	sto
	sto
	sto
	mov x,eip
	sub x,count
	mov [cuda],x	
	bc otcuda
	mov [otcuda],25FF
	add otcuda,2
	mov [otcuda],cuda
	add cuda,4
	run
	jmp f_bpx
Запускаем его. После того как окно запустится и перестанет бегать строчка: Ctrl-G > 0040110E. И вот что там:
Код:
 
0040110E   .-E9 EDEE4600    JMP 00870000
00401113     FF             DB FF
00401114    -FF25 5F114000  JMP DWORD PTR DS:[40115F]                ;  kernel32.GetModuleHandleA
0040111A    -FF25 6B114000  JMP DWORD PTR DS:[40116B]                ;  USER32.BeginPaint
00401120    -FF25 63114000  JMP DWORD PTR DS:[401163]                ;  USER32.DialogBoxParamA
00401126   $-E9 21EF4600    JMP 0087004C
0040112B     FF             DB FF
0040112C    -FF25 7B114000  JMP DWORD PTR DS:[40117B]                ;  USER32.EndPaint
00401132    -FF25 67114000  JMP DWORD PTR DS:[401167]                ;  USER32.LoadBitmapA
00401138   $-E9 81EF4600    JMP 008700BE
0040113D     FF             DB FF
0040113E    -FF25 77114000  JMP DWORD PTR DS:[401177]                ;  GDI32.BitBlt
00401144    -FF25 6F114000  JMP DWORD PTR DS:[40116F]                ;  GDI32.CreateCompatibleDC
0040114A    -FF25 7F114000  JMP DWORD PTR DS:[40117F]                ;  GDI32.DeleteDC
00401150   $-E9 AAEF4600    JMP 008700FF
00401155     FF             DB FF
00401156    -FF25 73114000  JMP DWORD PTR DS:[401173]                ;  GDI32.SelectObject
Да определились не все функции, но ведь не все бряки сработали. Закрываем программу. И строчка опять побежала, после остановки: Ctrl-G > 0040110E.
Код:
0040110E   .-FF25 8F114000  JMP DWORD PTR DS:[40118F]                ;  kernel32.ExitProcess
00401114   .-FF25 5F114000  JMP DWORD PTR DS:[40115F]                ;  kernel32.GetModuleHandleA
0040111A   $-FF25 6B114000  JMP DWORD PTR DS:[40116B]                ;  USER32.BeginPaint
00401120   .-FF25 63114000  JMP DWORD PTR DS:[401163]                ;  USER32.DialogBoxParamA
00401126   $-FF25 8B114000  JMP DWORD PTR DS:[40118B]                ;  USER32.EndDialog
0040112C   $-FF25 7B114000  JMP DWORD PTR DS:[40117B]                ;  USER32.EndPaint
00401132   $-FF25 67114000  JMP DWORD PTR DS:[401167]                ;  USER32.LoadBitmapA
00401138   $-FF25 83114000  JMP DWORD PTR DS:[401183]                ;  USER32.SendMessageA
0040113E   $-FF25 77114000  JMP DWORD PTR DS:[401177]                ;  GDI32.BitBlt
00401144   $-FF25 6F114000  JMP DWORD PTR DS:[40116F]                ;  GDI32.CreateCompatibleDC
0040114A   $-FF25 7F114000  JMP DWORD PTR DS:[40117F]                ;  GDI32.DeleteDC
00401150   $-FF25 87114000  JMP DWORD PTR DS:[401187]                ;  GDI32.DeleteObject
00401156   $-FF25 73114000  JMP DWORD PTR DS:[401173]                ;  GDI32.SelectObject
0040115C     00             DB 00
0040115D     00             DB 00
0040115E     00             DB 00
0040115F   . 29B5807C       DD kernel32.GetModuleHandleA
00401163   . E188D477       DD USER32.DialogBoxParamA
00401167   . A867D477       DD USER32.LoadBitmapA
0040116B   . B1B4D377       DD USER32.BeginPaint
0040116F   . 105EF177       DD GDI32.CreateCompatibleDC
00401173   . A059F177       DD GDI32.SelectObject
00401177   . C06DF177       DD GDI32.BitBlt
0040117B   . C5B4D377       DD USER32.EndPaint
0040117F   . A66CF177       DD GDI32.DeleteDC
00401183   . AEE2D377       DD USER32.SendMessageA
00401187   . 3B6AF177       DD GDI32.DeleteObject
0040118B   . C96CD477       DD USER32.EndDialog
0040118F   . A2CA817C       DD kernel32.ExitProcess
Копируем всё это великолепие через binary copy.
Перезапускаем программу, идём до OEP, Ctrl-A, Ctrl-G > 0040110E, вставляем всё что накопровали.
Ctrl-A, поднимитесь выше!!
Код:
004010A5  |. 50             PUSH EAX                                 ; /pPaintstruct
004010A6  |. FF75 08        PUSH DWORD PTR SS:[EBP+8]                ; |hWnd
004010A9  |. E8 6C000000    CALL packed.0040111A                     ; \BeginPaint
004010AE  |. 8945 BC        MOV DWORD PTR SS:[EBP-44],EAX
004010B1  |. FF75 BC        PUSH DWORD PTR SS:[EBP-44]               ; /hDC
004010B4  |. E8 8B000000    CALL packed.00401144                     ; \CreateCompatibleDC
Без комментариев!!

Заключение
Не парься %)!
 
Ответить с цитированием

  #2  
Старый 11.12.2006, 01:10
Аватар для taha
taha
Постоянный
Регистрация: 20.08.2006
Сообщений: 327
Провел на форуме:
2472378

Репутация: 1077
По умолчанию

Если немного изменить мой скрипт, может прокатить и с PESpin 1.304.
 
Ответить с цитированием
Ответ



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Распаковка Upx'ов для новичков KindEcstasy Авторские статьи 0 29.11.2006 22:45
Распаковка. Общий подход. taha Авторские статьи 0 22.11.2006 14:48
Ручная распаковка и взлом HP-crackme ProTeuS Авторские статьи 2 14.08.2006 16:23



Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ