论坛: 编程破解 标题: [转帖]菜鸟学算法<三>算法分析篇 复制本贴地址    
作者: yongmin [yongmin]    论坛用户   登录
作者:鹭影依凌
转贴自:一蓑烟雨
声明:
1.以下内容都是个人在学习中的一些心得体会,写给新手的,高手飘过
2.文章难免有疏漏之处,欢迎各位兄弟批评指正
3.本文原创于UnPaKcN,如转载,请保持文章完整性


经过的前面两篇知识积累和过程分析,下面我们开始进行第三篇---算法分析

程序实例仍旧是Media-WorkShop

前文回顾
先来看看我们在第二篇的部分代码分析
;---------------------------<载入注册计算方案(一)>-------------------|
0046021C  |.  57            push    edi                              ;  压栈(序列号)
0046021D  |.  55            push    ebp                              ;  压栈(用户名)
0046021E  |.  E8 6DF9FFFF  call    0045FB90                        ;  |*|注册算法<一>
00460223  |.  83C4 08      add    esp, 8
00460226  |.  85C0          test    eax, eax                        ;  标志位测试
00460228  |.  75 0E        jnz    short 00460238                  ;  //不跳则进入算法二
;---------------------------<载入注册计算方案(二)>-------------------|
0046022A  |.  57            push    edi                              ;  压栈(序列号)
0046022B  |.  55            push    ebp                              ;  压栈(用户名)
0046022C  |.  E8 8FFBFFFF  call    0045FDC0                        ;  |*|注册算法<二>
00460231  |.  83C4 08      add    esp, 8
00460234  |.  85C0          test    eax, eax                        ;  标志位测试
00460236  |.  74 0A        je      short 00460242                  ;  //跳则挂
;---------------------------<标志位赋值(注册成功EAX=1)>--------------|
00460238  |>  5F            pop    edi
00460239  |.  5E            pop    esi
0046023A  |.  5D            pop    ebp
0046023B  |.  B8 01000000  mov    eax, 1                          ;  标志位赋值:EAX = 1
00460240  |.  5B            pop    ebx
00460241  |.  C3            retn                                    ;  //返回
;---------------------------<标志位赋值(注册失败EAX=0)>--------------|
00460242  |>  5F            pop    edi                              ;  跳转来自 004601DE, 0046021A, 00460236
00460243  |.  5E            pop    esi
00460244  |.  5D            pop    ebp
00460245  |.  33C0          xor    eax, eax                        ;  EAX置零
00460247  |.  5B            pop    ebx
00460248  \.  C3            retn                                    ;  //返回
;--------------------------------------------------------------------|




下面开始进行注册算法一的分析

;====================================================================|
;在地址0046021E处F7跟进注册算法CALL->0045FB90
;--------------------------------------------------------------------|
0045FB90  /$  6A FF        push    -1                              ;  //本地调用来自 0046021E
0045FB92  |.  68 70414700  push    00474170                        ;  SE 处理程序安装
0045FB97  |.  64:A1 0000000>mov    eax, dword ptr fs:[0]
0045FB9D  |.  50            push    eax
0045FB9E  |.  64:8925 00000>mov    dword ptr fs:[0], esp
0045FBA5  |.  83EC 14      sub    esp, 14
0045FBA8  |.  8B4424 24    mov    eax, dword ptr [esp+24]          ;  EAX = 用户名
0045FBAC  |.  53            push    ebx
0045FBAD  |.  55            push    ebp                              ;  用户名压栈
0045FBAE  |.  56            push    esi
0045FBAF  |.  57            push    edi                              ;  序列号压栈
0045FBB0  |.  50            push    eax                              ;  用户名压栈
0045FBB1  |.  8D4C24 18    lea    ecx, dword ptr [esp+18]
0045FBB5  |.  E8 B8800000  call    <jmp.&MFC42.#537>
0045FBBA  |.  8D4C24 14    lea    ecx, dword ptr [esp+14]          ;  ECX = 用户名的地址
0045FBBE  |.  C74424 2C 000>mov    dword ptr [esp+2C], 0
0045FBC6  |.  E8 E5840000  call    <jmp.&MFC42.#6282>
0045FBCB  |.  8D4C24 14    lea    ecx, dword ptr [esp+14]
0045FBCF  |.  E8 D6840000  call    <jmp.&MFC42.#6283>
0045FBD4  |.  6A 20        push    20
0045FBD6  |.  8D4C24 18    lea    ecx, dword ptr [esp+18]
0045FBDA  |.  E8 71870000  call    <jmp.&MFC42.#2915>
0045FBDF  |.  8B4C24 38    mov    ecx, dword ptr [esp+38]          ;  ECX = 序列号
0045FBE3  |.  8BD8          mov    ebx, eax                        ;  EBX = 用户名
0045FBE5  |.  51            push    ecx                              ;  序列号压栈
0045FBE6  |.  8D4C24 14    lea    ecx, dword ptr [esp+14]
0045FBEA  |.  E8 83800000  call    <jmp.&MFC42.#537>
0045FBEF  |.  8D4C24 10    lea    ecx, dword ptr [esp+10]
0045FBF3  |.  C64424 2C 01  mov    byte ptr [esp+2C], 1
0045FBF8  |.  E8 B3840000  call    <jmp.&MFC42.#6282>
0045FBFD  |.  8D4C24 10    lea    ecx, dword ptr [esp+10]
0045FC01  |.  E8 A4840000  call    <jmp.&MFC42.#6283>
0045FC06  |.  6A 20        push    20
0045FC08  |.  8D4C24 14    lea    ecx, dword ptr [esp+14]
0045FC0C  |.  E8 3F870000  call    <jmp.&MFC42.#2915>
0045FC11  |.  8BD0          mov    edx, eax                        ;  EDX = 序列号
0045FC13  |.  83CE FF      or      esi, FFFFFFFF
0045FC16  |.  8BFA          mov    edi, edx                        ;  EDI = 序列号
0045FC18  |.  8BCE          mov    ecx, esi
0045FC1A  |.  33C0          xor    eax, eax                        ;  EAX置零
;---------------------------<用户名长度不能大于序列号长度>---------------|
0045FC1C  |.  895424 20    mov    dword ptr [esp+20], edx          ;  [esp+20] = 序列号
0045FC20  |.  F2:AE        repne  scas byte ptr es:[edi]
0045FC22  |.  F7D1          not    ecx
0045FC24  |.  49            dec    ecx                              ;  ECX = 序列号长度
0045FC25  |.  8BFB          mov    edi, ebx                        ;  EDI = 用户名
0045FC27  |.  8BE9          mov    ebp, ecx                        ;  EBP = 用户名长度
0045FC29  |.  8BCE          mov    ecx, esi
0045FC2B  |.  F2:AE        repne  scas byte ptr es:[edi]
0045FC2D  |.  F7D1          not    ecx
0045FC2F  |.  49            dec    ecx                              ;  ECX = 用户名长度
0045FC30  |.  3BCD          cmp    ecx, ebp
0045FC32  |.  0F87 54010000 ja      0045FD8C                        ;  //跳则挂(未实现)
;---------------------------<用户名不能为空>---------------------------|
0045FC38  |.  8BFB          mov    edi, ebx                        ;  EDI = 用户名
0045FC3A  |.  8BCE          mov    ecx, esi
0045FC3C  |.  F2:AE        repne  scas byte ptr es:[edi]
0045FC3E  |.  F7D1          not    ecx
0045FC40  |.  49            dec    ecx                              ;  ECX = 用户名长度
0045FC41  |.  0F84 45010000 je      0045FD8C                        ;  //跳则挂(未实现)
;---------------------------<序列号不能为空>---------------------------|
0045FC47  |.  8BFA          mov    edi, edx                        ;  EDI = 序列号
0045FC49  |.  8BCE          mov    ecx, esi
0045FC4B  |.  F2:AE        repne  scas byte ptr es:[edi]
0045FC4D  |.  F7D1          not    ecx
0045FC4F  |.  49            dec    ecx                              ;  ECX = 序列号长度
0045FC50  |.  0F84 36010000 je      0045FD8C                        ;  //跳则挂(未实现)
;---------------------------<注册运算验证>-----------------------------|
0045FC56  |.  894424 38    mov    dword ptr [esp+38], eax          ;  [esp+38]初始化为0
;------------------------------------[第一层开始]
0045FC5A  |>  8B5424 38    /mov    edx, dword ptr [esp+38]        ;  EDX = [esp+38]
0045FC5E  |.  8D4C24 34    |lea    ecx, dword ptr [esp+34]        ;  加载序列号地址
0045FC62  |.  8A82 887E4900 |mov    al, byte ptr [edx+497E88]      ;  三次依次出现'P'/'W'/'M'
0045FC68  |.  884424 18    |mov    byte ptr [esp+18], al          ;  [esp+18] = al
0045FC6C  |.  E8 37800000  |call    <jmp.&MFC42.#540>
0045FC71  |.  8BFB          |mov    edi, ebx                        ;  EDI = 用户名
0045FC73  |.  83C9 FF      |or      ecx, FFFFFFFF
0045FC76  |.  33C0          |xor    eax, eax                        ;  EAX置零
0045FC78  |.  33ED          |xor    ebp, ebp                        ;  EBP置零
0045FC7A  |.  F2:AE        |repne  scas byte ptr es:[edi]
0045FC7C  |.  F7D1          |not    ecx
0045FC7E  |.  49            |dec    ecx                            ;  ECX = 用户名长度
0045FC7F  |.  C64424 2C 02  |mov    byte ptr [esp+2C], 2            ;  [esp+2C] = 2
0045FC84  |.  74 4B        |je      short 0045FCD1                  ;  //作用:跳过下面循环体
;---------------------------[第二层开始]                                [对用户名字符进行查表替换]
0045FC86  |>  8A042B        |/mov    al, byte ptr [ebx+ebp]        ;  用户名的第i个字符
0045FC89  |.  33F6          ||xor    esi, esi                      ;  ESI置零
;---------[第三层开始]                                                  [对第i个字符进行查表替换]                                 
0045FC8B  |>  3A0475 207E49>||/cmp    al, byte ptr [esi*2+497E20]  ;  查表比较
0045FC92  |.  74 08        |||je      short 0045FC9C                ;  //找到后,跳出本循环体
0045FC94  |.  46            |||inc    esi                          ;  ESI++
0045FC95  |.  83FE 34      |||cmp    esi, 34
0045FC98  |.^ 7C F1        ||\jl      short 0045FC8B                ;  //继续查找密码表中下一个字符
;---------[第三层结束]
0045FC9A  |.  EB 11        ||jmp    short 0045FCAD                ;  //没找到,跳走
;---------<(I)找到了则跳到这>
0045FC9C  |>  8A0C75 217E49>||mov    cl, byte ptr [esi*2+497E21]    ;  找到密码表中对应的字母
0045FCA3  |.  51            ||push    ecx
0045FCA4  |.  8D4C24 38    ||lea    ecx, dword ptr [esp+38]
0045FCA8  |.  E8 83820000  ||call    <jmp.&MFC42.#940>
;---------<(II)没找到则跳到这>
0045FCAD  |>  83FE 34      ||cmp    esi, 34                        ;  和34比较
0045FCB0  |.  75 0E        ||jnz    short 0045FCC0                ;  若上面没找到,则在此处不跳
;---------<没有找到时进行的操作>
0045FCB2  |.  8B5424 18    ||mov    edx, dword ptr [esp+18]        ;
0045FCB6  |.  8D4C24 34    ||lea    ecx, dword ptr [esp+34]        ;  加载序列号地址
0045FCBA  |.  52            ||push    edx
0045FCBB  |.  E8 70820000  ||call    <jmp.&MFC42.#940>              ;  将替换字符和前面所得字符串链接
;---------|
0045FCC0  |>  8BFB          ||mov    edi, ebx                      ;  EDI = 用户名
0045FCC2  |.  83C9 FF      ||or      ecx, FFFFFFFF
0045FCC5  |.  33C0          ||xor    eax, eax                      ;  EAX置零
0045FCC7  |.  45            ||inc    ebp
0045FCC8  |.  F2:AE        ||repne  scas byte ptr es:[edi]
0045FCCA  |.  F7D1          ||not    ecx
0045FCCC  |.  49            ||dec    ecx                            ;  用户名长度
0045FCCD  |.  3BE9          ||cmp    ebp, ecx
0045FCCF  |.^ 72 B5        |\jb      short 0045FC86                ;  //循环length(name)次
;---------------------------[第二层]
;---------<当运算所得字符串长度>=10H时,直接作为序列号>
0045FCD1  |>  8B4424 34    |mov    eax, dword ptr [esp+34]        ;  (ASCII "eWHEyMPP")
0045FCD5  |.  8B48 F8      |mov    ecx, dword ptr [eax-8]          ;  字符串的长度
0045FCD8  |.  83F9 10      |cmp    ecx, 10
0045FCDB  |.  7D 3A        |jge    short 0045FD17                  ;  //大于等于10跳走
;---------<当运算所得字符串长度<10H时,进行尾部补充>
0045FCDD  |.  8BC1          |mov    eax, ecx                        ;  EAX = 长度
0045FCDF  |.  B9 10000000  |mov    ecx, 10                        ;  ECX = 10H
0045FCE4  |.  2BC8          |sub    ecx, eax                        ;  ECX = ECX - EAX
0045FCE6  |.  8D5424 1C    |lea    edx, dword ptr [esp+1C]        ;  加载补充字符串地址
0045FCEA  |.  51            |push    ecx                            ;  补充字符串长度压栈
0045FCEB  |.  52            |push    edx
0045FCEC  |.  B9 C02B4E00  |mov    ecx, 004E2BC0
0045FCF1  |.  E8 42800000  |call    <jmp.&MFC42.#4129>              ;  确定补充字符串
0045FCF6  |.  50            |push    eax
0045FCF7  |.  8D4C24 38    |lea    ecx, dword ptr [esp+38]        ;  加载上面运算所得字符串地址
0045FCFB  |.  C64424 30 03  |mov    byte ptr [esp+30], 3
0045FD00  |.  E8 25820000  |call    <jmp.&MFC42.#939>              ;  将两字符川进行链接
0045FD05  |.  8D4C24 1C    |lea    ecx, dword ptr [esp+1C]
0045FD09  |.  C64424 2C 02  |mov    byte ptr [esp+2C], 2
0045FD0E  |.  E8 4D7F0000  |call    <jmp.&MFC42.#800>
0045FD13  |.  8B4424 34    |mov    eax, dword ptr [esp+34]        ;  (ASCII "eWHEyMPPLdQsBcmp")
0045FD17  |>  8B4C24 20    |mov    ecx, dword ptr [esp+20]        ;  假码
0045FD1B  |.  51            |push    ecx                            ; /s2 = 真码
0045FD1C  |.  50            |push    eax                            ; |s1 = 假码
0045FD1D  |.  FF15 A45A4700 |call    dword ptr [<&MSVCRT._mbscmp>]  ; \(msvcrt._mbscmp)字符串比较
0045FD23  |.  83C4 08      |add    esp, 8
0045FD26  |.  8D4C24 34    |lea    ecx, dword ptr [esp+34]
0045FD2A  |.  85C0          |test    eax, eax                        ;  测试标志位
0045FD2C  |.  C64424 2C 01  |mov    byte ptr [esp+2C], 1            ;  [esp+2C] = 1
0045FD31  |.  74 1B        |je      short 0045FD4E                  ;  //跳出循环体
0045FD33  |.  33F6          |xor    esi, esi                        ;  ESI置零
0045FD35  |.  E8 267F0000  |call    <jmp.&MFC42.#800>
0045FD3A  |.  8B4424 38    |mov    eax, dword ptr [esp+38]
0045FD3E  |.  40            |inc    eax                            ;  EAX++
0045FD3F  |.  83F8 03      |cmp    eax, 3
0045FD42  |.  894424 38    |mov    dword ptr [esp+38], eax        ;  [esp+38] = eax
0045FD46  |.^ 0F8C 0EFFFFFF \jl      0045FC5A                        ;  //循环(三次)
;------------------------------------[第一层结束]
;---------<若从这跳则越过ESI=1,进而EAX=ESI=0,注册失败>
0045FD4C  |.  EB 0A        jmp    short 0045FD58
0045FD4E  |>  BE 01000000  mov    esi, 1                          ;  ESI = 1
0045FD53  |.  E8 087F0000  call    <jmp.&MFC42.#800>
0045FD58  |>  8D4C24 10    lea    ecx, dword ptr [esp+10]          ;  加载假码地址
0045FD5C  |.  C64424 2C 00  mov    byte ptr [esp+2C], 0
0045FD61  |.  E8 FA7E0000  call    <jmp.&MFC42.#800>
0045FD66  |.  8D4C24 14    lea    ecx, dword ptr [esp+14]          ;  加载用户名地址
0045FD6A  |.  C74424 2C FFF>mov    dword ptr [esp+2C], -1
0045FD72  |.  E8 E97E0000  call    <jmp.&MFC42.#800>
0045FD77  |.  8BC6          mov    eax, esi                        ;  EAX = ESI
0045FD79  |.  5F            pop    edi
0045FD7A  |.  5E            pop    esi
0045FD7B  |.  5D            pop    ebp
0045FD7C  |.  5B            pop    ebx
0045FD7D  |.  8B4C24 14    mov    ecx, dword ptr [esp+14]
0045FD81  |.  64:890D 00000>mov    dword ptr fs:[0], ecx
0045FD88  |.  83C4 20      add    esp, 20
0045FD8B  |.  C3            retn                                    ;  //返回(EAX=ESI)
;-------------<跳到下面就算玩完~~~>
0045FD8C  |>  8D4C24 10    lea    ecx, dword ptr [esp+10]          ;  跳转来自 0045FC32, 0045FC41, 0045FC50
0045FD90  |.  C64424 2C 00  mov    byte ptr [esp+2C], 0
0045FD95  |.  E8 C67E0000  call    <jmp.&MFC42.#800>
0045FD9A  |.  8D4C24 14    lea    ecx, dword ptr [esp+14]
0045FD9E  |.  897424 2C    mov    dword ptr [esp+2C], esi
0045FDA2  |.  E8 B97E0000  call    <jmp.&MFC42.#800>
0045FDA7  |.  8B4C24 24    mov    ecx, dword ptr [esp+24]
0045FDAB  |.  5F            pop    edi
0045FDAC  |.  5E            pop    esi
0045FDAD  |.  5D            pop    ebp
0045FDAE  |.  33C0          xor    eax, eax                        ;  EAX置零
0045FDB0  |.  5B            pop    ebx
0045FDB1  |.  64:890D 00000>mov    dword ptr fs:[0], ecx
0045FDB8  |.  83C4 20      add    esp, 20
0045FDBB  \.  C3            retn                                    ;  //返回(EAX=0)
;====================================================================|

在运行到0045FC8B时候,
0045FC62  |.  8A82 887E4900 |mov      al, byte ptr [edx+497E88]
0045FC8B  |>  3A0475 207E49>||/cmp    al, byte ptr [esi*2+497E20]
跟随数据窗口,可以得到一张密码表换算表:

00497E20  61 43 62 78 63 69 64 49 65 41 66 58 67 4D 68 6B  aCbxcidIeAfXgMhk
00497E30  69 45 6A 56 6B 5A 6C 65 6D 52 6E 79 6F 42 70 4B  iEjVkZlemRnyoBpK
00497E40  71 64 72 54 73 53 74 50 75 57 76 6C 77 6A 78 44  qdrTsStPuWvlwjxD
00497E50  79 48 7A 46 41 7A 42 71 43 70 44 4F 45 6B 46 67  yHzFAzBqCpDOEkFg
00497E60  47 59 48 6D 49 74 4A 61 4B 72 4C 51 4D 6E 4E 73  GYHmItJaKrLQMnNs
00497E70  4F 75 50 55 51 47 52 4A 53 4C 54 4E 55 62 56 63  OuPUQGRJSLTNUbVc
00497E80  57 66 58 68 59 6F 5A 77 50 57 4D 00 25 30 32 64  WfXhYoZwPWM.%02d
00497E90  3A 25 30 32 64 3A 25 30 32 64 00 00 25 73 25 73  :%02d:%02d..%s%s
00497EA0  00 00 00 00 4C 64 51 73 42 63 6D 70 4A 70 61 45  ....LdQsBcmpJpaE
00497EB0  73 58 74 6F 00 00 00 00 25 30 38 6C 58 2D 25 30  sXto....%08lX-%0

换算关系如下:
a -> C  b -> q  c -> i  d -> H  e -> S  f -> X  g -> M
h -> k  i -> E  j -> V  k -> Z  l -> e  m -> R  n -> y
o -> B  p -> K  q -> d  r -> T  s -> A  t -> F
u -> W  v -> l  w -> j  x -> D  y -> I  z -> P

A -> z  B -> x  C -> p  D -> O  E -> k  F -> g  G -> Y
H -> m  I -> t  J -> a  K -> r  L -> Q  M -> n  N -> s
O -> u  P -> U  Q -> G  R -> J  S -> L  T -> N
U -> b  V -> c  W -> f  X -> h  Y -> o  Z -> w

非大小写类字母统一替换成P或W或M
注意,只能替换成同一个字母,不允许P、W、M交杂

用于补充作用的链接字符串为:LdQsBcmpJpaEsXto

算法总结:
1.先将用户名的各个字符进行替换
替换规则如下
(1).大小写字母进行查表
(2).非字母则统一替换为P或W或M
2.进行序列号长度校验
若长度小于10H,则用LdQsBcmpJpaEsXto进行补充,直至长度等于10H
若长度>=10H,则直接作为序列号


运算示例:
ID:luying10
SN:eWHEyMPPLdQsBcmp  eWHEyMWWLdQsBcmp  eWHEyMMMLdQsBcmp

一个有趣的小问题
如果ID是中文的,因为不是英文字符,所以只能用P或W或M统一替换
所以,所有中文用户名对应的序列号只有三个
PPPPPPPPLdQsBcmp  WWWWWWWWLdQsBcmp    MMMMMMMMLdQsBcmp





好了,分析完注册算法一,借着兴致,一举拿下注册算法二

试练码:
ID:luying10
SN:10000000-02000000-00300000-00040000-00005000-00000600-00000070-00000008
BTW:在地址0045FF2B 处%08lx...提示了我们序列号的格式
sn = s1-s2-s3-s4-s5-s6-s7-s8

;====================================================================|
;在地址0046022C处跟进注册算法(二)CALL->0045FDC0
;====================================================================|
0045FDC0  /$  6A FF        push    -1                              ;  //本地调用来自 0046022C
0045FDC2  |.  68 D9414700  push    004741D9                        ;  SE 处理程序安装
0045FDC7  |.  64:A1 0000000>mov    eax, dword ptr fs:[0]
0045FDCD  |.  50            push    eax
0045FDCE  |.  64:8925 00000>mov    dword ptr fs:[0], esp
0045FDD5  |.  81EC 94000000 sub    esp, 94
0045FDDB  |.  8B8424 A40000>mov    eax, dword ptr [esp+A4]          ;  EAX = [esp+A4] = 用户名
0045FDE2  |.  53            push    ebx
0045FDE3  |.  56            push    esi
0045FDE4  |.  50            push    eax                              ;  用户名压栈
0045FDE5  |.  8D4C24 10    lea    ecx, dword ptr [esp+10]
0045FDE9  |.  C74424 60 DF4>mov    dword ptr [esp+60], C95841DF
0045FDF1  |.  C74424 64 12E>mov    dword ptr [esp+64], 717AE412
0045FDF9  |.  C74424 68 ACE>mov    dword ptr [esp+68], F015E3AC
0045FE01  |.  C74424 6C B17>mov    dword ptr [esp+6C], 1127EB1
0045FE09  |.  C74424 70 895>mov    dword ptr [esp+70], 1D455E89
0045FE11  |.  C74424 74 51F>mov    dword ptr [esp+74], 5375F151
0045FE19  |.  C74424 78 6E4>mov    dword ptr [esp+78], D34D4B6E
0045FE21  |.  C74424 7C 81F>mov    dword ptr [esp+7C], 88C5F181

n = 0x88C5F181D34D4B6E5375F1511D455E8901127EB1F015E3AC717AE412C95841DF

0045FE29  |.  E8 447E0000  call    <jmp.&MFC42.#537>
0045FE2E  |.  8B8C24 B00000>mov    ecx, dword ptr [esp+B0]          ;  ECX = [esp+B0] = 序列号
0045FE35  |.  C78424 A40000>mov    dword ptr [esp+A4], 0
0045FE40  |.  51            push    ecx                              ;  序列号压栈
0045FE41  |.  8D4C24 0C    lea    ecx, dword ptr [esp+C]
0045FE45  |.  E8 287E0000  call    <jmp.&MFC42.#537>
0045FE4A  |.  8B5424 0C    mov    edx, dword ptr [esp+C]          ;  EDX = [esp+0C] = 用户名
0045FE4E  |.  8B35 A45A4700 mov    esi, dword ptr [<&MSVCRT._mbscmp>;  msvcrt._mbscmp
;---------------------------<检测用户名是否为空>---------------------|
0045FE54  |.  68 84014A00  push    004A0184                        ; /s2 = ""
0045FE59  |.  52            push    edx                              ; |s1 = "用户名"
0045FE5A  |.  C68424 AC0000>mov    byte ptr [esp+AC], 1            ; |[esp+AC] = 1
0045FE62  |.  FFD6          call    esi                              ; \_mbscmp
0045FE64  |.  83C4 08      add    esp, 8
0045FE67  |.  85C0          test    eax, eax
0045FE69  |.  0F84 0F020000 je      0046007E                        ;  //跳则挂(未实现)
;---------------------------<检测序列号是否为空>---------------------|
0045FE6F  |.  8B4424 08    mov    eax, dword ptr [esp+8]          ;  EAX = [esp+8] = 序列号
0045FE73  |.  68 84014A00  push    004A0184
0045FE78  |.  50            push    eax                              ;  序列号压栈
0045FE79  |.  FFD6          call    esi
0045FE7B  |.  83C4 08      add    esp, 8
0045FE7E  |.  85C0          test    eax, eax
0045FE80  |.  0F84 F8010000 je      0046007E                        ;  //跳则挂(未实现)
;--------------------------------------------------------------------|
0045FE86  |.  57            push    edi                              ;  序列号压栈
0045FE87  |.  6A 00        push    0                                ; 
0045FE89  |.  8D4C24 44    lea    ecx, dword ptr [esp+44]
0045FE8D  |.  E8 EE3D0000  call    00463C80                        ; 
0045FE92  |.  6A 00        push    0
0045FE94  |.  8D4C24 4C    lea    ecx, dword ptr [esp+4C]
0045FE98  |.  C68424 AC0000>mov    byte ptr [esp+AC], 2
0045FEA0  |.  E8 DB3D0000  call    00463C80                        ; 
0045FEA5  |.  B3 03        mov    bl, 3
0045FEA7  |.  68 01000100  push    10001                            ;  e = 10001H = 65537D
0045FEAC  |.  8D4C24 5C    lea    ecx, dword ptr [esp+5C]
0045FEB0  |.  889C24 AC0000>mov    byte ptr [esp+AC], bl
0045FEB7  |.  E8 C43D0000  call    00463C80                        ; 
0045FEBC  |.  8D4C24 58    lea    ecx, dword ptr [esp+58]
0045FEC0  |.  C68424 A80000>mov    byte ptr [esp+A8], 4
0045FEC8  |.  51            push    ecx
0045FEC9  |.  8D4C24 4C    lea    ecx, dword ptr [esp+4C]
0045FECD  |.  E8 0E3E0000  call    00463CE0
0045FED2  |.  8D4C24 58    lea    ecx, dword ptr [esp+58]
0045FED6  |.  889C24 A80000>mov    byte ptr [esp+A8], bl
0045FEDD  |.  E8 4E3E0000  call    00463D30
0045FEE2  |.  8D5424 60    lea    edx, dword ptr [esp+60]
0045FEE6  |.  6A 08        push    8
0045FEE8  |.  52            push    edx
0045FEE9  |.  8D4C24 48    lea    ecx, dword ptr [esp+48]
0045FEED  |.  E8 5E3C0000  call    00463B50
0045FEF2  |.  B9 08000000  mov    ecx, 8
0045FEF7  |.  33C0          xor    eax, eax                        ;  EAX置零
0045FEF9  |.  8D7C24 18    lea    edi, dword ptr [esp+18]
0045FEFD  |.  8D5424 2C    lea    edx, dword ptr [esp+2C]
0045FF01  |.  F3:AB        rep    stos dword ptr es:[edi]
0045FF03  |.  8D4424 34    lea    eax, dword ptr [esp+34]
0045FF07  |.  8D4C24 30    lea    ecx, dword ptr [esp+30]
0045FF0B  |.  50            push    eax
0045FF0C  |.  51            push    ecx
0045FF0D  |.  8D4424 30    lea    eax, dword ptr [esp+30]
0045FF11  |.  52            push    edx
0045FF12  |.  8D4C24 30    lea    ecx, dword ptr [esp+30]
0045FF16  |.  50            push    eax
0045FF17  |.  8D5424 30    lea    edx, dword ptr [esp+30]
0045FF1B  |.  51            push    ecx
0045FF1C  |.  8D4424 30    lea    eax, dword ptr [esp+30]
0045FF20  |.  52            push    edx
0045FF21  |.  8B5424 24    mov    edx, dword ptr [esp+24]          ;  EDX = [esp+24] = 序列号
0045FF25  |.  8D4C24 30    lea    ecx, dword ptr [esp+30]
;---------------------------<对假序列号进行变形运算>-----------------|
0045FF29  |.  50            push    eax
0045FF2A  |.  51            push    ecx
0045FF2B  |.  68 B87E4900  push    00497EB8                        ; |%08lx-%08lx-%08lx-%08lx-%08lx-%08lx-%08lx-%08lx\n
0045FF30  |.  52            push    edx                              ; |s
0045FF31  |.  FF15 405A4700 call    dword ptr [<&MSVCRT.sscanf>]    ; \sscanf
0045FF37  |.  8B4424 50    mov    eax, dword ptr [esp+50]          ;  s5 = 00005000
0045FF3B  |.  8B4C24 4C    mov    ecx, dword ptr [esp+4C]          ;  s4 = 00040000
0045FF3F  |.  8B7C24 48    mov    edi, dword ptr [esp+48]          ;  s3 = 00300000
0045FF43  |.  8B5424 44    mov    edx, dword ptr [esp+44]          ;  s2 = 02000000
0045FF47  |.  03C1          add    eax, ecx                        ;  s5 = s5 + s4 = 00045000
0045FF49  |.  8B4C24 5C    mov    ecx, dword ptr [esp+5C]          ;  s8 = 00000008
0045FF4D  |.  03C7          add    eax, edi                        ;  s5 = s5 + s3 = 00345000
0045FF4F  |.  8B7C24 58    mov    edi, dword ptr [esp+58]          ;  s7 = 00000070
0045FF53  |.  03C2          add    eax, edx                        ;  s5 = s5 + s2 = 02345000
0045FF55  |.  8B5424 40    mov    edx, dword ptr [esp+40]          ;  s1 = 10000000 (CDRIP.#299)
0045FF59  |.  33C8          xor    ecx, eax                        ;  s8 = s8 | s5 = 02345008
0045FF5B  |.  8B4424 54    mov    eax, dword ptr [esp+54]          ;  s6 = 00000600
0045FF5F  |.  83C4 28      add    esp, 28
0045FF62  |.  03C2          add    eax, edx                        ;  s6 = s6 + s1 = 10000600
0045FF64  |.  894C24 34    mov    dword ptr [esp+34], ecx          ;  ecx=02345008
0045FF68  |.  33F8          xor    edi, eax                        ;  s7 = s7 | s6 = 10000670
;--------------------------------------------------------------------|
0045FF6A  |.  6A 00        push    0
0045FF6C  |.  8D4C24 3C    lea    ecx, dword ptr [esp+3C]
0045FF70  |.  897C24 34    mov    dword ptr [esp+34], edi          ;  [esp+34] = edi = 10000670 (CDRIP.10000670)
0045FF74  |.  E8 073D0000  call    00463C80
0045FF79  |.  8D4C24 18    lea    ecx, dword ptr [esp+18]
0045FF7D  |.  6A 08        push    8
0045FF7F  |.  51            push    ecx                              ;  sn变形后的SerNum
0045FF80  |.  8D4C24 40    lea    ecx, dword ptr [esp+40]
0045FF84  |.  C68424 B00000>mov    byte ptr [esp+B0], 5
0045FF8C  |.  E8 BF3B0000  call    00463B50                        ;  rsa_de(),计算 c = SerNum^e mod n
0045FF91  |.  8D5424 38    lea    edx, dword ptr [esp+38]
0045FF95  |.  8D4424 50    lea    eax, dword ptr [esp+50]
0045FF99  |.  52            push    edx
0045FF9A  |.  50            push    eax
0045FF9B  |.  8D4C24 48    lea    ecx, dword ptr [esp+48]
0045FF9F  |.  E8 0CC5FFFF  call    0045C4B0                        ;  结果以大数输出 c
0045FFA4  |.  B9 08000000  mov    ecx, 8
0045FFA9  |.  33C0          xor    eax, eax
0045FFAB  |.  8D7C24 18    lea    edi, dword ptr [esp+18]
0045FFAF  |.  6A 08        push    8
0045FFB1  |.  F3:AB        rep    stos dword ptr es:[edi]
0045FFB3  |.  8D4C24 1C    lea    ecx, dword ptr [esp+1C]
0045FFB7  |.  C68424 AC0000>mov    byte ptr [esp+AC], 6
0045FFBF  |.  51            push    ecx
0045FFC0  |.  8D4C24 58    lea    ecx, dword ptr [esp+58]
0045FFC4  |.  E8 C73B0000  call    00463B90                        ;  大数结果转为十六进制字节串
0045FFC9  |.  B9 08000000  mov    ecx, 8
0045FFCE  |.  33C0          xor    eax, eax                        ;  EAX置零
0045FFD0  |.  8DBC24 800000>lea    edi, dword ptr [esp+80]
0045FFD7  |.  F3:AB        rep    stos dword ptr es:[edi]          ; 
0045FFD9  |.  5F            pop    edi                              ;  序列号
;-------------<交换每一个dword的高位,低位>
0045FFDA  |>  8A5404 17    /mov    dl, byte ptr [esp+eax+17]
0045FFDE  |.  8A4C04 16    |mov    cl, byte ptr [esp+eax+16]
0045FFE2  |.  885404 7C    |mov    byte ptr [esp+eax+7C], dl
0045FFE6  |.  8B5404 14    |mov    edx, dword ptr [esp+eax+14]
0045FFEA  |.  884C04 7D    |mov    byte ptr [esp+eax+7D], cl
0045FFEE  |.  8A4C04 14    |mov    cl, byte ptr [esp+eax+14]
0045FFF2  |.  C1EA 08      |shr    edx, 8
0045FFF5  |.  885404 7E    |mov    byte ptr [esp+eax+7E], dl
0045FFF9  |.  884C04 7F    |mov    byte ptr [esp+eax+7F], cl
0045FFFD  |.  83C0 04      |add    eax, 4                          ;  EAX = EAX + 4
00460000  |.  83F8 20      |cmp    eax, 20
00460003  |.^ 7C D5        \jl      short 0045FFDA                  ;  //循环(8次)

循环前:
0012EEF4  C4 3A 70 C1 5B DE 26 77 90 A1 42 3B E5 D8 0E 8A  ?p羀?w悺B;遑
0012EF04  40 B3 B2 FE 55 96 4A 1B EC B3 E0 78 D2 AE 42 6A  @巢㑳朖斐鄕耶Bj

循环后:
0012EF5C  C1 70 3A C4 77 26 DE 5B 3B 42 A1 90 8A 0E D8 E5  羛:膚&轠;B?劐
0012EF6C  FE B2 B3 40 1B 4A 96 55 78 E0 B3 EC 6A 42 AE D2  矦J朥x喑靔B

;--------------------------------------------------------------------|
00460005  |.  8D5424 7C    lea    edx, dword ptr [esp+7C]          ;  加载转换后的地址
00460009  |.  8D4C24 10    lea    ecx, dword ptr [esp+10]          ;  //固定字符串地址
0046000D  |.  52            push    edx
0046000E  |.  E8 5F7C0000  call    <jmp.&MFC42.#537>
00460013  |.  8B4424 10    mov    eax, dword ptr [esp+10]          ;  堆栈 ss:[0012EEF0]=02449248
00460017  |.  8B4C24 0C    mov    ecx, dword ptr [esp+C]          ;  堆栈 ss:[0012EEEC]=003FB228, (ASCII "luying10")
0046001B  |.  50            push    eax                              ;  转化后数值的地址
0046001C  |.  51            push    ecx                              ;  用户名
0046001D  |.  FFD6          call    esi                              ;  比较
0046001F  |.  83C4 08      add    esp, 8
00460022  |.  8D4C24 10    lea    ecx, dword ptr [esp+10]
00460026  |.  85C0          test    eax, eax
00460028  |.  C68424 A40000>mov    byte ptr [esp+A4], 6
00460030  |.  0F84 86000000 je      004600BC                        ;  //关键跳
;--------------------------------------------------------------------|
00460036  |.  E8 257C0000  call    <jmp.&MFC42.#800>
0046003B  |.  8D4C24 4C    lea    ecx, dword ptr [esp+4C]
0046003F  |.  C68424 A40000>mov    byte ptr [esp+A4], 5
00460047  |.  E8 E43C0000  call    00463D30
0046004C  |.  8D4C24 34    lea    ecx, dword ptr [esp+34]
00460050  |.  889C24 A40000>mov    byte ptr [esp+A4], bl
00460057  |.  E8 D43C0000  call    00463D30
0046005C  |.  8D4C24 44    lea    ecx, dword ptr [esp+44]
00460060  |.  C68424 A40000>mov    byte ptr [esp+A4], 8
00460068  |.  E8 C33C0000  call    00463D30
0046006D  |.  8D4C24 3C    lea    ecx, dword ptr [esp+3C]
00460071  |.  C68424 A40000>mov    byte ptr [esp+A4], 1
00460079  |.  E8 B23C0000  call    00463D30
0046007E  |>  8D4C24 08    lea    ecx, dword ptr [esp+8]
00460082  |.  C68424 A40000>mov    byte ptr [esp+A4], 0
0046008A  |.  E8 D17B0000  call    <jmp.&MFC42.#800>
0046008F  |.  8D4C24 0C    lea    ecx, dword ptr [esp+C]
00460093  |.  C78424 A40000>mov    dword ptr [esp+A4], -1
0046009E  |.  E8 BD7B0000  call    <jmp.&MFC42.#800>
004600A3  |.  5E            pop    esi
004600A4  |.  33C0          xor    eax, eax                        ;  EAX置零
004600A6  |.  5B            pop    ebx
004600A7  |.  8B8C24 940000>mov    ecx, dword ptr [esp+94]
004600AE  |.  64:890D 00000>mov    dword ptr fs:[0], ecx
004600B5  |.  81C4 A0000000 add    esp, 0A0
004600BB  |.  C3            retn                                    ;  //返回(EAX=0)
;--------------------------------------------------------------------|
004600BC  |>  E8 9F7B0000  call    <jmp.&MFC42.#800>
004600C1  |.  8D4C24 4C    lea    ecx, dword ptr [esp+4C]
004600C5  |.  C68424 A40000>mov    byte ptr [esp+A4], 5
004600CD  |.  E8 5E3C0000  call    00463D30
004600D2  |.  8D4C24 34    lea    ecx, dword ptr [esp+34]
004600D6  |.  889C24 A40000>mov    byte ptr [esp+A4], bl
004600DD  |.  E8 4E3C0000  call    00463D30
004600E2  |.  8D4C24 44    lea    ecx, dword ptr [esp+44]
004600E6  |.  C68424 A40000>mov    byte ptr [esp+A4], 9
004600EE  |.  E8 3D3C0000  call    00463D30
004600F3  |.  8D4C24 3C    lea    ecx, dword ptr [esp+3C]
004600F7  |.  C68424 A40000>mov    byte ptr [esp+A4], 1
004600FF  |.  E8 2C3C0000  call    00463D30
00460104  |.  8D4C24 08    lea    ecx, dword ptr [esp+8]
00460108  |.  C68424 A40000>mov    byte ptr [esp+A4], 0
00460110  |.  E8 4B7B0000  call    <jmp.&MFC42.#800>
00460115  |.  8D4C24 0C    lea    ecx, dword ptr [esp+C]
00460119  |.  C78424 A40000>mov    dword ptr [esp+A4], -1
00460124  |.  E8 377B0000  call    <jmp.&MFC42.#800>
00460129  |.  8B8C24 9C0000>mov    ecx, dword ptr [esp+9C]
00460130  |.  5E            pop    esi
00460131  |.  B8 01000000  mov    eax, 1                          ;  EAX = 1
00460136  |.  5B            pop    ebx
00460137  |.  64:890D 00000>mov    dword ptr fs:[0], ecx
0046013E  |.  81C4 A0000000 add    esp, 0A0
00460144  \.  C3            retn                                    ;  //返回(EAX=1)
;====================================================================|


算法总结:
1.对输入的假序列号进行变换
sn = s1-s2-s3-s4-s5-s6-s7-s8

s6' = s6 + s1
s7' = s7 | (s6 + s1)
s8' = s8 | (s2 + s3 + s4 + s5)

SerNum = s1-s2-s3-s4-s5-s6'-s7'-s8'

2.运算
  c = SerNum ^ e mod n;

3.比较c和name


利用RSATool搞定RSA参数:

n = 88C5F181D34D4B6E5375F1511D455E8901127EB1F015E3AC717AE412C95841DF
e = 10001

n = p * q

p:92D9586271DFD8D47C9AE783DED37E9F
q:EE6F5C9077D0A54887558B9CA262B4C1

d:7AAB6636F5681EDE3D96CBAFDF9BE6F38A66563EB122E21AE8B94121DC164781

逆推:
1.将用户名每四个字符倒序排列,并且转成十六进制
2.进行ESA运算
3.计算SerNum
4.进行XOR运算,求得最终的serial number

ID:luying10
SN:8F2D4BBE-A742BFC7-0BBDF498-9E74023E-8AFCE799-AA97BDD7-1B8A741B-8980044D


通过文本,希望读者能够掌握两类比较典型的算法
1.查表类算法(密码表字符替换)
2.密码学算法(RSA)


关于算法分析推荐一篇文章:

《Ultra-$hare系列算法分析》 http://www.unpack.cn/viewthread.php?tid=19935

该实例特点:
1.非明码比较
2.运用密码学加密算法
3.有对字符和字符串的操作
4.一些隐含的东西(连字符,序列号头部特定字符等)

本篇是菜鸟学算法系列最后一篇,有些地方写的潦草,兄弟们多多担待~
希望各位兄弟早日步入算法分析的大门```.o(n_n)o.

                            鹭影依凌[2007.12.15]

地主 发表时间: 07-12-17 11:02

论坛: 编程破解

20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon

粤ICP备05087286号