Приветствую тебя, Anton!
29 января 2006 года, в воскресенье, в 01:16:52 часов, Anton Veselkov писал
к Renat Khaliullin:
RK>> Кстати, экзешники, пожатые ASPack'ом я pаспаковываю за тpи
RK>> минyты,
RK>> без отладчика ;-) , использyя только HIEW и PE Tools ;-) Если
RK>> интеpесно, могy pассказать как ;-)
AV> Ага давай, если не затpyднит.
Понадобяться: HIEW, PETools (лежит на www.uinc.ru), экзешник, упакованный
ASPack'ом, прямые руки ;-)
Пара замечаний: в разных экзешниках разные адреса, и поэтому перед
фрагментами дизассемблированного кода я пишу "примерно". Все адреса и
результаты вычислений даны в шестнадцатеричной системе счисления!
Открываем экзешник HIEW'ом, переключаемся в режим дизассемблирования, и
переходим на точку входа (F4->Decode, F8, F5).
Ищем в коде инструкцию "repe movsb" (F7, F7, repe movsb)
Если все выполнено правильно, то окажемся в примерно таком коде:
=== Допущено. Служба безопасности Night Zone Station ===
[... пропущено ...]
.0042F177: 8BB552010000 mov esi,[ebp][00000152]
.0042F17D: C1F902 sar ecx,002 ;""
.0042F180: F3A5 repe movsd
.0042F182: 8BC8 mov ecx,eax
.0042F184: 83E103 and ecx,003 ;""
.0042F187: F3A4 repe movsb
.0042F189: 5E pop esi
.0042F18A: 6800800000 push 000008000 --- (1)
.0042F18F: 6A00 push 000
.0042F191: FFB552010000 push d,[ebp][00000152]
.0042F197: FF9551050000 call d,[ebp][00000551]
.0042F19D: 83C608 add esi,008 ;""
.0042F1A0: 833E00 cmp d,[esi],000000000
.0042F1A3: 0F851EFFFFFF jne .00042F0C7 --- (2)
.0042F1A9: 6800800000 push 000008000 --- (3)
.0042F1AE: 6A00 push 000
[... пропущено ...]
=== Допущено. Служба безопасности Night Zone Station ===
Переходим на адрес .0042F1A9 (в разных экзешниках адреса могут не
совпадать) (можно довести курсор до этого адреса вручную, а можно с помощью
перехода на адрес (F5, .0042F1A9))
Меняем байт 68h на байт CCh (F3, CC, F9)
Если все сделано правильно, увидим такой код:
=== Допущено. Служба безопасности Night Zone Station ===
[... пропущено ...]
.0042F177: 8BB552010000 mov esi,[ebp][00000152]
.0042F17D: C1F902 sar ecx,002 ;""
.0042F180: F3A5 repe movsd
.0042F182: 8BC8 mov ecx,eax
.0042F184: 83E103 and ecx,003 ;""
.0042F187: F3A4 repe movsb
.0042F189: 5E pop esi
.0042F18A: 6800800000 push 000008000 --- (1)
.0042F18F: 6A00 push 000
.0042F191: FFB552010000 push d,[ebp][00000152]
.0042F197: FF9551050000 call d,[ebp][00000551]
.0042F19D: 83C608 add esi,008 ;""
.0042F1A0: 833E00 cmp d,[esi],000000000
.0042F1A3: 0F851EFFFFFF jne .00042F0C7 --- (2)
.0042F1A9: CC int 3
.0042F1AA: 008000006A00 add [eax][006A0000],al
.0042F1B0: FFB556010000 push d,[ebp][00000156]
.0042F1B6: FF9551050000 call d,[ebp][00000551]
[... пропущено ...]
=== Допущено. Служба безопасности Night Zone Station ===
Теперь можно выйти из HIEW'а, и запустить экзешник. Сразу хочу
предупредить, что окно с ошибкой закрывать не надо! Если все было сделано
правильно ;-) то появится окно с примерно таким сообщением:
Исключение unknown software exception (0x80000003) в приложении по адресу
0x0042f1a9
_Окно_с_ошибкой_закрывать_не_надо!_
Теперь запускаем PETools, заходим в настройки PETools, и _включаем_
следующие опции:
Task Viewer
Full Dump: fix header
Full Dump: rebuild image
PE Rebuilder
Dump fix
Validate PE
Rebuild PE
Жмем OK, и находим в перечне процессов в главном окне PETools имя
экзешника, который мы распаковываем.
Щелкаем по нему правой кнопкой мыши, и выбираем Dump Full... и сохраняем
его образ в файл (имя файла для сохранения оставляем по умолчанию).
Если сохранение прошло нормально, появится окно с сообщением. В этом
сообщении _должны_ быть такие строки:
DumpFix...Done!
Rebuilding...Done!
Validate PE Image...Done!
После закрытия этого окна появится окно с сообщением "Dumping done !!!".
Закрываем его, и выходим из PETools.
После этого можно закрыть самое первое окно - с сообщением об ошибке ;-)
Теперь открываем HIEW'ом файл Dumped.exe
HIEW выдаст сообщение о том, что таблица импорта неправильная (Import:
Invalid data). Это нормально, сейчас мы поменяем адрес таблицы импорта, изменив
его на адрес оригинальной таблицы импорта.
Сначала мы найдем адрес начала оригинальной таблицы импорта. Переключаемся
в режим дизассемблирования и переходим на точку входа (F4->Decode, F8, F5).
Ищем инструкцию test eax, eax (F7, F7, test eax, eax). Мы должны оказаться
в примерно таком участке кода:
=== Допущено. Служба безопасности Night Zone Station ===
[... пропущено ...]
.0042F274: 66AB stosw
.0042F276: EBF1 jmps .00042F269 --- (2)
.0042F278: BE00A00200 mov esi,00002A000 --- (3)
.0042F27D: 8B9522040000 mov edx,[ebp][00000422]
.0042F283: 03F2 add esi,edx
.0042F285: 8B460C mov eax,[esi][0C]
.0042F288: 85C0 test eax,eax
.0042F28A: 0F840A010000 je .00042F39A --- (4)
.0042F290: 03C2 add eax,edx
.0042F292: 8BD8 mov ebx,eax
.0042F294: 50 push eax
[... пропущено ...]
=== Допущено. Служба безопасности Night Zone Station ===
Адрес оригинальной таблицы импорта заноситься в регистр esi после jmp'а и
перед mov edx,[ebp][00000422].
2A000 - это относительный виртуальный адрес (RVA) оригинальной таблицы
импорта.
Далее нам нужно узнать размер оригинальной таблицы импорта. Здесь задача
чуть-чуть сложнее. Hам нужно переключится в hex-режим просмотра (F4->Hex), и
перейти на адрес оригинальной таблицы импорта (F5, .42A000). Переключимся в
режим отображения реальных физических адресов (относительно начала файла)
(Alt-F1), и запомним адрес, на котором мы в данный момент находимся. В моем
случае это 00021800.
Мы увидим массив байтов, и идем вниз до тех пор, пока не увидим названия
функций и имена DLL'ок. Теперь очень важный момент: нам нужно узнать адрес
первой строки, в которой все байты - нулевые:
=== Допущено. Служба безопасности Night Zone Station ===
[... пропущено ...]
00022110: 61 72 54 6F-4F 65 6D 41-00 00 00 00-45 6E 75 6D arToOemA Enum
00022120: 54 68 72 65-61 64 57 69-6E 64 6F 77-73 00 00 00 ThreadWindows
00022130: 4D 65 73 73-61 67 65 42-6F 78 41 00-00 00 77 73 MessageBoxA ws
00022140: 70 72 69 6E-74 66 41 00-00 00 00 00-00 00 00 00 printfA
00022150: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00
00022160: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00
[... пропущено ...]
=== Допущено. Служба безопасности Night Zone Station ===
Строка по адресу 00022150 первая, в которой все байты нулевые. Запомним ее
адрес - 00022150. Теперь нам нужно отнять от этого адреса физический адрес
начала оригинальной таблицы импорта - 00021800:
00022150h - 00021800h = 950h
950h - размер оригинальной таблицы импорта.
Теперь нам нужно поменять адрес и размер текущей таблицы импорта на адрес и
размер оригинальной таблицы импорта. Жмем F8, потом F10, и увидим примерно
такое окно:
=== Допущено. Служба безопасности Night Zone Station ===
╔═ Name RVA Size ═╗
║ Export 0002B000 00000912 ║
║ Import 0002FFAC 00000060 ║
║ Resource 0002C000 00000200 ║
║ Exception 00000000 00000000 ║
║ Security 00000000 00000000 ║
║ Fixups 0002FF54 00000008 ║
║ Debug 00000000 00000000 ║
║ Description 00000000 00000000 ║
║ MIPS GP 00000000 00000000 ║
║ TLS 0002FF3C 00000018 ║
║ Load config 00000000 00000000 ║
║ Bound Import 00000000 00000000 ║
║ Import Table 00000000 00000000 ║
║ Delay Import 00000000 00000000 ║
║ COM Runtime 00000000 00000000 ║
║ (reserved) 00000000 00100000 ║
╚════════════════════════════════╝
=== Допущено. Служба безопасности Night Zone Station ===
Выбираем Import (обратите внимание: именно Import, а на Import Table) и
жмем F3. Редактируем RVA - вводим 2A000 (RVA оригинальной таблицы импорта),
затем Enter, и редактируем Size - вводим 950 (размер оригинальной таблицы
импорта), далее жмем Enter, и сохраняем все нажатием F9.
Теперь адрес таблицы импорта указывает на оригинальную таблицу импорта!
Hу и последнее: нам нужно изменить значение адреса точки входа, поменяв его
на адрес оригинальной точки входа. Для этого переключаемся в режим
дизассемблирования (F4->"Decode"), и переходим на точку входа (F8, F5).
Ищем следующую инструкцию: mov [ebp+3a8], eax (F7, F7, mov [ebp+3a8], eax).
После поиска мы окажемся примерно в таком участке кода:
=== Допущено. Служба безопасности Night Zone Station ===
[... пропущено ...]
.0042F389: 894610 mov [esi][10],eax
.0042F38C: 83C614 add esi,014 ;""
.0042F38F: 8B9522040000 mov edx,[ebp][00000422]
.0042F395: E9EBFEFFFF jmp .00042F285 --- (1)
.0042F39A: B808110000 mov eax,000001108 --- (2)
.0042F39F: 50 push eax
.0042F3A0: 038522040000 add eax,[ebp][00000422]
.0042F3A6: 59 pop ecx
.0042F3A7: 0BC9 or ecx,ecx
.0042F3A9: 8985A8030000 mov [ebp][000003A8],eax
.0042F3AF: 61 popad
.0042F3B0: 7508 jne .00042F3BA --- (3)
.0042F3B2: B801000000 mov eax,000000001 --- (4)
.0042F3B7: C20C00 retn 0000C ;" "
.0042F3BA: 6800000000 push 000000000 ;'MZP'
.0042F3BF: C3 retn
[... пропущено ...]
=== Допущено. Служба безопасности Night Zone Station ===
Для того, чтобы узнать адрес оригинальной точки входа посмотрим на строку
по адресу .0042F39A: mov eax,000001108
Адрес оригинальной точки входа заноситься в регистр eax после jmp'а и перед
push eax.
1108 - это адрес оригинальной точки входа без учета Image Base (то есть в
виде RVA - относительного виртуального адреса). Hам нужно преобразовать RVA в
VA (виртуальный адрес). Для этого прибавим к RVA значение Image Base, которое
можно узнать, нажав клавишу F8 (не забудьте потом закрыть окно с информацией из
заголовка!). Узнав значение Image Basе, прибавим его к 000001108 (то самое
число, которое заносится в регистр eax, об этом я писал выше):
00400000h + 000001108h = 401108h
Получившийся результат - адрес оригинальной точки входа.
Теперь нам нужно исправить текущее значение адреса точки входа на значение
адреса оригинальной точки входа. Открываем окно с информацией из заголовка
(F8), нажимаем F3, находим Entry point, и нажимаем еще раз F3, потом вводим
туда адрес оригинальной точки входа, которое мы рассчитали, нажимаем Enter и
потом F9).
Все! Экзешник распакован и готов к запуску!
ASPack'овский код остался в экзешнике, но он не получает управление, и
теперь бесполезен. Его размер не такой уж большой, но кому он мешает -
попробуйте вырезать его ;-)
Ух, наконец-то написал ;-)
Распаковать - дело трех минут, а описать процесс распаковки... ;-)
║▐│║▐║▌│║▐│║ Всего доброго!
║▐│║▐║▌│║▐│║
2║5084║30║34║> Renat (AKA Stranger)