Имеется простой вирь, который дописывает себя в конец последней секции. После записи надо, как я понял, поменять следующие значения: 1. SizeOfRawData, он же Physical Size. Размер секции на диске, кратный значению FileAlignment. Берем размер внедренного кода, делаем его кратным FileAlignment, складываем с SizeOfRawData и получаем новое значение SizeOfRawData. 2. Virtual Size, он же Virtual Size. Не кратный ничему размер секции в памяти. Чтобы он не стал меньше, чем SizeOfRawData сделаем его равным SizeOfRawData. 3. Characteristics. Ставим 0E0000000h т.е. в секции можно читать, писать и выполнять. Поправьте где я не прав, и что еще надо изменить. Поможите кто чем может
Не обязательно. Только в том случае, если он меньше чем SizeOfRawData. В противном случае его трогать не надо. Уменьшать его не стоит, иначе появятся дыры в размещении секций.
Так не всегда будет работать. Могут попасться файлы у которых последняя секция физически расположенная в файле виртуально располагается где-то между другими, и если увеличить ее VirtualSize, то может произойти наложение секций и файл не запустится. Если увеличивать значения у последней виртуальной секции то нужно следить за тем чтобы она проецировала добавленный в конец файла код. Т.е. SizeOfRawData = FileSize - AlignDown(PointerToRawData,FileAlignment) + NewDataSize Еще надо проследить чтобы VirtualSize у этой секции был либо VirtualSize + NewDataSize, либо SizeOfRawData, смотря какое значение больше SizeOfRawData и VirtualSize в win 2000/XP допускаются без выравниваний (в 9x хз) Еще не забыть изменить SizeOfImage = VirtualAddress + AlignUp(VirtualSize,SectionAlignment) последний виртуальной секции, и не забыть про оверлеи. PS: хотя это все довольно редко встречается и тоже не факт что после такого будет все правильно работать.
KondraT Можно почитать http://wasm.ru/article.php?article=peinfector. А еще советую под рукой иметь мануал по PE-формату от Hard Wisdom (правда там есть маленькие неточности и недоговорки).
Спасибо за ответы. Сделал следующее: 1. SizeOfRawData = AlignUp(ASizeOfRawData + VirusSize),FileAlignment 2. VirtualSize: если VirtualSize + VirSize > SizeOfRawData то VirtualSize = VirtualSize + VirSize если VirtualSize + virsize <= SizeOfRawData то VirtualSize = SizeOfRawData после этого VirtualSize не выравнивал 3. SizeOfImage = VirtualAddress + AlignUp(VirtualSize,SectionAlignment) yuzvir: Я перед этим ищу секцию последнюю физически и виртуально Про них как - то не подумал. А если я их затру кодом?
В большинстве файлов оверлей можно просто передвинуть в конец, а в некоторых прийдется сначала объединять с файлом и дописываться уже после него. Хотя я бы на месте вируса вообще не трогал такие файлы, либо можно делать элементарные проверки, например в SFX RAR архивах его можно передвигать, а в некоторых инсталяторах нужно объединять и даже править где-то внутри CRC
Каким образом обнаружить наличие оверлея? Возможно ли таким образом: Если PointerToRawData + SizeOfRawData последней секции физ. и виртуально меньше полученного значения GetFileSize, то оверлей есть ?
Блин. Всю голову уже сломал! Вроде все ок, НО! Если в конец последней секции записывается только часть кода вируса, т.е. только до конца файла. Почему - не могу понять. После всех правок делаю как обычно: UnmapViewOfFile, CloseHandle, CloseHandle. Почему не увеличивается последняя секция и, соответственно, сам размер файла?
Я понял в чем проблема: я передавал CreateFileMapping параметр dwMaximumSizeLow равный нулю, поэтому проекция получалась равна размеру файла и не больше. Прийдется файл отрывать два раза - с его обычным размером и с размером + размер внедряемого кода
Great: Я имел в виду первый раз спроецировать для проверки файла на возможность его заражения, потом закрыть и опять спроецировать с размером + размер кода вируса
Чтобы не создавать новой темы, спрошу тут: поставил точку входа на последнюю секцию - НОД ругается. какие есть способы изменения точки входа кроме как оставить ту же и по ее адресу сделать jmp на код вируса. (мне кажется этот способ не очень удобный, т.к. надо будет сохранять, а потом восстанавливать первые байты программы).