逆向工程之小试牛刀
汇编语言与逆向工程 作业1
解题步骤概要:
对于该题,采用IDA软件对程序进行逆向,分析程序的内在执行逻辑,对关键逻辑进行重点分析,最后根据不同的目的采取不同的方式进行操作,求出flag或达到目的。
解题过程:
1. 使用IDA打开程序“cpp3.exe”文件,双击“Functions window”中的“_main_0”函数,点按空格键,查看该程序执行流程图:
- 分析:观察流程图可以发现,该程序结构可以以循环为主体分为两大部分,所以该程序执行的关键逻辑很可能就在两个循环当中,接下来逐步分析
2. 观察第一个主要代码块,发现这里主要声明了4个局部变量:“var_58”“var_18”“var_14”“var_4”,且从第一个代码块可以看出来“var_58”主要用于存储返回地址。该代码块调用了3个函数:“_printf”“_scanf”“_strlen”,又可以得出,程序会打印字符串“Please give me your answer:\n”并要求我们输入一个字符串并存入变量“var_14”,通过“_strlen”函数获得输入的字符串的长度并存入变量“var_18”。注意这里有一条关键指令“cmp [ebp+var_18], 8”即将所输入的字符串的长度与8作对比,若等于8则进入一个循环,否则不进入循环直接打印“Sorry, you are wrong!\n”,这显然不是我们想要的结果,所以我们输入的字符串即“flag”的长度应该为8:
3. 接下来进入一个循环,很显然这里的变量“var_4”即循环计数器,就相当于for循环中的“i”。显然,程序左侧代码先执行,应该就是映射过程即加密过程,右侧代码即对比过程。若要得到“flag”,则需重点分析加密过程。根据加密过程代码块的指令,得知该代码主要进行了以下操作:
(1)取所输入字符串中的一个字符,对其编码和7Eh进行与运算,即最高位与最低位清零,得到的结果存入edx;
(2)取所输入字符串中的一个字符,对其编码和80h进行与运算,得到的结果存入ecx,再将其值右移7位,再和edx进行或运算,结果存到edx,即取最高位存入原字符编码最低位;
(3)取所输入字符串中的一个字符,对其编码和1进行与运算,得到的结果存入ecx,再将其值左移7位,再和edx进行或运算,结果存到edx,即取最高位存入源字符编码最高位;
(4)将处理后的编码存回“var_14”,再将其与数据“byte_429A38”进行异或运算,最终结果存回“var_14”。这里的“byte_429A38”相当于密钥。
4. 加密过程分析清楚,现在只需要获取密钥和密文的值,即可以破解密文获得“flag”,很显然上一循环中得到密钥变量名称为“byte_429A38”,密文的引用大概率应该在右侧对比过程中,这里找出其名称为“byte_429A30”
5. 分别点击“byte_429A38”,“byte_429A30”获取到两者的值如图:
6. 密文密钥已经获得,接下来编写密码破解程序,这里我使用了Python语言进行脚本编写,破解逻辑为:
(1)先将密文与密钥进行异或运算;
(2)将所得结果最高位和最低位进行交换,交换逻辑和上述汇编语言中的代码逻辑类似。
7. 执行破解逻辑代码,获得“flag”为“TAKEeasy”。
8. 破解成功。
总结:
从逆向过程的复杂性、代码逻辑的复杂性、加密过程的复杂性三个维度进行评价,该题属于较为简单的题型。所用软件主要为逆向静态分析器“IDA”,逆向过程并不复杂。
该题要求求出“flag”,但如果只是要求程序判断输入字符为正确并打印“Congratulations! You are right!”,可直接利用“IDA”或者二进制编辑器“010editor”对相关跳转指令进行打补丁操作,即可实现关键代码逻辑的修改,从而实现程序的破解。
在实际应用中,市面上的一些盗版软件通常利用“打补丁”的方式对程序进行操作,跳过其付费认证的逻辑,从而实现软件破解为免费版。当然,除了直接修改程序中的指令,还可以进行“DLL劫持注入”进行“打补丁”操作。