比如,我写了一个简单的C程序:
#include<stdio.h>
int a;
int main(){
printf("a:%d\n", a);
return 0;
}
然后我用gcc编译它,它输出一个可执行文件a.exe
。
现在我想编写另一个程序来读取a.exe
并更改变量a
的值。
我怎么做?
我只想保存一些数据而不是黑客。
是否有任何库可以帮助我完成此操作?
我不确定以这种方式修改可执行文件有什么价值。 如果您需要一个程序的不同副本来使用不同的选项,请尝试使用配置文件或环境变量。
如果使用代码签名,您还会发现不可能分发修改后的应用程序。 如果没有有效的签名,人们根本就不愿意运行您的代码。
话虽如此,我并不认为为了达到如此微不足道的目的而对可执行文件格式进行详细的研究有多大意义。 因此,您不妨通过标记要更改的数据的位置来使自己的生活变得轻松。 这里有一个简单的例子来说明你是如何做到这一点的。 (我在这里运行的是Mac OS,但类似的方法可能也适用于Windows.)
打印数字1并退出的简单程序。 将其保存在名为app1.c
的文件中。
#include <stdio.h>
int main() {
volatile unsigned int v[3] = { 0xdeadbeef, 0x00000001, 0xbadc0de };
printf("This is app%u\n", v[1]);
return 0;
}
volatile
关键字告诉编译器在编译的代码中保留这个数组,即使它可以被优化掉。
将源代码编译为一个名为app1
的应用程序。
cc app1.c -o app1
运行一行Perl脚本,将v[1]
的值从1更改为2,并将结果保存在名为app2
的文件中。 chmod0755
命令使输出文件可执行。
perl -pe 's/\xef\xbe\xad\xde\x01\x00\x00\x00\xde\xc0\xad\x0b/\xef\xbe\xad\xde\x02\x00\x00\x00\xde\xc0\xad\x0b/' <app1 >app2
chmod 0755 app2
注意:在x86机器上(这意味着现在的大多数台式PC),int
值以小端字节顺序存储。 因此,用于匹配V[]
内容的字节以相反的顺序出现(例如,EF be ad DE
而不是DE ad be EF
)。
您需要编写一个程序来读取可执行文件并进行适当的修改。 在Windows上,您的程序需要理解可移植的可执行文件格式。 在Linux和许多其他类似UNIX的操作系统上,您的程序必须理解ELF或a.out,或者可能是coff。 Mac和其他苹果设备使用Mach-O。 天哪,有很多这样的格式--你的程序必须非常聪明。