Делаю IDA PRO plugin, сохраняющий тело функции в asm файл. Код (Text): void __stdcall run(int arg) { func_t *function = get_func(get_screen_ea()); if (!function) { msg("ERROR: Can't Get Pointer On Current func_t Structure...\n"); return; } FILE *fp = fopen("D:\\asm_listing.asm", "w"); if (!fp) { msg("Can't Open File...\n"); return; } int result = gen_file(OFILE_ASM, fp, function->startEA, function->endEA-1, GENFLG_ASMTYPE); msg("Number Of The Generated Lines = %i\n", result); fclose(fp); } Вылезает соoбщение: Access violation at address 10021941 in module 'IDA.WLL'. Read of address FE3F35F0 В чем может быть проблема?
С этим все правильно Код (Text): // Get pointer to function structure by address // ea - any address in a function // Returns ptr to a function or NULL // This function returns a function entry chunk idaman func_t *ida_export get_func(ea_t ea);
ozzman Плагинов к иде никогда не писал, но думаю трабл тут: Код (Text): int result = gen_file(OFILE_ASM, [b]fp[/b], function->startEA, function->endEA-1, GENFLG_ASMTYPE); Сомнительно, чтоб ида юзала стандартный FILE потому что его реализация может не совпадать с тем что кушает gen_file иначе получается что СДК заточен под конкретный компилятор...
semen Да тут тоже проблем не должно быть: idaman int ida_export gen_file(ofile_type_t otype, FILE *fp, ea_t ea1, ea_t ea2, int flags); Почему "конкретный"? Структура FILE определена в C давным давно в стандартной библиотеке, поставляющейся с любым(?) С-компилятором. Хотя, может и чего и пропустил...
ozzman Ха! А вот это уже более серьезно! Комментарий к файлу "fpro.h": Код (Text): // This file contains q.. counterparts of FILE* functions from Clib. // The only difference is that they set 'qerrno' variable too. // [b]You should not use C standard I/O functions in your modules.[/b] // The reason: Borland keep FILE * information local to a DLL // so if you open a file in the plugin and pass the handle to the // kernel, the kernel will not be able to use it. Может в том и проблема, что используется стандартный "fopen"? Попробуй вместо него "qfopen"...
Sergey_R Покажи где в стандарте расписана структура FILE - каждый рантайм делает ее какую хочет - в борланде, МС и ваткоме они различаются. Логичнее всего для СДК было бы сделать свой ввод вывод или просто юзать виндовые хэндлы. Можно так же сделать свои ф. ввода вывода, но во вне приводить свой дескриптор к типу FILE* для удобства - хотя это тока путаницу вводит: Код (Text): FILE *ida_fopen(const char *pFileName, const char *pMode) { IDA_FILE *pNewFile = (IDA_FILE *)malloc(sizeof(IDA_FILE)); ... return (FILE *)pNewFile; } Если же сделано так, что юзается напрямую FILE какого-то рантайма - то и работать будет тока с этим рантаймом.
semen Возможно, спорить не буду. Watcom'ом никогда не пользовался. У меня сейчас под рукой только Borland'овские заголовочные файлы, но насколько я знаю, они, по крайней мере основные, совпадают с MS. (В пользу этого может говорить и то, что версии плагинов под Win компилируются только Borland'ом и Visual C++. Linux - это "отдельная статья", тем не менее в SDK нигде не видел, что там НЕЛЬЗЯ использовать структуру FILE.) Хотя, признаю, что относительно "стандарта"(!) - это я погорячился. :о) Имел в виду именно заголовочные файлы. Что же касаемо , для обсуждения этого одному из нас нужно быть Ильфаком. ;о) Иначе высказывать сожаления по поводу IDA друг другу мы можем долго и безуспешно... :o\ Да и к теме ДАННОЙ ветке это не относится...
Раньше я тоже грешил на получение FILE *fp, но при беглом просмотре sdk видимо пропустил qfopen() и qfclose(). С ними все работает. Спасибо!
Sergey_R К ветке это как раз относитася и дело именно в этом - в иде реализован вариант 3 т.е. ida_fopen == qfopen.
semen Извини, ты это проверял или просто предполагаешь, как "логичнее"? ;о) Я бы охотно согласился с тобой. (Хотя мои глаза мне говорят об обратном. Фактически, в ida.wll экспортируемая функция qfopen это всего-лишь "обертка" последующего вызова библиотечной Borland'овской функции fopen. Ну да Бог с этим, не исключаю, что был не слишком внимателен, и не лез очень глубоко.) Но даже если ты и прав, то какое значение имеет _внутренняя_ реализация функции, если вовне она экспортируется с прототипом: Код (Text): idaman FILE *ida_export qfopen(const char *file, const char *mode); #define idaapi __stdcall #define idaman extern "C" #define ida_export idaapi Сама структура FILE в SDK не определена, но в заголовочном файле vm.hpp есть "занятная" строчка: Код (Text): #include <stdio.h> // we need declaration of FILE * И потом она используется именно как 'FILE'. Более того, подобные включения этого заголовочного файла есть везде, где используется эта структура FILE. Зачем? Голову морочить? ;о) Не исключаю, но вряд ли...
Sergey_R Охотно верю что обертка, тока дело в том что теперь все верно работает. Теперь работа с борландовым CRT ведется внутри ida.wll и ничего не слетает. т.е. внутри ida.wll делаем так: Код (Text): FILE *qfopen(const char *pFileName, const char *pMode) { // using borland standart file return fopen(pFileName, pMode); } юзаем извне qfopen и все ок, но если в ida.wll извне передать FILE* так-же созданный извне, а юзать как свой, внутренний, борландовский - то это ошибка, т.к. создавали эти дескрипторы совершенно разные(возможно) библиотеки crt, более того глобальные данные этих crt находятся в разных модулях. Да что я тут один отдуваюсь? Это же очевидно - поддержите наконец кто-нибудь! не голову морочить, а именно за этим: // we need declaration of FILE * Как я уже говорил - это 3й, не лучший вариант - для уменьшения путаницы надо было просто в СДК сделать пустую структуру IDA_FILE и такую-же обертку - т.е. первый вариант. Кстати как именно "как FILE" структура от qfopen используется? Разименование указателя где-нибудь происходит или передается в функции стандартной библиотеки в плагинах? Можешь с гордостью везде вместо FILE* написать void* и все будет пахать...
semen :o) :beer: Успокойся, ни в чьей СПЕЦИАЛЬНОЙ поддержке ты не нуждаешься! Я во многом с тобой согласен. Просто "спор" наш получается ни о чем. ;о) Не обижайся! Но вопрос был: "В чем ошибка?", а ты пускаешься в теорию, как надо было _бы_ сделать в IDA... Опять же согласен: "Да, лучше _бы_ так!", но ... но каким образом это приблизит нас к решению ДАННОГО вопроса? ;о) Ведь действовать-то приходится не в "желаемом мире" - собственной структуры "IDA_FILE", а в рамках "объективной реальности" (о как! ;о)) - структуры, декларированной "во внешнем" stdio.h. А уж что с ним происходит дальше, это "личное" ;о) дело IDA. Так что еще раз - :beer: :о)
Sergey_R Я и не обижаюсь, просто мне показалось что ты не согласен и я разьяснял подробнее, что то что я сказал верно. и в первом посте я фактически подразумевал тоже самое: сомнительно, что gen_file кушает FILE* от стандартной библиотеки плагина - скорее всего это то что должна вернуть какя-то функция СДК (просто указатель, а структуре FILE от стандартной библиотеки используемой в плагине вовсе не обязана соответствовать). Просто у меня не было под рукой СДК чтоб посмотреть эту функцию, которую ты нашел, но предположение было верно. А темы спора если он был я даже не вижу - я просто не понял почему "мои глаза мне говорят об обратном" - о чем обратном я не понял и увидел вопрос зачем <stdio.h>, на что и отвечал. В любом случае проблема уже решена...