用户
搜索
  • TA的每日心情
    慵懒
    7 天前
  • 签到天数: 117 天

    连续签到: 2 天

    [LV.6]常住居民II

    i春秋作家

    推荐小组成员

    Rank: 7Rank: 7Rank: 7

    109

    主题

    258

    帖子

    544

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

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

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

    本文章首发于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大的作品
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册