任务内容
1.学习IDA的使用。结合四个例题学习IDA的静态分析和动态调试。
2.掌握base64编解码原理,使用python编写自定义表的base64编解码脚本
3.阅读书籍《程序员的自我修养》
学习笔记
第一章 温故而知新
1.计算机主要分为硬件和软件,计算机中最核心的三个硬件是CPU,内存,I/O控制芯片。这三个部件的速度不同,计算机的发展一方面为了提升三者各自的速度,同时又更好的加强三者之间协助。发展历程大致分为早期 – 北桥 – 南桥 – 多核。
2.软件分为应用软件和系统软件,系统软件分为平台性的和用于程序开发的,计算机软件体系结构采用一种层的结构,每个层次之间都需要相互通信,则要有协议,这个协议就是接口。下图为计算机软件体系结构:
3.中间层的存在使应用程序和硬件之间保持相对的独立。
4.系统软件一般指的是的一些开发工具,它们都是调用的操作系统应用程序编程接口(API),API的提供者是运行库(简单理解就是一些大佬写好的代码给我等小白使用),什么样的运行库提供什么样的API,比如Linux下的Glibc库提供POSIX的API。运行库使用操作系统提供的系统调用接口(SCI)。
5.操作系统内核层对于硬件层来说是硬件接口的使用者,而硬件是接口的定义者,硬件接口驱动程序如何操作硬件等等,这种接口叫做硬件规格。
任务实现
一、学习IDA的使用,结合四个例题学习IDA的静态分析和动态调试。
1.IDA目录的结构
(1)cfg目录:包含各种配置文件,包括基本IDA配置文件ida.cfg、GUI配置文件idagui.cfg、文本模式用户界面配置文件idatui.cfg。
(2)Idc目录:包含IDA的内置脚本语言IDC所需的核心文件。
(3)Ids目录:包含一些符号文件(IDA语法中的IDS文件),这些文件用于描述可被加载到IDA的二进制文件引用的共享库的内容。
(4)loaders目录:用于包含在文件加载过程中用于识别和解析PE或ELF等已知文件格式的IDA扩展。
(5)plugins目录:包含专门为IDA提供附加功能的IDA模块,也就是我们所说的插件。
(6)procs目录:包含已安装的IDA版本所支持的处理器模块。处理器模块为IDA提供机器语言-汇编语言的转换功能,并负责生成在IDA用户界面中显示的汇编语言。
(7)sig目录:包含IDA在各种模式匹配操作中利用的现有代码的签名。通过模式匹配,IDA能够将代码序列确定为已知的库代码,从而节省大量的分析时间。
(8)til目录:包含一些类型库信息,IDA通过这些信息记录特定于各种编译器库的数据结构的布局。
2.IDA功能界面
1)导航条
IDA主界面中存在一项颜色各异的导航条。通过导航条可了解分析可执行文件各部分数据分布情况。
2)函数窗口
IDA提供函数窗口供用户查找函数信息,在窗口按下“CTRL + F”快捷键便可根据需求搜索函数名,快速定位函数名方式可提供逆向分析效率。
3)主界面窗口
当 IDA 对 Mach-O 解析完成后,会默认出现 6 个选项卡视图,分别是汇编视图,二进制查看视图,结构体视图,枚举类型视图,导入的函数视图,导出的函数视图。
①反汇编窗口“IDA View-A”
反汇编窗口属于逆向分析过程中关注频率最高的窗口,通过此窗口可以逆向分析反汇编代码,移动端中分析频率最高的属于Arm指令集,反汇编窗口属于“IDA View-A”标签项内容。反汇编窗口可分为两种模式,分别为:默认模式和图形模式。
Ⅰ.默认模式:反汇编窗口默认模式属于使用频率很高的常规模式
(这个图是写的helloworld)
(下面是reverse1)
解释一下:
标号1:此处对应名称为sub_140012450,属于IDA使用默认方式标识函数名,默认命名规则为:sub_+函数内存相对偏移。可执行程序部分由大量的函数代码组成,属于代码片段基本组成单位。
标号2:表示反汇编代码对应内存的相对偏移及所属的节段名称,此处需区分内存偏移和文件偏移,IDA以内存偏移的方式加载可执行文件各节段内容。
标号3:表示函数内部的局部代码块,通常以跳转目的地址为规则定义代码块,属于IDA使用默认方式标识函数名。该部分命名规则为:loc _+函数内存相对偏移,通常与跳转操作密切相关。
标号4:表示反汇编文本内容,通过反汇编内容可进行逆向分析。
标号5:对应内容为“; CODE XREF: sub_140012A00+BE↓p”,表示当前代码的交叉引用,对应标号的文本含义为:“sub_140012450”上层调用由“sub_140012A00”函数内部偏移0xBE↓p出调用
Ⅱ.图形模式:反汇编窗口默认模式中按下键盘的“空格”键便转入图形模式,也可通过图形模式界面如下图所示:
(reverse1)
图形界面以单个函数为单位,通过图形界面能够快速的掌握函数内部程序执行过程(对于分析C++的IF跳转语句、循环语句的反汇编代码结构所提供的帮助尤为明显)
A.浅绿色方向线,表示C、C++等编程语言的判断语句为YES所跳转执行流程。
B.红色方向线,表示C、C++等编程语言的判断语句为NO所跳转执行流程。
C.蓝色方向线,表示程序顺序执行过程。
②二进制查看窗口“Hex View-1”
二进制窗口可支持用户查看可执行文件对应相对偏移的二进制机器码数据,二进制查看窗口对应“Hex View-1”选项内容。
二进制查看窗口总共分为三部分,含义分别为:
左边数据:表示二进制数据对应的内存相对偏移。
中间数据:表示内存中数据的具体内容。
右边数据:表示内存数据的字符串显示,该功能可辅助读者快速识别字符串内容。
用户可在二进制查看窗口中编辑二进制数据,从而满足篡改数据的测试需求
③结构窗口
结构窗口提供用户查询已定义的结构体,同时IDA可识别出可执行文件包含的部分结构体数据,结构窗口可通过快捷键“+”、“-”展开和收缩结构体,IDA结构窗口支持用户自定义结构体。
④导入函数窗口
IDA提供导入函数窗口,用于可在导入函数窗口中查看当前可执行文件导入哪些外部函数库及函数,通过导入函数窗口可获取到函数内存相对偏移地址、函数名、导入函数所属的库文件。
⑤导出函数窗口
IDA的导出函数窗口提供可执行文件导出函数信息,通过导出函数窗口可获取到导出的函数名、函数对应的内存相对偏移地址。
3.IDA分析可执行文件
判断IDA分析完毕的方法:
1)IDA的“Output Window”窗口输出“The initial autoanalysis has been finished”日志时,则说明IDA已分析完毕。
2)导航条的进度条处橘黄色向上箭头消失时,则表明IDA分析完毕。
3)IDA界面左下角AU处于”idle”状态时,也表明IDA分析完毕。
4.静态分析:还原源代码
使用 IDA 反汇编二进制文件的目的是,利用工具得到反汇编之后的伪代码,还原出真正的程序源码。
双击左边Function name 到达这个函数在二进制文件中的内存地址,按 F5 可以就查看这个反编译的伪代码。
双击main进入,按esc可以返回上一层,然后F5便可以显示c代码
但是有时候函数多的时候找不到main函数,re的题目通常都没加密字符串
所以用另一种可行办法:alt+T搜索可用的字符串,字符串可以运行程序获得
二、掌握base64编解码原理,使用python编写自定义表的base64编解码脚本
(一)base64编解码原理
1.Base64的由来:传输8Bit字节代码的编码方式之一,在参数传输的过程中经常遇到的一种情况:使用全英文的没问题,但一旦涉及到中文就会出现乱码情况。与此类似,网络上传输的字符并不全是可打印的字符,比如二进制文件、图片等。Base64的出现就是为了解决此问题,它是基于64个可打印的字符来表示二进制的数据的一种方法。
2.Base64的编码原理:每当使用Base64时都会先定义一个类似这样的数组:
[‘A’, ‘B’, ‘C’, … ‘a’, ‘b’, ‘c’, … ‘0’, ‘1’, … ‘+’, ‘/’]这个就是Base64的索引表,字符选用了"A-Z、a-z、0-9、+、/" 64个可打印字符,这是标准的Base64协议规定。在日常使用中还会看到“=”或“==”号出现在Base64的编码结果中,“=”在此是作为填充字符出现。
3.具体转换步骤
第一步,将待转换的字符串每三个字节分为一组,每个字节占8bit,那么共有24个二进制位。
第二步,将上面的24个二进制位每6个一组,共分为4组。
第三步,在每组前面添加两个0,每组由6个变为8个二进制位,总共32个二进制位,即四个字节。
第四步,根据Base64编码对照表(见下图)获得对应的值。
从上面的步骤我们发现:
Base64字符表中的字符原本用6个bit就可以表示,现在前面添加2个0,变为8个bit,会造成一定的浪费。因此,Base64编码之后的文本,要比原文多大约三分之一。
为什么使用3个字节一组呢?因为6和8的最小公倍数为24,三个字节正好24个二进制位,每6个bit位一组,恰好能够分为4组。
4.实例说明
但是如若遇到位数不足的情况:
若需要但没有则用0补充,若是不需要的完全没有数据的则用“=”补上。
5.注意事项:
• 大多数编码都是由字符串转化成二进制的过程,而Base64的编码则是从二进制转换为字符串。与常规恰恰相反,
• Base64编码主要用在传输、存储、表示二进制领域,不能算得上加密,只是无法直接看到明文。也可以通过打乱Base64编码来进行加密。
• 中文有多种编码(比如:utf-8、gb2312、gbk等),不同编码对应Base64编码结果都不一样。
6.延伸:上面Base64是用6位(2的6次幂就是64)表示字符,因此成为Base64。同理,Base32就是用5位,Base16就是用4位。
(二)使用python编写自定义表的base64编解码脚本
引:假如在Unicode中汉字“你”的编码为“u4F60”,把它转换为二进制为100111101100000,然后按照UTF-8的方法进行转换。可以将Unicode二进制从地位往高位取出二进制数字,每次取6位,如上述的二进制就可以分别取出为如下所示的格式,前面按格式填补,不足8位用0填补。
unicode:100111101100000 4F60
utf-8: 11100100,10111101,10100000 E4BDA0
从上面就可以很直观的看出Unicode到UTF-8之间的转换,当然知道了UTF-8的格式后,就可以进行逆运算,就是按照格式把它在二进制中的相应位置上取出,然后在转换就是所得到的Unicode字符了(这个运算可以通过“位移”来完成)。如上述的“你”的转换,由于其值大于0x800小于0x10000,因此可以判断为三字节存储,则最高位需要向右移“12”位再根据三字节格式的最高位为11100000(0xE0)求或(|)就可以得到最高位的值了。同理第二位则是右移“6”位,则还剩下最高位和第二位的二进制值,可以通过与111111(0x3F)求按位于(&)操作,再和11000000(0x80)求或(|)。第三位就不用移位了,只要直接取最后六位(与111111(ox3F)取&),在与11000000(0x80)求或(|)。
代码如下: