Android逆向进阶-ELF文件分析(2)(c解析ELF head)
本文章首发于i春秋。# 0x00 前言
这里是[无价之宝](http://blog.csdn.net/qq_36869808/article/details/79367884)
之前的(http://blog.csdn.net/qq_36869808/article/details/79334437)已经有了一定的分析,这次我们接着进行分析。
## 说明:
![这里写图片描述](http://t1.aixinxi.net/o_1c7h7qa5v19001m6dsipfp41k4la.jpg-j.jpg)
我们在分析ELF文件的时候必然要先明白这样的知识。
### 什么是文件的静态解析?
文件的静态解析就是,在winhex打开文件的时候,对其各个字段进行分析的过程就是文件的静态解析。那么现在就应该知道我们之前做的其实都是文件的静态解析。
### 什么是文件的动态解析?
文件在执行的时候,内存也要对文件进行解析,那么这个解析就是动态解析。
### 文件的执行流程是什么?
打开——加载——解析——运行
## 内容:
1.前置知识补充
2.c语言实现ELF文件的静态分析
# 0x01 前置知识补充
![这里写图片描述](http://t1.aixinxi.net/o_1c7h97lfj38ia80jie1i2m1fm9a.jpg-j.jpg)
## 1.ELF中常用数据格式
先来看看这个
// Name Size Alignment Purpose
// ==== ==== ========= =======
// Elf32_Addr 4 4 Unsigned program address
// Elf32_Half 2 2 Unsigned medium integer
// Elf32_Off 4 4 Unsigned file offset
// Elf32_Sword 4 4 Signed large integer
// Elf32_Word 4 4 Unsigned large integer
// unsigned char1 1 Unsigned small integer
这个是elf.h文件中的内容。
我们还是来看看这个,这个相对来说是比较清晰的。
![这里写图片描述](http://t1.aixinxi.net/o_1c7h9e9d41cis14rp1v91l731666a.png-j.jpg)
## 2.目标文件格式
静态解析:链接视图
动态解析:执行视图
![这里写图片描述](http://t1.aixinxi.net/o_1c7h9uar811ersk51hgf187n1eqa.png-j.jpg)
## 3.ELF文件重点理解
ELF文件其实段和节从本质上来说是一样的,段是由节而组成。
而节则是我们需要重点来看的。
如果ELF文件不进行运行的话,那么就没有必要研究段,但是文件只有在运行的时候才有意义,所以研究段和研究节都是必不可少的。
# 0x02 c语言实现ELF文件的静态分析
![这里写图片描述](http://t1.aixinxi.net/o_1c7m3dq9g1dlc14081nrp11b9ih7a.jpg-j.jpg)
python写多了,感觉c都有点写不来了。有一个elf.h的头文件,但是我不想用,还是自己来写吧,自己来写的顺手一点。我们主要是为了熟悉elf文件,不是为了工具而工具。
## 内容:
1. 命令行格式
2. ELF Header 解析(010 Editor 同步对比)
## 1.命令行格式
### (1)基本代码
```
int main(int argc, char *argv[])
{
// 判断输入的内容是否为3个
if (argc != 3)
{
// 用户输入了-h命令
if (strcmp(argv, "-h") == 0)
{
printf("-head elf is head Analiyses!\n");
exit(1);
}
p();
printf("please enter -h");
exit(1);
}
//判断输入的指令是否为“-head”
if (strcmp(argv,"-head")==0)
{
}
return 0;
}
```
### (2)运行测试
非-h测试
![这里写图片描述](http://t1.aixinxi.net/o_1c7m3ptsd11os1eru1ekr1q9noqfa.png-j.jpg)
-h测试
![这里写图片描述](http://t1.aixinxi.net/o_1c7m3t32o14h1evk122a1pq2ckua.png-j.jpg)
## 2.ELF Header 解析
原本是找了半天的如何输出一个十六进制的内容,现在终于找到了。而且还是东拼西凑才找到的。恩,还是使用最原始的方法进行分析吧。
突然发现python写多了,写c的时候成强迫症了。。。
首先是前16个字节的内容:
![这里写图片描述](http://t1.aixinxi.net/o_1c7mbra2uabc5mf5ettjpe35a.png-j.jpg)
成功解析。
我们来看看代码。
```
printf("Magic:");
for (i = 0; i < head; i++){
c = fgetc(fp);
j = c;
hex_str = inttohex(j);
h1 = j;
if (j < 9){
printf("0%s ", hex_str);
}
else
{
printf("%s ", hex_str);
}
}
printf("\n");
if (h1 == 127 && h1 == 69 && h1 == 76 && h1 == 70)
{
}
else
{
printf("This is not a ELF file.——for HAI_ help\n");
exit(1);
}
```
这里为了更加方便利于我们的观察特此写了辅助版以及大神版。
### 2.1.1 e_ident 分析
这里采用10进制进行对比。可以看到这里的辅助内容还是写的很详细的。
![这里写图片描述](http://t1.aixinxi.net/o_1c7mcbunv16anosh1qmo9q510hla.png-j.jpg)
这里贴出关键代码:
```
if (h1 == 127 && h1 == 69 && h1 == 76 && h1 == 70)
{
printf("Read the first four bytes\n");
printf("characteristic value is :%c%c%c%c\n", h1, h1, h1, h1, h1);
printf("This is a ELF file.——for HAI_ help\n");
}
else
{
printf("This is not a ELF file.——for HAI_ help\n");
exit(1);
}
```
### 2.1.2EI_CLASS解析
上次说到EI_CLASS是标识文件的类别。
那么我们这里就进行一个简单的判断就可以了。
![这里写图片描述](http://t1.aixinxi.net/o_1c7md2etev2b1jb663c1pag4b2a.png-j.jpg)
```
void EI_CLASS(int i)
{
printf("EI_CLASS:");
if (i == 0)
printf("Illicit type.\n");
else if (i==1)
{
printf("32 bits ELF file. \n");
}
else if (i == 2)
{
printf("64 bits ELF file. \n");
}
}
```
### 2.1.3EI_DATA
含义:数据编码格式
来看下程序的辅助运行。
![这里写图片描述](http://t1.aixinxi.net/o_1c7mdinkqu1l75nrqjclv1l4aa.png-j.jpg)
```
void EI_DATA(int i)
{
printf("EI_DATA:");
if (i == 0)
printf("Illegal data coding.\n");
else if (i == 1)
{
printf("MSB first. \n");
}
else if (i == 2)
{
printf("LSB first. \n");
}
}
```
### 2.1.4EI_VERSION
版本号字段
![这里写图片描述](http://t1.aixinxi.net/o_1c7mdp8mrtor3vd1ik91hf11o8ma.png-j.jpg)
这里直接输出即可。
```
void EI_VERSION(){
printf("EI_VERSION:");
printf("%d", h1);
}
```
### 2.1.5 其他
其他位置就是补充的字段了。其余位置全部 00
2018年3月4日01:17:36,睡觉去了~明天继续,已经走上了正轨,技术方面没有问题了。
![这里写图片描述](http://t1.aixinxi.net/o_1c7meetfieqe1lsbpno1jeulefa.jpg-j.jpg)
2018年3月4日13:14:21,陪女朋友出去,现在回来接着写。
在写代码的时候,我们顺便使用 010 Editor 进行对比。
![这里写图片描述](http://t1.aixinxi.net/o_1c7no3t5ub801eagdvabi7j6ba.png-j.jpg)
### 2.2 e_type
该段表示为目标文件类型。
![这里写图片描述](http://t1.aixinxi.net/o_1c7noqfhspshko6pf11l4l1qkma.png-j.jpg)
利用简单的读取以及ELF头文件的分析来进行解析。
```
printf("e_type:");
for (i = 0; i < 2; i++)
{
c = fgetc(fp);
j = c;
hex_str = inttohex(j);
h1 = j;
if (j < 9){
printf("0%s ", hex_str);
}
else
{
printf("%s ", hex_str);
}
}
if (h1 == 3)
{
printf("(共享目标文件)\n");
}
else
{
printf("(其他文件类型)\n");
}
```
010 Editor 对照。
![这里写图片描述](http://t1.aixinxi.net/o_1c7np2s32fdo1mvadi5i2nh79a.png-j.jpg)
### 2.3 e_machine
该段说明目标体系结构类型。
读取两个字节。
![这里写图片描述](http://t1.aixinxi.net/o_1c7np93kp1trr1ktin1q9601i7va.png-j.jpg)
代码就不贴了,没什么技术难度。
010 editor对比:
![这里写图片描述](http://t1.aixinxi.net/o_1c7npcs2a149niaq1867ri4qaia.png-j.jpg)
### 2.4 e_version
目标文件版本
因为和之前的一样,这里就不再进行解析。
但是还是来看一下010 Editor吧。
![这里写图片描述](http://t1.aixinxi.net/o_1c7npg32rhpd17hnik98n11665a.png-j.jpg)
### 2.5 e_entry
程序入口的虚拟地址。如果目标文件没有程序入口,可以为 0。
![这里写图片描述](http://t1.aixinxi.net/o_1c7npmu961dd31u8753p29epula.png-j.jpg)
010 editor
![这里写图片描述](http://t1.aixinxi.net/o_1c7npoouuj6qto1q7k1sfv1nc5a.png-j.jpg)
### 2.6 e_phoff
程序头部表格(Program Header Table)的偏移量(按字节计算)。
![这里写图片描述](http://t1.aixinxi.net/o_1c7npvj3f7m1jh1211r1dp1qa.png-j.jpg)
关键代码展示:
```
printf("e_phoff:");
for (i = 0; i < 4; i++)
{
c = fgetc(fp);
j = c;
hex_str = inttohex(j);
h1 = j;
if (j < 9){
printf("0%s ", hex_str);
}
else
{
printf("%s ", hex_str);
}
}
printf("(%dbits)",h1);
printf("\n");
```
010 editor进行对比
![这里写图片描述](http://t1.aixinxi.net/o_1c7nq1hup1hoflr11phauja8dka.png-j.jpg)
### 2.7 e_shoff
节区头部表格(Section Header Table)的偏移量(按字节计算)。如果文件
没有节区头部表格,可以为 0。
![这里写图片描述](http://t1.aixinxi.net/o_1c7nqm1uq1d7v1o9q1qvr1k8tff6a.png-j.jpg)
核心代码
```
printf("e_phoff:");
for (i = 0; i < 4; i++)
{
c = fgetc(fp);
j = c;
hex_str = inttohex(j);
h1 = j;
if (j < 9){
printf("0%s ", hex_str);
}
else
{
printf("%s ", hex_str);
}
}
printf("(%d bits)", h1+h1*16*16+h1*16*16*16*16+h1*16*16*16*16*16*16);
printf("\n");
```
010 editor对比
![这里写图片描述](http://t1.aixinxi.net/o_1c7nqpl0qq0l1l6cmv515tv1kn3a.png-j.jpg)
### 2.8 e_flags
保存与文件相关的,特定于处理器的标志。
![这里写图片描述](http://t1.aixinxi.net/o_1c7nr0fh81iba1e431a0q73araa.png-j.jpg)
010 editor对比
![这里写图片描述](http://t1.aixinxi.net/o_1c7nr2lj11t641b948c1kao1709a.png-j.jpg)
### 2.9 e_ehsize
ELF 头部的大小
![这里写图片描述](http://t1.aixinxi.net/o_1c7nr7bcaeki1tpn1etuhpau41a.png-j.jpg)
010 Editor
![这里写图片描述](http://t1.aixinxi.net/o_1c7nr8o4s1lh5uk0tb1cbnbssa.png-j.jpg)
### 2.10 e_phentsize
程序头部表格的表项大小。
![这里写图片描述](http://t1.aixinxi.net/o_1c7nrcq2jor8ncm12i8174bk4oa.png-j.jpg)
010 editor
![这里写图片描述](http://t1.aixinxi.net/o_1c7nrh1ce10opg641lprcqg3bja.png-j.jpg)
### 2.11 e_phnum
程序头部表格的表项数目。
![这里写图片描述](http://t1.aixinxi.net/o_1c7nrhqro1bu912uaa572ugfl3a.png-j.jpg)
这里就不截010 editor的图了。有软件自己看看吧。
### 2.12 e_shentsize
节区头部表格的表项大小。
![这里写图片描述](http://t1.aixinxi.net/o_1c7nrmv72fbmm64tnc7jlfa0a.png-j.jpg)
### 2.13 e_shnum
节区头部表格的表项数目。可以为 0。
![这里写图片描述](http://t1.aixinxi.net/o_1c7nrpobav71k71glc15la1gq1a.png-j.jpg)
### 2.14 e_shstrndx
节区头部表格中与节区名称字符串表相关的表项的索引。
![这里写图片描述](http://t1.aixinxi.net/o_1c7nrt0uc1jp94a71ivo18s21v24a.png-j.jpg)
## 3.测试。
### 测试 demo 1.so
自己的程序(有一个小错误已经更改)
![这里写图片描述](http://t1.aixinxi.net/o_1c7nsjgpfv231sphnqn1srl3c0a.png-j.jpg)
readelf
![这里写图片描述](http://t1.aixinxi.net/o_1c7ns6p321t91esr6v2m0t19gaa.png-j.jpg)
看起来还是人家的美观一点,我没有调整对齐。还有显示等。当然我们的重点是理解格式,以及分析内容的准确性。
### 测试 demo 2.so
![这里写图片描述](http://t1.aixinxi.net/o_1c7nvpjf3r6ltp21tc39uqtloa.png-j.jpg)
![这里写图片描述](http://t1.aixinxi.net/o_1c7nvqrobp64f5s7063cdh5ja.png-j.jpg)
###
## 4. 总结
总的来说c语言写工具其实也并没有想象中那么难,其实和脚本语言挺相似的,只是处理的方式不同,写程序会让你对大小,以及字节,还有内容进行一个更深层次的了解。
那么我们的elf head 部分就彻底写完了。
代码部分,还有其他的东西都会打包起来进行上传。
# 0x03 结束语
之后还有一波对Program Headers的分析,恩,有点啰嗦了不要介意。 JmNkS 发表于 2018-10-29 20:28
不知道什么原因,楼主的一些图片在论坛里经常随机加载失败,得“在新标签中打开图片”才能正常显示
唉,当时没有钱,用的免费图床,然后现在懒得重新写了。。。。 TopGreat 发表于 2018-11-4 05:17
elf.h里有 Elf32_Ehdr 的定义,直接读取就行, 不用这么麻烦。
嗯嗯嗯嗯,010还是很好用的 好详细的教程,楼主给你点赞 为你点赞,很详细的教程 想知道附件在哪里?? 部分图挂了 qtfreet00 发表于 2018-3-5 09:39
部分图挂了
我这边图片都是存在的,是不是因为网络原因? Andy0214 发表于 2018-3-5 09:17
想知道附件在哪里??
附件上传了,原谅我不知道怎么弄进去 先收藏,然后慢慢看 很详细,思路清晰
页:
[1]
2