Получение базы образа во время выполнения
Одна из самых наиболее частых заблуждений - это мнение, что база образа будет всегда одной и той же или всегда будет равна 400000h. Но на самом деле, все далеко не так. Независимо от того, какая база образа будет указана в заголовке вашего файла, система может легко поменять во время запуска, поэтому мы будем пытаться получить доступ к неверному адресу и получить неожиданные результаты. Получить базу образа можно достаточно просто. Просто используйте обычную процедуру получения дельта-смещения.
virus_start: call tier ; Push'им в ESP адрес возврата tier: pop ebp ; Получаем адрес возврата sub ebp,offset realcode ; И отнимаем начальное смещение
Ок? Давайте представим, что, например, выполнение началось по адресу 401000h (как почти во всех слинкованных TLINK'ом файлах). Поэтому когда мы делаем POP, в EBP у нас будет что-то вроде 00401005h. Тогда что вы получите, если вычтете от него virus_start, а от результата мы снова вычтем текущий EIP (который во всех TLINKованных файлах равен 1000h)? Да, мы получим базу образа! Таким образом, мы будем делать следующее:
virus_start: call tier ; Push'им в ESP адрес возврата tier: pop ebp ; Получаем текущий адрес mov eax,ebp sub ebp,offset realcode ; И отнимаем начальное смещение sub eax,00001000h ; Отнимаем текущий EIP (должен NewEIP equ $-4 ; быть пропатчен во время заражения sub eax,(tier-virus_start) ; Отнимаем остальное :)
И не забудьте пропатчить переменную NewEIP во время заражения (если модифицируете EIP), что она всегда была равна переменной по смещению 28h заголовка PE, то есть RVA EIP программы :).