// Скриптик для востановления кода после аспра: // call 0BA0000 ;Call CreateFileA // После скрипта: // call [Real_addr_in_IAT] //Писал для AlterWind Log Analyzer Professional 3.0.0.1 // До скорого, братья. by BiT-H@ck in 26.08.2005 3:42:) #log var calladdr var aftercalladdr var filesecend var startscan var endscan var VirtualAllocExAddr var realfunction var iatcell var temp var endmemoryspice var OEP var x var y var IATend gpa "VirtualAllocEx", "kernel32.dll" //Получили адрес VirtualAllocEx, эта функция будет юзаться для получния реального адреса mov VirtualAllocExAddr, $RESULT mov endmemoryspice, 0F21000 //Конец заалоченной памяти и начало системных библиотек mov IATend, 005321BC mov startscan, 00401000 //Начальная граница сканирования (секция кода, возможно не полностью) mov endscan, 00448BB1 //Конечная граница сканирования (секция кода) mov filesecend, 5E0000 //Конец секций файла в памяти mov OEP, eip jmp @finder @continue2: //Главный цикл скрипта (поиск call`а, проверка на принадлежность к аспровскому) mov startscan, $RESULT //Сохранили адрес найденного байта inc $RESULT //Если это call aspr_code, по адреу call aspr_code+1 лежит dword - смещение отнасительно следующей инструкции mov calladdr, [$RESULT] //Получаем кол-во байт для смещения от следующей команды add $RESULT, 4 //Адрес, от которого отчитается смещение (первый байт инструкции после call aspr_code). mov aftercalladdr, $RESULT //Сохранили адрес следующей инструкции add aftercalladdr, calladdr //Получили адрес aspr_code (адрес, на который переходит call) mov calladdr, aftercalladdr and calladdr, FF000000 cmp calladdr, 0 jne @finder cmp startscan, endscan ja @endscript //Проверяем границы кода для сканирования (не выходит ли адрес анализируемого call`а за границы) cmp calladdr, endmemoryspice jae @finder //Проверяем, чтобы скрипт не загрёб вооще другую инструкцию в которой содержится байт E8 cmp aftercalladdr, endmemoryspice jae @finder cmp aftercalladdr, filesecend jae @reconstruct //call ведёт за пределы файла в памяти? Да - это проделки аспра jmp @finder //Продолжем поиски, мы ещё должны всю вселенную обойти:) by Factor 2 @reconstruct: //В это процедуре будет происходить самое главное - востановление call aspr mov eip, startscan //Установили eip на call aspr_code bp VirtualAllocExAddr //Для остановки внутри функции получения адреса реальной функции, после получения адреса, будем юзать VirtualAllocEx run //Установили eip на call aspr_code, поставили бряк на VirtualAllocEx, запустили программу bc VirtualAllocExAddr //Остановились, удалили брейкпоинт mov temp, esp add temp, 5C //В esp+5C лежит адрес реальной функции mov realfunction, [temp] //Взяли адрес реальной функции bphws startscan, "x" //Установили брейкпоинт на call aspr_code run bphwc startscan //Вышли из call aspr_code и попали обратно на него-же, но он уже ведёт на другой адрес @IAT_write: mov [IATend], realfunction //Сейчас будем востанавливать call aspr_code, заменяя на call [IAT_cell] mov [eip], #FF25# //FF15 - опкод call [XXXXXXXX] add eip,2 //Сместили указатель на 2, тут надо будет писать адрес, по которому лежит адрес для перехода mov [eip], IATend add IATend, 4 //Записали адрес ячейки таблицы импорта (call [Iat_cell]) jmp @finder //Продолжаем поиск, востановление и т.д. @endscript: mov eip, OEP //Устанавливаем eip на адрес, которму равнялся eip до начала выполнения скрипта, обычно это ОЕР или очень близкий к ОЕР код ret //Вышли из скрипта @finder: mov $RESULT, startscan @manual_find: //Цикл поиска и тут пришлось писать свой:( add $RESULT, 1 mov iatcell, [$RESULT] and iatcell, 000000FF cmp iatcell, 000000E8 jne @manual_find add $RESULT, 1 mov iatcell, [$RESULT] and iatcell, FF000000 cmp iatcell, 00000000 jne @manual_find sub $RESULT, 1 log $RESULT jmp @continue2