首页
社区
课程
招聘
[原创]第7题算法分析步骤
发表于: 2017-6-14 15:12 3491

[原创]第7题算法分析步骤

2017-6-14 15:12
3491

工具:OD,VB,IDA

 

破解步骤:

1.该程序在Win7x64下运行异常,放入WinXP虚拟机,OD载入直接运行,下断:bp GetDlgItemTextA,输入注册码123456后回车,断下来了,返回到用户代码:

004104CD  /$  68 >push    0x90

004104D2  |.  B8 >mov     eax, 0045037E

004104D7  |.  E8 >call    00413FD7

004104DC  |.  8BF>mov     esi, ecx

004104DE  |.  6A >push    0x65

004104E0  |.  8D4>lea     eax, dword ptr [ebp-0x80]

004104E3  |.  6A >push    0x0

004104E5  |.  50  push    eax

004104E6  |.  E8 >call    004156A0

004104EB  |.  83C>add     esp, 0xC

004104EE  |.  8D4>lea     eax, dword ptr [ebp-0x80]

004104F1  |.  6A >push    0x64                                    ; /Count = 64 (100.)

004104F3  |.  50  push    eax                                     ; |Buffer

004104F4  |.  68 >push    0x3E8                                   ; |ControlID = 3E8 (1000.)

004104F9  |.  FF7>push    dword ptr [esi+0x4]                     ; |hWnd

004104FC  |.  FF1>call    dword ptr [<&USER32.GetDlgItemTextA>]   ; \GetDlgItemTextA

00410502  |.  8D4>lea     eax, dword ptr [ebp-0x80]

00410505  |.  50  push    eax                                     ; /Arg1

00410506  |.  8D8>lea     ecx, dword ptr [ebp-0x98]               ; |

0041050C  |.  E8 >call    0040FD2D                                ; \7-不问少.0040FD2D

00410511  |.  836>and     dword ptr [ebp-0x4], 0x0

00410515  |.  8D4>lea     eax, dword ptr [ebp-0x18]

00410518  |.  6A >push    0x5

0041051A  |.  50  push    eax

0041051B  |.  BB >mov     ebx, 0x1AA

00410520  |.  C74>mov     dword ptr [ebp-0x18], 0x49444550

00410527  |.  53  push    ebx

00410528  |.  BF >mov     edi, 00411B30

0041052D  |.  C64>mov     byte ptr [ebp-0x14], 0x59

00410531  |.  57  push    edi

00410532  |.  E8 >call    00410DD6                                ;  code dec

00410537  |.  51  push    ecx

00410538  |.  51  push    ecx

00410539  |.  8D8>lea     eax, dword ptr [ebp-0x98]

0041053F  |.  89A>mov     dword ptr [ebp-0x9C], esp

00410545  |.  8BC>mov     ecx, esp

00410547  |.  50  push    eax                                     ; /Arg1

00410548  |.  E8 >call    0040FD07                                ; \7-不问少.0040FD07

0041054D  |.  C64>mov     byte ptr [ebp-0x4], 0x1

00410551  |.  C64>mov     byte ptr [ebp-0x4], 0x0

00410555  |.  8D4>lea     ecx, dword ptr [esi+0x40]

00410558  |.  E8 >call    00411B30                                ;  code exec:user key exchange

0041055D  |.  6A >push    0x5                                     ; /Arg4 = 00000005

0041055F  |.  8D4>lea     eax, dword ptr [ebp-0x18]               ; |

00410562  |.  50  push    eax                                     ; |Arg3

00410563  |.  53  push    ebx                                     ; |Arg2

00410564  |.  57  push    edi                                     ; |Arg1

00410565  |.  E8 >call    00410DD6                                ; \code enc

0041056A  |.  83C>add     esp, 0x10

0041056D  |.  8D4>lea     ecx, dword ptr [esi+0x40]

00410570  |.  E8 >call    00411825                                ;  calc key???

00410575  |.  834>or      dword ptr [ebp-0x4], 0xFFFFFFFF

00410579  |.  8D8>lea     ecx, dword ptr [ebp-0x98]

0041057F  |.  6A >push    0x0                                     ; /Arg2 = 00000000

00410581  |.  6A >push    0x1                                     ; |Arg1 = 00000001

00410583  |.  E8 >call    <_memfree>                              ; \7-不问少.00410AE3

00410588  |.  33C>xor     eax, eax

0041058A  |.  E8 >call    00413F81

0041058F  \.  C2 >retn    0x10

没有明显的比较过程,只能每个CALL里都看一下了。

 

2.00410532  call    00410DD6这个CALL里的操作是对00411B30处长度为0x1AA的代码使用“PEDIY”进行解码,然后00410558  call 00411B30运行,最后00410570  call    00411825再把代码加密。需要解密才运行,可见call 00411B30里有关键代码,跟进观察。

 

3.这个CALL 00411B30里算法比较绕,花了很长时才搞明白,分以下几步:

1)先对输入码key xor 0xCC

2)按字节调用00411C13  call 00410F4C在一个表里找索引值index,该表为:

tb1:

0016CFD0  89 BC 95 FC FB BA ED 9A BB AE FE 99 A2 98 B9 F9

0016CFE0  9F 84 9C FD 83 AD B6 A9 A5 F5 8C A7 9E 96 8A F4

0016CFF0  85 BE A8 8F 86 AF 88 9D 87 BF FF A1 8B 81 A0 AB

0016D000  8E BD B5 AA 82 94 A4 8D A3 F8 B4 FA 9B A6 B8 80

此表XOR 0xCC可以得到初始字符串列表:“EpY07v!Vwb2UnTu5SHP1Oazei9@kRZF8IrdCJcDQKs3mGMlgBqyfNXhAo4x6WjtL

将索引值index进行计算,计算结果查上面的表tb1然后保存到原位置。算法用VB表示为:

    For i = 1 To Len(s)

        n = InStr(1, ss, Mid$(s, i, 1)) - 1

        For j = 1 To i

            n = (n + n \ 5 + 5) Mod &H40

        Next

        bb(i) = tb1(n)

    Next

3)在00411CA4  call    00410F75里,按字节XOR 0xCCror(5),保存回原位置,记为key2

 

4.00410565  call    00410DD6把执行后的代码加密后,在00410570  call    00411825里验证刚才计算的结果,正确时执行后续操作。验证过程全部在00410570  call    00411825里,步骤为:

100411987  call    0041191F把上一步计算的结果key2转换为HEX字符,记为key3

2key3按字节调用004119F4  call 00410F4C在一个表里找索引值index,该表tb2为:

tb2:

00403D50  30 31 32 33 34 35 36 37 38 39 41 42 43 44 45 46  0123456789ABCDEF

将索引值index转换为四进制值保存。

3)判断四进制结果的长度是否为0x50,即80字节。

4)四进制结果与一个固定值比较,该固定值为:

tb3:

0016D120  02 02 00 03  00 00 02 03  00 01 02 03  02 00 00 02  10100011 00001011 00011011 10000010  A30B1B82

0016D130  02 00 02 02  02 03 02 03  01 00 02 02  02 01 02 03  10001010 10111011 01001010 10011011  8ABB4A9B

0016D140  02 02 02 01  02 03 02 03  02 01 00 03  02 02 02 02  10101001 10111011 10010011 10101010  A9BB93AA

0016D150  02 02 00 03  01 02 02 03  02 00 00 02  02 02 02 02  10100011 01101011 10000010 10101010  A36B82AA

0016D160  00 00 00 02  01 00 02 02  02 03 00 02  01 00 00 03  00000010 01001010 10110010 01000011  024AB243

把此四进制表转换为16进制,得到结果字符串为“A30B1B828ABB4A9BA9BB93AAA36B82AA024AB243”。

 

5.已经得到完整算法了,简化后VB表示为:

Function ShlAndSar(value As Byte) As Byte

    Dim v1 As Long, v2 As Long

    

    v1 = value

    v1 = (v1 * 8) And &HFF

    v2 = value And &H7F

    If (value And &H80) <> 0 Then v2 = -v2

    v2 = v2 \ 32

    ShlAndSar = (v1 Or v2) And &HFF

End Function

 

Private Sub Command1_Click()

    Dim ss As String

    Dim i As Long, j As Long

    Dim n As Byte

    Dim s As String, t As String

    

    ss = "EpY07v!Vwb2UnTu5SHP1Oazei9@kRZF8IrdCJcDQKs3mGMlgBqyfNXhAo4x6WjtL"

    

    s = Text1.Text

    

    For i = 1 To Len(s)

        n = InStr(1, ss, Mid$(s, i, 1)) - 1

        For j = 1 To i

            n = (n + n \ 5 + 5) Mod &H40

        Next

        n = Asc(Mid$(ss, n + 1, 1))

        n = ShlAndSar(n)

        t = t & Right$("00" & Hex(n), 2)

    Next

    Text2.Text = t

End Sub

 

6.根据此算法,逆推还原算法,VB表示为:

Private Function GetIndex(ByVal n As Long, ByVal c As Long) As String

    Dim i As Long, j As Long, k As Long

    Dim s As String

    Dim ss As String

    ss = "EpY07v!Vwb2UnTu5SHP1Oazei9@kRZF8IrdCJcDQKs3mGMlgBqyfNXhAo4x6WjtL"

    

    For i = 0 To 63

        k = i

        For j = 1 To n

            k = (k + k \ 5 + 5) Mod &H40

        Next

        If k = c Then

            s = Mid$(ss, i + 1, 1)

            Exit For

        End If

    Next

    GetIndex = s

End Function

 

Private Sub Command2_Click()

    Dim ss As String

    Dim i As Long, j As Long, k As Long

    Dim n As Byte

    Dim c As String

    Dim s As String, t As String

    

    Dim mm(&HFF) As Byte

    For i = 0 To &HFF

        mm(i) = ShlAndSar((i And &HFF))

    Next

    

    ss = "EpY07v!Vwb2UnTu5SHP1Oazei9@kRZF8IrdCJcDQKs3mGMlgBqyfNXhAo4x6WjtL"

    

    s = Text1.Text

    

    For i = 1 To Len(s) \ 2

        n = Val("&H" & Mid$(s, i * 2 - 1, 2))

        For j = 0 To &H7F

            If mm(j) = n Then

                n = InStr(1, ss, Chr(j)) - 1

                t = t & GetIndex(i, n)

            End If

        Next

    Next

    Text2.Text = t

End Sub

得到注册码:BwndYbPHdPy2017@J9Ok

 

7.本来以为到这里就结束了,但是将此结果填进去还是没有正确提示。继续往下看,发现还有后续操作:

00411825   $  6A >push    0x18

00411827   .  B8 >mov     eax, 0045054A

0041182C   .  E8 >call    0041400E

00411831   .  894>mov     dword ptr [ebp-0x1C], ecx

00411834   .  E8 >call    00411975                                ;  校验注册码,必须返回1

00411839   .  84C>test    al, al

0041183B   .  0F8>je      00411919

00411841   .  6A >push    0x40                                    ; /Protect = PAGE_EXECUTE_READWRITE

00411843   .  BB >mov     ebx, 0x1000                             ; |

00411848   .  53  push    ebx                                     ; |AllocationType => MEM_COMMIT

00411849   .  53  push    ebx                                     ; |Size => 1000 (4096.)

0041184A   .  33F>xor     esi, esi                                ; |

0041184C   .  56  push    esi                                     ; |Address => NULL

0041184D   .  FF1>call    dword ptr [<&KERNEL32.VirtualAlloc>]    ; \申请空间

00411853   .  8BF>mov     edi, eax

00411855   .  897>mov     dword ptr [ebp-0x18], edi

00411858   .  68 >push    0x94                                    ; /Arg4 = 00000094

0041185D   .  68 >push    00411A9C                                ; |Arg3 = 00411A9C

00411862   .  53  push    ebx                                     ; |Arg2 => 00001000

00411863   .  57  push    edi                                     ; |Arg1

00411864   .  E8 >call    004121ED                                ; \复制代码

00411869   .  83C>add     esp, 0x10

0041186C   .  8BC>mov     ecx, edi

0041186E   .  894>mov     dword ptr [ebp-0x14], ecx

00411871   .  897>mov     dword ptr [ebp-0x4], esi

00411874   .  897>mov     dword ptr [ebp-0x20], esi

00411877   .  8B4>mov     ecx, dword ptr [ebp-0x1C]

0041187A   >  81F>cmp     esi, 0x94

00411880   .  7D >jge     short 004118A9

00411882   .  8BC>mov     eax, esi

00411884   .  33D>xor     edx, edx

00411886   .  F77>div     dword ptr [ecx+0x34]

00411889   .  46  inc     esi

0041188A   .  897>mov     dword ptr [ebp-0x20], esi

0041188D   .  8D4>lea     eax, dword ptr [ecx+0x24]

00411890   .  837>cmp     dword ptr [eax+0x14], 0x10

00411894   .  72 >jb      short 00411898

00411896   .  8B0>mov     eax, dword ptr [eax]

00411898   >  8A0>mov     al, byte ptr [eax+edx]

0041189B   .  8B5>mov     edx, dword ptr [ebp-0x14]

0041189E   .  300>xor     byte ptr [edx], al                      ;  使用输入key对代码解密

004118A0   .  42  inc     edx

004118A1   .  895>mov     dword ptr [ebp-0x14], edx

004118A4   .  895>mov     dword ptr [ebp-0x24], edx

004118A7   .^ EB >jmp     short 0041187A

004118A9   >  8B4>mov     eax, dword ptr [ecx+0x34]

004118AC   .  894>mov     dword ptr [ebp-0x1C], eax

004118AF   .  83C>add     ecx, 0x24

004118B2   .  837>cmp     dword ptr [ecx+0x14], 0x10

004118B6   .  72 >jb      short 004118BA

004118B8   .  8B0>mov     ecx, dword ptr [ecx]

004118BA   >  8BC>mov     eax, esi

004118BC   .  33D>xor     edx, edx

004118BE   .  F77>div     dword ptr [ebp-0x1C]

004118C1   .  8A0>mov     al, byte ptr [edx+ecx]

004118C4   .  8B4>mov     ecx, dword ptr [ebp-0x14]

004118C7   .  300>xor     byte ptr [ecx], al

004118C9   .  8D4>lea     ecx, dword ptr [edi+0x60]

004118CC   .  BA >mov     edx, 00411A9C

004118D1   .  8BC>mov     eax, edx

004118D3   .  2BC>sub     eax, ecx

004118D5   .  83C>add     eax, 0x60

004118D8   .  014>add     dword ptr [ecx+0x1], eax

004118DB   .  8D8>lea     ecx, dword ptr [edi+0x8B]

004118E1   .  8B4>mov     eax, dword ptr [ecx+0x1]

004118E4   .  2BC>sub     eax, ecx

004118E6   .  81C>add     edx, 0x8B

004118EC   .  03C>add     eax, edx

004118EE   .  894>mov     dword ptr [ecx+0x1], eax

004118F1   .  FF5>call    dword ptr [ebp-0x18]                    ;  跳到解密代码执行

 

需要使用输入的注册码对代码解密,注册成功的提示藏在解密代码里。使用刚才得到的注册码,解密代码有错误指令。看来注册码有多解,需要逐一尝试才能得到正确的指令代码。先修改之前的VB程序:

Private Function GetIndex(ByVal n As Long, ByVal c As Long) As String

    Dim i As Long, j As Long, k As Long

    Dim s As String

    Dim ss As String

    ss = "EpY07v!Vwb2UnTu5SHP1Oazei9@kRZF8IrdCJcDQKs3mGMlgBqyfNXhAo4x6WjtL"

    

    For i = 0 To 63

        k = i

        For j = 1 To n

            k = (k + k \ 5 + 5) Mod &H40

        Next

        If k = c Then

            s = s & "," & Mid$(ss, i + 1, 1)

        End If

    Next

    GetIndex = s

End Function

 

Private Sub Command2_Click()

    Dim ss As String

    Dim i As Long, j As Long, k As Long

    Dim n As Byte

    Dim c As String

    Dim s As String, t As String

    

    Dim mm(&HFF) As Byte

    For i = 0 To &HFF

        mm(i) = ShlAndSar((i And &HFF))

    Next

    

    ss = "EpY07v!Vwb2UnTu5SHP1Oazei9@kRZF8IrdCJcDQKs3mGMlgBqyfNXhAo4x6WjtL"

    

    s = Text1.Text

    

    For i = 1 To Len(s) \ 2

        n = Val("&H" & Mid$(s, i * 2 - 1, 2))


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//