我这里有一个.so文件,其中包含一个语言包,我想对其进行编辑。我的问题是,我总是没有足够的空间来进行清晰的翻译。
是否可以创建更多空间?
占位符并调整文件大小并跳转到二进制文件的末尾?
或可能引用.txt文件? >

#1 楼

注意:我的原始答案没有访问您要修改的文件的公式,因此,根据您上载的文件,将出现另一个答案。
如果要修改程序中的数据,这是必不可少的了解如何(以及在​​何处)访问它。您的情况涉及三个部分:

.data
.data.rel.ro
.rodata

.data
文件中的所有字符串都通过.data部分,其中包含一个数组,其中包含指向.data.rel.ro中条目的指针,其中存储了指向.rodata中字符串的实际指针。经过radare2的分析后,.data看起来像:

因此,它只是包含每个字符串项的指针和索引的对数组。这是前面提到的三个部分中唯一不需要更改的部分。
.rodata
包含文件中所有使用的中英文字符串。

这是我建议首先更改的部分-将所有中文字符串替换为德语对应的字符串。您可以按照我之前的答案中描述的方式来执行此操作,即用先前创建的文件内容替换整个部分。
.data.rel.ro
这是您要修改的最后一部分。它包含指向您在修改之前在.rodata部分中的字符串的指针。
因此,现在您需要修复此处包含的所有指针,以指向刚刚创建的新.rodata部分中的字符串。请注意,这里的每个条目只是一个指针(即,包含4字节,因此具有固定的长度),因此您可以立即对其进行修补,而无需使用objcopy替换此部分。
完成这些步骤之后,您可以应该已经翻译了所有字符串。

评论


通过您的贡献,我得以成功地用C#编写程序。它将.rodata导出为CSV。编辑后,您可以导入它,并且.data.rel.ro中的指针会自动打补丁。但是现在我有了另一个不同的二进制文件。欢迎您来看看:reverseengineering.stackexchange.com/questions/25943/…

– Alonia
9月22日8:43

#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