神器BinDiff安装的一个小坑

2020-04-12 anhkgg 9999

开始

BinDiff在漏洞分析领域久负盛名,一直无缘得见。

今日因分析某x,需要对比版本变化,于是终得见其真容。

简单安装

使用BinDiff,下载地址

一路next傻瓜安装,没什么特殊的,但注意安装中指定自己的IDA目录。

安装成功后,先用ida打开对比两个目标,分析完成后关闭ida,生成两个idb(i64)文件。

打开BinDiff,新建一个workspace,然后菜单diff选择要比较的两个文件。

结果遇到这个错误:BinDiff error: "Can't start disassembler. Please set correct path in the main settings first"

搜索一下找到这个解决方法,说是没有正确指定IDA目录。

img

我确认配置的IDA目录正确,那究竟是什么原因呢,这一度让我猜测Bindiff是不支持IDA7.0。

简单分析

既然不知道原因,那上工具,分析一下把。

jd-gui打开bindiff.jar,搜索disassembler,找到NewDiffImplementation.class

public String createNewDiff() { try { setDescription("Creating destination directory..."); if ((!this.destinationDirectory.isDirectory()) && (!this.destinationDirectory.mkdirs())) { logger.at(Level.SEVERE).log("Could not create destination directory"); CMessageBox.showError(this.parentWindow, "Could not create destination directory."); return null; } String str1 = createUniqueExportFileName(ESide.PRIMARY); String str2 = createUniqueExportFileName(ESide.SECONDARY); if (this.primaryIdbFile != null) { try { logger.at(Level.INFO).log("- Exporting primary IDB '%s' to '%s'", this.primaryIdbFile.getPath(), this.destinationDirectory.getPath()); setDescription("Exporting primary IDB..."); File localFile1 = ExternalAppUtils.getIdaExe(this.primaryIdbFile); if ((localFile1 == null) || (!localFile1.canExecute())) { String str4 = "Can't start disassembler. Please set correct path in the main settings first."; logger.at(Level.SEVERE).log("Can't start disassembler. Please set correct path in the main settings first."); CMessageBox.showError(this.parentWindow, "Can't start disassembler. Please set correct path in the main settings first."); return null; } ExportProcess.startExportProcess(localFile1, this.destinationDirectory, this.primaryIdbFile, str1); }

看到ExternalAppUtils.getIdaExe获取一个File,如果失败或者不能执行就弹出前面的提示。

跟进ExternalAppUtils.getIdaExe看看,很简单,通过配置找到IDA目录,拼接ida.exe的目录,根据idb(32)和i64(64)找不同的ida.exe。

public static File getIdaExe(File paramFile) { String str = FileUtils.getFileExtension(paramFile); GeneralSettingsConfigItem localGeneralSettingsConfigItem = BinDiffConfig.getInstance().getMainSettings(); if (str.equalsIgnoreCase("idb")) { return new File(localGeneralSettingsConfigItem.getIdaDirectory() + File.separatorChar + IdaHelpers.IDA32_EXECUTABLE); } if (str.equalsIgnoreCase("i64")) { return new File(localGeneralSettingsConfigItem.getIdaDirectory() + File.separatorChar + IdaHelpers.IDA64_EXECUTABLE); } return null; } }

继续看看IdaHelpers.IDA32_EXECUTABLEIdaHelpers.IDA64_EXECUTABLE

static { if (SystemHelpers.isRunningWindows()) { IDA32_EXECUTABLE = "ida.exe"; IDA64_EXECUTABLE = "ida64.exe"; } else { IDA32_EXECUTABLE = "ida"; IDA64_EXECUTABLE = "ida64"; } }

找到问题了,印象中ida目录中的ida.exe文件名是idaq.exe idaq64.exe,并不是ida.exe

怎么回事,BinDiff不可能出这么弱智的问题吧。

难道是因为我没有使用正版,而是破解的绿色版。所以并不正版直接安装后的情况,难道正版安装后是ida.exe

不管这些了,解决方法也简单,手工拷贝那两个idaq文件为ida.exe ida64.exe,ok。

img

搜索engine,找到DiffProcess.class

public static void startDiffProcess(String paramString1, String paramString2, String paramString3, File paramFile) { File localFile = new File(paramString1); if (!localFile.exists()) { throw new DifferException("Can't find BinDiff engine at '" + paramString1 + "'."); } if (!localFile.canExecute()) { throw new DifferException("BinDiff engine is not an executable '" + paramString1 + "'."); }

调用者是NewDiffImplementation.class

public String createNewDiff() {
static { if (SystemHelpers.isRunningWindows()) { BINDIFF_ENGINE_EXECUTABLE = "bindiff.exe"; } else { BINDIFF_ENGINE_EXECUTABLE = "bindiff"; } } }
public void read() { File localFile = new File(getConfigFileName()).getCanonicalFile(); if (!localFile.exists()) { localFile = new File(getMachineConfigFileName()); } DocumentBuilder localDocumentBuilder; try { localDocumentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); } catch (ParserConfigurationException localParserConfigurationException) { throw new RuntimeException(localParserConfigurationException); } try { Document localDocument = localFile.exists() ? localDocumentBuilder.parse(localFile.getPath()) : localDocumentBuilder.newDocument(); this.mainSettings.load(localDocument); } public static String getConfigFileName() { return getConfigurationDirectory() + "bindiff.xml"; } public static String getConfigurationDirectory() { return SystemHelpers.getApplicationDataDirectory("BinDiff"); } public static String getApplicationDataDirectory(String paramString) { return getApplicationDataDirectory() + (isRunningLinux() ? "." + paramString.toLowerCase() : paramString) + File.separator; } public static String getApplicationDataDirectory() { String str; if (isRunningWindows()) { str = System.getenv("APPDATA"); } else { str = System.getProperty("user.home"); if (isRunningMacOSX()) { str = str + "/Library/Application Support"; } } return FileUtils.ensureTrailingSlash(str); }

C:\Users\xxx\AppData\Roaming\BinDiff

<ui directory="C:\Program Files\BinDiff\bin" java-binary="C:\Program Files\BinDiff\jre\bin\javaw.exe" port="2000" retries="20" server="127.0.0.1"/>

改一下,一定要在退出bindiff.jar的情况下,修改,否则修改的内容也会被bindfiff重写。

img

public class DiffProcess { private static final FluentLogger logger = ; private static void handleExitCode(int paramInt) { if (paramInt != 0) { if (paramInt == 1) { throw new DifferException("An error occurred while diffing. Exit code 1."); } if (paramInt == 2) { throw new DifferException("An error occurred while diffing. Exit code 2."); } if (paramInt == 3) { throw new DifferException("Machine ran out of memory. Exit code 3."); } throw new DifferException(String.format("Unknown error occurred while diffing. Exit code %d.", new Object[] { Integer.valueOf(paramInt) })); } }

最后

最终验证bindiff6支持ida7的,不过分析速度感人。

img

(完)

参考:

  1. https://www.cnblogs.com/lsdb/p/10543411.html
  2. https://bbs.pediy.com/thread-246326.htm

【汉客儿原创】转载请注明出处:http://www.hankeer.org/article/analyze-bindiff.html