Олдфаг
-
Автор темы
- #1
- Что это такое?
Это упаковщик, стоящий на одну ступеньку выше, чем UPX. Ничем не отличается в сложности от UPX, так как антиотладочных приемов - ноль, а найти истинную точку входа AsPack-программе почти также просто. Отличает его другая модель упаковки. Код распаковшика более изменчив от версии к версии, чем у UPX, но эти изменения - только в деталях, поэтому распознавание остается тем же.
В живой природе встречается раза в 2 реже чем UPX, но несмотря на это в сети легко найти руководство по его снятию.
- Как выглядит?
Заархивировав RAR'ос упакованный AsPack'ом файл, мы увидим... что упаковщик со своей задачей справляется плохо. Причина в том, что AsPack, как и многие другие, обрабатывает каждую секцию отдельно. Из-за этого теряется много места на выравнивание, что особенно заметно на файлах с множеством маленьких секций. Зато имена секций и их виртуальные адреса остаются нетронутыми.
Распаковщик находится в предпоследней секции программы, которая получает имя '.aspack'. Последняя секция 'adata' - пустая (physsize = 0) и всегда занимает в памяти 1000h байт. В самых первых версиях упаковщика этой пустой секции не было, посему распаковщик оказывался последней секцией. Обе секции получают атрибуты 'read', 'write', и 'initdata'. Автору наплевать, что у распаковщика нет атрибута 'execute' или 'code', из-за чего файл откажет запускаться на архитектурах где право 'read' не считается правом исполнения. Также известны проблемы с AsPack'ом в эмуляторе Wine.
Пример 1. Delphi-программа (comersan-1.00b)
Пример 2. программа на Visual C (Drwebupw-2.12)
Теперь рассмотрим примеры. Первый пример - одна из первых версий, поэтому распаковщик находится в посл. секции, а во втором примере секция '.aspack' переименована в '.drweb'.
!!! с NonExecute-битом
- Импорт
AsPack импортирует ф-ю GetModuleHandle, считая зазорным узнавать ее адрес самому :).
- Точка входа
Поскольку код распаковщика меняется с каждой версией, точка входа может выглядеть как угодно. Но опознать AsPack по точке входа все же можно!
Во-первых, она отстоит от начала секции на 1 байт и начинается с pushad (60h), сразу после которой расположены 2 относительные команды перехода - call (E8 или E9) и jmp (EB), причем между ними может стоять пара мусорных байт. Это нормальный случай.
То, что идет дальше - отличается от версии к версии. В большинстве случаев перед командой pushad стоит байт 90h, который является командой nop. Поэтому иногда точку входа переставляют на него (и тогда она уже точно совпадает с началом секции). Смещения всего на 1 байт уже достаточно, чтобы сигнатуры антивирусов не сработали. В результате антивирусы, распознающие AsPack по сигнатуре в точке входа (например, хваленый Касперский), уже не узнают, что файл упакован!
Еще можно команды nop и pushad поменять местами. Иногда можно рискнуть и затереть команду pushad командой nop (как в случае с UPX). Поскольку мы внесли изменения в тело распаковщика, это изменение может повлиять на его работу (но в большинстве случаев этого не случится). Просто запустите пропатченную программу - если заработает - все нормально, если нет - верните команду pushad на место! Максимум получится 2 команды nop, которые теперь можно заменить на любые 2 однобайтные ничего не делающие команды (например inc eax, dec eax). И программы с такими командами уже встречаются.
Кроме этого перед началом секции расположено много нулей, оставшихся от выравнивания. Их тоже можно заменить незначащими командами, правда тогда точка входа попадет в другую секцию.
Как видите, вариантов - множество. Но - самое главное понять, что файл обработан навесным упаковщиком, а распознать упаковщик можно вручную по опыту (через тот же HEX-редактор).
Сигнатуру можно описать так:
* 90/60, 90/60, E8/E9 03 00 00 00 ?? EB 04
- Ручная распаковка
Вобщем, почти не отличается от UPX. Поскольку в начале выполняется pushad, то перед передачей управления надо сделать popad:
Ставим бряк на popad и продолжаем. jnz addr перепрыгивает первый retn, а далее push заносит адрес возврата и retn делает по нему переход на настоящую точку входа. Сбрасываем дамп.
- Признаки упаковщика
Итак, давайте обсудим, как мы можем узнать AsPack. Сначала текстовые строки:
1) последняя секция называется '.aspack'
2) или предпоследняя секция называется '.aspack', а последняя - '.adata'
По точке входа:
1) находится в последней или предпоследней секции
2) указывает на 0-ой или 1-ый байта секции
3) начинается с pushad или nop, далее должен быть call на 3 байта вперед (EB 03), потом неск. лишних байт и jmp.
Наконец, самый надежный способ - по формату файла
1) после секции ресурсов .rsrc или, если их нет, после секции неинициализированных данных должно быть 1-2 секции, причем если их там две, то 2-ая должна иметь нулевой физический размер и вирт. размер = 1000h.
2) обе последние секции имеют аттрибуты только read, write и initdata.
Второй признак не надежен, так как без влияния можно заменить read на execute или code. Так что стоит ориентироваться по первому признаку.
Это упаковщик, стоящий на одну ступеньку выше, чем UPX. Ничем не отличается в сложности от UPX, так как антиотладочных приемов - ноль, а найти истинную точку входа AsPack-программе почти также просто. Отличает его другая модель упаковки. Код распаковшика более изменчив от версии к версии, чем у UPX, но эти изменения - только в деталях, поэтому распознавание остается тем же.
В живой природе встречается раза в 2 реже чем UPX, но несмотря на это в сети легко найти руководство по его снятию.
- Как выглядит?
Заархивировав RAR'ос упакованный AsPack'ом файл, мы увидим... что упаковщик со своей задачей справляется плохо. Причина в том, что AsPack, как и многие другие, обрабатывает каждую секцию отдельно. Из-за этого теряется много места на выравнивание, что особенно заметно на файлах с множеством маленьких секций. Зато имена секций и их виртуальные адреса остаются нетронутыми.
Распаковщик находится в предпоследней секции программы, которая получает имя '.aspack'. Последняя секция 'adata' - пустая (physsize = 0) и всегда занимает в памяти 1000h байт. В самых первых версиях упаковщика этой пустой секции не было, посему распаковщик оказывался последней секцией. Обе секции получают атрибуты 'read', 'write', и 'initdata'. Автору наплевать, что у распаковщика нет атрибута 'execute' или 'code', из-за чего файл откажет запускаться на архитектурах где право 'read' не считается правом исполнения. Также известны проблемы с AsPack'ом в эмуляторе Wine.
Пример 1. Delphi-программа (comersan-1.00b)
Код:
CODE rva 00001000, vsize 00086000, offset 00000400, psize 0003EC00
DATA rva 00087000, vsize 00002000, offset 0003F000, psize 00000C00
BSS rva 00089000, vsize 00001000, offset 0003FC00, psize 00000000
.idata rva 0008A000, vsize 00003000, offset 0003FC00, psize 00001000
.tls rva 0008D000, vsize 00001000, offset 00040C00, psize 00000000
.rdata rva 0008E000, vsize 00001000, offset 00040C00, psize 00000200
.reloc rva 0008F000, vsize 00009000, offset 00040E00, psize 00000000
.rsrc rva 00098000, vsize 0004F000, offset 00040E00, psize 00030400
.data rva 000E7000, vsize 00001000, offset 00071200, psize 00000800
Код:
.text rva 00001000, vsize 00029000, offset 00000600, psize 00013E00
.rdata rva 0002A000, vsize 00008000, offset 00014400, psize 00002400
.data rva 00032000, vsize 0000C000, offset 00016800, psize 00001600
.rsrc rva 0003E000, vsize 00008000, offset 00017E00, psize 00002200
.drweb rva 00046000, vsize 00003000, offset 0001A000, psize 00002400
.adata rva 00049000, vsize 00001000, offset 0001C400, psize 00000000
!!! с NonExecute-битом
- Импорт
AsPack импортирует ф-ю GetModuleHandle, считая зазорным узнавать ее адрес самому :).
- Точка входа
Поскольку код распаковщика меняется с каждой версией, точка входа может выглядеть как угодно. Но опознать AsPack по точке входа все же можно!
Во-первых, она отстоит от начала секции на 1 байт и начинается с pushad (60h), сразу после которой расположены 2 относительные команды перехода - call (E8 или E9) и jmp (EB), причем между ними может стоять пара мусорных байт. Это нормальный случай.
Код:
pushad
call +3$
??
jmp +4$
Еще можно команды nop и pushad поменять местами. Иногда можно рискнуть и затереть команду pushad командой nop (как в случае с UPX). Поскольку мы внесли изменения в тело распаковщика, это изменение может повлиять на его работу (но в большинстве случаев этого не случится). Просто запустите пропатченную программу - если заработает - все нормально, если нет - верните команду pushad на место! Максимум получится 2 команды nop, которые теперь можно заменить на любые 2 однобайтные ничего не делающие команды (например inc eax, dec eax). И программы с такими командами уже встречаются.
Кроме этого перед началом секции расположено много нулей, оставшихся от выравнивания. Их тоже можно заменить незначащими командами, правда тогда точка входа попадет в другую секцию.
Как видите, вариантов - множество. Но - самое главное понять, что файл обработан навесным упаковщиком, а распознать упаковщик можно вручную по опыту (через тот же HEX-редактор).
Сигнатуру можно описать так:
* 90/60, 90/60, E8/E9 03 00 00 00 ?? EB 04
- Ручная распаковка
Вобщем, почти не отличается от UPX. Поскольку в начале выполняется pushad, то перед передачей управления надо сделать popad:
Код:
popad
jnz addr
mov eax, 1
retn 0C
push oep
retn
- Признаки упаковщика
Итак, давайте обсудим, как мы можем узнать AsPack. Сначала текстовые строки:
1) последняя секция называется '.aspack'
2) или предпоследняя секция называется '.aspack', а последняя - '.adata'
По точке входа:
1) находится в последней или предпоследней секции
2) указывает на 0-ой или 1-ый байта секции
3) начинается с pushad или nop, далее должен быть call на 3 байта вперед (EB 03), потом неск. лишних байт и jmp.
Наконец, самый надежный способ - по формату файла
1) после секции ресурсов .rsrc или, если их нет, после секции неинициализированных данных должно быть 1-2 секции, причем если их там две, то 2-ая должна иметь нулевой физический размер и вирт. размер = 1000h.
2) обе последние секции имеют аттрибуты только read, write и initdata.
Второй признак не надежен, так как без влияния можно заменить read на execute или code. Так что стоит ориентироваться по первому признаку.