Qimage 2006 Professional Edition 2006.255

整个算法流程很清晰,但是算法很繁琐,而且每次启动程序只能试着注册4次,4次完后还要再启动程序,所以搞了个小伎俩,利用新建eip并修改待计算的注册码,一直穷举,这样不用重启程序。
另外反推注册码的思路应该是一种另类解法。

1.定位注册按钮:
Borland Delphi 4.0 - 5.0
TForm23:TBitBtn:OnClick = FormDeactivate
0055A760;005646D4;0057673C;00577068;583550;58459C;59588C;59DD00;5AD9A8;5AE674;6659E0;
断在:0059DD00     55                push ebp

2.流程:
2.1第一次运算比较:
0059DD38     E8 13B1E9FF     call Qimage.00438E50                 ; yhm
0059DD3D     8B45 E8         mov eax,dword ptr ss:[ebp-18]
...
0059DD6A     E8 E1B0E9FF     call Qimage.00438E50                 ; zcm
0059DD6F     8B45 DC         mov eax,dword ptr ss:[ebp-24]
...
0059DDF3     E8 2C65E6FF     call Qimage.00404324                    ; 连接注册码用户名
0059DDF8     8B45 D0         mov eax,dword ptr ss:[ebp-30]           ; 值
0059DDFB     8D55 D4         lea edx,dword ptr ss:[ebp-2C]
0059DDFE     E8 152D0300     call Qimage.005D0B18                    ; 运算
0059DE03     8B55 D4         mov edx,dword ptr ss:[ebp-2C]           ; 用户名+注册码的运算值
0059DE06     A1 18106900     mov eax,dword ptr ds:[691018]
0059DE0B     E8 B462E6FF     call Qimage.004040C4
0059DE10     A1 50146900     mov eax,dword ptr ds:[691450]
0059DE15     FF00            inc dword ptr ds:[eax]
0059DE17     8D55 C4         lea edx,dword ptr ss:[ebp-3C]
0059DE1A     8B07            mov eax,dword ptr ds:[edi]              ; 用户名
0059DE1C     E8 4F3B0800     call Qimage.00621970                    ; 对用户名的运算
0059DE21     8B45 C4         mov eax,dword ptr ss:[ebp-3C]           ; 
0059DE24     8D55 C8         lea edx,dword ptr ss:[ebp-38]
0059DE27     E8 EC2C0300     call Qimage.005D0B18                    ; 运算
0059DE2C     8B45 C8         mov eax,dword ptr ss:[ebp-38]           ; 用户名运算值
0059DE2F     8B15 18106900   mov edx,dword ptr ds:[691018]           ; Qimage.006FBAA0
0059DE35     8B12            mov edx,dword ptr ds:[edx]              ; 用户名+注册码的运算值
0059DE37     E8 F065E6FF     call Qimage.0040442C
0059DE3C     0F85 15010000   jnz Qimage.0059DF57

下断连接后的用户名注册码,然后进入call Qimage.005D0B18发现运算为:
005D0B5A     8D45 F4         lea eax,dword ptr ss:[ebp-C]
005D0B5D     8B55 FC         mov edx,dword ptr ss:[ebp-4]             ; 用户名+注册码
005D0B60     8A5432 FF       mov dl,byte ptr ds:[edx+esi-1]           ; 顺取
005D0B64     80F2 0F         xor dl,0F                                ; 断在此
005D0B67     E8 AC36E3FF     call Qimage.00404218                     ; 转移
005D0B6C     8B55 F4         mov edx,dword ptr ss:[ebp-C]             ; 转移后的地址
005D0B6F     8D45 F8         lea eax,dword ptr ss:[ebp-8]
005D0B72     E8 AD37E3FF     call Qimage.00404324
005D0B77     46              inc esi
005D0B78     4B              dec ebx
005D0B79   ^ 75 DF           jnz short Qimage.005D0B5A
顺取用户名+注册码,XOR 0F,得到字符串。

小结:
取出用户名注册码,然后连接,然后轮流XOR 0F得到比较值之一,
对用户名的运算得到字符串,轮流XOR 0F得到比较值之二,
两个值相等就成功?
比如用户名cyto,注册码8765432112345678
连接后cyto8765432112345678,
XOR值=堆栈 ss:[0032EA7C]=0156C080, (ASCII "lv{`789:;<=>>=<;:987")

用户名cyto的运算得到字符串:ASCII "QQLZ-5XKN-ZX3P-2VHH"
XOR值=堆栈 ss:[0032EF3C]=014FD090, (ASCII "^^CU":WDA"UW<_"=YGG")

如果相等的话就注册成功,感觉不能逆推得到注册码。
不等就继续下面的运算。

2.2第二次运算比较:
0059DF77     8D55 A8         lea edx,dword ptr ss:[ebp-58]
0059DF7A     8B06            mov eax,dword ptr ds:[esi]
0059DF7C     8B80 F8020000   mov eax,dword ptr ds:[eax+2F8]
0059DF82     E8 C9AEE9FF     call Qimage.00438E50
0059DF87     8B45 A8         mov eax,dword ptr ss:[ebp-58]          ; zcm
0059DF8A     8D55 AC         lea edx,dword ptr ss:[ebp-54]
0059DF8D     E8 CABF0100     call Qimage.005B9F5C                   ; 对注册码的运算
0059DF92     8B45 AC         mov eax,dword ptr ss:[ebp-54]          ; 注册码运算值
0059DF95     8D55 B0         lea edx,dword ptr ss:[ebp-50]
0059DF98     E8 7B2B0300     call Qimage.005D0B18                   ; 注册码运算值 XOR 0F
0059DF9D     8B55 B0         mov edx,dword ptr ss:[ebp-50]          ; XOR值
0059DFA0     A1 18106900     mov eax,dword ptr ds:[691018]
0059DFA5     E8 1A61E6FF     call Qimage.004040C4
0059DFAA     8D55 A0         lea edx,dword ptr ss:[ebp-60]
0059DFAD     8B07            mov eax,dword ptr ds:[edi]             ; YHM
0059DFAF     E8 A8840800     call Qimage.0062645C                   ; 对用户名的运算
0059DFB4     8B45 A0         mov eax,dword ptr ss:[ebp-60]          ; 用户名运算值
0059DFB7     8D55 A4         lea edx,dword ptr ss:[ebp-5C]
0059DFBA     E8 592B0300     call Qimage.005D0B18                   ; 用户名运算值 XOR OF
0059DFBF     8B45 A4         mov eax,dword ptr ss:[ebp-5C]          ; XOR值,用户名
0059DFC2     8B15 18106900   mov edx,dword ptr ds:[691018]          ; Qimage.006FBAA0
0059DFC8     8B12            mov edx,dword ptr ds:[edx]             ; XOR值,注册码运算值
0059DFCA     E8 5D64E6FF     call Qimage.0040442C                   ; 又一个比较
0059DFCF   ^ 0F84 6DFEFFFF   je Qimage.0059DE42

对注册码的计算: call Qimage.005B9F5C
005B9F9B     BE 01000000     mov esi,1
005B9FA0     8B45 FC         mov eax,dword ptr ss:[ebp-4]
005B9FA3     8A5C30 FF       mov bl,byte ptr ds:[eax+esi-1]              ; 顺取注册码
005B9FA7     33C0            xor eax,eax                                 ; 断在此
005B9FA9     8AC3            mov al,bl
005B9FAB     F7EE            imul esi                                    ; ×位数序号
005B9FAD     F7E8            imul eax                                    ; ×
005B9FAF     8B15 70146900   mov edx,dword ptr ds:[691470]               ; Qimage.00692044
005B9FB5     8902            mov dword ptr ds:[edx],eax
005B9FB7     80FB 2D         cmp bl,2D                                   ; 是不是-号
005B9FBA     75 17           jnz short Qimage.005B9FD3
005B9FBC     8D45 F0         lea eax,dword ptr ss:[ebp-10]
005B9FBF     8BD3            mov edx,ebx
005B9FC1     E8 52A2E4FF     call Qimage.00404218
005B9FC6     8B55 F0         mov edx,dword ptr ss:[ebp-10]
005B9FC9     8D45 F4         lea eax,dword ptr ss:[ebp-C]
005B9FCC     E8 53A3E4FF     call Qimage.00404324
005B9FD1     EB 39           jmp short Qimage.005BA00C
005B9FD3     B8 22000000     mov eax,22
005B9FD8     E8 1B8EE4FF     call Qimage.00402DF8                        ; 运算
005B9FDD     8BD8            mov ebx,eax
005B9FDF     80FB 08         cmp bl,8
005B9FE2     74 05           je short Qimage.005B9FE9
005B9FE4     80FB 0E         cmp bl,0E
005B9FE7     75 01           jnz short Qimage.005B9FEA
005B9FE9     43              inc ebx
005B9FEA     80FB 1A         cmp bl,1A
005B9FED     72 05           jb short Qimage.005B9FF4
005B9FEF     80C3 18         add bl,18
005B9FF2     EB 03           jmp short Qimage.005B9FF7
005B9FF4     80C3 41         add bl,41
005B9FF7     8D45 EC         lea eax,dword ptr ss:[ebp-14]
005B9FFA     8BD3            mov edx,ebx
005B9FFC     E8 17A2E4FF     call Qimage.00404218
005BA001     8B55 EC         mov edx,dword ptr ss:[ebp-14]
005BA004     8D45 F4         lea eax,dword ptr ss:[ebp-C]
005BA007     E8 18A3E4FF     call Qimage.00404324
005BA00C     46              inc esi
005BA00D     4F              dec edi
005BA00E   ^ 75 90           jnz short Qimage.005B9FA0

顺取注册码,所取的注册码是不是-号,是的话不变,下一位;
如果不是的话,×序号,平方,平方×8088405,+1,再平方,取高位edx的值;
edx值小于1A的话+41得到一位注册码,值大于等于1A的话+18得到一位注册码。
比如注册码:8765432112345678得到:ASCII "NXSLJJB8397UY29K"

对用户名的计算:
006264D6     0145 EC         add dword ptr ss:[ebp-14],eax          ; 断在此
下断后跟踪,非常繁琐。
用户名cyto,得到字符串:(ASCII "NSTE-AH82-P4ST-HWUR-NQK4")

然后注册码运算值与用户名运算值分别与0F异或,所得的值比较。

看来注册码运算值要=用户名运算值。
如果用户名=cyto,那么,用户名运算值=NSTE-AH82-P4ST-HWUR-NQK4
也即注册码运算值=NSTE-AH82-P4ST-HWUR-NQK4。

3.反推注册码:
注册码的运算也是比较繁琐的,不过可以巧解,那就是穷举,因为各个位置的注册码互相不影响。
NSTE-AH82-P4ST-HWUR-NQK4总共24位,输入的注册码也要24位。
如果输入24位一样的数比如888888888888888888888888,那么就能计算得到24个位置的字母各个值,依此类推。

小技巧:
涉及到注册码计算的代码如下几行:
0059DF87     8B45 A8         mov eax,dword ptr ss:[ebp-58]     ; zcm
0059DF8A     8D55 AC         lea edx,dword ptr ss:[ebp-54]
0059DF8D     E8 CABF0100     call Qimage.005B9F5C              ; 对注册码的运算
0059DF92     8B45 AC         mov eax,dword ptr ss:[ebp-54]     ;  (ASCII "NXSLJJB8397UY29K")
因为程序限制了只能计算4次就要重新运行程序,所以搞了个技巧,在0059DF92处设断,断下后修改[ebp-58]的值,然后在0059DF87新建eip,进行下一个计算,这样就不要老启动程序了。呵呵。

各个字符的计算结果:
9:堆栈 ss:[0032EA54]=014F0F40, (ASCII "83TJ4KYAHLMJE5RCS6GMPPMF")
8:堆栈 ss:[0032EF20]=014FD24C, (ASCII "NVWRGW8CAZKX55XKZAD9XHTY")
7:堆栈 ss:[0032EA54]=014FE8B4, (ASCII "7XK2DJJF5P4DHF9VEQXYVM8N")
6:堆栈 ss:[0032EA54]=014FE8AC, (ASCII "RASCUEXJ3N9TF2M9VJ6TH6TJ")
5:堆栈 ss:[0032EA54]=0156C090, (ASCII "ETKLWJFM4VXCYW6PJN3QQ2MJ")
4:堆栈 ss:[0032EF20]=014FD01C, (ASCII "4NWVJWYQ8EAU55S8B4LSPBMM")
3:堆栈 ss:[0032EA54]=01560C54, (ASCII "VQT6QJLVF77FWMLR8VSXCXTW")
2:堆栈 ss:[0032EA54]=015660B0, (ASCII "P3BGJGB2P9P2AFHFAZN7NY8D")
1:堆栈 ss:[0032EA54]=01560C30, (ASCII "LMDQTM383KSPAJH5GH6JMETX")
0:堆栈 ss:[0032EF20]=014FD228, (ASCII "KGX2Q2WFJ7HDUXMVR9CZA6MP")

A:堆栈 ss:[0032EA54]=0156E57C, (ASCII "TKHJR6PE9AHSCYSSX9PD648H")
B:堆栈 ss:[0032EA54]=0156E57C, (ASCII "XZHBJ55H9DUR2PQ6X6PNZPSA")
C:堆栈 ss:[0032EF20]=014FD214, (ASCII "5P24UEMLAPUQDPRL5DD3JPL9")
D:堆栈 ss:[0032EA54]=014F0F40, (ASCII "DN6URV7PFCGRBZX3EWNLP3LC")
E:堆栈 ss:[0032EA54]=014F0F64, (ASCII "NUUN9NUUN9NTTM9MTTM8LSSL")
F:堆栈 ss:[0032EA54]=014F0F64, (ASCII "ZB5GBPKZXFFXYJN9E29X6W7Z")
G:堆栈 ss:[0032EA54]=014F0F40, (ASCII "GZW9WXE7CVS3QR6X4LJREFSJ")
H:堆栈 ss:[0032EA54]=014F0F64, (ASCII "WXC24JADTMR94ATPWJFPCAL9")
I:堆栈 ss:[0032EA54]=014F0F40, (ASCII "H6ATUB8KEMCH34LJWQZQWJL4")
J:堆栈 ss:[0032EA54]=014F0F40, (ASCII "4LRN7D9SZWHPM8HFZB9V76S4")
K:堆栈 ss:[0032EA54]=014F0F64, (ASCII "RBUG3PD2QH9ZSNJDA765567A")
L:堆栈 ss:[0032EA54]=014F0F40, (ASCII "JAJAJAJBJBKCLDMENFPHQJSK")
M:堆栈 ss:[0032EA54]=014F0F40, (ASCII "BHP4J5SKGFJPYEVH7ZWW2ALZ")
N:堆栈 ss:[0032EA54]=014F0F64, (ASCII "7WJW685UFS24YP9MUVRHZELM")
O:堆栈 ss:[0032EA54]=014F0F40, (ASCII "4MTQBKJ6HH6JLCQUN5B5NVRD")
P:堆栈 ss:[0032EA54]=014F0F64, (ASCII "4LQK27ZHMFVZS9D6LPHVZQ7A")
Q:堆栈 ss:[0032EA54]=014F0F64, (ASCII "6S8ED3KTTM7JMH4JPLBRZZRB")
R:堆栈 ss:[0032EA54]=014F0F40, (ASCII "9999887765432ZYWVTSQPMKJ")
S:堆栈 ss:[0032EA54]=014F0F64, (ASCII "FXT3NLVJJVLN3TXF9FXT2MKU")
T:堆栈 ss:[0032EA54]=014F0F40, (ASCII "PWZWPAPX2XPAPX2YPCQZ4ZRD")
U:堆栈 ss:[0032EA54]=014F0F64, (ASCII "Y5QRA7JCLAEXXEALDK8ASR7Z")
V:堆栈 ss:[0032EA54]=014F0F40, (ASCII "CL2MFDHR8UNNS5MA55BP7VRS")
W:堆栈 ss:[0032EA54]=014F0F64, (ASCII "RCVJ5SH8XQJE96322246AEKR")
X:堆栈 ss:[0032EA54]=014F0F40, (ASCII "AABDFHKNRVZ6BHNU3AJQZAKU")
Y:堆栈 ss:[0032EA54]=014F0F64, (ASCII "TJB8AGP5NB3YY5DQ9ULGGJR4")
Z:堆栈 ss:[0032EA54]=014F0F40, (ASCII "GYU4PNXMMZQT927PKRCAJ76J")

NSTE-AH82-P4ST-HWUR-NQK4
第01位是N的有:8,E
第02位是S的有:Q
第03位是T的有:3,9,O(字母),S
第04位是E的有:Q
第06位是A的有:L,T
第07位是H的有:V,W
第08位是8的有:1,W
第09位是2的有:T
第11位是P的有:2,T
第12位是4的有:N
第13位是S的有:K,P
第14位是T的有:S
第16位是H的有:M
第17位是W的有:H,I
第18位是U的有:Y
第19位是R的有:N
第21位是N的有:2,O(字母)
第22位是Q的有:P
第23位是K的有:R,S,W,X
第24位是4的有:I,J,Y

挑一组:8Q3Q-LV1T-2NKS-MHYN-2PRI

解锁成功,写入注册表:
HKCU\Software\Qimage\Name/Company  SUCCESS  "cyto"  
HKCU\Software\Qimage\Unlock Code  SUCCESS  "A\[J"NG7="_;\["GXZ]"A^D;"