· Начало · Статистика · WASM.RU · Noir.Ru ·

 WASM Phorum (Оффлайн - 24.11.2003) —› WASM.RESEARCH —› Сброс дампа и пара вопросов

Посл.отвђт Сообщенiе


Дата: Июл 21, 2003 01:56:56 · Поправил: volodya

Теперь и моя очередь вопросы задавать пришла. В сети не нашел :) Ни в русской, ни в английской.

Практически во всех источниках по снятию пакеров говориться, что программу надо загонять в бесконечный цикл. У меня было (звучит как!) достаточно много программ, которые я сбрасывал на диск просто так и все фурычило.

В одной статье я встретил фразу:
У начинающего распаковщика может возникнуть вопрос: а зачем зацикливать программу? Почему нельзя снять дамп с работающего приложения? Дело в том, что программа при запуске много чего инициализирует в секции данных и кода. А когда дамп пытается сделать это еще раз, у него естественно ничего не получается, а чаще всего выходит "Ошибка при инициализации приложения (0xc000007b)"

Посидел над ней, подумал. Вообще-то, чего-то смутно мне помнится, есть неинициализированные секции в PE файле. Особенно много такой гадости в васиковских программах, и, ессно, после сброса дампа из памяти они УЖЕ будут инициализированны и дамп будет неработоспособен.
Вопрос - кто же инициализирует такие секции? Лоадер? Почти однозначно, нет. Приложение? Скорее всего да. Я прав? Хотя тогда при чем тут "ошибка инициализации приложения"???? Это объява бывает только от лоадера! И еще я балдею от "инициализации данных в секции кода". Что-то у меня такое чувство, что я не дружу с головой!

Есть программа любопытная - Refox. Линк в разделе инструментов. Ковыряю ее помаленьку. Запакована Aspack. Распаковывается bpm esp-4, дамп, ImpRec с OEP 401000. Таблица импорта ОК, точка входа ОК. Файл признается Windows как нормальный. Загружается... И тут же вылетает! Я вот сижу и думаю... Его что, ввобще по секциям собирать надо. Что-то я не учитываю :(


Дата: Июл 21, 2003 02:16:24

Тут что-то не то, ASPack всегда распаковывался без проблем ;-)
Нужно посмотреть...


Дата: Июл 21, 2003 05:45:26

Спасибо.
Еще больше меня интересует вопрос с инициализацией секций. Тут у меня ум за разум заходит :(


Дата: Июл 21, 2003 07:49:21

Секции с неинициализировнными данными (там обычно содержатся неинициализированные глобальные переменные) заполняются загрузчиком нулями, а программа уже сама во время работы модифицирует данные в них.
Кстати, "ошибка инициализации приложения" может возникунуть, если у файла неправильная таблица импорта, а может быть, и если неправильная таблица экспорта или каталог ресурсов.


Дата: Июл 21, 2003 08:22:39

volodya
В одной статье я встретил фразу
IMHO автор неправильно выразился или его слова неправильно перевели :) Я понимаю это следующим образом. Некоторые пакеры приводят в порядок данные и код (!) прямо по ходу выполнения (как в PELock). Поэтому их нужно досконально прогонять по всем ф-циям для задействования самых малоиспользуемых участков программы. Если это не сделать, дамп может в конечном счёте напороться на нераспакованный кусок кода и/или данных и сдохнуть. Вот, и к BSS это никакого отношения не имеет. Мысли вслух :)


Дата: Июл 21, 2003 12:01:05

Смысл зацикливания на OEP перед дампом в том, чтобы не дать программе испортить начальные значения своих глобальных и статических переменных.

На вопрос о том, кто инициализирует эти данные, правильный ответ - компилятор.

Расположены они, как правило, в секции данных и к бсс-у отношения не имеют. А с инициализацией программой своей кодовой секции, автор (или переводчик) той статьи, похоже, действительно погорячился. Сразу оговорюсь, что это всё справедливо для типовых программ из-под компиляторов, потому как руками можно сделать всё, что угодно.

Распаковка по ходу выполнения - это совсем другой случай, и действовать при нем нужно соответственно.

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

Резюмируя: В общем случае, рекомендация должна звучать примерно так: секции данных лучше дампить на OEP. :)


Дата: Июл 21, 2003 12:31:23

Простейший пример - создание кучи при инициализации CRT, вполне может выглядеть так:
static void* h_heap = 0;
void* user_malloc(size_t cnt)
{
  if ( !h_heap )
    h_heap = HeapCreate(...);
  return HeapAlloc(h_heap, ...);
}


Соответсно если ты снимешь дамп песле вызова этой функции, то h_heap уже будет проиничено, и при следующем запуске будет проискодить обращение к несуществующей куче и как следствие GPF :)
Хотя обычно проблема только в tls цепочках, а рантайм не делает таких проверок. Так штаа в общем случае, рекомендация должна звучать примерно так: секции данных лучше дампить сразу после раскриптовки/распаковки, ибо протектор может их подпортить еще до ОЕР (hi Alex ;)


Дата: Июл 21, 2003 13:04:46 · Поправил: Dr.Golova

А по поводу аспака вот что я могу сказать для того рефокса что лежит на официальном сайте:
.compro:0069316F                 mov     edi, [esi]      ; section rva
.compro:00693171                 add     edi, [ebp+422h] ; image_base
.compro:00693177                 mov     esi, [ebp+152h] ; temp buffer
.compro:0069317D                 sar     ecx, 2
.compro:00693180                 rep movsd
.compro:00693182                 mov     ecx, eax
.compro:00693184                 and     ecx, 3
.compro:00693187                 rep movsb
.compro:00693189                 pop     esi
.compro:0069318A                 push    8000h
.compro:0069318F                 push    0
.compro:00693191                 push    dword ptr [ebp+152h] ; temp buffer
.compro:00693197                 call    dword ptr [ebp+551h] ; VirtualFree
.compro:0069319D                 add     esi, 8
.compro:006931A0                 cmp     dword ptr [esi], 0 ; next section rva
.compro:006931A3                 jnz     unpack_loop
.compro:006931A9                 push    8000h
.compro:006931AE                 push    0
.compro:006931B0                 push    dword ptr [ebp+156h] ; huffman table
.compro:006931B6                 call    dword ptr [ebp+551h] ; VirtualFree


Соответсно сделав bpm 6931A9 x и сняв дампик тут мы получим распакованными все секции. Идем дельше.
.compro:006931CE                 mov     edx, [ebp+422h] ; image base
.compro:006931D4                 mov     eax, [ebp+52Dh] ; original base
.compro:006931DA                 sub     edx, eax
.compro:006931DC                 jz      short reloc_done
.compro:006931DE                 mov     eax, edx
.compro:006931E0                 shr     eax, 10h
.compro:006931E3                 xor     ebx, ebx
.compro:006931E5                 mov     esi, [ebp+539h] ; reloc table rva
.compro:006931EB                 add     esi, [ebp+422h] ; image base
.compro:006931F1 
.compro:006931F1 loc_6931F1:
.compro:006931F1                 cmp     dword ptr [esi], 0 ; page rva
.compro:006931F4                 jz      short reloc_done


Тут соответсно при необходимости получаем адрес таблицы релоков.
.compro:00693278                 mov     esi, 1B0000h    ; import table rva
.compro:0069327D                 mov     edx, [ebp+422h] ; image base
.compro:00693283                 add     esi, edx
.compro:00693285 
.compro:00693285 loc_693285: 
.compro:00693285                 mov     eax, [esi+0Ch]  ; dll name rva
.compro:00693288                 test    eax, eax
.compro:0069328A                 jz      loc_69339A
.compro:00693290                 add     eax, edx
.compro:00693292                 mov     ebx, eax
.compro:00693294                 push    eax
.compro:00693295                 call    dword ptr [ebp+0F4Dh] ; GetModuleHandleA


Отсюда имеем rva таблицы импорта (а в уже снятом дампе она целенькая, так штаа про imprec можно забыть :)
.compro:0069339A                 mov     eax, 1000h      ; oep rva
.compro:0069339F                 push    eax
.compro:006933A0                 add     eax, [ebp+422h] ; image base
.compro:006933A6                 pop     ecx
.compro:006933A7                 or      ecx, ecx
.compro:006933A9                 mov     [ebp+3A8h], eax ; patch push at 6933BAh
.compro:006933AF                 popa
.compro:006933B0                 jnz     short loc_6933BA
.compro:006933B2                 mov     eax, 1
.compro:006933B7                 retn    0Ch
loc_6933BA:
.compro:006933BA                 push    0
.compro:006933BF                 retn


Вот собсно и все что нужно для регулярной половой жизни, все это я естесно посмотрел только в дизассемблере и проверять не стал - лениво =)


Дата: Июл 21, 2003 13:28:34

Секции, инициализируемые при загрузке программы, ИМХО, нужно заново удалять из дампа. То есть все секции, в которых есть только нули, нужно выкинуть из дампа, прописывая им нулевой физический размер в РЕ-хидере, но оставляя виртуальный размер нетронутым.
Или я не вьехал в суть вопроса?


Дата: Июл 21, 2003 15:13:32

Quantum wrote
пакеры приводят в порядок данные и код (!) прямо по ходу выполнения (как в PELock).
Это как он такое делает?
Просто ставит "No access" страницам и дешифрует их в рантайме, или дизассемблирует прогу и внедряется в нее?
первое - достаточно слабо (Hex писАл про армадилло),
а вот второе - очччень интересно, но тут возникает проблема разделения кода и данных...


Дата: Июл 21, 2003 17:07:53

[ bsl_zcs: Резюмируя: В общем случае, рекомендация должна звучать примерно так: секции данных лучше дампить на OEP. :)]

Не всегда(!), на OEP данные уже инициализированные, поэтому иногда
приходится дампить ещё раньше ;-)


Дата: Июл 21, 2003 18:21:50

Спасибо всем за столь классные ответы. Мне теперь есть над чем тыкву почесать :)


Дата: Июл 22, 2003 18:35:58

Да, кстати, Dr. Golova, рановато вам лениво стало. Снять Aspack тривиально. Снять Aspack с ReFox - не так, чтоб очень :)


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.068