是否可以创建更多空间?
占位符并调整文件大小并跳转到二进制文件的末尾?
或可能引用.txt文件? >
#1 楼
注意:我的原始答案没有访问您要修改的文件的公式,因此,根据您上载的文件,将出现另一个答案。如果要修改程序中的数据,这是必不可少的了解如何(以及在何处)访问它。您的情况涉及三个部分:
.data
.data.rel.ro
.rodata
.data
文件中的所有字符串都通过
.data
部分,其中包含一个数组,其中包含指向.data.rel.ro
中条目的指针,其中存储了指向.rodata
中字符串的实际指针。经过radare2
的分析后,.data
看起来像:因此,它只是包含每个字符串项的指针和索引的对数组。这是前面提到的三个部分中唯一不需要更改的部分。
.rodata
包含文件中所有使用的中英文字符串。
这是我建议首先更改的部分-将所有中文字符串替换为德语对应的字符串。您可以按照我之前的答案中描述的方式来执行此操作,即用先前创建的文件内容替换整个部分。
.data.rel.ro
这是您要修改的最后一部分。它包含指向您在修改之前在
.rodata
部分中的字符串的指针。 因此,现在您需要修复此处包含的所有指针,以指向刚刚创建的新
.rodata
部分中的字符串。请注意,这里的每个条目只是一个指针(即,包含4
字节,因此具有固定的长度),因此您可以立即对其进行修补,而无需使用objcopy
替换此部分。完成这些步骤之后,您可以应该已经翻译了所有字符串。
#2 楼
对的,这是可能的。尽管您可以通过多种方式解决问题,但我认为我将为您提供最简单的解决方案。您可以使用的工具是objcopy。它允许您更改ELF文件的内容,我将逐步向您展示如何使用它来实现目标的示例。在下面提供的示例中,我正在64位Linux机器上工作。请考虑以下C程序:暂时没有源代码(因为我想使其尽可能简单,所以这里没有错误检查)。如您所见,它在其开始处带有参数(语言的索引),并以给定的语言打印字符串。但是我们想添加一个额外的字符串,例如
stringInYourFavouriteLanguage
,并使我们的程序也能够打印它。我们的第一步将是找到包含所有不同语言字符串的ELF部分。为此,您可以使用objdump-仅查看部分名称,即可在其中看到这些字符串。就我而言,它是
.rodata
,如下所示:请注意,我们在这里遇到了其他问题-
LANGUAGES_TABLE
中的每个字符串仅占用21个字节,而stringInYourFavouriteLanguage
使用30个字节。我将返回它一段时间后。现在,我们想准备一个文件
langData
,其中包含我们希望在新.rodata
部分中获得的数据。我建议您只复制现有的一个,然后以不同的语言附加字符串的修补版本-这样一来,您将避免更改代码中.rodata
访问中的所有偏移量;您只需要更改与语言相关的内容即可。 在我们的示例中,我们还需要将
LANGUAGES_TABLE
的第二维更改为30,因此我们将在此数组中每个字符串的末尾添加9个NULL字节。然后,将stringInYourFavouriteLanguage
+ NULL附加到文件末尾。在附加到包含来自.rodata
的全部数据的文件之前,我们的文件应如下所示:现在,我们可以连接这些文件,并得到一个文件-
langData
,其中包含要添加到.rodata
的新数据。然后我们使用objcopy这样:#include <stdio.h>
#include <stdlib.h>
#define NUM_OF_LANGUAGES 5
#define MAX_STR_LENGTH 21
const char LANGUAGES_TABLE[NUM_OF_LANGUAGES][MAX_STR_LENGTH] = {
"stringInEnglish",
"stringInPolish",
"stringInSpanish",
"stringInItalian",
"stringInFrench"
};
char* someOtherData = "some other data";
char* lastString = "last string in file";
int main(int argc, char** argv)
{
int langID = atoi(argv[1]);
printf("%s\n", LANGUAGES_TABLE[langID]);
return 0;
}
,其中
langPack
是我们要修改的ELF文件,langPackPatched
是输出文件。现在,您可以使用objdump检查该文件,并确认确实已进行了更改。所以,现在,我们有所需内容的
.rodata
。现在我们要使可执行文件也能够打印stringInYourFavouriteLanguage
。要实现这一点,我们实际上需要在程序中更改一些代码-首先,我们必须更改偏移量,以便每个内存访问
LANGUAGES_TABLE
将使用我们的附加数据,其次,我们需要更改缩放比例,因此我们的程序将打印PATCHED_LANGUAGES_TABLE[21*arg]
而不是打印PATCHED_LANGUAGES_TABLE[30*arg]
。这是整个过程中最棘手的部分。首先,您需要找到要修补的代码。在我们的示例中为:
请注意,从偏移量
0x6e8
开始的21个字节实际上负责将arg乘以21,并将LANGUAGES_TABLE
的地址加载到RDX。在此,lea
使用RIP计算此偏移量。我们需要做的是确定要添加到RIP以获得LANGUAGES_TABLE_PATCHED
的偏移量。在这里,请记住一件重要的事情-我们必须确定偏移量,具体取决于地址修补后的
文件中的此
lea
指令。 因此,或者我们将其留在原处并仅更改偏移量(即操作码的最后4个字节),以便它指向我们的已修补表,或者我们只编写代码,然后添加相关代码
nop
的数量(然后我们可以将lea
写为lea [rip]
,然后简单地使用调试器检查所需的偏移量并将其更改为lea [rip+offset]
)-这就是我所做的。不过,我们的修补代码可能看起来像这样:它负责计算
LANGUAGES_TABLE_PATCHED[30*arg]
的地址。就是这样了!我们现在可以对其进行测试;如果运行
./langPackPatched 5
,则会得到:objcopy --update-section .rodata=langData langPack langPackPatched
,而其他参数的程序行为保持不变。
评论
谢谢您的想法。💡您能帮我吗?我可以跟着你,但是我做不到。
– Alonia
19年4月9日在19:01
当然,我可以。您能否指定答案的哪一部分不清楚?
–bart1e
19年4月9日在20:48
我不知道如何将其应用于我的文件。我可以在这里发送个人消息吗?我还没有找到重点。然后,我可以向您显示文件。
– Alonia
19年4月10日在5:08
据我所知,不可能在这里发送PM。因此,您可以考虑将其上传到此处,或提出另一个问题来精确描述您遇到的困难。
–bart1e
19年4月10日在8:55
我会看的,但是我鼓励您使用这些文件来更新您的问题,以便其他用户也可以为您提供帮助。
–bart1e
19年4月10日在10:02
评论
通过您的贡献,我得以成功地用C#编写程序。它将.rodata导出为CSV。编辑后,您可以导入它,并且.data.rel.ro中的指针会自动打补丁。但是现在我有了另一个不同的二进制文件。欢迎您来看看:reverseengineering.stackexchange.com/questions/25943/…
– Alonia
9月22日8:43