• 脱壳实践之手动构造输入表


    0x00 前言

      对于脱壳后的程序往往不能直接运行,这是因为它们很多都没有重建输入表。当然用的od脱壳可能可以。重建输入表一般都是用专业软件比如ImportREC。但是对于逆向研究者来说会自己重讲输入表是必须的技能。这就需要读者对前面几篇所讲的PE文件格式非常熟悉。

    0x01 寻找OEP脱壳脱壳

      前面已经提到对于区段信息全都已经改的面目全非的加壳程序,用两次内存断点法是无法找到OEP地址的,比如今天我们用的这个程序,下图为它的区段信息:

     上图可知我们根本无法知晓哪个区段存放数据,哪个区段存放代码。这种情况下用两次断点法难免会失效。因此我们应该采用堆栈平衡法来寻找OEP地址。这里步骤就省去了,毕竟今天的主题是构造输入表,有兴趣了解堆栈平衡法的可以去我的博客按标题查看。下图为找的OEP地址:

    既然找到了OEP地址,就直接使用OD来脱壳了。点击插件的ollydump,把重建输入表去掉,毕竟这个是我们接下来的工作。如下图:

      0x02 手动重建输入表

      思路:找到被调用的api函数——》将DLL函数和api函数写入脱壳后的文件的空白区域——》空白区域重写IMAGE_THUNK_DATA数组——》空白区域重写IID数组——》将IID数组地址写入数据目录表第二项。

     重建之前我们先来看看脱壳后的程序的输入表,如下图:

     明显看出这个输入表已经紊乱了。接下来我们一步步重建它。

    1)我们先用没有加壳的原程序来看看他调用了哪些函数(一定要用没有加壳的,加了壳的调用的函数会很不同)。见下图:

    上图可知共调用了四个个函数KERNEL32.DLL调用了ExitProcessCreateFileAUSER32.DLL调用了MessageBoxA

    2)将输入DLL以及被调用的函数写入脱壳后程序的空白区域

    此表是DLL已经函数写入的地址(这里的地址都是高低位互换的便易在hexworkshop中读写)

    DLL名及DLL地址

    函数名及函数地址

    KERNEL32.DLL

    0016 0000

    ExitProcess

    1a16 0000

    CreateFileA

    2816 0000

    USER32.DLL

    0d16 0000

    MessageBoxA

    3616 0000

     

     

    PSDLL之间应该有一个字符空隙,DLLAPI函数,API函数与API函数之间应该有三个字符间隙,因为前面API函数前面个两个字节是预留给IMAGE_IMPORT_BY_NAMEHint字段多余的一个作为间隙)

    3)在空白区域构造IMAGE_THUNK_DATA数组。

      构造IMAGE_THUNK_DATA数组起始位置16b0

    第一个IID数组的IMAGE_THUNK_DATA数组

    1a16 0000-2=1816(16b0)

    28160000-2=2616 (16b4)

    第二个IID数组的IAMGE_THUNK_DATA数组

    3616 0000-2=3416(16BC)

    构造完成之后如下图:

    IID数组之间预留四个字节的间隙

    4)构造IID数组

    另找一块空白区域,我们这里选用1760处。

    构造IID数组位置:1760

    DLL名称

    OriginalFristThunk

    TimaStamp

    ForwordChian

    Name

    FristThunk

    KERNEL32.DLL

    B016 0000

    0000 0000

    0000 0000

    0016 0000

    B016 0000

    USER32.DLL

    Bc16 0000

    0000 0000

    0000 0000

    0d16 0000

    Bc16 0000

    结束标志

    0000 0000

    0000 0000

    0000 0000

    0000 0000

    0000 0000

    构造后如下图:

    5)将数据目录表的第二项改成IID的地址1760,后面四个字节写入IID数组大小28,如下图:

     至此手动构造完毕,保存文件。

    0x03 检验构造的输入表是否起作用。

    我们用LordPE打开保存后的文件,点击目录信息,再点击输入表即可查看信息,如下图:

     

     很明显,我们手动构造的输入表已经起作用了。

     0x04 总结

    虽然手动构造输入表成功了,但是我发现脱壳后的程序并不能正常运行,这两天一直在思考其中的缘由,如果有幸哪位大佬看到这篇文章请留言指导一二。

  • 相关阅读:
    类名+函数名(参数1,参数2.....){.......return this;}
    报错!无法从静态上下文中引用非静态 变量
    ERROR无法从静态上下文中引用非静态变量
    字符编码笔记:ASCII,Unicode和UTF-8
    MySQL其他类型常用函数
    MySQL流程函数
    MySQL日期和时间函数
    MySQL数值函数
    MySQL字符串函数
    MySQL位运算符优先级
  • 原文地址:https://www.cnblogs.com/2f28/p/9870848.html
Copyright © 2020-2023  润新知