一、基本流程
一般来说,拿到一个crack_me的时候,先查壳,用PEid查下壳,并看一看有没有 TLS Callback, 入口点有没有被修改啊, 有没有 RWE 权限的区段;再用PEid插件Krypto ANALyzer看一下用没用加密算法,再解决反调试和PE修改问题,(使用strings命令行了解一些程序的基本信息),最后再来分析代码算法。
如果发现不是PE结构,在elf环境下也不能识别,那使用winhex看一下文件特点,有些时候会存在题目程序是PE文件,但是文件格式有一些小的修改,一般是修改DOS头里的固定信息。
二、程序特色分析
(一)如果是C#,且没加壳或者混淆,那就直接祭出Dnspy等,一般就能够进一步分析
(二)简单的.NET程序,可以直接使用ILSpy工具进行分析,在ILSpy中可以看到反编译的源码
(三)如果是MFC程序无壳,需要输入,那就直接下GetWinodowTextA 断点,然后然后回溯来到关键位置。
(四)如果是apk程序,没有外置so库调用,可以在APK改之理中分析MainActivity部分,如果有外置so的分析时,大多数需要进行调试(安卓APK动态调试)。
(五)如果是elf文件,在Kali中使用gdb(带有peda插件)调试
三、核心代码的定位
逆向一般是带有强烈的目的性的,要完成这样的功能就需要定位到具体的函数上。
(一)基本方法
1.如果程序使用了容易搜索出的字符串或者二进制硬编码,可以通过字符串搜索(view->string、智能搜索、strings)或二进制字串搜索(hex面板里寻找)
2.在动态调试的时候,如果了解读写了特定的地址,可以使用硬件读写断点或软件读写断点。
3.分析程序功能,在可能的关键函数API下断点,分析。
关键函数:
GetDlgItemText 得指定输入框输入字符串
GetWindowTextA该函数将指定窗口的标题条文本(如果存在)拷贝到一个缓存区内。
MessageBox显示一信息对话框
ReadFile 从文件中读出数据
(二)动静态结合
一些程序并没有打开ASLR,也就是说在OD(或GDB)动态与IDA静态中的地址是一样的,可以在IDA中了解程序框架后,获取关键地址后直接在OD中跳转到对应位置。即使存在地址随机化,可以关键函数处下断点,再跳转,获取之后两者比对。
注:在一些程序中会出现自修改代码的环节,而这些部分可能是通过多进程信息交互修改内存data,或者通过加密解密对一块data修改后再跳转到,又或者将一些可见函数的操作进行修改。针对最后一种方式,当我们遇到一些执行关键函数的交叉引用中既有data xref和code xref,那有可能存在自修改的情况。(验证最好就是在OD对应位置下一个断点然后运行至断点,如果流程经过那里就会停止,也就验证了自修改假设)
四、加密逆推思路
(一)对于一些加密的动作,是对一位一位字符进行分析,如果是一一隐射,可以考虑在其中输入所有可输入的字符,就可以得到字符与转换后的一张对应表;即使不是一一隐射,也是可以遍历可见字符(0x20,0x7E)来比对一位位爆破。把握关键函数段,如验证,比对等,向前向后分析主体。
(二)加密的动作运用到了现代密码学的密码的时候,需要熟悉密码的特点;常见的有如DES,AES,RSA,RC4加密函数。
五、未知函数功能识别
先识别出函数的返回值, 形参个数,形参, 局部变量;函数一般是使用 eax 寄存器来保存返回值.但有一些编译器可能用其他的方式来传递返回值,注意32位与64位的不一样。
(一)如果函数不复杂的话可以直接还原函数操作
(二)函数比较复杂,不清楚具体操作,可以使用动态调试,观察结果的形式猜测函数的操作是什么,比如base64的操作,可以从结果中的‘==’发现一些可能性,或者strlen的变形函数,运行之后eax变成了输入串的长度,这些都可以这样猜测出来。
(三)函数操作元的识别,IDA能够识别一些函数并显示函数名主要是使用了symbol,巧妙使用symbol可以提高函数识别的能力,(如果是因为没有正确使用symbol文件的话,可以在IDA中进行设置,设置方式:File -> Load File -> FLIRT signature file)同时我们也可以自己写一些IDC或者idapython脚本来通过一些标记(如字符串,移位次数)实现函数识别。观察函数中的报错字符串信息或者函数中调用的一些简单系统函数,或者比照一些常见的代码段,猜测可能满足的功能设定或者进行的一些修改。
(四)如果以上几种方法不能实现,则只能考虑手动分析;可以参考文章,增加对代码的认识。要在分析中去除程序中的干扰代码(多余函数封装,花指令,可以求值的代码)。
六、寻找学习平台
看雪学院、吾爱破解
书籍:《加密与解密》