[Immunity Dbg Scripts]
[Intro]
Извиняюсь за долгое свое отсутствие и слабую активность в последнее время – виной тому экзамены и некоторые финансовые затруднения. Сейчас, настало некое “furore poetico”, образно выражаясь, конечно. Появилось некоторое количество свободного времени, которое можно потратить с пользой.
[Scripting]
Решила поднять эту тему, так как имунити дбг и скрипты под него до сего момента не особенно активно обсуждались в разделе. Так же меня не устраивало то, что за все время нашла сборничек из 15 скриптов (кто смотрел, обнаружил, что, например, некоторые там явно под ODbgScript) и 13 плагинов + довольно скудный набор примеров в самом отладчике. Потом все имеющееся плохо откомментировано, если вообще откомментировано. Сей пробел я и собираюсь заполнить.
В данной теме постим скрипты под иммунити.
Только просьба – комментируйте подробно код- это необходимое условие. И описание небольшое делайте.
Начну
Некогда (не так давно, кстати) на tuts4you выкладывался UnPackMe Mimoza 0.86 – под него писала скрипт сначала под OllyScript, а затем из спортивного интереса написала на питоне
Код:
# -*- coding: cp1251 -*-
from immlib import *
import struct,sys
#------------------------------------------------------------------------------|
#-------------------0x0c0de (c) 2008-----------------------------------|
#------------------------------------------------------------------------------|
#----------Mimoza 0.86 Unpacking script-----------------------------|
def main(args):
imm = Debugger()
v_alloc_address = imm.getAddress("kernel32.VirtualAlloc") # получаем адрес VirtualAlloc
if v_alloc_address>0: # если адрес получен успешно
imm.Log(" ")
imm.Log("VirtualAlloc address-> 0x%08X " % v_alloc_address)
imm.setHardwareBreakpoint(v_alloc_address,1,4)
imm.Log("Breakpoint at -> 0x%08X " % v_alloc_address)
imm.Log("Running ..")
imm.Run()
regs=imm.getRegs()
addres_of_region =regs['EAX']
imm.Log("Address Region -> 0x%08X " % addres_of_region) #в лог пишем адрес региона, где лежит наш файл
size_=regs['ECX']
imm.Log("Region size-> 0x%08X " % size_) # выводим в лог размер файла
imm.runTillRet() # Ctrl+F9
imm.stepIn() # F7
regs=imm.getRegs() # получаем все регистры
cur=regs['EIP']+53 # получаем адрес команды REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI] - текущий eip+53
imm.setHardwareBreakpoint(cur,1,4) # ставим аппаратную точку останова на команду REP MOVSB
imm.Run() # F9
imm.setReg('ECX',size_)
imm.stepOver() # F8
imm.stepOver() # F8
f=open("Mimoza_unpacked.exe", "wb") # создаем файл для дампа
buff_=imm.readMemory(addres_of_region,size_) #записываем в него содержимое нашего распакованного файла
f.write(buff_)
f.close()
imm.Log("Unpacked file at Mimoza_unpacked.exe")
else:
imm.Log("No address")
return "Done"
# поместите файл mimoza.py в директорию PyCommands ImmunityDbg и вызывайте командой !mimoza
Обратите внимание на то, что вначале я указываю кодировку. Иначе комментарии на русском не прокатят (о кодировках написано в любом учебнике/документации по питону)
Скрипт поиска апи-функции во всех загруженных в АП процесса модулях
Код:
# -*- coding: cp1251 -*-
from immlib import*
#данный скрипт осуществляет поиск функции, полученной в качестве аргумента во всех загруженных модулях
#вызов скрипта !apifinder имя_функции в командной строке (сам скрипт поместите в директорию PyCommands)
def main(args):
imm = Debugger()
imm.Log("Simple Api Finder by 0x0c0de")
modul_list=imm.getAllModules() #получаем имена всех модулей, подгруженных в АП
for mod in modul_list.keys(): # цикл обработки всех имен модулей
lenstr=len(mod)-3 # убираем расширение
mystr="" #очищаем буфер
func_addr=0
for char_ in mod:
if lenstr>0:
mystr=mystr+char_
else:
func_addr=imm.getAddress(mystr+args[0]) #получаем адрес функции
if func_addr>0: # если не возникло ошибки, адрес получен
imm.Log(mod+" function "+args[0]+" address -> 0x%08X " % func_addr)
return "All good. See log window" #завершаем работу скрипта
else:
imm.Log("No function " +args[0]+" in "+mod)
break
lenstr=lenstr-1
return "No function! See log window" #если получает управление эта команда, то функция не найдена
Мелочь, а приятно. Запуск нужный тулз из имунити.
Код:
import sys,os
def usage(imm):
imm.Log(" Tools runner by 0x0c0de")
def main(args):
os.startfile("C:\Tools\Lord\LordPE.EXE")
os.startfile("C:\Tools\ImpREC 1.7c\ImpREC 1.7c\ImportREC.exe")
return "Done!"
Используйте скрипт hidedebug с опцией All_Debug для убийства типичной антиотладки (его здесь не привожу, так как его можно нарыть в вышеупомянутой сборке (в конце поста я приведу все ссылки)
Next…
Код:
# -*- coding: cp1251 -*-
from immlib import *
import struct,sys
#антиотладку убиваете !hidedebug All_Debug (см выше по тексту)
# обязательно поставьте в опциях игнорирование всех исключений Alt+O вкладка Exceptions - везде галочки
#скрипт помещаете в директорию PyCommands ImmunityDbg и запускаете командой !имя_скрипта
#simple YodaCrypter OEP Finder by 0x0c0de
def main(args):
imm=Debugger()
isdebpres = imm.getAddress("kernel32.IsDebuggerPresent") # определяем адрес IsDebuggerPresent
imm.setBreakpoint(isdebpres) # ставим обычный бряк на функцию
imm.Run() #F9
imm.deleteBreakpoint(isdebpres) #удаляем бряк
imm.runTillRet() # Ctrl+F9
imm.stepIn() # F7
imm.runTillRet() # Ctrl+F9
imm.stepIn() #F7
cur = imm.getCurrentAddress() #Получаем текущий адрес
cur = cur+31 #Адрес команды push eax
imm.setHardwareBreakpoint(cur,1,4) # ставим бряк на push eax
imm.Run() #запускаем прогу
regs=imm.getRegs() #получаем все регистры
addres_of_seh =regs['EAX'] #в eax - адрес нужного нам seh-обработчика
imm.setHardwareBreakpoint(addres_of_seh+36,1,4)
imm.Run() #запускаем программу
regs=imm.getRegs() #получаем все регистры
imm.setHardwareBreakpoint(regs['EDI'],1,4) #ставим breakpoint на oep
imm.Run() #Запускаем
imm.Log("OEP -> 0x%08X " % regs['EDI'])
return "Done. See log window"
Итак, так же OEP finder. Читаем комменты к коду. Так как есть определенное искажение текста скрипта при его копипасте из поста и в пост – лучше скачайте архив (ниже ссылки - если не нра файлообменник - я перезалью кому надо)..
Код:
# -*- coding: cp1251 -*-
from immlib import *
import struct,sys
#------------------------------------------------------------------------------|
#-------------------0x0c0de (c) 2008-----------------------------------|
#------------------------------------------------------------------------------|
#----------12311134 OEP Finder script---------------------------------|
def main(args):
imm = Debugger()
imm.Log("Running 12311134 oep finder script..")
gpa_address = imm.getAddress("kernel32.GetProcAddress") # получаем адрес GetProcAddress
if gpa_address==0: # произошла ошибка и нельзя получить адрес нужной функции
return "No address GetProcAddress"
imm.setBreakpoint(gpa_address) # обычный брекпоинт на GetProcAddress
imm.Run() # F9
imm.deleteBreakpoint(gpa_address) #удаляем бряк с GetProcAddress
imm.runTillRet() # Ctrl+F9
imm.stepIn() # F7
cur=imm.getCurrentAddress() # текущий адрес
oep_per=imm.searchCommandsOnModule(cur,"jmp eax") #поиск команды jmp eax
for oep_jmpeax in oep_per: # цикл по элементам списка
imm.Log("Command jmp eax found -> 0x%08X address" % oep_jmpeax[0]) # выводим в лог все адреса с командой jmp eax, но нам нужен только последний
imm.setHardwareBreakpoint(oep_jmpeax[0],1,4) # ставим на последний в списке jmp eax хардварный бряк
imm.Run() # F9
imm.stepIn() # F7
regs=imm.getRegs() # получаем все регистры
imm.Log("oep -> 0x%08X " % regs['EIP']) # записываем в лог адрес oep
return "EIP is OEP"
MEW
Код:
# -*- coding: cp1251 -*-
from immlib import *
import struct,sys
#------------------------------------------------------------------------------|
#-------------------0x0c0de (c) 2008-----------------------------------|
#------------------------------------------------------------------------------|
#----------MEW OEP Finder script-------------------------------------|
def main(args):
imm = Debugger()
imm.Log("MEW12 Dumper by 0x0c0de...")
imm.stepIn() # F7
gpa_address = imm.getAddress("kernel32.GetProcAddress") # получаем адрес GetProcAddress
if gpa_address==0: # произошла ошибка и нельзя получить адрес нужной функции
return "No address GetProcAddress"
imm.setBreakpoint(gpa_address) # обычный брекпоинт на GetProcAddress
imm.Run() # F9
imm.deleteBreakpoint(gpa_address) #удаляем бряк с GetProcAddress
imm.runTillRet() # Ctrl+F9
imm.stepIn() # F7
cur=imm.getCurrentAddress() # текущий адрес
imm.setBreakpoint(cur+5)
imm.Run()
imm.stepIn() # F7
regs=imm.getRegs() # получаем все регистры
imm.Log("oep -> 0x%08X " % regs['EIP']) # записываем в лог адрес oep
imm.setComment(regs['EIP'],'< - OEP') # коммент на oep
return "Script finished! See log window"
NSpack
Код:
# -*- coding: cp1251 -*-
from immlib import *
import struct,sys
#------------------------------------------------------------------------------|
#-------------------0x0c0de (c) 2008-----------------------------------|
#------------------------------------------------------------------------------|
#----------NSPack37 OEP Finder script-------------------------------|
def main(args):
imm = Debugger()
regs=imm.getRegs()
imm.setHardwareBreakpoint(regs['ESP']-4,2,1) # HR ESP-4
imm.Run() # f9
imm.Run() #f9
imm.stepIn() # F7
regs=imm.getRegs() # получаем все регистры
imm.Log("oep -> 0x%08X " % regs['EIP']) # записываем в лог адрес oep
imm.setComment(regs['EIP'],'< - OEP') # коммент на oep
return "Script finished! See log window"
Далее, реализовала простой поиск строки в загруженном в отладчик модуле. Функция getReferencedStrings - функция поиска всех ссылок на строки (Search for-> All referenced text strings в имунити) . Ищется именно вся строка, а не ее часть. Поиск в 2-х кодировках – ASCII и UNICODE.
Код:
# -*- coding: cp1251 -*-
from immlib import *
import struct,sys
#Простой скрипт для поиска строки
#Вызываете скрипт командой !имя_скрипта строка
#Поиск в кодировках ASCII, UNICODE
def main(args):
imm = Debugger()
if not args:
imm.Log("Error search string. No args")
return "Error. See log window"
str = " ".join(args)
imm.Log("Search string -> "+str) #выводим в лог, что ищем
str_="ASCII \""+str+"\"" #ищем строки в кодировке ASCII
cur=imm.getCurrentAddress() # получаем текущий адрес
mod_=imm.findModule(cur) #получаем информацию о загруженной в отладчик проге
hep=imm.getReferencedStrings(mod_[1]) # ищем все строки (а точнее, ссылки на них)
for info_str in hep: #пробегаемся по всем строкам
if info_str[2]==str_: #если нашли такую строку
imm.Log("String found at address (ASCII)-> 0x%08X" % info_str[0]) #выводим в лог где найдена строка
#если ничего не нашли в ASCII - попробуем найти в UNICODE
str_="UNICODE \""+str+"\"" #ищем строки в кодировке UNICODE
for info_str in hep: #пробегаемся по всем строкам
if info_str[2]==str_: #если нашли такую строку
imm.Log("String found at address (UNICODE)-> 0x%08X" % info_str[0]) #выводим в лог где найдена строка
return "Done. See log window"
[Ссылки]
http://reversengineering.wordpress.com/category/tools/immunity-debugger/ - здесь 15 скриптов и 13 плагов
http://0x0c0de.net/immscr.rar - скрипты из поста и hidedebugger
http://0x0c0de.net/examples_packed.rar - здесь примеры для тестирования скриптов
[Outro]
Если тема приживется – закреплю..
Простимулировать активность общественности могу только поощрением репутации . Ставлю от +3 за каждый выложенный рабочий скрипт (проверяйте лично перед тем, как выкладывать!).
Если у вас есть ко мне какие-либо вопросы по этой теме – пишите в pm или icq (буду только рада указанию на ошибки и неточности). Причем пользоваться лучше вторым средством связи.
Grazie dell'attenzione, 0x0c0de