菜鸟学算法<三>算法分析篇
作者:鹭影依凌转贴自:一蓑烟雨
声明:
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:
0045FB9D|.50 push eax
0045FB9E|.64:8925 00000>mov dword ptr fs:, esp
0045FBA5|.83EC 14 sub esp, 14
0045FBA8|.8B4424 24 mov eax, dword ptr ;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
0045FBB5|.E8 B8800000 call <jmp.&MFC42.#537>
0045FBBA|.8D4C24 14 lea ecx, dword ptr ;ECX = 用户名的地址
0045FBBE|.C74424 2C 000>mov dword ptr , 0
0045FBC6|.E8 E5840000 call <jmp.&MFC42.#6282>
0045FBCB|.8D4C24 14 lea ecx, dword ptr
0045FBCF|.E8 D6840000 call <jmp.&MFC42.#6283>
0045FBD4|.6A 20 push 20
0045FBD6|.8D4C24 18 lea ecx, dword ptr
0045FBDA|.E8 71870000 call <jmp.&MFC42.#2915>
0045FBDF|.8B4C24 38 mov ecx, dword ptr ;ECX = 序列号
0045FBE3|.8BD8 mov ebx, eax ;EBX = 用户名
0045FBE5|.51 push ecx ;序列号压栈
0045FBE6|.8D4C24 14 lea ecx, dword ptr
0045FBEA|.E8 83900000 call <jmp.&MFC42.#537>
0045FBEF|.8D4C24 10 lea ecx, dword ptr
0045FBF3|.C64424 2C 01mov byte ptr , 1
0045FBF8|.E8 B3840000 call <jmp.&MFC42.#6282>
0045FBFD|.8D4C24 10 lea ecx, dword ptr
0045FC01|.E8 A4840000 call <jmp.&MFC42.#6283>
0045FC06|.6A 20 push 20
0045FC08|.8D4C24 14 lea ecx, dword ptr
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 , edx ; = 序列号
0045FC20|.F2:AE repne scas byte ptr es:
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:
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:
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:
0045FC4D|.F7D1 not ecx
0045FC4F|.49 dec ecx ;ECX = 序列号长度
0045FC50|.0F84 36010000 je 0045FD8C ;//跳则挂(未实现)
;---------------------------<注册运算验证>-----------------------------|
0045FC56|.894424 38 mov dword ptr , eax ;初始化为0
;------------------------------------[第一层开始]
0045FC5A|>8B5424 38 /mov edx, dword ptr ;EDX =
0045FC5E|.8D4C24 34 |lea ecx, dword ptr ;加载序列号地址
0045FC62|.8A82 887E4900 |mov al, byte ptr ;三次依次出现'P'/'W'/'M'
0045FC68|.884424 18 |mov byte ptr , al ; = 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:
0045FC7C|.F7D1 |not ecx
0045FC7E|.49 |dec ecx ;ECX = 用户名长度
0045FC7F|.C64424 2C 02|mov byte ptr , 2 ; = 2
0045FC84|.74 4B |je short 0045FCD1 ;//作用:跳过下面循环体
;---------------------------[第二层开始] [对用户名字符进行查表替换]
0045FC86|>8A042B |/mov al, byte ptr ;用户名的第i个字符
0045FC89|.33F6 ||xor esi, esi ;ESI置零
;---------[第三层开始] [对第i个字符进行查表替换]
0045FC8B|>3A0475 207E49>||/cmp al, byte ptr ;查表比较
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 ;找到密码表中对应的字母
0045FCA3|.51 ||push ecx
0045FCA4|.8D4C24 38 ||lea ecx, dword ptr
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 ;
0045FCB6|.8D4C24 34 ||lea ecx, dword ptr ;加载序列号地址
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:
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 ;(ASCII "eWHEyMPP"
0045FCD5|.8B48 F8 |mov ecx, dword ptr ;字符串的长度
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 ;加载补充字符串地址
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 ;加载上面运算所得字符串地址
0045FCFB|.C64424 30 03|mov byte ptr , 3
0045FD00|.E8 25820000 |call <jmp.&MFC42.#939> ;将两字符川进行链接
0045FD05|.8D4C24 1C |lea ecx, dword ptr
0045FD09|.C64424 2C 02|mov byte ptr , 2
0045FD0E|.E8 4D7F0000 |call <jmp.&MFC42.#800>
0045FD13|.8B4424 34 |mov eax, dword ptr ;(ASCII "eWHEyMPPLdQsBcmp"
0045FD17|>8B4C24 20 |mov ecx, dword ptr ;假码
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
0045FD2A|.85C0 |test eax, eax ;测试标志位
0045FD2C|.C64424 2C 01|mov byte ptr , 1 ; = 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
0045FD3E|.40 |inc eax ;EAX++
0045FD3F|.83F8 03 |cmp eax, 3
0045FD42|.894424 38 |mov dword ptr , eax ; = 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 ;加载假码地址
0045FD5C|.C64424 2C 00mov byte ptr , 0
0045FD61|.E8 FA7E0000 call <jmp.&MFC42.#800>
0045FD66|.8D4C24 14 lea ecx, dword ptr ;加载用户名地址
0045FD6A|.C74424 2C FFF>mov dword ptr , -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
0045FD81|.64:890D 00000>mov dword ptr fs:, ecx
0045FD88|.83C4 20 add esp, 20
0045FD8B|.C3 retn ;//返回(EAX=ESI)
;-------------<跳到下面就算玩完~~~>
0045FD8C|>8D4C24 10 lea ecx, dword ptr ;跳转来自 0045FC32, 0045FC41, 0045FC50
0045FD90|.C64424 2C 00mov byte ptr , 0
0045FD95|.E8 C67E0000 call <jmp.&MFC42.#800>
0045FD9A|.8D4C24 14 lea ecx, dword ptr
0045FD9E|.897424 2C mov dword ptr , esi
0045FDA2|.E8 B97E0000 call <jmp.&MFC42.#800>
0045FDA7|.8B4C24 24 mov ecx, dword ptr
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:, ecx
0045FDB8|.83C4 20 add esp, 20
0045FDBB\.C3 retn ;//返回(EAX=0)
;====================================================================|
在运行到0045FC8B时候,
0045FC62|.8A82 887E4900 |mov al, byte ptr
0045FC8B|>3A0475 207E49>||/cmp al, byte ptr
跟随数据窗口,可以得到一张密码表换算表:
00497E2061 43 62 78 63 69 64 49 65 41 66 58 67 4D 68 6BaCbxcidIeAfXgMhk
00497E3069 45 6A 56 6B 5A 6C 65 6D 52 6E 79 6F 42 70 4BiEjVkZlemRnyoBpK
00497E4071 64 72 54 73 53 74 50 75 57 76 6C 77 6A 78 44qdrTsStPuWvlwjxD
00497E5079 48 7A 46 41 7A 42 71 43 70 44 4F 45 6B 46 67yHzFAzBqCpDOEkFg
00497E6047 59 48 6D 49 74 4A 61 4B 72 4C 51 4D 6E 4E 73GYHmItJaKrLQMnNs
00497E704F 75 50 55 51 47 52 4A 53 4C 54 4E 55 62 56 63OuPUQGRJSLTNUbVc
00497E8057 66 58 68 59 6F 5A 77 50 57 4D 00 25 30 32 64WfXhYoZwPWM.%02d
00497E903A 25 30 32 64 3A 25 30 32 64 00 00 25 73 25 73:%02d:%02d..%s%s
00497EA000 00 00 00 4C 64 51 73 42 63 6D 70 4A 70 61 45....LdQsBcmpJpaE
00497EB073 58 74 6F 00 00 00 00 25 30 38 6C 58 2D 25 30sXto....%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交杂
用于补充作用的链接字符串为dQsBcmpJpaEsXto
算法总结:
1.先将用户名的各个字符进行替换
替换规则如下
(1).大小写字母进行查表
(2).非字母则统一替换为P或W或M
2.进行序列号长度校验
若长度小于10H,则用LdQsBcmpJpaEsXto进行补充,直至长度等于10H
若长度>=10H,则直接作为序列号
运算示例:
ID:luying10
SN:eWHEyMPPLdQsBcmpeWHEyMWWLdQsBcmpeWHEyMMMLdQsBcmp
一个有趣的小问题
如果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:
0045FDCD|.50 push eax
0045FDCE|.64:8925 00000>mov dword ptr fs:, esp
0045FDD5|.81EC 94000000 sub esp, 94
0045FDDB|.8B8424 A40000>mov eax, dword ptr ;EAX = = 用户名
0045FDE2|.53 push ebx
0045FDE3|.56 push esi
0045FDE4|.50 push eax ;用户名压栈
0045FDE5|.8D4C24 10 lea ecx, dword ptr
0045FDE9|.C74424 60 DF4>mov dword ptr , C95841DF
0045FDF1|.C74424 64 12E>mov dword ptr , 717AE412
0045FDF9|.C74424 68 ACE>mov dword ptr , F015E3AC
0045FE01|.C74424 6C B17>mov dword ptr , 1127EB1
0045FE09|.C74424 70 895>mov dword ptr , 1D455E89
0045FE11|.C74424 74 51F>mov dword ptr , 5375F151
0045FE19|.C74424 78 6E4>mov dword ptr , D34D4B6E
0045FE21|.C74424 7C 81F>mov dword ptr , 88C5F181
n = 0x88C5F181D34D4B6E5375F1511D455E8901127EB1F015E3AC717AE412C95841DF
0045FE29|.E8 447E0000 call <jmp.&MFC42.#537>
0045FE2E|.8B8C24 B00000>mov ecx, dword ptr ;ECX = = 序列号
0045FE35|.C78424 A40000>mov dword ptr , 0
0045FE40|.51 push ecx ;序列号压栈
0045FE41|.8D4C24 0C lea ecx, dword ptr
0045FE45|.E8 287E0000 call <jmp.&MFC42.#537>
0045FE4A|.8B5424 0C mov edx, dword ptr ;EDX = = 用户名
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 , 1 ; | = 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 ;EAX = = 序列号
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
0045FE8D|.E8 EE3D0000 call 00463C80 ;
0045FE92|.6A 00 push 0
0045FE94|.8D4C24 4C lea ecx, dword ptr
0045FE98|.C68424 AC0000>mov byte ptr , 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
0045FEB0|.889C24 AC0000>mov byte ptr , bl
0045FEB7|.E8 C43D0000 call 00463C80 ;
0045FEBC|.8D4C24 58 lea ecx, dword ptr
0045FEC0|.C68424 A80000>mov byte ptr , 4
0045FEC8|.51 push ecx
0045FEC9|.8D4C24 4C lea ecx, dword ptr
0045FECD|.E8 0E3E0000 call 00463CE0
0045FED2|.8D4C24 58 lea ecx, dword ptr
0045FED6|.889C24 A80000>mov byte ptr , bl
0045FEDD|.E8 4E3E0000 call 00463D30
0045FEE2|.8D5424 60 lea edx, dword ptr
0045FEE6|.6A 08 push 8
0045FEE8|.52 push edx
0045FEE9|.8D4C24 48 lea ecx, dword ptr
0045FEED|.E8 5E3C0000 call 00463B50
0045FEF2|.B9 08000000 mov ecx, 8
0045FEF7|.33C0 xor eax, eax ;EAX置零
0045FEF9|.8D7C24 18 lea edi, dword ptr
0045FEFD|.8D5424 2C lea edx, dword ptr
0045FF01|.F3:AB rep stos dword ptr es:
0045FF03|.8D4424 34 lea eax, dword ptr
0045FF07|.8D4C24 30 lea ecx, dword ptr
0045FF0B|.50 push eax
0045FF0C|.51 push ecx
0045FF0D|.8D4424 30 lea eax, dword ptr
0045FF11|.52 push edx
0045FF12|.8D4C24 30 lea ecx, dword ptr
0045FF16|.50 push eax
0045FF17|.8D5424 30 lea edx, dword ptr
0045FF1B|.51 push ecx
0045FF1C|.8D4424 30 lea eax, dword ptr
0045FF20|.52 push edx
0045FF21|.8B5424 24 mov edx, dword ptr ;EDX = = 序列号
0045FF25|.8D4C24 30 lea ecx, dword ptr
;---------------------------<对假序列号进行变形运算>-----------------|
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 ;s5 = 00005000
0045FF3B|.8B4C24 4C mov ecx, dword ptr ;s4 = 00040000
0045FF3F|.8B7C24 48 mov edi, dword ptr ;s3 = 00300000
0045FF43|.8B5424 44 mov edx, dword ptr ;s2 = 02000000
0045FF47|.03C1 add eax, ecx ;s5 = s5 + s4 = 00045000
0045FF49|.8B4C24 5C mov ecx, dword ptr ;s8 = 00000008
0045FF4D|.03C7 add eax, edi ;s5 = s5 + s3 = 00345000
0045FF4F|.8B7C24 58 mov edi, dword ptr ;s7 = 00000070
0045FF53|.03C2 add eax, edx ;s5 = s5 + s2 = 02345000
0045FF55|.8B5424 40 mov edx, dword ptr ;s1 = 10000000 (CDRIP.#299)
0045FF59|.33C8 xor ecx, eax ;s8 = s8 | s5 = 02345008
0045FF5B|.8B4424 54 mov eax, dword ptr ;s6 = 00000600
0045FF5F|.83C4 28 add esp, 28
0045FF62|.03C2 add eax, edx ;s6 = s6 + s1 = 10000600
0045FF64|.894C24 34 mov dword ptr , ecx ;ecx=02345008
0045FF68|.33F8 xor edi, eax ;s7 = s7 | s6 = 10000670
;--------------------------------------------------------------------|
0045FF6A|.6A 00 push 0
0045FF6C|.8D4C24 3C lea ecx, dword ptr
0045FF70|.897C24 34 mov dword ptr , edi ; = edi = 10000670 (CDRIP.10000670)
0045FF74|.E8 073D0000 call 00463C80
0045FF79|.8D4C24 18 lea ecx, dword ptr
0045FF7D|.6A 08 push 8
0045FF7F|.51 push ecx ;sn变形后的SerNum
0045FF80|.8D4C24 40 lea ecx, dword ptr
0045FF84|.C68424 B00000>mov byte ptr , 5
0045FF8C|.E8 BF3B0000 call 00463B50 ;rsa_de(),计算 c = SerNum^e mod n
0045FF91|.8D5424 38 lea edx, dword ptr
0045FF95|.8D4424 50 lea eax, dword ptr
0045FF99|.52 push edx
0045FF9A|.50 push eax
0045FF9B|.8D4C24 48 lea ecx, dword ptr
0045FF9F|.E8 0CC5FFFF call 0045C4B0 ; 结果以大数输出 c
0045FFA4|.B9 08000000 mov ecx, 8
0045FFA9|.33C0 xor eax, eax
0045FFAB|.8D7C24 18 lea edi, dword ptr
0045FFAF|.6A 08 push 8
0045FFB1|.F3:AB rep stos dword ptr es:
0045FFB3|.8D4C24 1C lea ecx, dword ptr
0045FFB7|.C68424 AC0000>mov byte ptr , 6
0045FFBF|.51 push ecx
0045FFC0|.8D4C24 58 lea ecx, dword ptr
0045FFC4|.E8 C73B0000 call 00463B90 ;大数结果转为十六进制字节串
0045FFC9|.B9 08000000 mov ecx, 8
0045FFCE|.33C0 xor eax, eax ;EAX置零
0045FFD0|.8DBC24 800000>lea edi, dword ptr
0045FFD7|.F3:AB rep stos dword ptr es: ;
0045FFD9|.5F pop edi ; 序列号
;-------------<交换每一个dword的高位,低位>
0045FFDA|>8A5404 17 /mov dl, byte ptr
0045FFDE|.8A4C04 16 |mov cl, byte ptr
0045FFE2|.885404 7C |mov byte ptr , dl
0045FFE6|.8B5404 14 |mov edx, dword ptr
0045FFEA|.884C04 7D |mov byte ptr , cl
0045FFEE|.8A4C04 14 |mov cl, byte ptr
0045FFF2|.C1EA 08 |shr edx, 8
0045FFF5|.885404 7E |mov byte ptr , dl
0045FFF9|.884C04 7F |mov byte ptr , cl
0045FFFD|.83C0 04 |add eax, 4 ;EAX = EAX + 4
00460000|.83F8 20 |cmp eax, 20
00460003|.^ 7C D5 \jl short 0045FFDA ;//循环(8次)
循环前:
0012EEF4C4 3A 70 C1 5B DE 26 77 90 A1 42 3B E5 D8 0E 8A?p羀?w悺B;遑
0012EF0440 B3 B2 FE 55 96 4A 1B EC B3 E0 78 D2 AE 42 6A@巢?朖斐鄕耶Bj
循环后:
0012EF5CC1 70 3A C4 77 26 DE 5B 3B 42 A1 90 8A 0E D8 E5羛:膚&轠;B??劐
0012EF6CFE 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 ;加载转换后的地址
00460009|.8D4C24 10 lea ecx, dword ptr ;//固定字符串地址
0046000D|.52 push edx
0046000E|.E8 5F7C0000 call <jmp.&MFC42.#537>
00460013|.8B4424 10 mov eax, dword ptr ;堆栈 ss:=02449248
00460017|.8B4C24 0C mov ecx, dword ptr ;堆栈 ss:=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
00460026|.85C0 test eax, eax
00460028|.C68424 A40000>mov byte ptr , 6
00460030|.0F84 86000000 je 004600BC ;//关键跳
;--------------------------------------------------------------------|
00460036|.E8 257C0000 call <jmp.&MFC42.#800>
0046003B|.8D4C24 4C lea ecx, dword ptr
0046003F|.C68424 A40000>mov byte ptr , 5
00460047|.E8 E43C0000 call 00463D30
0046004C|.8D4C24 34 lea ecx, dword ptr
00460050|.889C24 A40000>mov byte ptr , bl
00460057|.E8 D43C0000 call 00463D30
0046005C|.8D4C24 44 lea ecx, dword ptr
00460060|.C68424 A40000>mov byte ptr , 8
00460068|.E8 C33C0000 call 00463D30
0046006D|.8D4C24 3C lea ecx, dword ptr
00460071|.C68424 A40000>mov byte ptr , 1
00460079|.E8 B23C0000 call 00463D30
0046007E|>8D4C24 08 lea ecx, dword ptr
00460082|.C68424 A40000>mov byte ptr , 0
0046008A|.E8 D17B0000 call <jmp.&MFC42.#800>
0046008F|.8D4C24 0C lea ecx, dword ptr
00460093|.C78424 A40000>mov dword ptr , -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
004600AE|.64:890D 00000>mov dword ptr fs:, 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
004600C5|.C68424 A40000>mov byte ptr , 5
004600CD|.E8 5E3C0000 call 00463D30
004600D2|.8D4C24 34 lea ecx, dword ptr
004600D6|.889C24 A40000>mov byte ptr , bl
004600DD|.E8 4E3C0000 call 00463D30
004600E2|.8D4C24 44 lea ecx, dword ptr
004600E6|.C68424 A40000>mov byte ptr , 9
004600EE|.E8 3D3C0000 call 00463D30
004600F3|.8D4C24 3C lea ecx, dword ptr
004600F7|.C68424 A40000>mov byte ptr , 1
004600FF|.E8 2C3C0000 call 00463D30
00460104|.8D4C24 08 lea ecx, dword ptr
00460108|.C68424 A40000>mov byte ptr , 0
00460110|.E8 4B7B0000 call <jmp.&MFC42.#800>
00460115|.8D4C24 0C lea ecx, dword ptr
00460119|.C78424 A40000>mov dword ptr , -1
00460124|.E8 377B0000 call <jmp.&MFC42.#800>
00460129|.8B8C24 9C0000>mov ecx, dword ptr
00460130|.5E pop esi
00460131|.B8 01000000 mov eax, 1 ;EAX = 1
00460136|.5B pop ebx
00460137|.64:890D 00000>mov dword ptr fs:, 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. 谢谢提供,辛苦了/:L 谢谢提供,辛苦了/:L /:L 好东西~~~~~~~~~~学习了呵呵~~ 谢谢提供 通俗易懂,谢谢 谢谢提供,辛苦了/:001 /:001 标志位测试
是什么,
看来还要慢慢的学习才行。 /:011 这个。。。这个 。。。很好 很强大
页:
[1]
2