用户
搜索
  • TA的每日心情
    难过
    4 天前
  • 签到天数: 127 天

    连续签到: 1 天

    [LV.7]常住居民III

    i春秋作家

    推荐小组成员

    Rank: 7Rank: 7Rank: 7

    112

    主题

    272

    帖子

    956

    魔法币
    收听
    0
    粉丝
    17
    注册时间
    2017-7-24

    幽默灌水王突出贡献春秋文阁i春秋签约作者i春秋推荐小组积极活跃奖春秋游侠秦

    HAI_ i春秋作家 推荐小组成员 幽默灌水王 突出贡献 春秋文阁 i春秋签约作者 i春秋推荐小组 积极活跃奖 春秋游侠 秦 楼主
    发表于 2018-3-4 16:09:18 1023414

    本文章首发于i春秋,未经允许,禁止转载。

    0x00 前言

    这里是无价之宝
    之前的Android逆向进阶-ELF文件分析(1)已经有了一定的分析,这次我们接着进行分析。

    说明:

    这里写图片描述
    我们在分析ELF文件的时候必然要先明白这样的知识。

    什么是文件的静态解析?

    文件的静态解析就是,在winhex打开文件的时候,对其各个字段进行分析的过程就是文件的静态解析。那么现在就应该知道我们之前做的其实都是文件的静态解析。

    什么是文件的动态解析?

    文件在执行的时候,内存也要对文件进行解析,那么这个解析就是动态解析。

    文件的执行流程是什么?

    打开——加载——解析——运行

    内容:

    1.前置知识补充
    2.c语言实现ELF文件的静态分析

    0x01 前置知识补充

    这里写图片描述

    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 char  1       1       Unsigned small integer

    这个是elf.h文件中的内容。

    我们还是来看看这个,这个相对来说是比较清晰的。

    这里写图片描述

    2.目标文件格式

    静态解析:链接视图
    动态解析:执行视图
    这里写图片描述

    3.ELF文件重点理解

    ELF文件其实段和节从本质上来说是一样的,段是由节而组成。
    而节则是我们需要重点来看的。
    如果ELF文件不进行运行的话,那么就没有必要研究段,但是文件只有在运行的时候才有意义,所以研究段和研究节都是必不可少的。

    0x02 c语言实现ELF文件的静态分析

    这里写图片描述
    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[1], "-h") == 0)
                            {
                                    printf("-head elf is head Analiyses!\n");
                                    exit(1);
                            }
                            p();
                            printf("please enter -h");
                            exit(1);
                    }
                    //判断输入的指令是否为“-head”
                    if (strcmp(argv[1],"-head")==0)
                    {
    
                    }
    
                    return 0;
    }

    (2)运行测试

    非-h测试
    这里写图片描述

    -h测试
    这里写图片描述

    2.ELF Header 解析

    原本是找了半天的如何输出一个十六进制的内容,现在终于找到了。而且还是东拼西凑才找到的。恩,还是使用最原始的方法进行分析吧。

    突然发现python写多了,写c的时候成强迫症了。。。

    首先是前16个字节的内容:

    这里写图片描述

    成功解析。

    我们来看看代码。

    printf("Magic:");
            for (i = 0; i < head[0]; i++){
                    c = fgetc(fp);
                    j = c;
                    hex_str = inttohex(j);
                    h1[i] = j;
                    if (j < 9){
                            printf("0%s ", hex_str);
                    }
                    else
                    {
                            printf("%s ", hex_str);
                    }
            }
            printf("\n");
            if (h1[0] == 127 && h1[1] == 69 && h1[2] == 76 && h1[3] == 70)
            {
            }
            else
            {
                    printf("This is not a ELF file.——for HAI_ help\n");
                    exit(1);
            }

    这里为了更加方便利于我们的观察特此写了辅助版以及大神版。

    2.1.1 e_ident 分析

    这里采用10进制进行对比。可以看到这里的辅助内容还是写的很详细的。

    这里写图片描述

    这里贴出关键代码:

    if (h1[0] == 127 && h1[1] == 69 && h1[2] == 76 && h1[3] == 70)
            {
                    printf("Read the first four bytes\n");
                    printf("characteristic value is :%c%c%c%c\n", h1[0], h1[1], h1[2], h1[3], h1[4]);
                    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是标识文件的类别。

    那么我们这里就进行一个简单的判断就可以了。
    这里写图片描述

    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

    含义:数据编码格式

    来看下程序的辅助运行。

    这里写图片描述

    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

    版本号字段

    这里写图片描述

    这里直接输出即可。

    void EI_VERSION(){
            printf("EI_VERSION:");
            printf("%d", h1[6]);
    }

    2.1.5 其他

    其他位置就是补充的字段了。其余位置全部 00

    2018年3月4日01:17:36,睡觉去了~明天继续,已经走上了正轨,技术方面没有问题了。

    这里写图片描述

    2018年3月4日13:14:21,陪女朋友出去,现在回来接着写。

    在写代码的时候,我们顺便使用 010 Editor 进行对比。

    这里写图片描述

    2.2 e_type

    该段表示为目标文件类型。

    这里写图片描述

    利用简单的读取以及ELF头文件的分析来进行解析。

    printf("e_type:");
            for (i = 0; i < 2; i++)
            {
                    c = fgetc(fp);
                    j = c;
                    hex_str = inttohex(j);
                    h1[i] = j;
                    if (j < 9){
                            printf("0%s ", hex_str);
                    }
                    else
                    {
                            printf("%s ", hex_str);
                    }
            }
            if (h1[0] == 3)
            {
                    printf("(共享目标文件)\n");
            }
            else
            {
                    printf("(其他文件类型)\n");
            }

    010 Editor 对照。

    这里写图片描述

    2.3 e_machine

    该段说明目标体系结构类型。

    读取两个字节。

    这里写图片描述

    代码就不贴了,没什么技术难度。

    010 editor对比:

    这里写图片描述

    2.4 e_version

    目标文件版本

    因为和之前的一样,这里就不再进行解析。

    但是还是来看一下010 Editor吧。
    这里写图片描述

    2.5 e_entry

    程序入口的虚拟地址。如果目标文件没有程序入口,可以为 0。

    这里写图片描述

    010 editor

    这里写图片描述

    2.6 e_phoff

    程序头部表格(Program Header Table)的偏移量(按字节计算)。

    这里写图片描述

    关键代码展示:

    printf("e_phoff:");
            for (i = 0; i < 4; i++)
            {
                    c = fgetc(fp);
                    j = c;
                    hex_str = inttohex(j);
                    h1[i] = j;
                    if (j < 9){
                            printf("0%s ", hex_str);
                    }
                    else
                    {
                            printf("%s ", hex_str);
                    }
            }
            printf("(%dbits)",h1[0]);
            printf("\n");

    010 editor进行对比
    这里写图片描述

    2.7 e_shoff

    节区头部表格(Section Header Table)的偏移量(按字节计算)。如果文件
    没有节区头部表格,可以为 0。

    这里写图片描述

    核心代码

    printf("e_phoff:");
            for (i = 0; i < 4; i++)
            {
                    c = fgetc(fp);
                    j = c;
                    hex_str = inttohex(j);
                    h1[i] = j;
                    if (j < 9){
                            printf("0%s ", hex_str);
                    }
                    else
                    {
                            printf("%s ", hex_str);
                    }
            }
            printf("(%d bits)", h1[0]+h1[1]*16*16+h1[2]*16*16*16*16+h1[3]*16*16*16*16*16*16);
            printf("\n");

    010 editor对比
    这里写图片描述

    2.8 e_flags

    保存与文件相关的,特定于处理器的标志。
    这里写图片描述
    010 editor对比
    这里写图片描述

    2.9 e_ehsize

    ELF 头部的大小

    这里写图片描述

    010 Editor
    这里写图片描述

    2.10 e_phentsize

    程序头部表格的表项大小。

    这里写图片描述

    010 editor
    这里写图片描述

    2.11 e_phnum

    程序头部表格的表项数目。

    这里写图片描述

    这里就不截010 editor的图了。有软件自己看看吧。

    2.12 e_shentsize

    节区头部表格的表项大小。

    这里写图片描述

    2.13 e_shnum

    节区头部表格的表项数目。可以为 0。

    这里写图片描述

    2.14 e_shstrndx

    节区头部表格中与节区名称字符串表相关的表项的索引。

    这里写图片描述

    3.测试。

    测试 demo 1.so

    自己的程序(有一个小错误已经更改)

    这里写图片描述
    readelf

    这里写图片描述

    看起来还是人家的美观一点,我没有调整对齐。还有显示等。当然我们的重点是理解格式,以及分析内容的准确性。

    测试 demo 2.so

    这里写图片描述

    这里写图片描述

    4. 总结

    总的来说c语言写工具其实也并没有想象中那么难,其实和脚本语言挺相似的,只是处理的方式不同,写程序会让你对大小,以及字节,还有内容进行一个更深层次的了解。

    那么我们的elf head 部分就彻底写完了。

    代码部分,还有其他的东西都会打包起来进行上传。

    0x03 结束语

    之后还有一波对Program Headers的分析,恩,有点啰嗦了不要介意。


    附件说明
    1.word文档一份
    2.测试练习demo,so文件两份
    3.程序源码一份
    4.可执行文件一份

    游客,如果您要查看本帖隐藏内容请回复

    以上

    本帖被以下淘专辑推荐:

    破解的目的是为了更好的开发
    感谢楼主分享
    使用道具 举报 回复
    感谢楼主分享,学习学习。
    使用道具 举报 回复
    支持HAI大的作品
    使用道具 举报 回复
    谢谢分享!好资料!
    使用道具 举报 回复
    看看我有多少魔法笔,我好像不够、、、
    使用道具 举报 回复

    回复就可以赚魔法笔了。
    使用道具 举报 回复
    再回复一个就够了。。。
    使用道具 举报 回复

    再回复一个就够了。。。
    使用道具 举报 回复

    再回复一个就够了。。。
    使用道具 举报 回复

    再回复一个就够了。。。
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册