Windows EXE/DLL: что такое "упакованное изображение"

Process Explorer иногда показывает EXE как "упакованное изображение", но что это значит.

Что я выяснил: Компиляция exe (с использованием Visual С++ 2010) с опцией /ZI приводит к упакованному изображению, но /ZI не работает. Почему такая разница?

BTW: DLL, скомпилированная с помощью /ZI, также считается "упакованным изображением" и помечена фиолетовым цветом.

введите описание изображения здесь

Ответ 1

"Упакованное изображение" - это формат, в котором исполняемый код сжимается с намерением сделать файл меньшим. Типичное сокращение размера файла составляет около 50%. Он использует "загрузчик" во время выполнения, чтобы распаковать данные до исполняемого кода до его запуска. Это было полезно в прежние времена с ограниченной дисковой емкостью и ограниченной пропускной способностью сети.

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

Точная эвристика, которую PE использует для обнаружения упаковки, не документирована. Конечно, нет, это слишком легко обойти. Это не тривиально, нет стандартного способа реализации упаковки. Грубо говоря, он будет смотреть на разделы в исполняемом файле и поднять синий флаг, если слишком большая часть его выглядит как неисполняемый код.

И да, когда вы будете использовать /ZI, тогда их будет много. Более значимым является опция linker/INCREMENTAL, автоматически включаемая при использовании /ZI. Это позволяет вам писать код во время отладки, параметр "Редактировать + Продолжить". И быстро пересканируйте исполняемый файл без необходимости компоновщика, чтобы полностью перегенерировать файл. Это может работать только тогда, когда в исполняемом файле имеется много свободного места, доступное для добавления новых байтов машинного кода. Это синий флаг.

Конечно, не вызывает особой озабоченности, ваш пользователь только увидит сборку выпуска вашей программы. Который построен без /ZI и без/INCREMENTAL.

Ответ 2

Из Исходный код процесса Hacker:

Изображение упаковано, если:

  • Он ссылается на менее 3 модулей и
  • Импортирует менее 5 функций и
  • Он не использует родную подсистему.

Или:

  • Коэффициент "функция-модуль" ниже 3 (в среднем из каждого модуля импортируется в среднем менее 3 функций) и
  • Он ссылается на более чем 2 модуля, но менее 6 модулей.

Или:

  • Коэффициент "функция-модуль" ниже 2 (в среднем из каждого модуля импортируется в среднем менее 2 функций) и
  • Он ссылается на более чем 5 модулей, но менее 31 модулей.

Или:

  • У него нет раздела с именем ".text".

Изображение не считается упакованным, если оно имеет только один импорт из модуль с именем "mscoree.dll".

Вы также можете взглянуть на код soruce, чтобы выяснить, как определить, упакован ли образ, или если это не так.

Ответ 3

Проверка, которую выполняет проводник процессов (для 32-разрядных систем):

section = (IMAGE_SECTION_HEADER *)(ntHeader + sizeof(IMAGE_NT_HEADERS));
sectionCount = ntHeader->FileHeader.NumberOfSections;
secCounter = 1;
if ( sectionCount < 1 )
goto NotPacked; // not enough info, guess not packed?

while ( 1 )
{
    secCharic = section->Characteristics;
    if ( secCharic & IMAGE_SCN_CNT_CODE )
    {
      secAddr = section->Misc.PhysicalAddress;
      if ( secAddr > 0x1000 && section->SizeOfRawData < secAddr - 0x1000 )
        break; // found a weird section, probably packed
    }

    if (section->Name == '.text')
    {
      secAddr = section->Misc.PhysicalAddress;
      if (secAddr > 0x1000 && section->SizeOfRawData < secAddr - 0x1000 )
        break; // found a weird section, probably packed
    }

    if (sec.HasName && section->SizeOfRawData < section->Misc.PhysicalAddress 
      || section->SizeOfRawData != 0
      && section->Misc.PhysicalAddress >= 0x1000
      && (section->Name != '.textbss')
      && (section->Name != '.tls')
      && (section->Name != '.bss')
      && (section->Name != '.data')
      && secCharic & IMAGE_SCN_MEM_EXECUTE
      && secCharic & IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_CNT_UNINITIALIZED_DATA) {
        break; // found a weird section, probably packed
    }

    ++secCounter;
    ++section;

    // Loop through all sections
    if ( secCounter > sectionCount )
      goto NotPacked;
    }
}
isPacked = 1;

Ответ 4

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