反编译实例1:helloworld

第一阶段:从源代码到可执行程序

第一个helloworld程序:

#include <stdio.h>

int main(int argc, char** argv)
{
printf("hello world\n");
return 0;

}
编译接生成可执行程序(armcc helloworld -o helloworld.axf):
默认生成的可执行文件为__image.axf,这里指定了生成的可执行文件名helloworld.axf,需要注意的是这一步同时生成了一个中间文件helloworld.o。

注意:直接运行.axf文件显然是行不通的,这里需要借助ads提供的调试工具AXD,当然在使用之前需要进行简单的配置,设定目标环境optition->Configure Target如图一:


然后File->Load Image选择helloworld.axf,如图二:


点击Go运行,执行结果如图三:


当然,在字符下运行程序也是可以的(armsd -ARMUL -EXEC helloworld.axf),运行结果如图四:


第二阶段:从目标文件到源代码

使用IDA打开helloworld.o,如图五:


我们可以非常简单的看到main函数以及printf函数,只不过printf是以_printf的形式出现,不过我们可能首先比较疑惑的一点就是:helloworld字符串在哪里?从调用_printf前的参数传递可以简单分析得出dword_14应该就是helloworld字符串的地址了,我们调整IDA的数据显示,把dword_14处的四字节数据改为单字节数据,显示结果如图六:


可以非常清晰的看出"hello world"字符串了。

接下来,我们开始分析汇编文件(在分析汇编之前最好熟悉一下汇编指令,否则逢指令就查还是挺耽误时间的),通过指令查找分析每一步的作用,注释如图七:


从汇编指令内容分析,main函数没仅仅调用printf输出了一个"hello world\n"字符串,而且这个字符串没有进行变量定义的字符串,最后通过给R0赋值0当做main返回值。
因此我们可以可以进行简单的书写C源代码helloworldnew.c如下:
#include <stdio.h>

int main(int argc, char** argv)
{
printf("hello world\n");
return 0;
}

armcc helloworldnew.c -o helloworldnew.axf生成可执行文件,并用IDA打开对应的helloworldnew.o文件,导出.asm文件,与之前IDA打开的helloworld.o导出的helloworld.asm使用beyond compare进行对比,比较结果如图八:


从图中可以看出,除了文件名上有所不同,其余的数据和指令是完全一样的。当然后续可能会明白,想要完全一致基本是不可能的,只能尽量的语义一致。

执行结果如图九:

到这里,整个反编译过程基本就结束了。

当然,你可以尝试一下如下的操作:

1、新的C源代码定义一个字符串并把"hello world\n"赋给该字符串指针,查看编译生成的.o的汇编代码;

2、函数的返回只修改一下,查看汇编代码;

1
阅读更多
文章标签: 汇编 image 工具 go c
个人分类: 反编译学习
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭