吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2454|回复: 11
收起左侧

[原创] 练习笔记之160Crackme-013

[复制链接]
xiaoyu2032 发表于 2022-5-10 23:04
本帖最后由 xiaoyu2032 于 2022-5-10 23:15 编辑

160CM-013

  012的编程语言太古老,大概了解了一下,以我的能力肯定搞不定,直接跳过……

1.追码

  这是一个二合一的题,有两个CrackMe,一个只需要输入序列号,另一个要输入名字和序列号。

2

2
  PE先看看,无壳,VB,还是先用VB Decompiler看看(这里推荐V11以上的版本,反编译后可以直接预览Form控件,方便识别按钮)。

10

10

  由于不同界面有些按钮使用了相同的名字,所以需要稍微看一下按钮对应的事件的代码,才能识别出各个按钮对应的事件。如下

11

11

  查看按钮Command4对应的事件代码,发现事件函数入口地址为4052AC,可是代码起始地址是4051DA,比函数入口地址还小?OD打开Ctrl+G跳转到4052AC,呃……都不是汇编代码。。。

3

3

  搜索一顿后才搞明白,原来这是VB的P-Code编译代码,这个一个解释型的代码,执行的时候是将代码数据加载到相应的函数中进行解释后再执行,因此在OD中对应的代码位置下断是断不下来的。
  死马当活马医,既然是VB的,那试试OD中的VB断点吧,最常用的字符比较断点,先试了下“_vbaStrCmp”,发现断不下来;再试试“__vbaStrComp”,发现运气不错,断了下来。这个时候在堆栈区,可以发现有几个UniCode的字符串,一个是“try again”,一个数字字符串,输入到输入框中,注册成功。
  切换到CrackMe 2.0,输入用户名,点击try按钮后,同样可以断下来,在堆栈区可以发现一个“xxxx-xxxxxx”的字符串,输入进去,注册成功。
  这个程序里面因为没有字符串加密,直接明码比较的,而且比较函数也是VB标准函数,因此侥幸能追到注册码,如果字符串加个密再比较或者用自写的函数进行比较,就没法这样追到注册码了。

2.爆破

  P-Code编译的程序,用OD基本没办法跟踪,因此不能用跟踪爆破法(P-code程序也有动态调试工具WKTVBDebugger,这个要win2000下才能运行,没有尝试过)。但是因为是P-Code,可以反编译得到VB代码,可以很方便的读懂程序逻辑,因此不需要动态分析,静态分析就能找到关键跳转,因此只要知道怎么修改跳转指令就可以了。
  我们先看CrackMe 1.0中的事件函数,“loc_4051DA: If (Me.Text3.Text = Me.Label3.Caption) Then”这一行是关键判断,在VB Decompiler的反汇编代码中找到地址4051DA位置,发现是“BranchF loc_405295”,这个跳转刚好跳过“Congratulation!”字符串代码区,进入“Try Again!”字符串代码区,因此我们只需要想办法修改这个跳转就可以。

9

9
  OD中打开程序,找到4051DA位置,发现内容是“1C F5”(由于这些代码是P-code代码,反汇编识别出来的都是错误信息),但是要怎么改呢?不用慌,前人已经给我们总结了P-code机器码的特点,如下:
p-code里面转向语句一共有三个:
Branch (1E) ---- 无条件跳转
BranchT(1D) ---- 栈顶数据为真则跳转
BranchF(1C) ---- 栈顶数据为假则跳转
  因此,我们只需要二进制修改将“1C”改成“1D”就可以了。

1

1

  同样,CrackMe 2.0中也可以找到关键跳转在405815位置,内容为“1C 09”,同样将“1C”改成“1D”就可以了。

7

7

3.算法

  由于有VB Decompiler的帮助,算法逆向过程应该不难。不过自己水平比较菜,中间还是踩了不少坑。
  先看CrackMe 1.0,前面已经找到事件函数对应Command4_Click,可以发现比较的内容为输入字符串和Label3的内容。

  Label3里有啥?我们把所有的事件函数找一遍,发现只有Combo1和Command4事件中对这个控件有赋值,Combo1中的代码如下:

4

4
  完整算法为

loc_4053DB: var_1D0 = CStr((((CLng((((Day(Now) * Day(23)) + (Month(Now) * Month(2))) + (Year(Now) * Year(3)))) + CLng((((Day(Now) * Day(23)) + (Month(Now) * Month(2))) + (Year(Now) * Year(3))))) + CLng((Day(14) * Year(2020)))) + CLng((Day(14) * Year(2020)))))

  算法理解起来不难,就是获取当前时间的年月日和某个数值对应的年月日相乘相加等等。因为VB没学过,这几个函数一看EXCEL里面好像都有,于是在EXCEL中列了个公式计算了一下,其中day(23)在EXCEL中计算值为23……
  算出一个值来填进去一试,发现不对(和之前追码得到的字符串对不上)。前后一阵查找,死活没找到问题在哪里,然后看了一下别人的破解教程,发现在VB中,day(23)=22。呃,,,都是微软同一家的东西为什么还搞出来不一样呢?
  没办法,硬着头皮搞搞VB吧,VS 2012中创建一个VB控制台项目,把算法代码弄进去,一编译,发现day函数等都无法识别,难不成还要装个VB6.0才能愉快的玩耍?
  最终,经过反复搜索,各种尝试,终于把算法代码撸出来了。

Dim day_now, day_23, month_now, month_2, year_now, year_3, day_14, year_2020, code As Integer

day_now = Now.Day
day_23 = Date.FromOADate(23).Day
month_now = Now.Month
month_2 = Date.FromOADate(2).Month
year_now = Now.Year
year_3 = Date.FromOADate(3).Year
day_14 = Date.FromOADate(14).Day
year_2020 = Date.FromOADate(2020).Year
code = (day_now * day_23 + month_now * month_2 + year_now * year_3) + (day_now * day_23 + month_now * month_2 + year_now * year_3) + (day_14 * year_2020) + (day_14 * year_2020)
MsgBox("注册码为:" & code)

  再看CrackMe 2.0,反编译出来的代码如下:

Private Sub Command2_Click() '4058EC
  'Data Table: 403D90
  Dim var_90 As Long
  Dim var_1CC As Variant
  loc_4055EE: If (Len(Me.Text1.Text) < 5) Then
  loc_4055FE:   Me.Text2.Text = "At least 5 characters!"
  loc_405606:   Exit Sub
  loc_405607: End If
  loc_40560A: var_94 = "0110617121214051216101106141404110614140411091211100810101608040610121608100416"
  loc_405622: var_98 = Me.Text1.Text
  loc_40562D: var_A8 = 1 'Variant
  loc_405641: For var_108 = 4 To CVar(Len(var_98)): var_C8 = var_108 'Variant
  loc_405698:   var_90 = CLng((CDbl(var_90) + (CDbl(Asc(Mid$(var_98, CLng(var_C8), 1))) * Val(Mid$(var_94, CLng((var_A8 * 3)), 3)))))
  loc_4056C4:   If ((var_A8 + 1) >= 39) Then
  loc_4056CC:     var_A8 = 0 'Variant
  loc_4056D0:   End If
  loc_4056D3: Next var_108 'Variant
  loc_4056DE: var_A8 = 1 'Variant
  loc_4056F2: For var_168 = 4 To CVar(Len(var_98)): var_C8 = var_168 'Variant
  loc_405764:   var_1CC = CVar((CDbl((Asc(Mid$(var_98, CLng(var_C8), 1)) * Asc(Mid$(var_98, CLng((var_C8 - 1)), 1)))) * Val(Mid$(var_94, CLng((var_A8 * 2)), 2)))) 'Double
  loc_40576C:   var_178 = (var_178 + var_1CC) 'Variant
  loc_40579D:   If ((var_A8 + 1) >= 39) Then
  loc_4057A5:     var_A8 = 0 'Variant
  loc_4057A9:   End If
  loc_4057AC: Next var_168 'Variant
  loc_405815: If (Me.Text2.Text = LTrim$(Str$(var_90)) & "-" & LTrim$(Str$(var_178))) Then
  loc_405824:   Me.Command2.Visible = False
  loc_405838:   Me.Command1.Visible = False
  loc_40584C:   Me.Command5.Visible = True
  loc_405860:   Me.Command3.Visible = False
  loc_405874:   Me.Text2.Visible = False
  loc_405888:   Me.Frame3.Visible = True
  loc_4058BD:   Me.Label3.Caption = "Congratulation " & Me.Text1.Text & " !"
  loc_4058D2:   GoTo loc_4058EA
  loc_4058D5: End If
  loc_4058E2: Me.Text2.Text = "Try Again!"
  loc_4058EA: ' Referenced from: 4058D2
  loc_4058EA: Exit Sub
End Sub

  上述算法不难理解,主要过程就是输入的字符串取字符经过某些运算得到新的字符串,然后进行拼接得到注册码。这里比较容易有问题的是,VB Decompiler的反编译代码不完整,其中漏掉了部分var_A8的计算代码,因此按上述代码计算得到的注册码是不正确的。这个时候就需要去掉“程序分析器和优化器”选项后重新发编译,可以看到在for循环中var_A8有个+1的计算过程。
  最终的算法代码如下:

Module Module1

    Sub Main()

        Dim day_now, day_23, month_now, month_2, year_now, year_3, day_14, year_2020, code As Integer
        day_now = Now.Day
        day_23 = Date.FromOADate(23).Day
        month_now = Now.Month
        month_2 = Date.FromOADate(2).Month
        year_now = Now.Year
        year_3 = Date.FromOADate(3).Year
        day_14 = Date.FromOADate(14).Day
        year_2020 = Date.FromOADate(2020).Year
        code = (day_now * day_23 + month_now * month_2 + year_now * year_3) + (day_now * day_23 + month_now * month_2 + year_now * year_3) + (day_14 * year_2020) + (day_14 * year_2020)
        MsgBox("注册码为:" & code)

        Dim Str, name, code3 As String
        Dim i, j, m, temp, var_1CC, var_178, k, code2 As Integer
        Str = "0110617121214051216101106141404110614140411091211100810101608040610121608100416"
        name = InputBox("请输入用户名(长度≥5):")
        m = 1
        temp = 1
        For i = 4 To Len(name)
            code2 = CLng((CDbl(code2) + CDbl(Asc(Mid$(name, CLng(i), 1))) * Val(Mid$(Str, CLng((m * 3)), 3))))
            temp = 1
            m = m + temp
            temp = 39
            If ((m + 1) >= 39) Then
                temp = 0
                m = 0
            End If
        Next i
        m = 1
        temp = 1
        For j = 4 To Len(name)
            var_1CC = (CDbl((Asc(Mid$(name, CLng(j), 1)) * Asc(Mid$(name, CLng((j - 1)), 1)))) * Val(Mid$(Str, CLng((m * 2)), 2)))
            var_178 = (var_178 + var_1CC)
            temp = 1
            m = m + temp
            temp = 39
            If ((m + 1) >= 39) Then
                temp = 0
                m = 0
            End If
        Next j
        code3 = LTrim$(CInt(code2)) & "-" & LTrim$(CInt(var_178))
        MsgBox("注册码为:" & code3)

    End Sub

End Module

4.总结

  • 第一次接触的P-Code编译的VB程序,大致了解了P-Code代码的工作方式和特点。破解过程中,VB断点有时候还是能派上用场的。爆破的话,需要掌握以下几个P-Code指令码:

P-Code里面跳转语句一共有三个:
Branch (1E) ---- 无条件跳转
BranchT(1D) ---- 栈顶数据为真则跳转
BranchF(1C) ---- 栈顶数据为假则跳转

注意:1C和1D可以互改,但是不能和1E互改,因为1C和1D操作时会执行数据出栈操作,而1E不会。

比较指令:
EqVarBool----比较变量相等:   FB 33
NeVarBool----比较变量不相等: FB 40

EqStr    ----比较字符串相等: FB 30
NeStr    ----比较字符串相等: FB 3D

  • 有些函数还是要在原语言环境下了解其具体功能,尝试用VB来编写VB程序的注册机,还是要省事一些,可以不用将函数翻译到其他语言,基本直接复制反编译出来的算法代码就可以。

  • 关于VB中day(23)和EXCEl中查1天的问题,查阅了官方文档,最终原因如下:

VB中的日期,数值范围为:-657435.0到2958465.99999999,0代表1899年12月30日00:00:00
奇怪之处:0.5和-0.5均表示1899年12月30日12:00:00(不明白为什么要定义成这样)
EXCEL中的日期,1代表1900 年 1 月 1 日 00:00:00,只允许正值;

免费评分

参与人数 1吾爱币 +1 收起 理由
XXFFKK + 1 热心回复!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

 楼主| xiaoyu2032 发表于 2022-5-14 08:09
wulei1873 发表于 2022-5-14 02:24
注意:1C和1D可以互改,但是不能和1E互改,因为1C和1D操作时会执行数据出栈操作,而1E不会

这个没看懂

1C和1D指令以栈顶数据进行判断并跳转,同时执行一次数据出栈操作,而1E只进行跳转,不进行出栈操作。如果1C或1D指令换成了1E,后续操作的堆栈数据就错位了,将导致后续代码执行出现异常。
martin313 发表于 2022-5-14 22:46
抽空请练习一下 Similarity ,我一直找不到关键的全局修改点,如果找到的话,请指点一二

官网地址:https://www.similarityapp.com/
moshuiNW 发表于 2022-5-11 06:58
aiyikegu 发表于 2022-5-11 07:59
牛牛牛,感谢分享
yuyi0 发表于 2022-5-11 09:11
感谢分享
0xchuxiuyun 发表于 2022-5-12 08:53
阔以,谢谢分享
测试学学 发表于 2022-5-12 11:02
真的可以学到很多东西
戰龍在野 发表于 2022-5-12 20:43
不错坚持就是胜利项起来
killsu 发表于 2022-5-12 23:25
感谢分享
wulei1873 发表于 2022-5-14 02:24
注意:1C和1D可以互改,但是不能和1E互改,因为1C和1D操作时会执行数据出栈操作,而1E不会

这个没看懂
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 21:38

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表