Сабж. Плаг позволяет писать скрипты на питоне под ольгу. Нашла 2 плага 2007 года под 2.4 питон, но увидеть воочию их работу мне так и не удалось. У меня стоял 2.5, а потому решила переписать под него. Проверила некоторые функции и написала небольшую либу, чтобы упростить работу. Понятное дело, что вам для теста требуется отладчик OllyDbg+Python 2.5+знание питона (у меня питон, который устанавливался с immunity dbg, отдельно не качала). В папке system32 обязательно должна быть либа Python25.dll Для тех, кто принципиально не заглядывает в readme [Install] 1.Файл ODBG_pyth.py и ollylib.py положите в папку \Python25\Lib 2.Файл _ODBG_pyth.pyd положите в папку \Python25\DLLs 3.Либу Python_Int.dll в директорию с плагинами OllyDbg Интерпретатор должен быть нормально настроен, чтобы все либы находились в вышеуказанных директориях и нормально работали. Запускать скрипт командой меню OllyDbgPython plugin -> Run script. И выбираем скрипт. Чтобы проверить работу плагина - воспользуйтесь примерами из папки example. *В этот момент в отладчик должно быть что-то загружено. В ollylib - те функции, которые я проверила. качаем, кому интересно http://0x0c0de.net/plugin_python.rar Пишем, что хотелось бы увидеть. Для каких функций требуются примеры. Багрепорты и пожелания лучше в осеку пишите, ибо там я в последнее время бываю чаще, чем на форуме. Набор апишек у ольги немаленький, потому за несколько дней кодеса обработать, проверить на работоспособность и привести в норм вид все просто нереально. Писалось для интереса, так как ничего подобного никогда не делала. И у меня уже за эти несколько дней были активные разборки со SWIG из-за типов данных) Видео по настройке и запуск примера http://0x0c0de.net/Ollypy.rar #-------Добавлено 4.07.2008------------------------ Перезалито. Добавлены новые функции в ollylib.py. В плагине и разделяемой библиотеке отключила прилинковку msvcp80, так что теперь не нужно доп либ никаких. #----Добавлено 6.07.2008--------------- 1. Добавлена функция Attach_by_name(имя_процесса_в_памяти) 2. Добавлена функция dump_mem(имя_файла_для_дампа,адрес_начала_региона, размер_региона) 3. Добавлен еще один пример использования И еще некоторые мелкие исправления *Иногда примеры нужно модифицировать (в зависимости от базового адреса загрузки загруженной под отладку проги) Nice try! #------Добавлено 7.07.2008----------------- 1. Все перезалито. Перекроила все примеры. Добавила доку по ollylib, которую вы можете лицезреть ниже #----------Добавлено 9.07.2008----------- 1. Снова апдейт. Добавлены новые функции. Смотрим последний пост #----------Добавлено 10.07.2008--------- Добавлена справка. немного модифицированы примеры #----------Добавлено 11.07.2008---------------- Перезалито, теперь более полную информацию можно получить в ollylib.py. Там есть прототипы функций... Добавлены новые примеры и функции. Смотрим последний пост
[Описание плагина] Делаю небольшое описание функций либы ollylib.py. [Скриптинг] 1. Начало работы Любой скрипт нужно начинать с подключении ollylib.py. Делается это так Code: from ollylib import* Таким образом вы сможете использовать в вашем скрипте api OllyDbg. 2. Получение значений всех регистров Для этих целей я написала функцию GReg. Вызывать так Code: GReg(имя_регистра) Например (и сразу вывод в лог значения): Code: eax = GReg("Eax") Log("eax is %X" % int(str(eax))) esp = GReg("eSp") Log("esp is %X" % int(str(esp))) ebp = GReg("ebp") Log("ebp is %X" % int(str(ebp))) esi = GReg("esi") Log("esi is %X" % int(str(esi))) edi = GReg("edi") Log("edi is %X" % int(str(edi))) eip = GReg("eip") Log("eip is %X" % int(str(eip))) ss = GReg("ss") Log("ss is %X" % int(str(ss))) ds = GReg("ds") Log("ds is %X" % int(str(ds))) efl = GReg("efl") Log("efl is %X" % int(str(efl))) и так далее .... Полностью пример в Get_Regs.py Функции вывода подробнее смотреть в п.4 3. Анализ текущего модуля AnalyseCurrentModule() Не знаю, нужно ли это было здесь, но все равно. Пример в файле Analyse.py 4.Результат работы скрипта – информационные функции Code: Log(”message”) – запись в лог Flashmes(“message”) msg(адрес,”message”) Err(“message”) – вывод сообщения об ошибке Info(“message”) Пример работы в файле Inf_func.py 5. Получение адреса библиотечной функции Пример: Code: addr_ = Getfuncaddr("kernel32.LoadLibraryA") и вывод в лог Code: Info("LoadLibraryA address %X" %int(addr_)) 6. Ассемблирование команды Code: Asm(“команда”,адрес) Пример: Code: Asm("sub eax,eax",0x0401000) Теперь по адресу 0x0401000 инструкция sub eax,eax 7. Постановка хардварного бряка Code: Sethardbp(address,size,type) Варианты типа бряка (последний аргумент) Code: HB_CODE бряк на исполнение HB_ACCESS бряк на доступ HB_WRITE бряк на запись Пример постановки бряка на библиотечную функцию Code: laddr = Getfuncaddr("kernel32.LoadLibraryA") Sethardbp(long(laddr),4,HB_CODE) Вся работа с бряками в файле breaks.py 8. Удаление хардварного бряка Удалить хардварный бряк можно двумя способами. Используя функцию Code: Deletehardbp(index) или Code: Deletehardbpbyaddr(адрес) В первом случае указываете значение от 0 до 3 – номер бряка. Во втором – адрес, по которому поставлен бряк. 9. Исполнение программы Функция Run () – эквивалент F9 Функция StepF8() – F8 Функция StepF7() - F7 Функция RunRet() – Ctrl+F9 Пример в файле ex.py 10. Атач к процессу Можно осуществить двумя способами. Если вам известен ProcessId, то воспользуйтесь функцией Code: Attach(pid) Если же вам известно имя процесса в памяти, то Code: Attachbyname(procname) Пример в файле Attach.py 11. Постановка мемори-бряков Функция Code: Setmembp(type,addr,size) Варианты первого параметра Code: MEMBP_READ мемори-бряк на чтение MEMBP_WRITE мемори-бряк на запись 12.Выбор и загрузка файла в отладчик Сначала вызов диалога открытия файла Code: Browsefile(title,buf,ext,mode) title – заголовок окна buf – буфер для имени ext – расширение файла Пример Code: buf = "" Browsefile("Test browse",buf,".exe",0) Если вы выберете какой-то файл – в переменной buf будет путь к этому файлу Затем нужно вызвать функцию Code: Runfile(path) Производная от OpenEXEfile из Олиного апи=) В нашем случае Code: Runfile(buf) Пример в файле open.py 13. Приостановка процесса Code: Suspend() 14. Восстановление всех нитей процесса Code: Restoreallthrd() 15. То, же, что 14, только для 1 треда Code: Runthread(thread_id) 16. Дамп региона в файл Code: Dumpreg(file_name,base,size) file_name – имя файла base – адрес начала региона size – размер региона Чтобы получить адрес начала региона воспользуйтесь функцией Code: Findmem(адрес_принадлежащий_региону) Функция возвращает структуру Code: typedef struct t_memory { // Memory block descriptor ulong base; // Base address of memory block ulong size; // Size of block ulong type; // Service information, TY_xxx ulong owner; // Address of owner of the memory ulong initaccess; // Initial read/write access ulong access; // Actual status and read/write access ulong threadid; // Block belongs to this thread or 0 char sect[SHORTLEN]; // Name of module section char *copy; // Copy used in CPU window or NULL ulong reserved[8]; // Reserved for plugin compatibility } t_memory; OllyDbg Plugin API v1.10 *взято из PluginSDK OllyDbg (так как не у всех читающих он есть) В этой структуре нам надо 2 поля base и size… Пример в файле dump.py
17. Запись в память Code: Writemem(addr,buf,size) addr – адрес buf – откуда копируем байты size – размер буфера 18. Дизассемблирование команды Code: Disassm(addr,type) Первый параметр – адрес, по которому нужно дизассемблировать команду Второй параметр – тип дизасма Code: DISASM_SIZE получение длины команды DISASM_ALL полное дизассемблирование Функция возвращает структуру t_disasm Code: typedef struct t_disasm { // Results of disassembling ulong ip; // (*) Instrucion pointer char dump[TEXTLEN]; // Hexadecimal dump of the command char result[TEXTLEN]; // Disassembled command char comment[TEXTLEN]; // Brief comment char opinfo[3][TEXTLEN]; // Comments to command's operands int cmdtype; // (*) One of C_xxx int memtype; // (*) Type of addressed variable in memory int nprefix; // (*) Number of prefixes int indexed; // Address contains register(s) ulong jmpconst; // (*) Constant jump address ulong jmptable; // (*) Possible address of switch table ulong adrconst; // (*) Constant part of address ulong immconst; // (*) Immediate constant int zeroconst; // (*) Whether contains zero constant int fixupoffset; // (*) Possible offset of 32-bit fixups int fixupsize; // (*) Possible total size of fixups or 0 ulong jmpaddr; // Destination of jump/call/return int condition; // 0xFF:unconditional, 0:false, 1:true int error; // (*) Error while disassembling command int warnings; // (*) Combination of DAW_xxx int optype[3]; // Type of operand (extended set DEC_xxx) int opsize[3]; // Size of operand, bytes int opgood[3]; // Whether address and data valid ulong opaddr[3]; // Address if memory, index if register ulong opdata[3]; // Actual value (only integer operands) t_operand op[3]; // Full description of operand ulong regdata[8]; // Registers after command is executed int regstatus[8]; // Status of registers, one of RST_xxx ulong addrdata; // Traced memory address int addrstatus; // Status of addrdata, one of RST_xxx ulong regstack[NREGSTACK]; // Stack tracing buffer int rststatus[NREGSTACK]; // Status of stack items int nregstack; // Number of items in stack trace buffer ulong reserved[29]; // Reserved for plugin compatibility } t_disasm; OllyDbg Plugin API v1.10 Интересное поле - текстовое представление команды – result Небольшой пример в файле disasm_test.py 19. Ввод числа Для этих целей существует функция Code: Getlng(title,size) title – заголовок откна ввода size – размер вводмого значения в байтах (1,2,4) Возвращаемое значение функции – введенное число Пример в файле example_input.py 20.Постановка темпового бряка Code: Tempbp(addr,type) Адрес, тип. 21.Обычные бряки Code: Setbp(addr,type,cmd) Повторюсь. Примеры использования в breaks.py
22. Получение информации о модуле Code: Findmod(addr) Адрес, принадлежащий модулю в качестве параметра. Функция возвращает структуру t_module . Опять привожу ее здесь, но не полностью (все тот же Plugin SDK OllyDbg). Только часто используемые поля Code: typedef struct t_module { // Executable module descriptor ulong base; // Base address of module ulong size; // Size occupied by module ulong type; // Service information, TY_xxx ulong codebase; // Base address of module code block ulong codesize; // Size of module code block ulong resbase; // Base address of resources ulong ressize; // Size of resources t_stringtable *stringtable; // Pointers to string resources or NULL int nstringtable; // Actual number of used stringtable int maxstringtable; // Actual number of allocated stringtable ulong entry; // Address of <ModuleEntryPoint> or NULL ulong database; // Base address of module data block ulong idatatable; // Base address of import data table ulong idatabase; // Base address of import data block ulong edatatable; // Base address of export data table ulong edatasize; // Size of export data table ulong reloctable; // Base address of relocation table ulong relocsize; // Size of relocation table char name[SHORTLEN]; // Short name of the module char path[MAXPATH]; // Full name of the module int nsect; // Number of sections in the module IMAGE_SECTION_HEADER *sect; // Copy of section headers from file ulong headersize; // Total size of headers in executable ulong fixupbase; // Base of image in executable file int nfixup; // Number of fixups in executable t_fixup *fixup; // Extracted fixups or NULL ….. } t_module; OllyDbg Plugin API v1.10 Пример использования в файле modul.py 23.Получение ид текущей нити Code: Getcputhrdid() 24. Получение информации о треде Code: Findthrd(id) Возвращает структуру t_thread, которую я уже не привожу здесь. Смотрим пример в файле thrd.py 25. Получение имени треда Code: Decodethrdname(buf, tid,mode) Буфер для хранения имени, ид треда, режим. Пример в thrd.py 26. Обнаружение VmWare Обнаружение VmWare. Code: IsVmWare() Возвращает 0, если мы не под варей и 1 в противном случае Пример в файле vmWarecheck.py. 27. Ввод строки пользователем Функция Code: Gettxt(title,text,letter,type,ind) Пример в файле get_text.py 28. Поиск команды “вперед” от текущей инструкции Code: Disasmin(addr,str) Где первый параметр адрес, с которого надо начинать поиск. Второй – текстовое представление инструкции. Например вам нужна инструкция push ebp. Тогда вы пишите в качестве аргумента "PUSH EBP". Заглавными. Возвращаемое значение - адрес инструкции, если она найдена и 0, если не найдена. Пример можно посмотреть в файле disasm_test.py 29. Поиск команды “назад” от текущей инструкции Code: Disasmback(addr,str) Где первый параметр адрес, с которого надо начинать поиск. Второй – текстовое представление инструкции. Возвращаемое значение - адрес инструкции, если она найдена и 0, если не найдена. Пример можно посмотреть в файле disasm_test.py 30. Поиск команда по опкоду "вперед" Code: Disasminbyopcode(addr,str) То, же, что и 28, только поиск по опкоду. Например вы хотите найти инструкцию с опкодом 33 C0. Тогда в качестве второго аргумента вы пишите "33C0". без пробелов заглавными. Первым аргументом - адрес, с которого следует начинать поиск. Пример там же, где и 28,29 31. Поиск команда по опкоду "назад" Code: Disasmbackbyopcode(addr,str) То, же, что и 29, только по опкоду. Описание такое же, как и в 30 и пример там же.
32. Получение информации об инструкции Code: asmfindmodel(model) В качестве параметра функция принимает структуру t_asmmodel Вы вводите инструкцию в окно ввода, функция заполняет структуру t_asmmodel информацией об этой команде. Напомню, что структура имеет вид Code: typedef struct t_asmmodel { // Model to search for assembler command char code[MAXCMDSIZE]; // Binary code char mask[MAXCMDSIZE]; // Mask for binary code (0: bit ignored) int length; // Length of code, bytes (0: empty) int jmpsize; // Offset size if relative jump int jmpoffset; // Offset relative to IP int jmppos; // Position of jump offset in command } t_asmmodel; Эта функция нужна для использования Findallcmds 33. Поиск команды Code: Findallcmds(pd,model,origin,title) Первый параметр - структура t_dump Второй параметр - заполненная структура t_asmmodel (см. п. 32) Третий параметр - адрес, которого следует начинать поиск Четвертый параметр - заголовок окна Поиск команды. Следует заполнить структуру t_dump (первый параметр) для того, чтобы все работало. Структура t_dump Code: typedef struct t_dump { // Current status of dump window t_table table; // Treat dump window as custom table int dimmed; // Draw in lowcolor if nonzero ulong threadid; // Use decoding and registers if not 0 int dumptype; // Current dump type, DU_xxx+count+size SPECFUNC *specdump; // Decoder of DU_SPEC dump types int menutype; // Standard menus, MT_xxx int itemwidth; // Length of displayed item, characters int showstackframes; // Show stack frames in address dump int showstacklocals; // Show names of locals in stack int showsource; // Show source as comment in disassembler char filename[MAXPATH]; // Name of displayed or backup file ulong base; // Start of memory block or file ulong size; // Size of memory block or file ulong addr; // Address of first displayed byte ulong lastaddr; // Address of last displayed byte + 1 ulong sel0; // Address of first selected byte ulong sel1; // Last selected byte (not included!) ulong startsel; // Start of last selection int captured; // Mouse is captured by dump ulong reladdr; // Addresses relative to this char relname[SHORTLEN]; // Symbol for relative zero address base char *filecopy; // Copy of the file or NULL char *backup; // Old backup of memory/file or NULL int runtraceoffset; // Offset back in run trace ulong reserved[8]; // Reserved for the future extentions } t_dump; OllyDbg Plugin API v1.10 Достаточно заполнить поля base и size (эту информацию можно получить с помощью функции из ollylib Findmod) Пример в файле find_cmds.py 34. Преобразование виртуального адреса в смещение в исполняемом файле Code: Searchfileoffset(pmod,addr) Пример использования в файле find_file_offset.py 35. Ввод 64-битного MMX числа Code: GetMmx(title,data,mode) Code: GetMmxXY(title,data,mode) Вторая функция тож самое, что и первая, ток можно координаты указать окна Пример в файле get_mmx.py Добавила прототипы функций в либу ollylib.py. Так что теперь удобней. Это лучшая справка =)
Справку перезалила отдельно от основного архива, сделала скрины, обновила набор функций. За прототипами go to ollylib.py. Сам плаг тоже перезалила download http://0x0c0de.net/Plugin_Python.chm
Полезное дополнение. 4 новых функции. Первая фукция Code: Getnumberofmods() Возвращает количество модулей, загруженных в АП отлаживаемого процесса. Возвращаемое значение типа int. Далее функция, напрямую зависящая от предыдущей Code: Getmodule(number) Принимает номер модуля в качестве параметра (номер просто для того, чтобы можно было пробежаться по всему списку модулей и найти нужный). Возвращаемое значение - структура mod_info [я еще в нормальный вид не до конца привела - вот руки дойдут и будут вам, товарищи, все поля] Code: typedef struct mod_info { ulong base; ulong size; ... ulong code_begin; ulong code_size; ulong resource; .... ulong Entry; ulong data_addr; ulong imp; .... .... char path[256]; }; Здесь, думаю все понятно. Пример использования этого всего в файле get_modules.py Далее две аналогичные функции, только для блоков памяти Code: Getnumberofblocks() Возвращает число выделенных блоков Code: Getmemoryblock(number) Получает номер блока [цель номера - та же, что и в предыдущем случае] Возвращаемое значение - структура mem_blocks Структура mem_blocks Code: typedef struct mem_blocks { ulong addr; ulong size; }mem_blocks; Пример этих функций было лень впихивать в отдельный скрипт, а потому там же, что и в предыдущем случае Все перезалито.
Все, что ты делаешь, это конечно круто, но: http://www.python.org/dev/peps/pep-0008/ Naming Conventions
>>http://www.python.org/dev/peps/pep-0008/ >>Naming Conventions Оо, спасибо. не видела этого. Дельно, исправлю имеющиеся косяки в ближайшее время.