内容简介:分析文件是exe格式,附带一个dll链接文件。要求得到解密后的三个key,exe主程序负责key1的解密,dll文件负责key2和key3的解密。文件可以在链接处下载(链接:
*文章原创作者:mintancy,本文属于FreeBuf原创奖励计划,未经许可禁止转载
背景
萌新第一次学习逆向,所以在这里也算总结和记录,如有错误之处还请指出。
分析文件是exe格式,附带一个dll链接文件。要求得到解密后的三个key,exe主程序负责key1的解密,dll文件负责key2和key3的解密。文件可以在链接处下载(链接: https://pan.baidu.com/s/1eS22yH0 密码:wtne)。
使用工具
ida(V6.8,吾爱破解网站下载)静态分析+ollydbg(V1.10,官网下载)动态分析。
运行环境
本人是mac系统,然后安装了虚拟机:vmware+windows xp sp3。
那么,我们进入正题吧。
一、ida静态分析
将程序crackme.exe在ida中打开,可以看到对应的汇编语言。
然后看到左侧列表有个main函数,直接双击,找到汇编程序的main入口处,f2加断点高亮显示:
此时,可以直接在高亮处按F5反汇编得到对应的C代码:
代码前面部分就是各种初始化,变量声明之类的,没什么特别。继续往下看,看到”&unk_40FA58″看起来是调用了数据段的某个地址的内容,于是双击看看是什么:
哟,很明显的字符串,会不会是key1呢?于是输入key1,显示错误。然后继续看看程序中使用这串字符串的位置:
可以看到,在程序找到字符串之后,接下来就是具体的解密部分,其实可以看到很明显的一句汇编语言:
.text:00401128 dec edi
寄存器edi中存储的是加密字符,执行的计算是减一,也可以理解是向前移位的计算。
到这一步,再打开ollydbg进行动态分析,验证自己的猜想。其实直接分析汇编语言也可以得到答案,只不过觉得执行程序得到结果更形象。
二、od动态分析
在之前还是简单地介绍一下od的界面和在之后用到的界面(其实也就是常用的几个界面):
汇编代码窗口和寄存器窗口是两个常用窗口,一个确定程序运行到了哪一步,一个确定需要的内容在内存的存储位置。
对照在ida找到的main函数,直接右键选择“Go To”跳到main函数位置设置断点(在没有ida静态分析不知道主函数位置的网上有各种方法):
然后反复调试程序设置合适的断点,可以确定汇编代码的功能并得到计算后的字符串:
这一段代码很短,可以一步一步调试(F7),然后注意oa右边的寄存器窗口,截图中解释的地址就是根据相应寄存器存储内容确定的。
解密算法执行结束之后到内存地址窗口找到存储解密字符串的位置[00393F68],可以看到一串熟悉的字符串亲切地躺在这里:
此时不太确定是不是key1,然后到程序上输入:
YEAH!!第一个key1找到啦!萌新特别开心!
然后一鼓作气,继续解决key2和key3。这个时候有点陷入汇编代码的茫茫大海中,直接在od中使用f7动态调试,没有再对照ida中的代码。本意是想分析一下后面的执行顺序,看看内存的变化。
f7太慢,然后又按f8。结果执行又太快,还没注意到具体解密算法,就看到右下角栈区域出现了一个疑似key的字符串。找到对应的内存位置,上下滚动一下发现有两个字符串:
然后拿到程序中试试:
踏破铁鞋无觅处,得来全不费工夫啊!
但是,本着认真学习的态度,我决定再回过头看看解密这两个字符串使用了什么算法。
od使用 alt+f2 重新载入程序。
三、再次分析
记住key2在内存中的写入位置:003B3D78,然后重新载入程序,设置内存写入断点,看看是什么时候在经历了什么步骤之后写入的。结果发现并没有这个位置,有可能是载入动态链接库之后才赋予的地址:
继续分析c代码,发现忽略了这两个地址引用:
就按照上一个key的方法再次找到汇编语言中使用这两字符串的地方:
同理在od中定位到[0040123D]然后继续在od中F8动态调试,找到合适的断点:
进入key2解密函数,此时已载入动态链接库。再查找内存地址003B3D78,出现了该地址内容。可以看到该内存地址还没有被初始化,在此位置设置内存写入断点(关于设置内存写入断点的细节可以参见链接: http://bbs.pediy.com/thread-187118.htm ):
然后F9执行之后在一行代码停下,可以看到此时key已经开始写入:
此时再使用f7可以单步执行溯源找到解密算法:
可得:key2的解密是让字符串与77进行亦或(xor)运算。
同理得到key3的解密算法,key3的内存写入地址是003B3DC0:
key3的解密是让字符串和0F做与运算然后左移4位。
四、一鼓作气
等等!你以为这样就结束了吗?!别走,快回来!
并没有,让我们再回过头来看看主程序的代码:
看到这个sub_401000()木有?程序调用了动态库的decode函数对字符串解密得到了key2和key3,也就是v21和v23,v24、v26分别是用户输入的key2和key3。然后它们分别经过sub_401000()函数的洗礼(加密),来看看这个函数到底在干什么:
没办法,萌新看到这一串 C语言 就觉得头疼,还是使用oa调试看看吧。这段代码可以当作是再次加密,同时将加密后字符串存入[003929A0]开头的地址中:
这段代码中,需要理解的就是imul操作符及后面的代码对字符进行的操作。在这里使用了IMUL单操作数的使用方法:
imul AL;
意思就是:
AL=AL*AL;
而后面的IMUL CL意思是:
AL=AL*CL;
综上对单个字符的操作描述为:取字符的十六进制数(寄存器EAX低八位即AL),平方后取低八位结果(存入AL中),用这结果再加上循环次数(CL)的平方得到加密字符存入BL中,再写入内存。
用 python 语言表示为:
#在寄存器中字符用16进制表示,在这里假设字符a也用16进制表示; #计数君ECX低八位CL用t表示: a = int(‘a’, 16); //计算的时候将a转化为10进制数 a = a * a; //自乘得到结果 a = hex(a – (a/255*255)); //取乘法结果的低八位再转化为16进制数 a = a +hex( ‘t*t’); //然后再与循环次数的平方相加得到最后结果
所以最后的结论就是,将存储在程序中的key2和key3解密并加密得到key22和key33,然后用户输入usr_key2和usr_key3用同样的加密算法加密得到usr_key22和usr_key33。最后比较key22和usr_key22,key33和usr_key33是否相等。
用户输入前程序做了什么:
1. key1向前移一位解密得key11。
程序输入key之后程序做了什么:
1. 输入usr_key1正确之后生成中间dll文件,程序载入两个dll文件; 2. key2与77做XOR运算再加密得key22; 3. key3与0F做AND运算然后左移4位再加密得key33; 4. 用户输入usr_key2,usr_key3; 5. usr_key2加密得usr_key22,usr_key3加密得usr_key33 6. if (key22 == usr_key22 && key33 == usr_key33),you win!
分析结束,撒花撒花~~
*文章原创作者:mintancy,本文属于FreeBuf原创奖励计划,未经许可禁止转载
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- Git入门操作(一)
- Scala入门reduce操作
- Tensorflow基础入门十大操作总结
- 一文带你入门操作系统
- Elasticsearch入门教程:索引和文档操作
- Zookeeper入门实战(3)-Curator操作Zookeeper
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Black Box Society
Frank Pasquale / Harvard University Press / 2015-1-5 / USD 35.00
Every day, corporations are connecting the dots about our personal behavior—silently scrutinizing clues left behind by our work habits and Internet use. The data compiled and portraits created are inc......一起来看看 《The Black Box Society》 这本书的介绍吧!