史上最全最完整,最详细,软件保护技术-程序脱壳篇-逆向工程学习记录(二)

简介: 史上最全最完整,最详细,软件保护技术-程序脱壳篇-逆向工程学习记录(二)

史上最全最完整,最详细,软件保护技术-程序脱壳篇-逆向工程学习记录(一)

https://developer.aliyun.com/article/1618653



三· 重建IAT输入表(Import Address Table)

1 . 啥是输入表?

在各种不同版本的Windows系统中,DLL的版本各不相同,同一函数在不同版本DLL中的位置也可能不同;另外一个原因在于DLL的重定位,DLL文件的ImageBase值一般为10000000,但当两个DLL尝试装载到同一个地址时会发生冲突,因此有一个DLL得寻找另一个地址装载,这就是所谓的DLL重定位。

因此当我们要调用某个DLL中的函数时,需要借助IAT(Import Address Table,导入地址表)作为中间桥梁。PE文件在装载时由PE装载器将导入函数的真实地址写入到IAT时,函数调用时则需要从IAT中获取函数的真实地址。

对于每一个引入的可执行文件(例如dll),有一个镜像引入描述符(IMAGE_IMPORT_DESCRIPTOR)。
typedef struct _IMAGE_IMPORT_DESCRIPTOR {
     union {
          DWORD Characteristics;         // 0 for terminating null import descriptor
          DWORD OriginalFirstThunk;   // RVA to original unbound IAT (PIMAGE_THUNK_DATA)
     };
     DWORD TimeDateStamp;           // 0 if not bound,
                                                                // -1 if bound, and real date\time stamp
                                                                // in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
                                                                // O.W. date/time stamp of DLL bound to (Old BIND)
      DWORD ForwarderChain;           // -1 if no forwarders
      DWORD Name;                             // RVA,指向字符串,是这个可执行文件的名字。例如"ACE.dll"
      DWORD FirstThunk;                     // RVA to IAT (if bound this IAT has actual addresses)
} IMAGE_IMPORT_DESCRIPTOR;
IAT是一个IMAGE_THUNK_DATA类型的数组。有多少个函数被导入,这个数组就有多少个成员。该数组以0结尾。
typedef struct _IMAGE_THUNK_DATA32 {
     union {
           DWORD ForwarderString;          // 一个RVA地址,指向forwarder string 
           DWORD Function;                       // PDWORD,被导入的函数的入口地址
           DWORD Ordinal;                         // 该函数的序数
           DWORD AddressOfData;           // 一个RVA地址,指向IMAGE_IMPORT_BY_NAME
      } u1;
} IMAGE_THUNK_DATA32;
PIMAGE_IMPORT_BY_NAME是一个非常简单的结构,就两个成员。
typedef struct _IMAGE_IMPORT_BY_NAME {
     WORD Hint;            // 该函数的导出序数
     BYTE Name[1];      // 该函数的名字
} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;

2 . OD跟踪输入表

例程序:

这是个简单的MessgeBoxA对话框程序,用OD打开:

虽然OD注释可以识别到这是MessgeBox,但点开这条指令是call 004011EA,那为什么它知道内存地址0x004011EA地址是一个MessgeBoxA的API函数呢?

那我们就在这行按下回车Enter键:

可以看到这是个跳转,其实周围还很多都是跳转,查看下面按是跳转到哪里:

上面显示的是取[00402048]内存地址里面的值=77D507EA跳转,为了验证一下,我们在内存窗口Ctrl+G输入00402048,就来到了这个地址:

根据小端存储,从右往左读,发现正是77D507EA!

所以我们可以知道在这整个程序无论到在个位置调用MessgeBoxA,它都相当于call 004011EA,在这里集中跳转到MessgeBoxA的动态链接库!

可以看到上面这些都是OD分析给我的,但是OD为什么会知道呢,其实就是根据IAT得出的!

接下来我们继续跟踪输入表,Alt+M到内存双击PE文件头,也就是00400000区块:

然后我们就可以看到标准PE头文件格式: 标志: Image Base:

偏移地址,这是输入表的地址Import Table address:

回到内存窗口,其实输入表所在地差不多就在这个位置:

接下来我们在代码窗口Ctrl+G搜索00402050,我们就来到了这里,但是发现没办法分析,因为它认为我们这不是在代码段:

所以我们要像之前一样安装一个新的插件:

安装好插件后重新打开,就可以点击Analyze This!

可见左边黑色数据是小端存储,右边绿色是OD简化成了我们方便阅读的字节形式,都是相对400000

的偏移地址,可见总共有两个IMAGE_IMPORT_DESCRIPTOR,最后一个全是0是作为结束的标识。我们先尝试Ctrl+G搜第一个参数OriginalFilrstThunk地址00402098:

然后就走到了INT的第一个参数IMACE_THUNK_DATA又是一个偏移地址00402122,继续搜:

可见我们就来到了IMAGE_IMPORT_BY_NAME内,可找到函数的名字(都是由ASCII码转换翻译的)!

然后看到IMAGE_IMPORT_DESCRIPTOR第五个参数FirstThunk,这才是真正指向IAT的偏移地址:

搜索到:

可见其实这就是IAT输入表!

3 . HOOK-API

壳为了防止输入表被还原,强化壳自身的保护功能,会在IAT大量加密。

例如:源程序要调用一个函数的时候需要找IAT,然后却进到了壳程序进行监控般的跳转才能最终回到IAT!


四· FSG压缩壳和ImportREC的使用

程序可以正常运行:

查看壳:

可见这是用Delphi7.0写的程序,API比较多,所以IAT修复比较麻烦!

安装壳程序,点击install.exe,或者自行解压fsg.rar:

给程序FishC加壳,拖拽即可!这是一个压缩壳,压缩44% 加壳后程序也可正常运行!

现在查看壳就可看到壳了:

把加FSG壳后的程序用OD打开:

此时用老方法较为复杂,目前使用一种新方法,步骤如上图1234,选项/调试选项/SFX/字节方式跟踪真正入口处/重新运行!

在这之后,还是回到了原来的地方,然后再带点击选项/调试选项/SFX/停在自解压器的入口/重新运行/,就可以看见左下角在疯狂的运行,这是在模拟程序的运行,自解压:

然后就来到了OEP,接下来就是右键/分析/从模块中删除分析:

接下来就可以dump操作了。由于SFG壳破坏了IAT,所以不要勾选重建输入表,因为勾选了也没用!我们接下来还要借助ImpREC.exe神奇工具修复IAT!

如图,要确保要修改的程序被OD打开中或者与运行中,ImpREC才能检测到,然后根据我们刚才跟踪到了SFX代码真正入口点的地址,提取偏移地址,修改上面红色框起来的OEP,然后点击IAT AutoSearch就弹出一个提示框:

ImportREC会自动搜索所有的IAT!

翻译:好像找到了一些东西,但也有可能不不正确,如果不正确,建议把RAV改成:00001000 Size改成:00094000

接下俩我们就来验证一下,在内存搜索RAV地址,看它是不是IAT的入口点:

就看到这里:

继续往下滑就可以看见熟悉的API函数:

可见00461BEC上面还包含一些数据其实也是,所以我们还要是要把RVA改成:0046B12C,把这些数据包含进去,这才能确保我们的IAT修复的是完整的,才能正常打开程序!

可见IAT最后到了这里:

所以Size也要修改,范围大了可以,范围小了就不可以,只要把全部IAT包含到了就可以!我们修改成大概10000吧

然后我们就可以点击Get Imports按钮了!

加载一会儿,可以看到很多的valid:NO这些就都是不合法的,总共有6642条都是不合法:

所以我们点击Show Invalid按钮把不合法的都展示出来,可见这些不合法的数据穿插在各个IAT里面,只要程序加载到这里的时候,加载不到,就会报错!所以我们右键/Cut thunk(s),把这些不合法的东西全部都给砍掉!

{AF36F00E-F579-4A0C-9764-32251CE916C7}.png

然后就可见我们见到的都是valid:YES的了,然后我们就点击Fix Dump按钮,选择覆盖刚才OD的dump文件:

{9317CEB9-AAAD-42D2-B3B7-C60ACEBC0661}.png

然后它就帮我们多生成了一个文件dump_可以正常运行!

然后再用PEiD查看壳,如果有时候查看不出来 image.png

可以选择选项/深度扫描: image.png

就出来了!也可以观察到,脱壳后的文件变大了!


五 . UPX和WinUpacx压缩壳

UPX官网

UPX壳是目前最流行的,最稳定的壳,更新也较块!

1 . upx309w命令行加\脱壳

image.png

win+R打开控制台,cd到壳程序目录下,upx.exe加壳,后面的才参数是我们待加壳地程序,加壳后可以看到,压缩到了原来的51.93%,大小从582656变成了302592字节!

其实也可以不用命令行,直接拖拽到upx.exe加壳!

然后我们就能查到壳: image.png

然后查阅文档可知,命令加上-d参数,即可脱壳: image.png

如下:

image.png

2 . Free UPX

image.png

点击Add files按钮选择程序,COMPRESS是加壳,DECOMPRESS脱壳,下面的Backup file可以选择create可以创建一个副本,备份原程序!

3 . OD脱UPX壳

OD打开加UPX壳后的fishc程序: image.png

通过堆栈平衡原理寻找OEP过程中,硬件断点来到这里: image.png

由于这是3.09的版本壳,在之前的版本有可能是jmp,但这里jmp在下面,所以我们先取消硬件断点,然后在下面的jmp加断点/运行至此/去掉断点/F8/分析/分析代码,就来到了OEP: image.png image.png

然后dump操作,注意不要勾选重建输入表,接下来我们要用ImportRE恢复!

5 . 使用ImportREC修复IAT

image.png

  1. 先点击小三角选择用OD正在运行的原程序文件
  2. 更具OD找到的OEP,修改ImportREC的OEP里面的偏移地址
  3. 点击IAT AutoSearch按钮确定
  4. 根据给出的RAV偏移地址去OD内存搜索验证,保证输入表没被修改,如果被修改了,就要把RAV的偏移地址调整过来,把IAT包含进去!这里可见上滑上面没有了,是可以的准确的,下面的Size也把IAT包含了,OK image.png
  5. 点击Get Imports按钮,点击Show Invalid按钮,可见没有错误的IAT image.png
  6. 就可以直接Fix Dump选择刚才OD的dumpupx文件了!

6 . WinUpacx壳

该壳压缩效率更高,但已不更新!

image.png

界面中文,比较友好!建议勾选3.清除导出表/4.清除重定位表

然后压缩之后会出现一个文件: image.png 这个文件去掉.bak后缀之后就是我们的原程序备份!

然后OD打开: image.png

入过一开始不是这里,那也可以Alt+M,双击fishc在数据窗口找到偏移地址,即可搜索: image.png

接下来就是根据堆栈平衡寻找OEP: image.png

就可进行dump操作,由于输入表已被破坏所以记得不用勾选重建,重建也是错误的!

然后其实和上一个程序一样操作ImportREC,不多赘述!

然后如果还不满意可以再进行LordPE操作: image.png

最后这就就完美啦!恭喜结业!!!芜湖!!!

相关文章
|
23天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
15天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
19天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2570 22
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
17天前
|
人工智能 IDE 程序员
期盼已久!通义灵码 AI 程序员开启邀测,全流程开发仅用几分钟
在云栖大会上,阿里云云原生应用平台负责人丁宇宣布,「通义灵码」完成全面升级,并正式发布 AI 程序员。
|
1天前
|
存储 人工智能 搜索推荐
数据治理,是时候打破刻板印象了
瓴羊智能数据建设与治理产品Datapin全面升级,可演进扩展的数据架构体系为企业数据治理预留发展空间,推出敏捷版用以解决企业数据量不大但需构建数据的场景问题,基于大模型打造的DataAgent更是为企业用好数据资产提供了便利。
152 2
|
19天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1566 16
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
2天前
|
JSON 自然语言处理 数据管理
阿里云百炼产品月刊【2024年9月】
阿里云百炼产品月刊【2024年9月】,涵盖本月产品和功能发布、活动,应用实践等内容,帮助您快速了解阿里云百炼产品的最新动态。
阿里云百炼产品月刊【2024年9月】
|
21天前
|
编解码 JSON 自然语言处理
通义千问重磅开源Qwen2.5,性能超越Llama
击败Meta,阿里Qwen2.5再登全球开源大模型王座
922 14
|
16天前
|
人工智能 开发框架 Java
重磅发布!AI 驱动的 Java 开发框架:Spring AI Alibaba
随着生成式 AI 的快速发展,基于 AI 开发框架构建 AI 应用的诉求迅速增长,涌现出了包括 LangChain、LlamaIndex 等开发框架,但大部分框架只提供了 Python 语言的实现。但这些开发框架对于国内习惯了 Spring 开发范式的 Java 开发者而言,并非十分友好和丝滑。因此,我们基于 Spring AI 发布并快速演进 Spring AI Alibaba,通过提供一种方便的 API 抽象,帮助 Java 开发者简化 AI 应用的开发。同时,提供了完整的开源配套,包括可观测、网关、消息队列、配置中心等。
693 9
|
15天前
|
存储 监控 调度
云迁移中心CMH:助力企业高效上云实践全解析
随着云计算的发展,企业上云已成为创新发展的关键。然而,企业上云面临诸多挑战,如复杂的应用依赖梳理、成本效益分析等。阿里云推出的云迁移中心(CMH)旨在解决这些问题,提供自动化的系统调研、规划、迁移和割接等功能,简化上云过程。CMH通过评估、准备、迁移和割接四个阶段,帮助企业高效完成数字化转型。未来,CMH将继续提升智能化水平,支持更多行业和复杂环境,助力企业轻松上云。