我有一个(C++)程序,在它的一个dll中,完成了以下操作:
if (m_Map.GetMaxValue() >= MAX_CLASSES) {
我有这个程序的两个二进制文件(用不同版本的Visual Studio编译),一个是MAX_CLASSES被#define 'd为50,另一个是75。这两个二进制文件是从不同的代码分支生成的,其他功能也不同。我需要的是一个二进制文件的版本,其中MAX_CLASSES被定义为50,除了更高的限制,即75。
所以一个理智的人会改变我需要的分支的源代码中的常量,重建并回家。但是,构建这个软件是复杂的,因为它是旧的,依赖关系和工具是旧的,等等;另外,我在构建安装程序和数据等方面也有问题。所以,我想,我只是修补这个二进制文件,这样这个常量就可以直接在DLL中更改了。我有模糊的记忆,在20世纪90年代做过类似的事情,嗯,可能是出于“教育”的目的。
但是时代变了,我几乎不记得做过这个,更不用说我当时是怎么做的了。(一个限制设置为75,这是我手头上的二进制-我将不得不重新做这一点,只要我有50限制的实际二进制,所以下面引用75,即0x 4 b来说明原理)在Ghidra中,经过一些调查,我发现了以下内容:
18005160e 3c 4b CMP AL,0x4b
180051610 0f 82 19 JC LAB_18005172f
01 00 00
在反编译器窗口中,我可以链接回
if (bVar3 < 0x4b)
以及之后的一些操作,我可以将这些操作Map到我所拥有的函数的源代码。
现在我的问题是:
- 如何解释上面的值(Ghidra输出)wrt到dll的二进制布局?当我将鼠标悬停在第一列值上时(“18005160 e”)在Ghidra中,我获得了“图像库偏移量”、“内存块偏移量”'function offset'和'byte source offset'。这个'byte source offset'是否是从这些指令开始的dll开头算起的实体地址?这个悬停气球中的实际值是50 a0 eh-这是Ghidra对0x 50 a0 e的表示法吗?也就是说,尾随的“h”表示“hex”吗?
- 然后,我尝试在常规十六进制编辑器中打开dll(“Hex Editor Neo”,我喜欢用它来查看/编辑二进制数据文件),并转到偏移量0x 50 a0 e,并在那里附近寻找值“3c 4 b”,但我没有找到。我在整个文件中搜索了这个字节序列,并找到了7个匹配项,其中没有一个是在0x 50 a0 e附近,这让我觉得我误解了Ghidra的“字节源偏移量”。
- 我如何做一个“补丁程序”呢?我想我需要的是一个程序,只做
文件名:fseek(fh,0x[魔术常数]); fwrite(fh,0x4b); f关闭(fh);
这里的'0x[magic constant]'很可能就是我从Ghidra的'byte source offset'中得到的值?或者这里还有什么我需要考虑的吗?有没有什么软件工具可以生成补丁程序?
- 谢谢-谢谢
1条答案
按热度按时间mnowg1ta1#
18005160e
是一个VA,即 * 虚拟地址 *。它是 * 基址 (最有可能是
180000000
)与RVA( 相对虚拟地址 *)之与.使用任何PE检查工具(例如CFF Explorer)或Ghidra本身查找DLL的基址。
从
18005160e
减去RVA的基地址,假设结果为5160e
。现在,您需要查找此RVA位于哪个部分。再次使用PE检查工具查找部分列表及其RVA/虚拟开始和RVA/虚拟大小。
假设RVA位于
.text
部分,从RVA1000
开始。从上述结果中减去该起始RVA:
5160e - 1000 = 4160e
.这是
.text
段中指令的偏移量。要找到文件中的偏移量,只需添加该部分的原始/偏移量开始(同样,您可以使用PE检查工具找到它)。假设
.text
部分开始于偏移量400
,则4160e + 400 = 41a0e
是对应于VA18005160e
的偏移量。这都是PE 101。