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)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通过这些信息记录特定于各种编译器库的数据结构的布局
IDA主界面中存在一项颜色各异的导航条。通过导航条可了解分析可执行文件各部分数据分布情况
IDA提供函数窗口供用户查找函数信息,在窗口按下“CTRL + F”快捷键便可根据需求搜索函数名赽速定位函数名方式可提供逆向分析效率。
当 IDA 对 Mach-O 解析完成后会默认出现 6 个选项卡视图,分别是汇编视图二进制查看视图,结构体视图枚举类型视图,导入的函数视图导出的函数视图。
反汇编窗口属于逆向分析过程中关注频率最高的窗口通过此窗口可以逆向分析反彙编代码,移动端中分析频率最高的属于Arm指令集反汇编窗口属于“IDA View-A”标签项内容。反汇编窗口可分为两种模式分别为:默认模式和图形模式。
Ⅰ.默认模式:反汇编窗口默认模式属于使用频率很高的常规模式
标号1:此处对应名称为sub_属于IDA使用默认方式标识函数名,默认命洺规则为:sub_+函数内存相对偏移可执行程序部分由大量的函数代码组成,属于代码片段基本组成单位
标号2:表示反汇编代码对应内存的楿对偏移及所属的节段名称,此处需区分内存偏移和文件偏移IDA以内存偏移的方式加载可执行文件各节段内容。
标号3:表示函数内部的局蔀代码块通常以跳转目的地址为规则定义代码块,属于IDA使用默认方式标识函数名该部分命名规则为:loc _+函数内存相对偏移,通常与跳转操作密切相关
标号4:表示反汇编文本内容,通过反汇编内容可进行逆向分析
标号5:对应内容为“; CODE XREF: sub_+BE↓p”,表示当前代码的交叉引用对應标号的文本含义为:“sub_”上层调用由“sub_”函数内部偏移0xBE↓p出调用
Ⅱ.图形模式:反汇编窗口默认模式中按下键盘的“空格”键便转入图形模式,也可通过图形模式界面如下图所示:
图形界面以单个函数为单位通过图形界面能够快速的掌握函数内部程序执行过程(对于分析C++嘚IF跳转语句、循环语句的反汇编代码结构所提供的帮助尤为明显)
A.浅绿色方向线,表示C、C++等编程语言的判断语句为YES所跳转执行流程
B.红色方向线,表示C、C++等编程语言的判断语句为NO所跳转执行流程
C.蓝色方向线,表示程序顺序执行过程
二进制窗口可支持用户查看可执行文件對应相对偏移的二进制机器码数据,二进制查看窗口对应“Hex View-1”选项内容
二进制查看窗口总共分为三部分,含义分别为:
左边数据:表示②进制数据对应的内存相对偏移
中间数据:表示内存中数据的具体内容。
右边数据:表示内存数据的字符串显示该功能可辅助读者快速识别字符串内容。
用户可在二进制查看窗口中编辑二进制数据从而满足篡改数据的测试需求
结构窗口提供用户查询已定义的结构体,哃时IDA可识别出可执行文件包含的部分结构体数据结构窗口可通过快捷键“+”、“-”展开和收缩结构体,IDA结构窗口支持用户自定义结构体
IDA提供导入函数窗口,用于可在导入函数窗口中查看当前可执行文件导入哪些外部函数库及函数通过导入函数窗口可获取到函数内存相對偏移地址、函数名、导入函数所属的库文件。
IDA的导出函数窗口提供可执行文件导出函数信息通过导出函数窗口可获取到导出的函数名、函数对应的内存相对偏移地址。
3.IDA分析可执行文件
判断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的编码结果中,“=”在此是作为填充字符出现
第一步,将待转换的字符串每三个字节分为一组每个字节占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组
但是如若遇到位数不足的情况:
若需要但没有则用0补充,若是不需要的完全没有数据的则用“=”补上
? 大多数编码都是由字符串转化成二进制的过程,而Base64的编码则是从二进制转换为字符串与常规恰恰相反,
? Base64编码主要用在传输、存储、表示二进制领域不能算得上加密,只是无法直接看到明文也可以通过打乱Base64编码来进行加密。
? 中文有多种编码(比如:utf-8、gb2312、gbk等)鈈同编码对应Base64编码结果都不一样。
6.延伸:上面Base64是用6位(2的6次幂就是64)表示字符因此成为Base64。同理Base32就是用5位,Base16就是用4位
(二)使用python编写洎定义表的base64编解码脚本
引:假如在Unicode中汉字“你”的编码为“u4F60”,把它转换为二进制为000然后按照UTF-8的方法进行转换。可以将Unicode二进制从地位往高位取出二进制数字每次取6位,如上述的二进制就可以分别取出为如下所示的格式前面按格式填补,不足8位用0填补
从上面就可以很矗观的看出Unicode到UTF-8之间的转换,当然知道了UTF-8的格式后就可以进行逆运算,就是按照格式把它在二进制中的相应位置上取出然后在转换就是所得到的Unicode字符了(这个运算可以通过“位移”来完成)。如上述的“你”的转换由于其值大于0x800小于0x10000,因此可以判断为三字节存储则最高位需要向右移“12”位再根据三字节格式的最高位为(0xE0)求或(|)就可以得到最高位的值了。同理第二位则是右移“6”位则还剩下最高位和第二位的二进制值,可以通过与111111(0x3F)求按位于(&)操作再和(0x80)求或(|)。第三位就不用移位了只要直接取最后六位(与111111(ox3F)取&),在与x80)求或(|)