Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   Реверсинг (https://forum.antichat.xyz/forumdisplay.php?f=94)
-   -   [Python plugin for OllyDbg] (https://forum.antichat.xyz/showthread.php?t=75757)

0x0c0de 02.07.2008 19:48

[Python plugin for OllyDbg]
 
Сабж. Плаг позволяет писать скрипты на питоне под ольгу.
Нашла 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. Там есть прототипы функций... Добавлены новые примеры и функции. Смотрим последний пост

0x0c0de 07.07.2008 21:51

[Описание плагина]

Делаю небольшое описание функций либы ollylib.py.

[Скриптинг]

1. Начало работы

Любой скрипт нужно начинать с подключении ollylib.py. Делается это так

Код:


from ollylib import*

Таким образом вы сможете использовать в вашем скрипте api OllyDbg.

2. Получение значений всех регистров
Для этих целей я написала функцию GReg.
Вызывать так

Код:

GReg(имя_регистра)
Например (и сразу вывод в лог значения):

Код:

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.Результат работы скрипта – информационные функции

Код:

Log(”message”) – запись в лог
Flashmes(“message”) 
msg(адрес,”message”)
Err(“message”) – вывод сообщения об ошибке
Info(“message”)

Пример работы в файле Inf_func.py

5. Получение адреса библиотечной функции
Пример:

Код:

addr_ = Getfuncaddr("kernel32.LoadLibraryA")
и вывод в лог

Код:

Info("LoadLibraryA address %X" %int(addr_))
6. Ассемблирование команды

Код:

Asm(“команда”,адрес)
Пример:

Код:

Asm("sub eax,eax",0x0401000)
Теперь по адресу 0x0401000 инструкция sub eax,eax

7. Постановка хардварного бряка

Код:

Sethardbp(address,size,type)
Варианты типа бряка (последний аргумент)

Код:

HB_CODE  бряк на исполнение     
HB_ACCESS  бряк на доступ   
HB_WRITE                    бряк на запись

Пример постановки бряка на библиотечную функцию

Код:


laddr = Getfuncaddr("kernel32.LoadLibraryA")
Sethardbp(long(laddr),4,HB_CODE)


Вся работа с бряками в файле breaks.py

8. Удаление хардварного бряка

Удалить хардварный бряк можно двумя способами. Используя функцию

Код:

Deletehardbp(index)
или

Код:

 
Deletehardbpbyaddr(адрес)

В первом случае указываете значение от 0 до 3 – номер бряка. Во втором – адрес, по которому поставлен бряк.

9. Исполнение программы

Функция Run () – эквивалент F9
Функция StepF8() – F8
Функция StepF7() - F7
Функция RunRet() – Ctrl+F9

Пример в файле ex.py

10. Атач к процессу

Можно осуществить двумя способами. Если вам известен ProcessId, то воспользуйтесь функцией

Код:

Attach(pid)
Если же вам известно имя процесса в памяти, то

Код:

Attachbyname(procname)
Пример в файле Attach.py

11. Постановка мемори-бряков

Функция

Код:

Setmembp(type,addr,size)
Варианты первого параметра

Код:

MEMBP_READ              мемори-бряк на чтение
MEMBP_WRITE              мемори-бряк на запись

12.Выбор и загрузка файла в отладчик

Сначала вызов диалога открытия файла

Код:

Browsefile(title,buf,ext,mode)
title – заголовок окна
buf – буфер для имени
ext – расширение файла

Пример

Код:

buf = ""
Browsefile("Test browse",buf,".exe",0)

Если вы выберете какой-то файл – в переменной buf будет путь к этому файлу

Затем нужно вызвать функцию

Код:

Runfile(path)
Производная от OpenEXEfile из Олиного апи=)
В нашем случае

Код:

Runfile(buf)
Пример в файле open.py

13. Приостановка процесса

Код:


Suspend()

14. Восстановление всех нитей процесса

Код:

Restoreallthrd()
15. То, же, что 14, только для 1 треда

Код:

Runthread(thread_id)

16. Дамп региона в файл

Код:

Dumpreg(file_name,base,size)
file_name – имя файла
base – адрес начала региона
size – размер региона

Чтобы получить адрес начала региона воспользуйтесь функцией

Код:

Findmem(адрес_принадлежащий_региону)
Функция возвращает структуру

Код:

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

0x0c0de 07.07.2008 21:53

17. Запись в память

Код:

Writemem(addr,buf,size)
addr – адрес
buf – откуда копируем байты
size – размер буфера

18. Дизассемблирование команды

Код:

Disassm(addr,type)
Первый параметр – адрес, по которому нужно дизассемблировать команду
Второй параметр – тип дизасма

Код:

DISASM_SIZE    получение длины команды
DISASM_ALL полное дизассемблирование

Функция возвращает структуру t_disasm

Код:

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. Ввод числа

Для этих целей существует функция

Код:

Getlng(title,size)
title – заголовок откна ввода
size – размер вводмого значения в байтах (1,2,4)

Возвращаемое значение функции – введенное число

Пример в файле example_input.py

20.Постановка темпового бряка

Код:


Tempbp(addr,type)

Адрес, тип.

21.Обычные бряки

Код:

Setbp(addr,type,cmd)
Повторюсь. Примеры использования в breaks.py

0x0c0de 07.07.2008 21:55

22. Получение информации о модуле

Код:

Findmod(addr)
Адрес, принадлежащий модулю в качестве параметра. Функция возвращает структуру t_module . Опять привожу ее здесь, но не полностью (все тот же Plugin SDK OllyDbg). Только часто используемые поля

Код:

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.Получение ид текущей нити

Код:

Getcputhrdid()
24. Получение информации о треде

Код:

Findthrd(id)
Возвращает структуру t_thread, которую я уже не привожу здесь. Смотрим пример в файле
thrd.py

25. Получение имени треда

Код:

Decodethrdname(buf, tid,mode)
Буфер для хранения имени, ид треда, режим. Пример в thrd.py

26. Обнаружение VmWare
Обнаружение VmWare.

Код:

IsVmWare()
Возвращает 0, если мы не под варей и 1 в противном случае

Пример в файле vmWarecheck.py.

27. Ввод строки пользователем

Функция

Код:


 Gettxt(title,text,letter,type,ind)

Пример в файле get_text.py

28. Поиск команды “вперед” от текущей инструкции

Код:

Disasmin(addr,str)
Где первый параметр адрес, с которого надо начинать поиск. Второй – текстовое представление инструкции. Например вам нужна инструкция push ebp. Тогда вы пишите в качестве аргумента "PUSH EBP". Заглавными. Возвращаемое значение - адрес инструкции, если она найдена и 0, если не найдена.
Пример можно посмотреть в файле disasm_test.py

29. Поиск команды “назад” от текущей инструкции


Код:

Disasmback(addr,str)
Где первый параметр адрес, с которого надо начинать поиск. Второй – текстовое представление инструкции. Возвращаемое значение - адрес инструкции, если она найдена и 0, если не найдена.
Пример можно посмотреть в файле disasm_test.py

30. Поиск команда по опкоду "вперед"

Код:


Disasminbyopcode(addr,str)

То, же, что и 28, только поиск по опкоду. Например вы хотите найти инструкцию с опкодом 33 C0. Тогда в качестве второго аргумента вы пишите "33C0". без пробелов заглавными. Первым аргументом - адрес, с которого следует начинать поиск. Пример там же, где и 28,29

31. Поиск команда по опкоду "назад"

Код:


Disasmbackbyopcode(addr,str)

То, же, что и 29, только по опкоду. Описание такое же, как и в 30 и пример там же.

0x0c0de 11.07.2008 20:13

32. Получение информации об инструкции

Код:


asmfindmodel(model)

В качестве параметра функция принимает структуру t_asmmodel
Вы вводите инструкцию в окно ввода, функция заполняет структуру t_asmmodel информацией об этой команде.

Напомню, что структура имеет вид

Код:

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. Поиск команды
Код:

Findallcmds(pd,model,origin,title)
Первый параметр - структура t_dump
Второй параметр - заполненная структура t_asmmodel (см. п. 32)
Третий параметр - адрес, которого следует начинать поиск
Четвертый параметр - заголовок окна

Поиск команды. Следует заполнить структуру t_dump (первый параметр) для того, чтобы все работало.
Структура t_dump

Код:

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. Преобразование виртуального адреса в смещение в исполняемом файле

Код:

Searchfileoffset(pmod,addr)
Пример использования в файле find_file_offset.py

35. Ввод 64-битного MMX числа

Код:

GetMmx(title,data,mode)
Код:

GetMmxXY(title,data,mode)

Вторая функция тож самое, что и первая, ток можно координаты указать окна
Пример в файле get_mmx.py
Добавила прототипы функций в либу ollylib.py. Так что теперь удобней. Это лучшая справка =)

0x0c0de 16.07.2008 10:24

Справку перезалила отдельно от основного архива, сделала скрины, обновила набор функций. За прототипами go to ollylib.py. Сам плаг тоже перезалила

download

http://0x0c0de.net/Plugin_Python.chm

0x0c0de 19.07.2008 19:45

Полезное дополнение. 4 новых функции.

Первая фукция

Код:

Getnumberofmods()
Возвращает количество модулей, загруженных в АП отлаживаемого процесса. Возвращаемое значение типа int.

Далее функция, напрямую зависящая от предыдущей

Код:

Getmodule(number)
Принимает номер модуля в качестве параметра (номер просто для того, чтобы можно было пробежаться по всему списку модулей и найти нужный).
Возвращаемое значение - структура mod_info [я еще в нормальный вид не до конца привела - вот руки дойдут и будут вам, товарищи, все поля]

Код:

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

Далее две аналогичные функции, только для блоков памяти

Код:

Getnumberofblocks()
Возвращает число выделенных блоков

Код:

Getmemoryblock(number)
Получает номер блока [цель номера - та же, что и в предыдущем случае]
Возвращаемое значение - структура mem_blocks
Структура mem_blocks

Код:


typedef struct mem_blocks {
ulong addr;
ulong size;
}mem_blocks;

Пример этих функций было лень впихивать в отдельный скрипт, а потому там же, что и в предыдущем случае
Все перезалито.

nerezus 19.07.2008 21:44

Все, что ты делаешь, это конечно круто, но:
http://www.python.org/dev/peps/pep-0008/
Naming Conventions

0x0c0de 19.07.2008 22:12

>>http://www.python.org/dev/peps/pep-0008/
>>Naming Conventions

Оо, спасибо. не видела этого. Дельно, исправлю имеющиеся косяки в ближайшее время.


Время: 00:36