说的是 IDA 7.2 SDK 插件、与QT相关的模块编译涉及的一些问题。
以windows下的IDA插件开发为主要目标。
官方文档里install_make.txt 和 install_visual.txt 分别对命令行和IDE中的编译开发做了基本说明。
我们以命令行编译为目标。
第一步:配置(GNU Make)
文档推进使用cygwin环境。
装好后,可以直接开启cygwin环境,切换到我们的IDA 7.2 SDK中执行后续步骤
也可以配置PATH环境【set PATH=C:\cygwin\bin;%PATH%】,直接在window的cmd环境编译
目的是使用make
第二步:相关配置和编译错误
官方文档是,简单make env一下根据make文件内存产生相应的cfp配置文件,然后就m.bat 或 m32.bat一下进行全部插件的编译
(一)VS编译工具和SDK配置问题
官方要求是VS2017以上,由于VS可能不安装在系统盘上,需要对defaults.mk进行修改
PROGRAMFILES 变量配置为我们VS的实际安装路径
WSDK也直接修改为我们的安装路径,如果版本不一致,可以下载相关版本,也可以修改为自己拥有的版本
同理PYTHON和QTDIR也做具体配置
如果使用jom,实际上QT相关版本中有,可以直接配置相关JOM_PATH路径
(二)头文件路径问题
x64_win_vc_32.cfg等
fatal error C1083: 无法打开包括文件: “ida.hpp”: No such file or directory
因为SDK路径可能有空格的存在,可以考虑在cfg文件中相应路径加上双引号
(三)文件中非法字符(非中文字符问题,俄罗斯人躺枪)
主要是因为许多插件样例都是俄罗斯人写的,里面很多注释都是俄语,936中文是无法识别。
笨点的办法是一个个把俄语注释删了,不过我们会发现,俄语文件太多。
治理我们对有问题的文件进行格式转换,见文件转换为UNICODE-LE格式
前提还要先去掉文件的只读属性,我们可以去掉所有文件的只读属性
pushd “d:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module“
attrib /S -R
attrib -R "d:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\ldr\ar\ar.hpp"
def convertfile(fn,dc='866',ec='UTF-16'): #866 855 russian
fstr = ''
with open(fn,'rb') as fin:
fstr = fin.read()
ustr = fstr.decode(dc)
with codecs.open(fn,'wb',ec) as fout:
fout.write(ustr)
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\c39\emu.cpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\c39\c39.hpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\c39\ana.cpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\c39\out.cpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\c39\reg.cpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\cr16\reg.cpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\dsp56k\ana.cpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\dsp56k\dsp56k.hpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\dsp56k\dsp56k.hpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\dsp56k\ana.cpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\dsp56k\out.cpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\java\ana.cpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\java\java.hpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\java\out.cpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\m32r\reg.cpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\mn102\ana.cpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\mn102\pan.hpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\mn102\emu.cpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\mn102\out.cpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\mn102\reg.cpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\oakdsp\emu.cpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\sam8\reg.cpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\tlcs900\reg.cpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\tms320c3\ana.cpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\tms320c3\emu.cpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\tms320c3\out.cpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\module\tms320c3\reg.cpp')
convertfile(r'd:\program files\ida 7.2\plugins\hexrays_sdk\wp\idasdk72\ldr\ar\ar.hpp')
(三)QT的问题
这个比较让人疑惑,实际上我们需要QT源码,又不需要QT源码
原版的QT是没有QT::空间的,为了避免IDA中一些函数与QT中的函数冲突,
IDA的QT全部封装到QT::空间,而我们的qtmake.mak也将我们用到的QT代码封装到QT空间,
但QT源码没有,所以IDA实际是提供了QT::空间的链接库的,而不适用源码的链接库,
这需要我们在qtplugin.mak中添加IDA 7.2 SDK提供的QT链接库
qproject.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: void __cdecl QT::QWidget::setLayout(class QT::QLayout *)" (__imp_?setLayout@QWidget@QT@@QEAAXPEAVQLayout@2@@Z),该符号在函数 "__int64 __cdecl ui_callback(void *,int,char *)" (?ui_callback@@YA_JPEAXHPEAD@Z) 中被引用
qproject.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: void __cdecl QT::QLayout::setMargin(int)" (__imp_?setMargin@QLayout@QT@@QEAAXH@Z),该符号在函数 "__int64 __cdecl ui_callback(void *,int,char *)" (?ui_callback@@YA_JPEAXHPEAD@Z) 中被引用
qproject.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: void __cdecl QT::QBoxLayout::addWidget(class QT::QWidget *,int,class QT::QFlags<enum QT::Qt::AlignmentFlag>)" (__imp_?addWidget@QBoxLayout@QT@@QEAAXPEAVQWidget@2@HV?$QFlags@W4AlignmentFlag@Qt@QT@@@2@@Z),该符号在函数 "__int64 __cdecl ui_callback(void *,int,char *)" (?ui_callback@@YA_JPEAXHPEAD@Z) 中被引用
qproject.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: __cdecl QT::QHBoxLayout::QHBoxLayout(void)" (__imp_??0QHBoxLayout@QT@@QEAA@XZ),该符号在函数 "__int64 __cdecl ui_callback(void *,int,char *)" (?ui_callback@@YA_JPEAXHPEAD@Z) 中被引用
qproject.obj : error LNK2019: 无法解析的外部符号 "__declspec(dllimport) public: virtual __cdecl QT::QHBoxLayout::~QHBoxLayout(void)" (__imp_??1QHBoxLayout@QT@@UEAA@XZ),该符号在函数 "public: virtual void * __cdecl QT::QHBoxLayout::`scalar deleting destructor'(unsigned int)" (??_GQHBoxLayout@QT@@UEAAPEAXI@Z) 中被引用
qproject.obj : error LNK2001: 无法解析的外部符号 "public: virtual void __cdecl QT::QBoxLayout::addItem(class QT::QLayoutItem *)" (?addItem@QBoxLayout@QT@@UEAAXPEAVQLayoutItem@2@@Z)
qproject.obj : error LNK2001: 无法解析的外部符号 "protected: virtual void __cdecl QT::QLayout::childEvent(class QT::QChildEvent *)" (?childEvent@QLayout@QT@@MEAAXPEAVQChildEvent@2@@Z)
qproject.obj : error LNK2001: 无法解析的外部符号 "protected: virtual void __cdecl QT::QObject::connectNotify(class QT::QMetaMethod const &)" (?connectNotify@QObject@QT@@MEAAXAEBVQMetaMethod@2@@Z)
graphwidget.obj : error LNK2001: 无法解析的外部符号 "protected: virtual void __cdecl QT::QObject::connectNotify(class QT::QMetaMethod const &)" (?connectNotify@QObject@QT@@MEAAXAEBVQMetaMethod@2@@Z)
node.obj : error LNK2001: 无法解析的外部符号 "protected: virtual void __cdecl QT::QObject::connectNotify(class QT::QMetaMethod const &)" (?connectNotify@QObject@QT@@MEAAXAEBVQMetaMethod@2@@Z)
qproject.obj : error LNK2001: 无法解析的外部符号 "public: virtual class QT::QFlags<enum QT::QSizePolicy::ControlType> __cdecl QT::QLayout::controlTypes(void)const " (?controlTypes@QLayout@QT@@UEBA?AV?$QFlags@W4ControlType@QSizePolicy@QT@@@2@XZ)
qproject.obj : error LNK2001: 无法解析的外部符号 "public: virtual int __cdecl QT::QBoxLayout::count(void)const " (?count@QBoxLayout@QT@@UEBAHXZ)
qproject.obj : error LNK2001: 无法解析的外部符号 "protected: virtual void __cdecl QT::QObject::customEvent(class QT::QEvent *)" (?customEvent@QObject@QT@@MEAAXPEAVQEvent@2@@Z)
graphwidget.obj : error LNK2001: 无法解析的外部符号 "protected: virtual void __cdecl QT::QObject::customEvent(class QT::QEvent *)" (?customEvent@QObject@QT@@MEAAXPEAVQEvent@2@@Z)
node.obj : error LNK2001: 无法解析的外部符号 "protected: virtual void __cdecl QT::QObject::customEvent(class QT::QEvent *)" (?customEvent@QObject@QT@@MEAAXPEAVQEvent@2@@Z)
qproject.obj : error LNK2001: 无法解析的外部符号 "protected: virtual void __cdecl QT::QObject::disconnectNotify(class QT::QMetaMethod const &)" (?disconnectNotify@QObject@QT@@MEAAXAEBVQMetaMethod@2@@Z)
graphwidget.obj : error LNK2001: 无法解析的外部符号 "protected: virtual void __cdecl QT::QObject::disconnectNotify(class QT::QMetaMethod const &)" (?disconnectNotify@QObject@QT@@MEAAXAEBVQMetaMethod@2@@Z)
node.obj : error LNK2001: 无法解析的外部符号 "protected: virtual void __cdecl QT::QObject::disconnectNotify(class QT::QMetaMethod const &)" (?disconnectNotify@QObject@QT@@MEAAXAEBVQMetaMethod@2@@Z)
qproject.obj : error LNK2001: 无法解析的外部符号 "public: virtual bool __cdecl QT::QObject::event(class QT::QEvent *)" (?event@QObject@QT@@UEAA_NPEAVQEvent@2@@Z)
qproject.obj : error LNK2001: 无法解析的外部符号 "public: virtual bool __cdecl QT::QObject::eventFilter(class QT::QObject *,class QT::QEvent *)" (?eventFilter@QObject@QT@@UEAA_NPEAV12@PEAVQEvent@2@@Z)
node.obj : error LNK2001: 无法解析的外部符号 "public: virtual bool __cdecl QT::QObject::eventFilter(class QT::QObject *,class QT::QEvent *)" (?eventFilter@QObject@QT@@UEAA_NPEAV12@PEAVQEvent@2@@Z)
qproject.obj : error LNK2001: 无法解析的外部符号 "public: virtual class QT::QFlags<enum QT::Qt::Orientation> __cdecl QT::QBoxLayout::expandingDirections(void)const " (?expandingDirections@QBoxLayout@QT@@UEBA?AV?$QFlags@W4Orientation@Qt@QT@@@2@XZ)
qproject.obj : error LNK2001: 无法解析的外部符号 "public: virtual class QT::QRect __cdecl QT::QLayout::geometry(void)const " (?geometry@QLayout@QT@@UEBA?AVQRect@2@XZ)
qproject.obj : error LNK2001: 无法解析的外部符号 "public: virtual bool __cdecl QT::QBoxLayout::hasHeightForWidth(void)const " (?hasHeightForWidth@QBoxLayout@QT@@UEBA_NXZ)
qproject.obj : error LNK2001: 无法解析的外部符号 "public: virtual int __cdecl QT::QBoxLayout::heightForWidth(int)const " (?heightForWidth@QBoxLayout@QT@@UEBAHH@Z)
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!