// Скриптик для востановления кода после аспра:
// 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:)
var calladdr
var aftercalladdr
var filesecend
var startscan
var endscan
var VirtualAllocExAddr
var realfunction
var iatcell
var iatstart
var iatstarttemp
var temp
var endmemoryspice
var OEP
var x
var y
var is_DLL

gpa "VirtualAllocEx", "kernel32.dll"	//Получили адрес VirtualAllocEx, эта функция будет юзаться для получния реального адреса
mov VirtualAllocExAddr, $RESULT

mov endmemoryspice, 2CF1000 //Конец заалоченной памяти и начало системных библиотек
mov iatstart, 00513000	//Адрес таблицы импорта
mov startscan, 00401000	//Начальная граница сканирования (секция кода, возможно не полностью)
mov endscan, 005047E9	//Конечная граница сканирования (секция кода)
mov filesecend, 6DA000	//Конец секций файла в памяти

@Oep_find_by_sanniassin:	//Скипт для поиска ОЕР был написан sanniassin, который разрешил его заюзать
mov x,esp 
sub x,48
bphws x,"r"
mov y,[eip]
and y,000000FF
cmp y,60
jne zzz
mov is_DLL,1

zzz:
run
mov y,[eip]
cmp y,01B80875
jne zzz
bphwc x
find edi,#83C404010424C3#
mov x,$RESULT
add x,6
bp x
run
bc x
sto
mov x,eip

findcall:
dec x
mov y,[x]
cmp y,5B5E5F5D
jne findcall
sub x,8
go x
sti
rtr
sto
mov x,eip
and x,0000FFFF
cmp x,0
mov x,esp
cmp is_DLL,1
jne is_exe
add x,10
jmp label_9
is_exe:
add x,8
label_9:
bphws x,"r"
run
mov y,eip
dec y
mov y,[y]
and y,000000FF
cmp y,5C
jne label_9
bphwc x
cmp is_DLL,1
jne is_exe2
find eip,#8944241C61FFE0#
add $RESULT,5
bp $RESULT
run
bc $RESULT
sto
jmp msg
is_exe2:
mov x,eax
go x
msg:
msg "OEP found! OEP not stolen."

mov OEP, eip

@continue:		//Главный цикл скрипта (поиск call`а, проверка на принадлежность к аспровскому)
findop startscan, #E8#	//Ищем оп-код 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)
cmp startscan, endscan	
jae @endscript		//Проверяем границы кода для сканирования (не выходит ли адрес анализируемого call`а за границы)
cmp calladdr, endmemoryspice 
jae @continue		//Проверяем, чтобы скрипт не загрёб вооще другую инструкцию в которой содержится байт E8
cmp aftercalladdr, filesecend
jae @reconstruct		//call ведёт за пределы файла в памяти? Да - это проделки аспра
jmp @continue		//Продолжем поиски, мы ещё должны всю вселенную обойти:) 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 и попали обратно на него-же, но он уже ведёт на другой адрес

			//Т.к. в OllyScript плохо реализован поиск, пришлось писать свой
mov iatstarttemp, iatstart	//Взяли во временную переменную адрес таблицы импорта	
sub iatstarttemp, 4		//Вычли из адреса 4, т.к. цикл начинается с добавления к адресу 4, следовательно один dword не будет захвачен поисковиком
@manual_find:		//Цикл поиска
add iatstarttemp, 4		//Сместили указатель на DWORD
mov iatcell, [iatstarttemp]	//Получили адрес
cmp iatcell, realfunction	//Проверили, не совподают ли значения реальной функции и полученной из IAT
jne @manual_find		//Нет? Продолжаем искать

			//Сейчас будем востанавливать call aspr_code, заменяя на call [IAT_cell]
mov [eip], #FF15#		//FF15 - опкод call [XXXXXXXX]
add eip,2			//Сместили указатель на 2, тут надо будет писать адрес, по которому лежит адрес для перехода
mov [eip], iatstarttemp	//Записали адрес ячейки таблицы импорта (call [Iat_cell])
jmp @continue		//Продолжаем поиск, востановление и т.д.
@endscript:
mov eip, OEP		//Устанавливаем eip на адрес, которму равнялся eip до начала выполнения скрипта, обычно это ОЕР или очень близкий к ОЕР код
ret			//Вышли из скрипта

