最近一直在忙着开发剑网三插件,需要用到Decoda这个软件进行程序注入和调试代码。因为对Decoda原有功能并不满意,又很早的听说这个软件已经开源,决定尝试自行重编译并且改进软件功能。整个过程蛋疼的一波三折,因此作文记录之,供后来人参考。

Decoda是神马


这个高端问题可以戳这里 http://unknownworlds.com/decoda/

官网的描述是这样的

Decoda is a free and open-sourced professional development environment fordebugging Lua script in your applications (A Lua IDE). It’s familiar and fast and you’ll wonder how you ever worked without it.

总而言之 想象它就是一个高端的Lua IDE就好了..

我们的目标


和标题一样,就是重编译啦。

详细一点说:对Decoda最新版本源代码进行本地重编译,并且修改部分功能直到它可以正常运行。

在这里,我使用Microsoft Visual Studio 2010 sp1作为我的IDE。重复这点很重要——因为如果用vs13的话就不会有这篇文章了。不过由于硬件原因(我只能/只想在32位环境下工作),vs10就是我唯一的选择了。

准备工作


本着事后诸葛亮的精神,我把所有可能用到的材料都提前罗列:

> vc++集成开发环境  vs2010/08/05/12/13  当然你也可以选择其他开发环境  不过这篇文章可能无法给你带来帮助
> Decoda最新源代码  它托管在github上 地址为 https://github.com/unknownworlds/decoda 我在写这篇文章的时候程序版本为1.17beta 代码最新提交时间为 Apr.10 2014
> premake4  这是一个基于lua语法的工程配置工具 decoda工程使用premake来创建 你在github的readme中可以看到这个说明 地址为 http://industriousone.com/premake/download 请使用4.4beta以上的版本。写这篇文章时最新版本为4.4-beta5,使用4.3或更早的版本会出错 
> tinyXml源代码  它托管在sourceforge上 地址为 http://sourceforge.net/projects/tinyxml/ 虽然我承认跳跃性很大...不过它在后续的工作中是会用到的... 写这篇文章时最新版本为2.6.2 如何获取适当的版本 后面也会提到

你可以一边下载一边阅读后续的内容

重构工程文件


decoda源代码下载后请解压到你的工作空间。我使用的文件夹为 D:\Library\decoda-master

把premake4下载好,解压到上述相同目录中

为premake4创建一个快捷方式,为其添加命令行参数"vs2010",并执行。 (这里可以对应你使用的IDE版本,premake的详细用法请参考 http://industriousone.com/premake/quick-start )

成功后你会看到新创建的build文件夹

用vs10打开build\Decoda.sln 如果成功的话可以看到解决方案下有3个工程

Frontend  前端 对应Decoda的主界面工程

LuaInject  对应lua钩子库  用于嵌入宿主程序进行调试

Shared  包含两个工程共用库

这里可以直接试图重编译一下,如果编译成功就大功告成了。不过更多可能性你可能会获得这样一大批错误:

错误 252error LNK2038: 检测到“_MSC_VER”的不匹配项: 值“1800”不匹配值“1600”(AboutDialog.obj 中)D:\Library\decoda-master\build\wxmsw28d_core.lib(treebkg.obj)Frontend

百度一下可以知道 是因为程序引用obj文件编译时使用的vc运行库,与当前使用运行库版本不符。究其原因,在github上的readme已经说明:

Decoda has only been tested with the vs2013 target, however it may be possible
to compile Decoda with older versions. It is not currently possible to build
Decoda as a 64-bit executable or a non-Windows application.

所以我们需要对全部引用库进行重编译

Decoda主要使用了wxWidgets,首先对wxWidgets进行重编译。

分别用vs10打开libs\wxWidgets\build\msw\wx.sln 以及 libs\wxScintilla\build\wxscintilla.sln 解决方案,对里面所有工程进行重新编译。虽然有很多warning不过应该会一次编译成功。

这里编译时需要注意解决方案配置,对于Debug和Release会生成不同的lib文件,当然对于不同的配置,生成文件也有不同的命名规则。主程序使用debug时,这里直接选择debug编译即可 如果顺利的话可以看到libs\wxWidgets\lib\vc_lib中的lib文件已被更新。

回到主工程,至此Frontend工程应该可以顺利编译了。

下面我们需要使LuaInject工程顺利编译。因为它引用了TinyXml,我们前面下载的TinyXml就派上了用场。至于使用哪个版本,可以查看工程文件libs\tinyxml\include\tinyxml.h,寻找这样一个段落:

const int TIXML_MAJOR_VERSION = 2;
const int TIXML_MINOR_VERSION = 6;
const int TIXML_PATCH_VERSION = 2;

这里描述了tinyXml的版本为2.6.2。如果未来有变化,最好下载对应的版本。

把tinyXml源代码随便解压,并打开工程。这里我们的目的是重编译tinyXml,使得版本对应。查看libs\tinyxml\lib下的文件,可以得知我们使用了STL库。所以我们只编译tinyxmlSTL工程即可。

首先修改输出路径为decoda的引用路径。简单的打开项目的属性,如下设置:

配置属性 - 库管理器 - 常规 输出文件  修改为decoda工程lib文件夹下的对应文件
注意 对于debug和release的文件名是不同的。

修改完成后,在debug和release下分别生成,然后回到decoda下重编译LuaInject工程查看结果,vc版本的问题解决,但是遇到了新的错误:

错误 35error LNK2019: 无法解析的外部符号 _main,该符号在函数 ___tmainCRTStartup 中被引用D:\Library\decoda-master\build\LIBCMTD.lib(crt0.obj)LuaInject
警告 34 warning LNK4098: 默认库“LIBCMTD”与其他库的使用冲突;请使用 /NODEFAULTLIB:libraryD:\Library\decoda-master\build\LINK LuaInject
警告 33 warning LNK4098: 默认库“MSVCRTD”与其他库的使用冲突;请使用 /NODEFAULTLIB:libraryD:\Library\decoda-master\build\LINK LuaInject

查看百度,这是因为引用库所使用的基础库和自身基础库冲突的原因

查看LuaInject的项目属性 - 配置属性 - C/C++ - 代码生成 运行库 项  默认在debug下为多线程调试 DLL(/MDd)  在Release下为多线程 DLL(/MD)。所以,对于tinyXml也需要改成相同的选项才能正常编译。

如图,对于release也要改成对应。再次重新编译tinyXml后,回到decoda,LuaInject已经可以正常编译,至此大功告成。

DIY


到了这个阶段后,我们可以考虑对Decoda进行调试编辑了

比如,使用Decoda进行Hook调试时,如果源文件为已编译的Lua二进制文件无法查看代码,可以进行如下修改。

LuaInject工程  DebugBackend::RegisterScript函数为钩住虚拟机执行新的Lua脚本时的回调。修改此文件

    // Check if this is a compiled/binary file.if (source != NULL && size >= 4){if (source[0] >= 27 && source[0] <= 33 && memcmp(source + 1, "Lua", 3) == 0){state = CodeState_Binary;source = NULL;}}

段落,检查是否是编译的二进制文件。
我们可以预先声明一个ToHex函数如下:

void DebugBackend::ToHexString(std::string& strDest, const char* pData, int nLength)
{for(int i=0;i<nLength;i++) {if (i%16==0){char szBuf[12] = {0};sprintf(szBuf, "%08xh: ", i);strDest += szBuf;}char szBuf[4] = {0};sprintf(szBuf, "%02x ", (unsigned char)pData[i]);strDest += szBuf;if (i%16==15) {strDest += "\r\n";}}
}

并修改原来函数段落为

    // Check if this is a compiled/binary file.if (source != NULL && size >= 4){if (source[0] >= 27 && source[0] <= 33 && memcmp(source + 1, "Lua", 3) == 0){state = CodeState_Binary;//source = NULL;std::string sb;this->ToHexString(sb, source, size);script->source = sb;        }}

即可以把二进制文件作为hex向前台传输。

下一步修改前台  在Frontend工程中寻找MainFrame::OpenFile* MainFrame::OpenProjectFile(Project::File* file)函数 寻找段落

else if (file->state == CodeState_Binary)
{.....
}

删掉即可。使代码自然进入else if (file->scriptIndex != -1)段落进行输出。
当然这里也可以做更多的判断,比如直接调用反编译函数的命令。因为这里不太熟悉C++,也不想借助C++.net/Cli完成,故此省略。

如果有其他修改的要求欢迎在下面讨论=w=

最后拿着这个利器去调试剑三插件应该很轻松了233333

Decoda1.17重编译实录相关推荐

  1. 探秘重编译(Recompilations)(1/2)

    什么是重编译? 在我谈SQL Server里重编译细节前,首先来看看下面一个很简单存储过程. 1 CREATE PROCEDURE DemonstrateTempTableRecompiles 2 A ...

  2. Ubuntu 17.04 编译安装 Nginx 1.9.9 配置 https 免费证书

    Ubuntu 17.04 编译安装 Nginx 1.9.9 配置 https 免费证书 安装 Nginx 安装依赖 $ apt-get update $ apt-get install build-e ...

  3. 存储过程中引用的常规表,临时表以及表变量是否会导致存储过程的重编译

    在存储过程中,经常要引用一些表来存储一些中间数据,用完即删.对于这个中间表,用常规表,临时表或者表变量有什么区别呢? 下面我们看一下这三种中间表是否会造成执行计划的重编译. 首先打开sql serve ...

  4. Win7x64+VS2012+OpenCV2.4.3+CMake2.8.10+TBB41重编译OpenCV

    原文:http://www.cnblogs.com/freedomshe/archive/2013/01/11/win7_vs2012_opencv_rebuild.html 还可以参考:http:/ ...

  5. Unity3D对apk反编译、重编译、重签名

    本文源链接:http://blog.csdn.net/qq393830887/article/details/56025923 工具 Java环境 Apktool(这玩意有些坑爹,不是官网最新的就好, ...

  6. 在Oracle中重编译所有无效的存储过程

    SQL_PLUS中 spool ExecCompProc.sql select 'alter procedure '||object_name||' compile;' From all_object ...

  7. opencv在vs2012下重编译详细教程——解决按f11进入不了源代码

    最近用到opencv人脸识别的代码,想进源码看看实现过程,大家都知道opencv的源码在opencv/modules下,但是光看那么长的源代码实在麻烦,要是能在调试的时候按f11直接就能跟进内部代码就 ...

  8. java编译sql存过_SQL SERVER 临时表导致存储过程重编译(recompile)的一些探讨

    SQLSERVER为了确保返回正确的值,或者处于性能上的顾虑,有意不重用缓存在内存里的执行计划,而重新编译执行计划的这种行为,被称为重编译(recompile).那么引发存储过程重编译的条件有哪一些呢 ...

  9. Win10 64位+VS2015+OpenCV3.4.2重编译

    一.准备 CMake官网 OpenCV官网 二.下载 CMake下载: 选择CMake 版本: 我这边下载的最新版的cmake-3.12.1-win64.msi 三.CMake生成库 1.用CMake ...

  10. mysql 存储过程 compile_SQLSERVER临时表导致存储过程重编译(recompile)的一些探讨_MySQL...

    SQLSERVER为了确保返回正确的值,或者处于性能上的顾虑,有意不重用缓存在内存里的执行计划,而重新编译执行计划的这种行为,被称为重编译(recompile).那么引发存储过程重编译的条件有哪一些呢 ...

最新文章

  1. 逻辑回归(Logistic Regression)简介及C++实现
  2. C - Catch That Cow POJ - 3278
  3. 生成对抗网络gan原理_生成对抗网络(GAN)的半监督学习
  4. Ubuntu 11.04 x64 下安装Python
  5. Monkey随机性能压测初探(一)
  6. 矩阵问题入门(矩阵乘法and矩阵快速幂)acm寒假集训日记22/1/15
  7. 搬运:【详解javascript中的this对象】
  8. 大四阶段的社会实践的主要目的是_大四寒假社会实践报告1500字范文
  9. 微软SQLHelper.cs类 中文版
  10. 45本Hadoop、大数据方向书籍,包邮送到家!
  11. nginx的配置总结
  12. Matlab中的滤波器
  13. 深度linux 无线网卡,在Deepin Linux系统无线网卡、蓝牙模块驱动安装和出现问题的解决...
  14. unity3d Space Game太空射击游戏资源包
  15. 360WiFi之愚见
  16. python 跳过_python怎么跳过异常继续执行
  17. velodyne16点云特征分类
  18. 中间件常见安全漏洞(转载)
  19. Mac通过命令行搜索文件
  20. 机器学习数学基础——全概率公式与贝叶斯公式

热门文章

  1. 计算机ip地址是指什么作用是什么,ip地址的作用是什么
  2. Java 获取文件的真实类型,修改后缀名也能识别出来
  3. 使用windows的快捷键快速操控窗口
  4. VMware安装_CentOS 7.x系统
  5. Excel插件快捷键弹窗事件(VSTO+键盘钩子实现)
  6. “国六”新要求——基于OBD系统的量产车评估测试 (PVE)
  7. FZU 2213 Common Tangents(公切线)
  8. DNS劫持是什么意思?DNS被劫持怎么办?dns被劫持了怎么处理
  9. 计算机协会游戏方案,计算机协会社团各月工作总结及工作计划
  10. 主程玩失踪,公司蒸发600w,创始人秒变打工仔(含视频)