【文章作者】: 斜阳残雪
【作者邮箱】: zlm324@126.com
【下载地址】: 附件提供
【编写语言】: VC++ 6.0
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
发帖前没有搜索,不知道发重了没有。
--------------------------------------------------------------------------------
【详细过程】
OD载入,找关键字,发现"Good job,man!",跟随,来到这里:
0040106D . 68 E9030000 push 3E9 ; /ControlID = 3E9 (1001.)
00401072 . 56 push esi ; |hWnd
00401073 . FF15 B4504000 call dword ptr [<&USER32.GetDlgItem>] ; \GetDlgItem
00401079 . 50 push eax ; /hWnd
0040107A . FF15 CC504000 call dword ptr [<&USER32.SetFocus>] ; \SetFocus
00401080 . 56 push esi
00401081 . E8 AA000000 call 00401130 ;关键Call
00401086 . 83C4 04 add esp, 4
00401089 . 85C0 test eax, eax
0040108B . 5E pop esi
0040108C . 0F84 8D000000 je 0040111F ;跳走则失败
00401092 . 6A 40 push 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
00401094 . 68 C4604000 push 004060C4 ; |Title = "Congratulations"
00401099 . 68 B4604000 push 004060B4 ; |Text = "Good job, man!"
0040109E . 6A 00 push 0 ; |hOwner = NULL
004010A0 . FF15 B8504000 call dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA
004010A6 . 33C0 xor eax, eax
004010A8 . C2 1000 retn 10
我们跟进关键Call:
(前面有一堆废话,略去)
004011B6 |. 68 C9000000 push 0C9 ; /Count = C9 (201.)
004011BB |. 52 push edx ; |Buffer
004011BC |. 68 E8030000 push 3E8 ; |ControlID = 3E8 (1000.)
004011C1 |. 50 push eax ; |hWnd
004011C2 |. FF15 AC504000 call dword ptr [<&USER32.GetDlgItemTe>; \GetDlgItemTextA
004011C8 |. 8BF0 mov esi, eax
004011CA |. 83FE 06 cmp esi, 6
004011CD |. 0F8C 3B020000 jl 0040140E
004011D3 |. 83FE 0F cmp esi, 0F ; 姓名在6~16个字符之间
004011D6 |. 0F8F 32020000 jg 0040140E
004011DC |. 8D4C24 4C lea ecx, dword ptr [esp+4C]
004011E0 |. 56 push esi
004011E1 |. 51 push ecx
004011E2 |. E8 39020000 call 00401420 ; 小写字母转换成大写
004011E7 |. 83C4 08 add esp, 8
004011EA |. 85C0 test eax, eax
004011EC |. 0F84 1C020000 je 0040140E
004011F2 |. 33ED xor ebp, ebp
004011F4 |. 33C9 xor ecx, ecx
004011F6 |. 3BF5 cmp esi, ebp
004011F8 |. 7E 2F jle short 00401229
004011FA |> 33FF /xor edi, edi ; 姓名处理过程,详见NameAnalysis
004011FC |. 3BCD |cmp ecx, ebp
004011FE |. 7E 24 |jle short 00401224
00401200 |> 8A543C 4C |/mov dl, byte ptr [esp+edi+4C]
00401204 |. 8A440C 4C ||mov al, byte ptr [esp+ecx+4C]
00401208 |. 3AD0 ||cmp dl, al
0040120A |. 75 13 ||jnz short 0040121F
0040120C |. 3BCE ||cmp ecx, esi
0040120E |. 8BC1 ||mov eax, ecx
00401210 |. 7D 0D ||jge short 0040121F ;此循环用于去掉一个字符后把后面的移动到前面去
00401212 |> 8A5404 4D ||/mov dl, byte ptr [esp+eax+4D]
00401216 |. 885404 4C |||mov byte ptr [esp+eax+4C], dl
0040121A |. 40 |||inc eax
0040121B |. 3BC6 |||cmp eax, esi
0040121D |.^ 7C F3 ||\jl short 00401212
0040121F |> 47 ||inc edi
00401220 |. 3BF9 ||cmp edi, ecx
00401222 |.^ 7C DC |\jl short 00401200
00401224 |> 41 |inc ecx
00401225 |. 3BCE |cmp ecx, esi
00401227 |.^ 7C D1 \jl short 004011FA
00401229 |> 8D4424 4C lea eax, dword ptr [esp+4C]
0040122D |. 50 push eax ; /String
0040122E |. FF15 04504000 call dword ptr [<&KERNEL32.lstrlenA>] ; \取处理完之后的姓名长度
00401234 |. 8BF0 mov esi, eax
00401236 |. 83FE 06 cmp esi, 6
00401239 |. 0F8C CF010000 jl 0040140E ; 处理过的姓名必须长于6字节
NameAnalysis代码:
Function NameProc(Name As String) As String
Dim n As Integer
For i = 2 To Len(Name)
If i > Len(Name) Then n = Len(Name) Else n = i
For k = 1 To n - 1
If Mid(Name, k, 1) = Mid(Name, i, 1) Then
If k <= i Then
Name = Left(Name, i - 1) & Right(Name, Len(Name) - i)
Else
Name = Left(Name, Len(Name) - 1)
End If
End If
Next k
Next i
NameProc = Name
End Function
这段程序是我按照汇编代码翻译的,没有优化,唯一的不同在于VB不能处理chr(0),所以有一个折中处理。
这段程序貌似是把姓名中重复的字符给去掉了,但细看的话却右不尽相同,
应该是去掉了一定范围内的重复字符,我也说不太清楚,毕竟这只是一段程序,大家可以与汇编代码和内存数据比对着理解。
例如:"PEDIYABCBIT"就会变成"PEDIYABCIT",近处的"B"被去掉了,但是远处的"I"却得以保留。
接下来:
0040123F |. 8D4C24 4C lea ecx, dword ptr [esp+4C]
00401243 |. 8D5424 20 lea edx, dword ptr [esp+20]
00401247 |. 51 push ecx ; /String2
00401248 |. 52 push edx ; |String1
00401249 |. FF15 00504000 call dword ptr [<&KERNEL32.lstrcpyA>] ; \lstrcpyA
0040124F |. B3 41 mov bl, 41 ; 41="A"
00401251 |. 896C24 10 mov dword ptr [esp+10], ebp
00401255 |. 8D7434 20 lea esi, dword ptr [esp+esi+20] ; 有效姓名长度入esi
00401259 |> 80FB 4A /cmp bl, 4A ; 4A="J"
0040125C |. 75 0A |jnz short 00401268
0040125E |. B3 49 |mov bl, 49 ; Change "J" into "I"
00401260 |. C74424 10 010>|mov dword ptr [esp+10], 1
00401268 |> 0FBEC3 |movsx eax, bl
0040126B |. 8D4C24 20 |lea ecx, dword ptr [esp+20]
0040126F |. 50 |push eax
00401270 |. 51 |push ecx
00401271 |. E8 2A020000 |call 004014A0 ;此Call的作用根据处理后的结果猜测而得,里面的内容看不懂-_-!
00401276 |. 83C4 08 |add esp, 8
00401279 |. 85C0 |test eax, eax
0040127B |. 75 03 |jnz short 00401280
0040127D |. 881E |mov byte ptr [esi], bl
0040127F |. 46 |inc esi
00401280 |> 8A5424 10 |mov dl, byte ptr [esp+10]
00401284 |. 896C24 10 |mov dword ptr [esp+10], ebp
00401288 |. FEC2 |inc dl
0040128A |. 02DA |add bl, dl
0040128C |. 80FB 5B |cmp bl, 5B
0040128F |.^ 75 C8 \jnz short 00401259 ; 此段循环把姓名中不含有的"A"~"Z"(不含"J")中的字符按顺序添加到姓名的后面
接上例:"PEDIYABCIT"又处理成"PEDIYABCITFGHKLMNOPQRSUVWXZ"
继续:
0040129F |. 68 C9000000 push 0C9 ; /Count = C9 (201.)
004012A4 |. 50 push eax ; |Buffer
004012A5 |. 68 E9030000 push 3E9 ; |ControlID = 3E9 (1001.)
004012AA |. 51 push ecx ; |hWnd
004012AB |. FF15 AC504000 call dword ptr [<&USER32.GetDlgItemTe>; \GetDlgItemTextA
004012B1 |. 83F8 0E cmp eax, 0E ; 注册码长度必须为14位
004012B4 |. 0F85 54010000 jnz 0040140E
004012BA |. 8D9424 140100>lea edx, dword ptr [esp+114]
004012C1 |. 50 push eax
004012C2 |. 52 push edx
004012C3 |. E8 58010000 call 00401420 ; 检查注册码是否含数字,含则挂,并且小写转大写
004012C8 |. 83C4 08 add esp, 8
004012CB |. 85C0 test eax, eax
004012CD |. 0F84 3B010000 je 0040140E
跟入004012C3处的Call:
00401420 /$ 53 push ebx
00401421 |. 8B5C24 0C mov ebx, dword ptr [esp+C]
00401425 |. 56 push esi
00401426 |. 33F6 xor esi, esi
00401428 |. 85DB test ebx, ebx
0040142A |. 57 push edi
0040142B |. 7E 4D jle short 0040147A
0040142D |. 8B7C24 10 mov edi, dword ptr [esp+10]
00401431 |> 833D FC624000>/cmp dword ptr [4062FC], 1
00401438 |. 7E 14 |jle short 0040144E
0040143A |. 0FBE043E |movsx eax, byte ptr [esi+edi]
0040143E |. 68 03010000 |push 103
00401443 |. 50 |push eax
00401444 |. E8 DF010000 |call 00401628
00401449 |. 83C4 08 |add esp, 8
0040144C |. EB 13 |jmp short 00401461
0040144E |> 0FBE0C3E |movsx ecx, byte ptr [esi+edi]
00401452 |. 8B15 F0604000 |mov edx, dword ptr [4060F0] ; CrackMe_.004060FA
00401458 |. 66:8B044A |mov ax, word ptr [edx+ecx*2]
0040145C |. 25 03010000 |and eax, 103
00401461 |> 85C0 |test eax, eax
00401463 |. 74 1E |je short 00401483
00401465 |. 0FBE043E |movsx eax, byte ptr [esi+edi]
00401469 |. 50 |push eax
0040146A |. E8 ED000000 |call 0040155C
0040146F |. 83C4 04 |add esp, 4
00401472 |. 88043E |mov byte ptr [esi+edi], al
00401475 |. 46 |inc esi
00401476 |. 3BF3 |cmp esi, ebx
00401478 |.^ 7C B7 \jl short 00401431
0040147A |> 5F pop edi
0040147B |. 5E pop esi
0040147C |. B8 01000000 mov eax, 1
00401481 |. 5B pop ebx
00401482 |. C3 retn
00401483 |> 5F pop edi
00401484 |. 5E pop esi
00401485 |. 33C0 xor eax, eax
00401487 |. 5B pop ebx
00401488 \. C3 retn
这里要查一个表,把注册码的每一位用表中的数据替换,然后再跟103H做And,结果为0则失败。
表在这里:
004060FA 20 00 20 00 20 00 20 00 20 00 20 00 20 00 20 00 . . . . . . . .
0040610A 20 00 28 00 28 00 28 00 28 00 28 00 20 00 20 00 .(.(.(.(.(. . .
0040611A 20 00 20 00 20 00 20 00 20 00 20 00 20 00 20 00 . . . . . . . .
0040612A 20 00 20 00 20 00 20 00 20 00 20 00 20 00 20 00 . . . . . . . .
0040613A 48 00 10 00 10 00 10 00 10 00 10 00 10 00 10 00 H........
0040614A 10 00 10 00 10 00 10 00 10 00 10 00 10 00 10 00 ........
0040615A 84 00 84 00 84 00 84 00 84 00 84 00 84 00 84 00 ????????
0040616A 84 00 84 00 10 00 10 00 10 00 10 00 10 00 10 00 ??......
0040617A 10 00 81 00 81 00 81 00 81 00 81 00 81 00 01 00 .??????.
0040618A 01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 ........
0040619A 01 00 01 00 01 00 01 00 01 00 01 00 01 00 01 00 ........
004061AA 01 00 01 00 01 00 10 00 10 00 10 00 10 00 10 00 ........
004061BA 10 00 82 00 82 00 82 00 82 00 82 00 82 00 02 00 .??????.
004061CA 02 00 02 00 02 00 02 00 02 00 02 00 02 00 02 00 ........
004061DA 02 00 02 00 02 00 02 00 02 00 02 00 02 00 02 00 ........
004061EA 02 00 02 00 02 00 10 00 10 00 10 00 10 00 20 00 ....... .
经计算可知:只有81、82、01、02与103H做And结果不为0,
查看这四个数字在表中的位置,可知只有字母才可以通过。
也就是说注册码只可以包含字母。
下面是最复杂的注册码判断过程:
004012D3 |. 8B5C24 10 mov ebx, dword ptr [esp+10]
004012D7 |. 896C24 1C mov dword ptr [esp+1C], ebp
004012DB |. 8B6C24 1C mov ebp, dword ptr [esp+1C]
004012DF |. 8B7C24 1C mov edi, dword ptr [esp+1C]
004012E3 |> 8B4424 1C /mov eax, dword ptr [esp+1C]
004012E7 |. 8A9404 140100>|mov dl, byte ptr [esp+eax+114]
004012EE |. 8A8C04 150100>|mov cl, byte ptr [esp+eax+115]
004012F5 |. 8DB404 150100>|lea esi, dword ptr [esp+eax+115]
004012FC |. 80FA 4A |cmp dl, 4A ; 4A="J"
004012FF |. 884C24 17 |mov byte ptr [esp+17], cl
00401303 |. 75 02 |jnz short 00401307
00401305 |. B2 49 |mov dl, 49 ; change "J" into "I"
00401307 |> 33C9 |xor ecx, ecx ;注:上面的变换只对该两位注册码的前一位有效,不对第二位做变换
00401309 |. 8D7424 20 |lea esi, dword ptr [esp+20]
0040130D |> 33C0 |/xor eax, eax
0040130F |> 381406 ||/cmp byte ptr [esi+eax], dl
00401312 |. 75 0A |||jnz short 0040131E
00401314 |. 8B5C24 10 |||mov ebx, dword ptr [esp+10]
00401318 |. 8BE9 |||mov ebp, ecx ; 循环过后ebp中应保留了在第几个五字节段中发现了前1位注册码(注意开始为0)
0040131A |. 894424 18 |||mov dword ptr [esp+18], eax ; esp+18中存放前一个注册码位于该五字节段的第几位(注意开始为0)
0040131E |> 40 |||inc eax
0040131F |. 83F8 05 |||cmp eax, 5
00401322 |.^ 7C EB ||\jl short 0040130F
00401324 |. 41 ||inc ecx
00401325 |. 83C6 05 ||add esi, 5
00401328 |. 83F9 05 ||cmp ecx, 5
0040132B |.^ 7C E0 |\jl short 0040130D
0040132D |. 33F6 |xor esi, esi
0040132F |. 8D4C24 20 |lea ecx, dword ptr [esp+20]
00401333 |> 33C0 |/xor eax, eax
00401335 |> 8A5424 17 ||/mov dl, byte ptr [esp+17] ; 上个循环取的两位注册码的第二位
00401339 |. 3811 |||cmp byte ptr [ecx], dl
0040133B |. 75 04 |||jnz short 00401341
0040133D |. 8BFE |||mov edi, esi ; 循环过后edi中保存了第几个五字节段取到后一位注册码
0040133F |. 8BD8 |||mov ebx, eax ; ebx中保留后一位注册码出现在五字节段的第几位
00401341 |> 40 |||inc eax
00401342 |. 41 |||inc ecx
00401343 |. 83F8 05 |||cmp eax, 5
00401346 |.^ 7C ED ||\jl short 00401335
00401348 |. 46 ||inc esi
00401349 |. 83FE 05 ||cmp esi, 5
0040134C |.^ 7C E5 |\jl short 00401333 ; 注意:两个循环记录的都是最后一次出现注册码字节的信息!!
0040134E |. 3BEF |cmp ebp, edi ;这里判断xa和ya是否相等
00401350 |. 895C24 10 |mov dword ptr [esp+10], ebx
00401354 |. 75 3A |jnz short 00401390
00401356 |. 8B4424 18 |mov eax, dword ptr [esp+18]
0040135A |. 85C0 |test eax, eax
0040135C |. 75 0A |jnz short 00401368
0040135E |. C74424 18 040>|mov dword ptr [esp+18], 4
00401366 |. EB 04 |jmp short 0040136C
00401368 |> FF4C24 18 |dec dword ptr [esp+18]
0040136C |> 85DB |test ebx, ebx
0040136E |. 75 07 |jnz short 00401377
00401370 |. BB 04000000 |mov ebx, 4
00401375 |. EB 01 |jmp short 00401378
00401377 |> 4B |dec ebx
00401378 |> 8B4424 18 |mov eax, dword ptr [esp+18]
0040137C |. 8BD5 |mov edx, ebp
0040137E |. 895C24 10 |mov dword ptr [esp+10], ebx
00401382 |. 8D0CA8 |lea ecx, dword ptr [eax+ebp*4]
00401385 |. 03D1 |add edx, ecx
00401387 |. 8D0CBB |lea ecx, dword ptr [ebx+edi*4]
0040138A |. 8A4414 20 |mov al, byte ptr [esp+edx+20] ;取字符1
0040138E |. EB 46 |jmp short 004013D6
00401390 |> 8B4C24 18 |mov ecx, dword ptr [esp+18]
00401394 |. 3BCB |cmp ecx, ebx ;这里判断xb和yb是否相等
00401396 |. 75 30 |jnz short 004013C8
00401398 |. 85ED |test ebp, ebp
0040139A |. 75 07 |jnz short 004013A3
0040139C |. BD 04000000 |mov ebp, 4
004013A1 |. EB 01 |jmp short 004013A4
004013A3 |> 4D |dec ebp
004013A4 |> 85FF |test edi, edi
004013A6 |. 75 07 |jnz short 004013AF
004013A8 |. BF 04000000 |mov edi, 4
004013AD |. EB 01 |jmp short 004013B0
004013AF |> 4F |dec edi
004013B0 |> 8D04A9 |lea eax, dword ptr [ecx+ebp*4]
004013B3 |. 8BCD |mov ecx, ebp
004013B5 |. 03C8 |add ecx, eax
004013B7 |. 8D14BB |lea edx, dword ptr [ebx+edi*4]
004013BA |. 8A440C 20 |mov al, byte ptr [esp+ecx+20] ;取字符1
004013BE |. 8BCF |mov ecx, edi
004013C0 |. 03CA |add ecx, edx
004013C2 |. 8A4C0C 20 |mov cl, byte ptr [esp+ecx+20] ;取字符2
004013C6 |. EB 16 |jmp short 004013DE
004013C8 |> 8D14AB |lea edx, dword ptr [ebx+ebp*4]
004013CB |. 8BC5 |mov eax, ebp
004013CD |. 03C2 |add eax, edx
004013CF |. 8D0CB9 |lea ecx, dword ptr [ecx+edi*4]
004013D2 |. 8A4404 20 |mov al, byte ptr [esp+eax+20] ;取字符1
004013D6 |> 8BD7 |mov edx, edi
004013D8 |. 03D1 |add edx, ecx
004013DA |. 8A4C14 20 |mov cl, byte ptr [esp+edx+20] ;取字符2
004013DE |> 8B5424 1C |mov edx, dword ptr [esp+1C] ;esp+1C里面存储的是计数器
004013E2 |. 3A4414 3C |cmp al, byte ptr [esp+edx+3C] ;与固定字符串的位比较
004013E6 |. 75 26 |jnz short 0040140E
004013E8 |. 3A4C14 3D |cmp cl, byte ptr [esp+edx+3D] ;与固定字符串的位比较
004013EC |. 75 20 |jnz short 0040140E
004013EE |. 83C2 02 |add edx, 2 ;计数器增2
004013F1 |. 83FA 0E |cmp edx, 0E ;是否已经到14
004013F4 |. 895424 1C |mov dword ptr [esp+1C], edx
004013F8 |.^ 0F8C E5FEFFFF \jl 004012E3
这个过程的大概思想是:依次取注册码的两字节,然后根据这两字节在处理后的姓名中的位置,分解成xa*5+xb、ya*5+yb的形式,
再根据xa=ya或xb=yb或都不相等这三种情况对xa、xb、ya、yb做相应的处理。再根据处理后变量,取姓名中相应位置的字符,
判断与"CRACKINGFORFUN"字符串依次两位是否相同,不同则失败。
我把这段代码翻译了一下,大致如下:
sc="CRACKINGFORFUN"
name="PEDIYABCITFGHKLMNOPQRSUVWXZ"
sn="ABCDEFGHIJKLMN" '随意写的
For scpos=1 To 14 Step 2
snb=Mid(sn,k,2)
If Left(snb,1)="J" Then snb="I" & Right(snb,1)
pos=0
For i=1 To 25
If Mid(name,i,1)=Left(snb) Then pos=i
Next i
If pos<>0 Then xa=(pos\5)-1:xb=(pos Mod 5)-1
pos=0
For i=1 To 25
If Mid(name,i,1)=Right(snb) Then pos=i
Next i
If pos<>0 Then ya=(pos\5)-1:yb=(pos Mod 5)-1
If xa=ya Then
If xb=0 Then xb=4 Else xb=xb-1
If yb=0 Then yb=4 Else yb=yb-1
'eax=xb:edx=xa:ecx=xb+xa*4:edx=edx+ecx
edx=xa+xb+xa*4
'ecx=yb+ya*4
al=Mid(name,edx+1,1)
'edx=ya:edx=edx+ecx
edx=ya+yb+ya*4
cl=Mid(name,edx+1,1)
Else
If xb=yb Then
If xa=0 Then xa=4 Else xa=xa-1
If ya=0 Then ya=4 Else ya=ya-1
'ecx=xb:eax=ecx+xa*4=xb+xa*4
'ecx=xa:edx=yb+ya*4:ecx=ecx+eax
ecx=xa+xb+xa*4
al=Mid(name,ecx+1,1)
'ecx=ya:ecx=ecx+edx
ecx=ya+yb+ya*4
cl=Mid(name,ecx+1,1)
Else
'edx=yb+xa*4:eax=xa:eax=eax+edx
eax=xa+yb+xa*4
'ecx=xb+ya*4
al=mid(name,eax+1,1)
'ecx=xb+ya*4:edx=ya:edx=edx+ecx
edx=ya+xb+ya*4
cl=mid(name,edx+1,1)
End if
End If
If al<>Mid(sc,scpos,1) Then die
If cl<>Mid(sc,scpos+1,1) Then die
Next scpos
根据上述思想,逆向写出注册机(VB代码):
Const SC = "CRACKINGFORFUN"
Dim SN(14) As String
Dim SNPos As Integer
Private Sub CmdGen_Click()
Dim Name As String
Dim z As String
Dim i As Integer
Dim j As Integer
Dim Succ As Boolean
For i = 1 To 14: SN(i) = "": Next i
TxtSN.Text = ""
If Len(TxtName.Text) < 6 Or Len(TxtName.Text) > 16 Then MsgBox "姓名应在6~16个字符之间!", vbInformation + vbOKOnly, "数据输入错误": Exit Sub
Name = NameProc(UCase(TxtName.Text))
If Len(Name) < 6 Then MsgBox "该姓名无法注册,请更换!", vbInformation + vbOKOnly, "数据输入错误": Exit Sub
For i = 65 To 90
z = Chr(i): If z = "J" Then z = "I"
If InStr(1, Name, z) = 0 Then Name = Name & z
Next i
Name = Left(Name, 25)
For SNPos = 1 To 14 Step 2
a = Mid(SC, SNPos, 1)
b = Mid(SC, SNPos + 1, 1)
For i = 25 To 1 Step -1
If Mid(Name, i, 1) = a Then
For j = 25 To 1 Step -1
If Mid(Name, j, 1) = b Then
Succ = Find(i, j, Name)
If Succ = True Then Exit For
End If
Next j
If Succ = True Then Exit For
End If
Next i
Next SNPos
For i = 1 To 14
If SN(i) = "" Then MsgBox "该姓名无法注册,请更换!", vbInformation + vbOKOnly, "算法错误": Exit Sub
Next i
For i = 1 To 14
TxtSN.Text = TxtSN.Text & SN(i)
Next i
End Sub
Private Sub Form_Load()
Me.Icon = LoadPicture("")
End Sub
Function NameProc(Name As String) As String
Dim n As Integer
For i = 2 To Len(Name)
If i > Len(Name) Then n = Len(Name) Else n = i
For k = 1 To n - 1
If Mid(Name, k, 1) = Mid(Name, i, 1) Then
If k <= i Then
Name = Left(Name, i - 1) & Right(Name, Len(Name) - i)
Else
Name = Left(Name, Len(Name) - 1)
End If
End If
Next k
Next i
NameProc = Name
End Function
Function Find(apos As Integer, bpos As Integer, Name As String) As Boolean
Dim xa As Integer
Dim xb As Integer
Dim ya As Integer
Dim yb As Integer
Dim z As Integer
Dim a As String
Dim b As String
xa = (apos - 1) \ 5: xb = apos Mod 5: If xb = 0 Then xb = 5
xb = xb - 1
ya = (bpos - 1) \ 5: yb = bpos Mod 5: If yb = 0 Then yb = 5
yb = yb - 1
If xa = ya Then
If xb = 4 Then xb = 0 Else xb = xb + 1
If yb = 4 Then yb = 0 Else yb = yb + 1
Else
If xb = yb Then
If xa = 4 Then xa = 0 Else xa = xa + 1
If ya = 4 Then ya = 0 Else ya = ya + 1
Else
z = xb: xb = yb: yb = z
End If
End If
a = Mid(Name, xa * 5 + xb + 1, 1): If InStr(xa * 5 + xb + 2, Name, a) <> 0 Then Find = False: Exit Function
b = Mid(Name, ya * 5 + yb + 1, 1): If InStr(ya * 5 + yb + 2, Name, b) <> 0 Then Find = False: Exit Function
SN(SNPos) = a
SN(SNPos + 1) = b
Find = True
End Function
--------------------------------------------------------------------------------
【经验总结】
做分析是一件很辛苦的事情,需以持久的耐心和坚定的毅力才能成功。
这篇文章看似简单,却耗费了我十几天的时间(中间有考试,而且自己水平不足是主要原因)
希望能给大家一点帮助。
-------------------------------------------------------------------------------- 2007年07月17日 14:37:50
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
上传的附件: