大家新年好!该吃年夜饭的时候了,我来贴上以前写的一篇:
Anti ****V2.6.1算法分析和注册机编写
国产反木马软件,选择它是看它算法简单;
我这儿不能上网,资料不好找,很多东西都是按我自己的理解,有错误的地方请大家指出,谢谢!
用Ollydbg1.10,怎样追到算法部分就略了,算法代码如下:(许多地方都是用C#描述的,大家将就看吧)
//在这之前注册码已被转换为大写格式
00403A34   /$  55                push ebp
00403A35   |.  8BEC              mov ebp,esp
00403A37   |.  81C4 CCFDFFFF     add esp,-234
00403A3D   |.  B8 BC4E5500       mov eax,00554EBC
00403A42   |.  53                push ebx
00403A43   |.  56                push esi
00403A44   |.  57                push edi
00403A45   |.  E8 9AAD1300       call 0053E7E4
00403A4A   |.  C745 F8 01000000  mov dword ptr ss:[ebp-8],1
00403A51   |.  8D55 08           lea edx,dword ptr ss:[ebp+8]
00403A54   |.  8D45 08           lea eax,dword ptr ss:[ebp+8]
00403A57   |.  E8 64AF1300       call 0053E9C0
00403A5C   |.  FF45 F8           inc dword ptr ss:[ebp-8]
00403A5F   |.  66:C745 EC 0800   mov word ptr ss:[ebp-14],8
00403A65   |.  68 C7000000       push 0C7
00403A6A   |.  837D 08 00        cmp dword ptr ss:[ebp+8],0
00403A6E   |.  74 05             je short 00403A75
00403A70   |.  8B55 08           mov edx,dword ptr ss:[ebp+8]
00403A73   |.  EB 05             jmp short 00403A7A
00403A75   |>  BA BC4B5500       mov edx,00554BBC
00403A7A   |>  52                push edx                                  ; |src
00403A7B   |.  8D85 0CFFFFFF     lea eax,dword ptr ss:[ebp-F4]             ; |
00403A81   |.  50                push eax                                  ; |dest
00403A82   |.  E8 27F91400       call <jmp.&CC3260MT._strncpy>             ; \_strncpy
00403A87   |.  83C4 0C           add esp,0C
00403A8A   |.  8D8D 0CFFFFFF     lea ecx,dword ptr ss:[ebp-F4]
00403A90   |.  68 80000000       push 80                                   ; /maxlen = 80 (128.)
00403A95   |.  51                push ecx                                  ; |src
00403A96   |.  68 340D5900       push 00590D34                             ; |dest = 00590D34
00403A9B   |.  E8 0EF91400       call <jmp.&CC3260MT._strncpy>             ; \_strncpy
00403AA0   |.  83C4 0C           add esp,0C
00403AA3   |.  8D85 0CFFFFFF     lea eax,dword ptr ss:[ebp-F4]
00403AA9   |.  C645 D3 00        mov byte ptr ss:[ebp-2D],0
00403AAD   |.  50                push eax
00403AAE   |.  E8 F9F71400       call <jmp.&CC3260MT.__lstrupr>
00403AB3   |.  59                pop ecx
00403AB4   |.  8D9D 0CFFFFFF     lea ebx,dword ptr ss:[ebp-F4]
00403ABA   |.  68 BD4B5500       push 00554BBD
00403ABF   |.  53                push ebx
00403AC0   |.  E8 78AC1300       call 0053E73D                     ;  找"-"
00403AC5   |.  83C4 08           add esp,8
00403AC8   |.  8BF0              mov esi,eax
00403ACA   |.  85F6              test esi,esi
00403ACC   |.  75 23             jnz short 00403AF1                ;  找不到就OVER
00403ACE   |.  33C0              xor eax,eax
00403AD0   |.  BA 02000000       mov edx,2
00403AD5   |.  50                push eax
00403AD6   |.  8D45 08           lea eax,dword ptr ss:[ebp+8]
00403AD9   |.  FF4D F8           dec dword ptr ss:[ebp-8]
00403ADC   |.  E8 07B11300       call 0053EBE8
00403AE1   |.  58                pop eax
00403AE2   |.  8B55 DC           mov edx,dword ptr ss:[ebp-24]
00403AE5   |.  64:8915 00000000  mov dword ptr fs:[0],edx
00403AEC   |.  E9 1D020000       jmp 00403D0E
00403AF1   |>  C606 00           mov byte ptr ds:[esi],0
00403AF4   |.  46                inc esi
00403AF5   |.  803E 00           cmp byte ptr ds:[esi],0                   ;  是不是偷懒,只输了一段注册码?:>
00403AF8   |.  75 23             jnz short 00403B1D
00403AFA   |.  33C0              xor eax,eax
00403AFC   |.  BA 02000000       mov edx,2
00403B01   |.  50                push eax
00403B02   |.  8D45 08           lea eax,dword ptr ss:[ebp+8]
00403B05   |.  FF4D F8           dec dword ptr ss:[ebp-8]
00403B08   |.  E8 DBB01300       call 0053EBE8
00403B0D   |.  58                pop eax
00403B0E   |.  8B55 DC           mov edx,dword ptr ss:[ebp-24]
00403B11   |.  64:8915 00000000  mov dword ptr fs:[0],edx
00403B18   |.  E9 F1010000       jmp 00403D0E
00403B1D   |>  68 BF4B5500       push 00554BBF
00403B22   |.  56                push esi
00403B23   |.  E8 15AC1300       call 0053E73D                             ;  找"-"
00403B28   |.  83C4 08           add esp,8
00403B2B   |.  8BF8              mov edi,eax
00403B2D   |.  85FF              test edi,edi
00403B2F   |.  75 23             jnz short 00403B54
00403B31   |.  33C0              xor eax,eax
00403B33   |.  BA 02000000       mov edx,2
00403B38   |.  50                push eax
00403B39   |.  8D45 08           lea eax,dword ptr ss:[ebp+8]
00403B3C   |.  FF4D F8           dec dword ptr ss:[ebp-8]
00403B3F   |.  E8 A4B01300       call 0053EBE8
00403B44   |.  58                pop eax
00403B45   |.  8B55 DC           mov edx,dword ptr ss:[ebp-24]
00403B48   |.  64:8915 00000000  mov dword ptr fs:[0],edx
00403B4F   |.  E9 BA010000       jmp 00403D0E
00403B54   |>  C607 00           mov byte ptr ds:[edi],0
00403B57   |.  47                inc edi
00403B58   |.  803F 00           cmp byte ptr ds:[edi],0
00403B5B   |.  75 23             jnz short 00403B80
00403B5D   |.  33C0              xor eax,eax
00403B5F   |.  BA 02000000       mov edx,2
00403B64   |.  50                push eax
00403B65   |.  8D45 08           lea eax,dword ptr ss:[ebp+8]
00403B68   |.  FF4D F8           dec dword ptr ss:[ebp-8]
00403B6B   |.  E8 78B01300       call 0053EBE8
00403B70   |.  58                pop eax
00403B71   |.  8B55 DC           mov edx,dword ptr ss:[ebp-24]
00403B74   |.  64:8915 00000000  mov dword ptr fs:[0],edx
00403B7B   |.  E9 8E010000       jmp 00403D0E
00403B80   |>  53                push ebx                                  ; /长征结束了!注册码格式:AAAA-SSSS-DDDD
00403B81   |.  E8 92010000       call 00403D18                             ; \第一段注册码转换为int

进入:
00403D18   /$  55                push ebp
00403D19   |.  8BEC              mov ebp,esp
00403D1B   |.  83C4 F8           add esp,-8
00403D1E   |.  53                push ebx
00403D1F   |.  56                push esi
00403D20   |.  8B5D 08           mov ebx,dword ptr ss:[ebp+8]
00403D23   |.  53                push ebx                                 ; /s
00403D24   |.  E8 79F61400       call <jmp.&CC3260MT._strlen>             ; \_strlen
00403D29   |.  59                pop ecx
00403D2A   |.  8945 FC           mov dword ptr ss:[ebp-4],eax
00403D2D   |.  33F6              xor esi,esi
00403D2F   |.  33C0              xor eax,eax
00403D31   |.  8BCB              mov ecx,ebx
00403D33   |.  8945 F8           mov dword ptr ss:[ebp-8],eax
00403D36   |.  EB 44             jmp short 00403D7C
00403D38   |>  8A01              /mov al,byte ptr ds:[ecx]                ;取输入的字符串
00403D3A   |.  8A51 01           |mov dl,byte ptr ds:[ecx+1]              ;取两个
00403D3D   |.  0FBED8            |movsx ebx,al                            ;编的话要用sbyte类型
00403D40   |.  83FB 46           |cmp ebx,46                              
00403D43   |.  7F 09             |jg short 00403D4E
00403D45   |.  83FB 41           |cmp ebx,41
00403D48   |.  7C 04             |jl short 00403D4E               
00403D4A   |.  04 C9             |add al,0C9                              ;如果有字符是"A"到"f"的,把Hex加上0xc9,否则加上0x40
00403D4C   |.  EB 02             |jmp short 00403D50                      ;这样"0"到"9"就成了0x0~0x9,"A"到"F"就成了0xA~0xF,
00403D4E   |>  04 D0             |add al,0D0                              ;很有意思,如果编注册机的话就简化了很多
00403D50   |>  0FBEDA            |movsx ebx,dl
00403D53   |.  83FB 46           |cmp ebx,46                              ;这是取得第二个
00403D56   |.  7F 0A             |jg short 00403D62
00403D58   |.  83FB 41           |cmp ebx,41
00403D5B   |.  7C 05             |jl short 00403D62
00403D5D   |.  80C2 C9           |add dl,0C9
00403D60   |.  EB 03             |jmp short 00403D65
00403D62   |    80C2 D0          |add dl,0D0
00403D65   |>  0FBEC0            |movsx eax,al
00403D68   |.  0FBED2            |movsx edx,dl
00403D6B   |.  C1E0 04           |shl eax,4                               ;第一个Int左移4
00403D6E   |.  C1E6 08           |shl esi,8                               ;上次结果左移8
00403D71   |.  03C2              |add eax,edx                             ;把两次结果组合起来
00403D73   |.  03F0              |add esi,eax                             ;把上次结果与这次组合
00403D75   |.  8345 F8 02        |add dword ptr ss:[ebp-8],2
00403D79   |.  83C1 02           |add ecx,2
00403D7C   |>  8B45 F8           | mov eax,dword ptr ss:[ebp-8]
00403D7F   |.  3B45 FC           |cmp eax,dword ptr ss:[ebp-4]
00403D82   \  ^ 72 B4            \jb short 00403D38
00403D84   |.  8BC6              mov eax,esi
00403D86   |.  5E                pop esi
00403D87   |.  5B                pop ebx
00403D88   |.  59                pop ecx
00403D89   |.  59                pop ecx
00403D8A   |.  5D                pop ebp
00403D8B   \.  C3                retn
假设输入"123ABC"
程序先取"1","2",Hex分别为0x31,0x32,因为0x30<0x41,用sbyte类型的0x31+0xd0,结果为0x1
同样,"2"的结果为0x2,再把0x2<<4后加上0x2,得0x12,再加上上次结果(第一次当然为0x0),最后结果0x12;
整个字符串结果0x123ABC;
这种算法使我们可以很轻松的编出注册机,我们要想把一个Int转换为可显示字符,就可以先把它转换为16进制形式的字符串,因为程序每次循环

要处理两个字符,所以还要在长度不为偶数的字符串前加"0",输出就可以了

退出Call,继续:
00403B86   |.  59                pop ecx
00403B87   |.  8BD8              mov ebx,eax
00403B89   |.  56                push esi                                  ; /Arg1
00403B8A   |.  E8 89010000       call 00403D18                             ; \第二段注册码转换为int
00403B8F   |.  59                pop ecx
00403B90   |.  8945 D8           mov dword ptr ss:[ebp-28],eax
00403B93   |.  57                push edi                                  ; /Arg1
00403B94   |.  E8 7F010000       call 00403D18                             ; \第三段注册码转换为int
00403B99   |.  59                pop ecx
00403B9A   |.  891D B40D5900     mov dword ptr ds:[590DB4],ebx
00403BA0   |.  8B4D D8           mov ecx,dword ptr ss:[ebp-28]
00403BA3   |.  33D2              xor edx,edx
00403BA5   |.  890D B80D5900     mov dword ptr ds:[590DB8],ecx             ;  第二段int
00403BAB   |.  A3 BC0D5900       mov dword ptr ds:[590DBC],eax             ;  第三段int,好像没用到它??
00403BB0   |.  8BC3              mov eax,ebx                               ;  第一段int,叫sn1吧
00403BB2   |.  B9 C7020000       mov ecx,2C7
00403BB7   |.  F7F1              div ecx                                   ;  sn1 / 0x2c7
00403BB9   |.  8D0C9B            lea ecx,dword ptr ds:[ebx+ebx*4]          ;  sn1 +sn1 *4
00403BBC   |.  8BD0              mov edx,eax                               ;  sn1 / 0x2c7的商
00403BBE   |.  C1E1 03           shl ecx,3                                 ;  (sn1 +sn1 *4)<<3
00403BC1   |.  8D049B            lea eax,dword ptr ds:[ebx+ebx*4]
00403BC4   |.  2BCB              sub ecx,ebx                               ;  ((sn1 +sn1 *4)<<3) -sn1
00403BC6   |.  8DBD 8CFEFFFF     lea edi,dword ptr ss:[ebp-174]
00403BCC   |.  C1E1 03           shl ecx,3                                 ;  (((sn1 +sn1 *4)<<3) -sn1)<<3
00403BCF   |.  BE 784A5500       mov esi,00554A78
00403BD4   |.  2BCB              sub ecx,ebx                               ;  ((((sn1 +sn1 *4)<<3) -sn1)<<3)-sn1
00403BD6   |.  D1E9              shr ecx,1                                 ;  (((((sn1 +sn1 *4)<<3) -sn1)<<3)-sn1)>>1
00403BD8   |.  C1E8 03           shr eax,3                                 ;  往上找eax:(sn1 +sn1 *4 )>>3
00403BDB   |.  03C1              add eax,ecx                               ;  上面两个相加,太长了,我晕!叫它sn1Temp吧
00403BDD   |.  B9 20000000       mov ecx,20
00403BE2   |.  03D0              add edx,eax                               ;  edx是sn1/0x2c7的商 + sn1Temp
00403BE4   |.  0FAFDA            imul ebx,edx                              ;  sn1和上面的相乘,叫它sn1Temp1
00403BE7   |.  8D0452            lea eax,dword ptr ds:[edx+edx*2]          ;  edx=(sn1/0x2c7)+((sn1+sn1*4)>>3)+

((((((sn1+sn1*4)<<3)-sn1)<<3)-sn1)>>1)
00403BEA   |.  C1E0 04           shl eax,4                                 ;  ((edx+edx*2)<<4)
00403BED   |.  2BC2              sub eax,edx                               ;  ((edx+edx*2)<<4)-edx
00403BEF   |.  C1E0 02           shl eax,2                                 ;  (((edx+edx*2)<<4)-edx)<<2
00403BF2   |.  2BC2              sub eax,edx                               ;  ((((edx+edx*2)<<4)-edx)<<2)-edx
00403BF4   |.  03C3              add eax,ebx                               ;  (((((edx+edx*2)<<4)-edx)<<2)-edx)+sn1Temp1
00403BF6   |.  8BD0              mov edx,eax
00403BF8   |.  F7D2              not edx                                   ;  ~((((((edx+edx*2)<<4)-edx)<<2)-edx)+sn1Temp1)
00403BFA   |.  F3:A5             rep movs dword ptr es:[edi],dword ptr ds:>;  俺们都是做苦力活的^_^幸亏有计算机,要我算的话还

不得算上十年八年!!
00403BFC   |.  33DB              xor ebx,ebx
00403BFE   |.  33C0              xor eax,eax
00403C00   |.  8DB5 8CFEFFFF     lea esi,dword ptr ss:[ebp-174]
00403C06   |>  8B0E              /mov ecx,dword ptr ds:[esi]               ;  一个固定的表,开始读数据
00403C08   |.  BF 01000000       |mov edi,1
00403C0D   |.  D3E7              |shl edi,cl                               ;  1<<*位,表中的数据,重要!
00403C0F   |.  85D7              |test edi,edx                             ;  拿它和上面的结果对比,做与运算
00403C11   |.  0F97C1            |seta cl                                  ;  设置标志
00403C14   |.  83E1 01           |and ecx,1                                ;  还是保险点好^_^
00403C17   |.  83C6 04           |add esi,4                                ;  为下次循环做准备
00403C1A   |.  8BF9              |mov edi,ecx
00403C1C   |.  8BC8              |mov ecx,eax                              ;  第n次
00403C1E   |.  D3E7              |shl edi,cl                               ;  True的话1<<n,False的话0<<n
00403C20   |.  0BDF              |or ebx,edi                               ;  循环n次的到ebx的值
00403C22   |.  40                |inc eax                                  ;  加1
00403C23   |.  83F8 20           |cmp eax,20                               ;  0x20次
00403C26   |.^ 7C DE             \jl short 00403C06
00403C28   |.  8BD3              mov edx,ebx
00403C2A   |.  81F2 918A4B3F     xor edx,3F4B8A91                          ;  结果^0x3f4b8a91
00403C30   |.  BE F84A5500       mov esi,00554AF8
00403C35   |.  8DBD 2CFEFFFF     lea edi,dword ptr ss:[ebp-1D4]
00403C3B   |.  B9 18000000       mov ecx,18
00403C40   |.  F3:A5             rep movs dword ptr es:[edi],dword ptr ds:>
00403C42   |.  66:C745 EC 0800   mov word ptr ss:[ebp-14],8
00403C48   |.  33DB              xor ebx,ebx
00403C4A   |.  33C0              xor eax,eax
00403C4C   |.  8DB5 2CFEFFFF     lea esi,dword ptr ss:[ebp-1D4]
00403C52   |>  8B0E              /mov ecx,dword ptr ds:[esi]               ;  另一个固定的表.
00403C54   |.  BF 01000000       |mov edi,1                                ;  同上
00403C59   |.  D3E7              |shl edi,cl                               ;  同上
00403C5B   |.  85D7              |test edi,edx                             ;  这个edx是经过上面运算的结果
00403C5D   |.  0F97C1            |seta cl                                  ;  同上
00403C60   |.  83E1 01           |and ecx,1
00403C63   |.  83C6 04           |add esi,4
00403C66   |.  8BF9              |mov edi,ecx
00403C68   |.  8BC8              |mov ecx,eax
00403C6A   |.  D3E7              |shl edi,cl
00403C6C   |.  0BDF              |or ebx,edi
00403C6E   |.  40                |inc eax
00403C6F   |.  83F8 18           |cmp eax,18                               
00403C72   |.^ 7C DE             \jl short 00403C52
00403C74   |.  8BD3              mov edx,ebx                               ;  转移
00403C76   |.  8B5D D8           mov ebx,dword ptr ss:[ebp-28]             ;  我们的sn2到现在才登场
00403C79   |.  F7D3              not ebx                                   ;  ~sn2
00403C7B       C1EB 08           shr ebx,8                                 ;  (~sn2)>>8
00403C7E   |.  33C0              xor eax,eax
00403C80   |.  8945 D4           mov dword ptr ss:[ebp-2C],eax
00403C83   |.  8DBD CCFDFFFF     lea edi,dword ptr ss:[ebp-234]
00403C89   |.  66:C745 EC 0800   mov word ptr ss:[ebp-14],8
00403C8F   |.  BE 584B5500       mov esi,00554B58
00403C94   |.  B9 18000000       mov ecx,18
00403C99   |.  F3:A5             rep movs dword ptr es:[edi],dword ptr ds:>
00403C9B   |.  8DB5 CCFDFFFF     lea esi,dword ptr ss:[ebp-234]
00403CA1   |.  33C0              xor eax,eax
00403CA3   |>  8B0E              /mov ecx,dword ptr ds:[esi]                ;这次除了表之外全和上次一样了
00403CA5   |.  BF 01000000       |mov edi,1
00403CAA   |.  D3E7              |shl edi,cl
00403CAC   |.  85DF              |test edi,ebx
00403CAE   |.  0F97C1            |seta cl
00403CB1   |.  83E1 01           |and ecx,1
00403CB4   |.  83C6 04           |add esi,4
00403CB7   |.  8BF9              |mov edi,ecx
00403CB9   |.  8BC8              |mov ecx,eax
00403CBB   |.  D3E7              |shl edi,cl
00403CBD   |.  097D D4           |or dword ptr ss:[ebp-2C],edi
00403CC0   |.  40                |inc eax
00403CC1   |.  83F8 18           |cmp eax,18
00403CC4   |.^ 7C DD             \jl short 00403CA3
00403CC6   |.  8B5D D4           mov ebx,dword ptr ss:[ebp-2C]
00403CC9   |.  3BDA              cmp ebx,edx                                ;比较sn1结果和sn2结果,经典!
00403CCB   |.  75 23             jnz short 00403CF0
00403CCD   |.  B8 01000000       mov eax,1
00403CD2   |.  BA 02000000       mov edx,2
00403CD7   |.  50                push eax
00403CD8   |.  8D45 08           lea eax,dword ptr ss:[ebp+8]
00403CDB   |.  FF4D F8           dec dword ptr ss:[ebp-8]
00403CDE   |.  E8 05AF1300       call 0053EBE8
00403CE3   |.  58                pop eax
00403CE4   |.  8B55 DC           mov edx,dword ptr ss:[ebp-24]
00403CE7   |.  64:8915 00000000  mov dword ptr fs:[0],edx
00403CEE   |.  EB 1E             jmp short 00403D0E
00403CF0   |>  33C0              xor eax,eax
00403CF2   |.  BA 02000000       mov edx,2
00403CF7   |.  50                push eax
00403CF8   |.  8D45 08           lea eax,dword ptr ss:[ebp+8]
00403CFB   |.  FF4D F8           dec dword ptr ss:[ebp-8]
00403CFE   |.  E8 E5AE1300       call 0053EBE8
00403D03   |.  58                pop eax
00403D04   |.  8B55 DC           mov edx,dword ptr ss:[ebp-24]
00403D07   |.  64:8915 00000000  mov dword ptr fs:[0],edx
00403D0E   |>  5F                pop edi
00403D0F   |.  5E                pop esi
00403D10   |.  5B                pop ebx
00403D11   |.  8BE5              mov esp,ebp
00403D13   |.  5D                pop ebp
00403D14   \.  C3                ret

我把下面的循环次数叫n,加密后的sn1还叫sn1,则sn2经过下面运算后应等于sn1
sn2计算过程:
输入假的sn2
把sn2转换为int              

~sn2
(~sn2)>>8                  

T=一张固定的表
1<<T                       
Test (1<<T),sn2            //结果和sn2做与运算(不返回结果,设置标志),根据结果:True,False.进行下一步运算
True的话用 1<<n   
False的话用 0<<n 相当于空操作;
用一个初始值为零的数(设为sn2A)与上面结果做或运算;
循环0x18次

得到sn2A,要想注册成功,要使sn2A=sn1;
为了逆算出sn2,我当初把这个循环拆为两部分:
1:根据sn2A的值逆算出每次循环的Bool值
2:根据Bool值逆算出sn2
这两个问题似乎并不好解决,我试了各种方法,都没用,于是乎就现放下,等有灵感时再解决;
这样一放就是几个月..........
一天,闲着无聊时又试了一下,有了新发现----我真是傻的可以-__-
其实第一个问题很好解决,因为sn1的最后一次循环和sn2的循环是一样的,要想的到Bool值,直接记录sn2最后一次循环中的Bool值,化为Bool

数组后为我所用就行了(我当初怎么没想到???).
第二个问题:
00403C52   |>  8B0E              /mov ecx,dword ptr ds:[esi]               ;这张固定的表是从0~0x17乱序排列的
00403C54   |.  BF 01000000       |mov edi,1                                
00403C59   |.  D3E7              |shl edi,cl                               
00403C5B   |.  85D7              |test edi,edx                             ;edx就是要求的值
假设edx=0x1234,把它化为二进制就是:1001000110100b
把1右移k(k是每次循环取的表的值)再与edx做与运算,是为了检测edx二进制第k位是否为1,是的话就是True,否则False;
例如:
cl=3
1<<3=0x8
二进制为:1000b
与0x1234做余运算:
0x1234=1001000110100b
1<<3=           1000b
这样就是False了
既然我们已经得到了所需的Bool数组(由第一个问题解决的),就可以根据这个数组,遇到True就使加上(1<<k),遇到False什么也不做,循环0x18次

就得到edx了;
怎么说不清楚~~~~还是看代码吧(c#):

 //省略部分系统初始化代码
private void button1_Click(object sender, System.EventArgs e)            
    {
      bool[] or=new bool [0x20];                             //这个就是我要用的Bool数组,下面是三张表:
      int[] num1=

{0x9,0x16,0x4,0x17,0x11,0xa,0xc,0x8,0x1b,0xf,0x7,0x5,0x1,0x1a,0x1f,0x1d,0x3,0x2,0xb,0x1c,0x10,0x12,0xd,0x0,0x1e,0x6,0x13,0x14

,0x18,0x19,0x15,0xe};
      int[] num2=

{0x14,0x0,0x15,0x18,0x7,0x9,0x1c,0x8,0x2,0xb,0x1d,0x1b,0xc,0x4,0x5,0xe,0x6,0x11,0x17,0xa,0x13,0x16,0xd,0x1f};
      int[] num3=

{0xe,0x8,0x17,0x13,0x6,0x15,0x1,0x0,0x4,0x10,0xf,0x3,0x7,0x16,0x5,0xb,0x12,0xa,0xd,0x9,0x14,0x11,0xc,0x2}; //
      int sn1=toint(textBox1.Text );                        //这个函数把sn1转换为Int
      int sn1num1=letgo(sn1);                               //LetGo!!就是sn1的初次运算
      int sn1num2=xunhuan(sn1num1,num1,ref or);             //经过初次运算后的结果进入第一次循环
      int sn1num3=xunhuan(sn1num2^0x3F4B8A91,num2,ref or);  //稍加运算后进入第一次循环
      int sn2=~((workout(num3,or))<<8);                     //根据结果算出sn2.
      string strsn2=Convert.ToString (sn2,16);              //仔细看一下由输入的String转换为Int的过程(地

址:00403D18~00403D8B)就明白,要想还原sn2为String,直接转换16进制,长度不是偶数的,前面补零就可以了
      if((strsn2.Length %2)!=0)
      {
        strsn2="0"+strsn2;
      }                                                     
      textBox2.Text =strsn2.ToUpper ();        //根据sn1计算出了sn2,sn3可随便写
      
    }      

    public int toint(string input)                                      //把sn1转换为Int (地址:00403D18~00403D8B) 

                         
    {
      char[] charcode=input.ToUpper().ToCharArray ();
      sbyte[] sbytecode=new sbyte [input.Length +1];               //要movsx,所以我用sbyte.
      int esi=0;

      for (int i=0;i<input.Length;i++)
      {
        sbytecode[i]=(sbyte)charcode[i];
      }

      for(int j=0;j<input.Length ;)
      {
               sbyte codetmp1=sbytecode[j];          
         sbyte codetmp2=sbytecode[j+1];
                              
                  
          if(codetmp1>0x46 | codetmp1<0x41)
          {
            codetmp1=(sbyte)(codetmp1+0xd0);
                      
          }
          else
          {
            codetmp1=(sbyte)(codetmp1+0xc9);          
          
          }
        if(codetmp2>0x46 | codetmp2<0x41)
        {
          codetmp2=(sbyte)(codetmp2+0xd0);
                      
        }
        else
        {
          codetmp2=(sbyte)(codetmp2+0xc9);          
          
        }  
      
          esi=(esi<<8)+((int)codetmp1<<4)+(int)codetmp2;                       
            j+=2;                
         
      }
             return esi;        

      }
    public int letgo(int sn1)                             
    {      
      uint sn1tmp=(uint)sn1;
      uint sn1tmp1,sn1tmp2;      
      sn1tmp1=((((((((sn1tmp+sn1tmp*4)<<3)-sn1tmp)<<3)-sn1tmp)>>1)+((sn1tmp+sn1tmp*4)>>3))+(sn1tmp/0x2c7)); 
      sn1tmp2=sn1tmp1*sn1tmp;
      sn1=(int)((((((sn1tmp1+sn1tmp1*2)<<4)-sn1tmp1)<<2)-sn1tmp1+sn1tmp2));
      sn1=~sn1;
      return sn1;

    }
    public int xunhuan(int sn1,int[] numArr,ref bool[]or)             //循环
    {
      int ebx=0;
      for(int i=0;i<numArr.Length ;i++)
      {
        if(Convert.ToBoolean((1<<numArr[i])&sn1)==true)
        {
          ebx|=(1<<i);
          or[i]=true;
        }
        else
        {          
          or[i]=false;
        }
        
      }
      return ebx;
      
    }
    public int workout(int[] numArr,bool[] or)                      //计算sn2的Int值
    {
      int sn2=0;
      for(int i=0;i<numArr.Length ;i++)
      {
        if(or[i]==true)
        {
          sn2=sn2+(1<<numArr[i]);
        }
      }
            return sn2;

    }