CRACKME 3:来源于《逆向工程核心原理 第八章》

前言:算是第一次正规的逆向了吧,该程序用vba语言编写,逆向其算法。怎么说呢,这个程序逆向了大概三天,这三天考了三门期末,本来对期末真没有以前那种热情,该水水就水水,考完回来继续分析这个程序,在这上面的时间三天至少花了20个小时,从一开始一脸蒙蔽一窍不通到基本逆向出其算法和vba函数的作用,可以说是值得的,下面就总结一下自己的收获:

一、逆向前的准备工作:

  1. 了解其是什么语言编写,然后去查该语言的逆向心得。比如,我这次是逆向 vba程序,其显著特点是一个变量占12个字节,前2个字节特征,后面4个字节才是真正的值。我刚开始晚上完全不懂,真的很蒙蔽,怎么弄怎么不对。第二天早上才有灵感一查才知道,还发现了前两个字节的特征,比如,是整数,则为0002,这是一定要吸取的教训。

二、逆向过程中的心得:

  1. 逆向的核心是搞懂函数作用+栈帧的分布:着重强调栈帧,这个可以说四个小时前我还一脸蒙蔽,睡觉前忽然才想起这个,真是,基础不牢,地动山摇啊。所有的局部变量都存储在栈帧中。我们之前着重分析函数,太多函数,各种寄存器绕的头晕,其实,寄存器只是一个中转站,最终还是存储在栈帧中,所以,我们弄清每一个栈帧具体表示的变量,之后看汇编代码会轻松很多。就算一个栈帧可能有多个情况,我们只需要在代码调用前查看其是哪种情况就好
  2. 函数分析
    1. 若OD中给出函数名,则先百度该函数名了解其作用。
    2. 获取参数,看函数调用前的栈帧。
    3. 少数函数通过寄存器传入参数,比如 __vbavarForInit 中 n 值通过 ebx 传入,而 __vbavarMove则是 edx->ecx,这些都是你应该要注意的。
    4. 了解传入的是地址还是指针,往往前面有 lea,则是指针,确切的办法是一个个参数浏览一遍。
    5. 调试函数时,多注意对比内存地址变化,有些传入的指针就是函数结构的存储地址,观察。
  3. 未来学习方向
    1. 先学好 OD 中的条件断点,比如某个内存改变,就断下来,这语法其实在调试过程中真的很方便,肉眼看真难受。
    2. 开始学 WINDOWS 的 PE结构,这是你需要明确的。

函数分析以及加密过程:

  1. 使用 vbaI4Var 将 i 的值 获取到寄存器 eax 中
  2. 利用存储在 eax中的 i 通过 rtcMidCharVar 获取 字符串特定的个字符(整个字符串存放在 [ebp-74])
  3. 通过 __vbaStrVarVal 函数获取该字符的ASCII码的内存地址 (直接指向该字符而不是字符变量)
  4. 通过 rtcAnsiValueBstr 获取该 ASCII码 值并保存在 eax 中(eax 直接存储着这个码)
  5. 通过 vbaVarAdd 函数实现 字符的ASCII码与 加密因子 64 相加
  6. 通过 rtcHexVarFromVar 来将计算结果转换为 UNICODE 形式
  7. 通过 _vbaBarCat 来将字符串连接在一起
    以上进行四次退出循环:
    得到的秘钥与用户的输入进行比较判断是否成立。

特征:

  1. 00000002 整数类型
  2. 00360008 字符串?字符? 指针类型

栈帧:
ebp - 24 整数 保存变量 i 的
ebp - 34 输入的密码 UNICODE形式
ebp - 44 指针 保存每次计算的UNICODE结果,A8" 第二次 “A8C9”,第三次 “A8C9DA”,最后用于比较
ebp - 74 指针 保存的字符串“Deverse”,
ebp - 54 指针 保存从 [ebp-0xac]获取的单个字符
整数 保存从 ebp - 9c 过来的add计算结果
ebp - 9c 整数 保存add的计算结果
指针 保存 add 计算结果的UNICODE 形式
指针 暂时保存CAT连接结果,最后送到 ebp-44
ebp - 0xac 整数 1. 保存每次获取的字符值 “D”、“e”、“v”、“e"的ASCII值
指针 2. 保存字符粘贴结果 即第一次 “A8” 第二次 “A8C9”,第三次 “A8C9DA”
ebp - DC 整数 保存加密因子 64
ebp - 134 整数 保存 i = i+t 的 t
ebp - 144 整数 保存 变量 n

Python 写的注册机:其实可以看出算法真的不难,但自己这水平,逆向起来就是另外一回事了。

strr = input("输入用户名")

i = 0
ans = ""
while i<4 :
    ans += str(hex(ord(strr[i])+0x64))
    i += 1

ans = ans.replace("0x", '').upper()
print(ans)

你可能感兴趣的:(CrackMe分析)