第15课keymake算法注册机技巧.docx
《第15课keymake算法注册机技巧.docx》由会员分享,可在线阅读,更多相关《第15课keymake算法注册机技巧.docx(24页珍藏版)》请在冰点文库上搜索。
第15课keymake算法注册机技巧
第一个需注意的问题是:
遇到数字,记得加上h。
第二个:
注意将dwordptr[ebp-xx]用变量xx替换。
变量xx在.data中定义如下:
xxdd0
〔例1〕用keymake写的算法注册机。
如下:
.const
.data
szHomePagedb"",0
szEmaildb"",0
szErrMessdb"请输入姓名!
",0
szHexdb"%lu",0
szBufferdb50dup(0)
a1dd0
a2dd0
lendd0
.code
movesi,eax
invokelstrlen,esi
movlen,eax
mova1,0
mova2,h
jmpn3
n2:
movedx,a1
addedx,1
mova1,edx
n3:
moveax,a1
cmpeax,len
jgen1
movecx,a1
movsxedx,byteptr[esi+ecx]
moveax,a2
addeax,edx
mova2,eax
movecx,a1
shlecx,8
movedx,a2
xoredx,ecx
mova2,edx
moveax,a1
addeax,1
movecx,len
imulecx,a1
notecx
imuleax,ecx
movedx,a2
imuledx,eax
mova2,edx
jmpn2
n1:
invokewsprintf,addrszBuffer,addrszHex,a2
leaeax,szBuffer
说明:
将dwordptrss:
[ebp-10]定义为a2,用a2替换
dwordptrss:
[ebp-20]定义为a1,用a1替换
dwordptrss:
[ebp-1C]定义为len,用len替换,表征姓名字符串的长度
注意:
在程序的反汇编代码中寻找a1、a2的初始值。
假设你看不懂算法,乱七八糟的一堆汇编代码,依然可以写出它的注册机。
二、keymake使用说明:
keymake程序初始时,默认的是,令EAX指向第一个编辑框(也就是输入序列号的窗口)收到用户输入的数据;令EBX指向第二个编辑框收到用户输入的数据;令ECX指向第三个编辑框收到用户输入的数据。
你如果要对用户输入的序列号或用户名等信息进行操作,那么可以就对EAX、EBX、ECX进行操作。
在keymake目录EXAMPLE下有一个例子程序,主要用来举例说明这个程序的使用(我先假设自己并不太懂Win32汇编)。
1.通过动态调试或反汇编例子程序可以得到以下注册码的计算过程(它不是根据你的序列号来计算注册码):
xxxx:
00401077CALLGetCommandLineA
xxxx:
0040107CCMP BYTEPTR[EAX],22
xxxx:
0040107FJNZ 401082
xxxx:
00401081INC EAX
xxxx:
00401082MOV CX,WORDPTR[EAX]
xxxx:
00401085MOV WORDPTR[0040306C],CX
xxxx:
0040108CMOV WORDPTR[0040306E],5C
xxxx:
00401095PUSH0
xxxx:
00401097PUSH0
xxxx:
00401099PUSH0
xxxx:
0040109BPUSH0
xxxx:
0040109DPUSHDWORD00403058
xxxx:
004010A2PUSH0
xxxx:
004010A4PUSH0
xxxx:
004010A6PUSHDWORD0040306C
xxxx:
004010ABCALLGetVolumeInformationA
………… …………
………… …………0040112F0040305C0040113C
40306C
40305C
种算注册码的方法不是直接从用户所输入的序列号来计算注册码的,所以并不适用于所有情况。
有时我们可能需要根据用户所填入的序列号来计算注册码。
下面的代码是本例根据用户所填入的序列号来计算注册码的方法:
MOVECX,EAX
;EAX指向用户输入的八位序列号,现在暂将它移动到ECX寄存器
XOREBX,EBX;EBX清零
;以下是一段典型的将内存中的ASCII码转换为十六进制代码。
n1:
MOVZXEAX,BYTEPTR[ECX]
ORAL,AL
JZn3
CMPAL,3Ah
JCn2
SUBAL,7
n2:
SUBAL,30h
SHLEBX,4
ADDEBX,EAX
INCECX
JMPn1
n3:
;我想以上的一段代码应该懂汇编就能写的出(如果不是很明白,那么你对我编写好的注册机用ollydbg调试一次就知道了)。
PUSHEBX
;最后的十六进制结果都保存在寄存器EBX中
;将EBX入栈,这是为了将EBX寄存器的数据保存起来。
因为经过CPUID这个指令后EBX的值将被修改。
然后后面就和上面一样照抄程序中的指令。
以下计算注册码的方法很简短。
但在实际的破解过程中,程序的算法可能会相当复杂。
这就需要你通过调试或反汇编将关键的运算指令都找出来,再写进来。
MOV EAX,1
CPUID
POPECX
;恢复EBX的值到ECX寄存器,开始计算注册码
XOR EDX,EDX
MUL ECX
ADD EAX,EDX
;下面的指令指的是输出格式,除了“%lX”可以修改,其他的请照抄
PUSHEAX
LEA EAX,a3
;令EAX指向a3,也就是指向字符“%lX”。
%lX"指的是输出数据的格式,你会C语言就肯定懂了
PUSHEAX
LEA EAX,a4
PUSHEAX
CALLwsprintfA
LEAEAX,a4
;令EAX指向a4。
因为程序最后显示的就是EAX寄存器所指向的内存地址的数据。
以下几个是进制转换函数和我加入的部分自定义函数,你也可以在编写注册机的过程中调用它们(使用时千万不要把大小写弄错了)。
atodw 将十进制的内存ASCII数值转换为数据元素
使用格式:
invokeatodw,指向存放内存数值的缓冲区
htodw 将十六进制的内存ASCII数值转换为数据元素
使用格式:
invokehtodw,指向存放内存数值的缓冲区
MakeCrypt 对内存缓冲区数据进行加密
使用格式:
invokeMakeCrypt,指向要加密的字符缓冲区,指向接收加密后的字符缓冲区
UnMakeCrypt 对内存缓冲区数据进行解密
使用格式:
invokeUnMakeCrypt,指向要解密的字符缓冲区,指向接收解密后的字符缓冲区
wsprintf 使用给定格式格式化数据元素
使用格式:
invokewsprintf,指向存储输出的字符缓冲区,指向以空值结尾的包含格式化选项的字符串,指向一个数据元素列表
数据格式化选项:
%d,%i 有符号十进制数值;
%ld,%li 长的有符号十进制整数值;
%u 无符号十进制整数值;
%lu 长的无符号十进制整数值;
%x,%X 十六进制整数值,%x输出小写,%X输出大写;
%lx,%lX 长的十六进制整数值,%lx输出小写,%lX输出大写;
# 0x字符串的前缀数据,一般在显示十六进制值时使用。
精度修饰符——小数点后跟一个数,指定复制到输出缓冲区数字的最小数目。
如果给定数字位数小于精度指定位数,域中用0填充,默认情况从左边填充。
假如给定精度“.10”,数“”复制到输出缓冲区后变为“”
如无特别说明或已经指定了输出位置,在Win32程序中所有的结果都返回在eax中。
使用举例一:
比如要将内存中的十进制数值“”转换为十六进制,输出结果以0x为前缀,再进行加密。
数据区:
szXor16db"%#lX",0
szNum10db"",0
szBufferdb50dup(0)
szOutMemdb50dup(0)
代码区:
invokeatodw,addrszNum10 ;这一句是将内存中的数值当做十进制转换为数据元素,返回的结果在eax中,那么eax=bc614e
invokewsprintf,addrszBuffer,addrszXor16,eax ;这一句是将eax中的值以十六进制大写输出到内存szBuffer位置。
invokeMakeCrypt,addrszBuffer,addrszOutMem ;这一句是将指向内存szBuffer的数据加密后输出到内存szOutMem的位置。
使用举例二:
比如要将内存中的十六进制数值“ABCDEF”转换为十进制,输出长度为20位数,再进行解密。
数据区:
szXor10db"%",0
szNum16db"ABCDEF",0
szBufferdb50dup(0)
szOutMemdb50dup(0)
代码区:
invokehtodw,addrszNum16 ;这一句是将内存中的数值ABCDEF当做十六进制转换为数据元素,返回的结果在eax中,那么eax=abcdef
invokewsprintf,addrszBuffer,addrszXor10,eax ;这一句是将eax中的值以十进制输出到内存szBuffer位置。
invokeUnMakeCrypt,addrszBuffer,addrszOutMem ;这一句是将指向内存szBuffer的数据解密后输出到内存szOutMem的位置。
=====以上部分摘自keymake的说明书======
〔例2〕某软件:
小护士,注册算法为:
注册码=机器码XOR78AB1234 的十进制值!
显然,78AB1234为16进制数。
根据上面学的,用atodw函数
.const
.data
szHomePagedb"",0
szEmaildb"",0
szErrMessdb"输入的机器码不正确!
",0
szFMTdb"%d",0
szBufferdb30dup(0)
.code
invokeatodw,eax
xoreax,78AB1234h
invokewsprintf,addrszBuffer,addrszFMT,eax
leaeax,szBuffer
〔例3〕象棋桥
关键代码如下:
004846B733C9xorecx,ecx
004846B98A08movcl,byteptrds:
[eax]
004846BB8B45F4moveax,dwordptrss:
[ebp-C]
004846BE33DBxorebx,ebx
004846C08A5801movbl,byteptrds:
[eax+1]
004846C38B45F4moveax,dwordptrss:
[ebp-C]
004846C60FB67002movzxesi,byteptrds:
[eax+2]
004846CA8B45F4moveax,dwordptrss:
[ebp-C]
004846CD0FB67803movzxedi,byteptrds:
[eax+3]
004846D18B45F4moveax,dwordptrss:
[ebp-C]
004846D40FB64004movzxeax,byteptrds:
[eax+4]
004846D88945F0movdwordptrss:
[ebp-10],eax
004846DB8D040Bleaeax,dwordptrds:
[ebx+ecx]
004846DE03FEaddedi,esi
004846E0F7EFimuledi
004846E2F76DF0imuldwordptrss:
[ebp-10]
004846E5B9A0860100movecx,186A0
004846EA99cdq
004846EBF7F9idivecx
004846ED8BDAmovebx,edx
004846EF8D55F4leaedx,dwordptrss:
[ebp-C]
如下:
.const
.data
szHomePagedb"",0
szEmaildb"",0
szErrMessdb"输入的序列号不正确!
",0
TempBufferdb100dup(0)
szHexdb"CCB21R-%lu",0
a1dd0
.code
xorecx,ecx
movcl,byteptr[eax]
xorebx,ebx
movbl,byteptr[eax+1]
movzxesi,byteptr[eax+2]
movzxedi,byteptr[eax+3]
movzxeax,byteptr[eax+4]
mova1,eax
leaeax,dwordptr[ebx+ecx]
addedi,esi
imuledi
imula1
movecx,000186A0h
cdq
idivecx
movebx,edx
invokewsprintf,addrTempBuffer,addrszHex,ebx
leaeax,TempBuffer
留意红色字体的部分
〔例4〕Flash注册算法
关键代码(企业版)如下:
:
005168E1BBDB070000movebx,000007DB
:
005168E68B45FCmoveax,dwordptr[ebp-04]
:
005168E9E832D8EEFFcall00404120
:
005168EE8BF0movesi,eax
:
005168F085F6testesi,esi
:
005168F27E4Ajle0051693E
:
005168F4BF01000000movedi,00000001
*Referencedbya(U)nconditionalor(C)onditionalJumpatAddress:
|:
0051693C(C)
|
:
005168F98B45FCmoveax,dwordptr[ebp-04]
:
005168FC8A4C38FFmovcl,byteptr[eax+edi-01]
:
0051690033C0xoreax,eax
:
005169028AC1moval,cl
:
005169048D570Dleaedx,dwordptr[edi+0D]
:
00516907F7EAimuledx
:
0051690903D8addebx,eax
:
0051690B8BC3moveax,ebx
:
0051690DBBFFC99A3Bmovebx,3B9AC9FF
:
0051691299cdq
:
00516913F7FBidivebx
:
005169158BDAmovebx,edx
:
005169178B45FCmoveax,dwordptr[ebp-04]
:
0051691A80F145xorcl,45
:
0051691D33C0xoreax,eax
:
0051691F8AC1moval,cl
:
00516921F76DF8imul[ebp-08]
:
0051692403D8addebx,eax
:
005169268BC3moveax,ebx
:
00516928B9FFC99A3Bmovecx,3B9AC9FF
:
0051692D99cdq
:
0051692EF7F9idivecx
:
005169308BDAmovebx,edx
:
0051693269C72B300600imuleax,edi,0006302B
:
0051693803D8addebx,eax
:
0051693A47incedi
:
0051693B4Edecesi
:
0051693C75BBjne005168F9
*Referencedbya(U)nconditionalor(C)onditionalJumpatAddress:
|:
005168F2(C)
|
:
0051693E8BC3moveax,ebx
:
00516940B9FFE0F505movecx,05F5E0FF
:
0051694599cdq
:
00516946F7F9idivecx
:
005169488BDAmovebx,edx
:
0051694A8BC3moveax,ebx
:
0051694CB0movecx,00000006
:
0051695199cdq
:
00516952F7F9idivecx
:
0051695483C241addedx,00000041
:
005169578855F3movbyteptr[ebp-0D],dl
:
0051695A895DECmovdwordptr[ebp-14],ebx
:
0051695DDB45ECfilddwordptr[ebp-14]
:
0051696083C4F4addesp,FFFFFFF4
:
00516963DB3C24fstptbyteptr[esp]
:
005169669Bwait
:
005169678D45E8leaeax,dwordptr[ebp-18]
:
0051696A8A55F3movdl,byteptr[ebp-0D]
:
0051696DE8D6D6EEFFcall00404048
:
005169728D45E8leaeax,dwordptr[ebp-18]
*PossibleStringDataReffromCodeObj->"00-000-000"
|
:
00516975BAC0695100movedx,005169C0
其文件如下:
.const
.data
szHomePagedb"",0
szEmaildb"",0
szErrMessdb"没输入姓名!
",0
szFmtdb"%",0
szTempdb10dup(0)
szCodedb14dup(0)
a1dd147h
.code
movebx,7DBh
invokelstrlen,eax
movesi,eax
movedi,1
n1:
leaeax,hInput1
movcl,byteptr[eax+edi-1]
xoreax,eax
moval,cl
leaedx,dwordptr[edi+0Dh]
imuledx
addebx,eax
moveax,ebx
movebx,3B9AC9FFh
cdq
idivebx
movebx,edx
xorcl,45h
xoreax,eax
moval,cl
imula1
addebx,eax
moveax,ebx
movecx,3B9AC9FFh
cdq
idivecx
movebx,edx
imuleax,edi,0006302Bh
addebx,eax
incedi
decesi
jnen1
moveax,ebx
movecx,05F5E0FFh
cdq
idivecx
movebx,edx
moveax,ebx
movecx,6
cdq
idivecx
addedx,41h
movbyteptrszTemp,dl
invokewsprintf,addrszTemp+1,addrszFmt,ebx
movedx,3
leaesi,szTemp
leaedi,szCode
n2:
movecx,3
repmovsb
mov[edi],byteptr"-"
incedi
decedx
jnzn2
mov[edi-1],byteptr0
leaeax,szCode
注意其中的红色的部分。
〔例5〕k4n2的注册算法(KEYGENNING4NEWBIES#2)
此软件有bug。
注册码的计算中涉及到一个edi的初值。
不同的机器是不同的。
无法制作通用在任何机器上的注册机。
但作为教学来说,还是一个很不错的例子。
可以制作针对本机的注册机。
我机器的edi初值为12F55C。
关键代码如下:
004010F733D2xoredx,edx
004010F933DBxorebx,ebx
004010FB8B55D4movedx,dwordptrss:
[ebp-2C]
004010FE0155C4adddwordptrss:
[ebp-3C],edx
004011010155C4adddwordptrss:
[ebp-3C],edx
004011048BC2moveax,edx
0040110683C005addeax,5
004011098945B8movdwordptrss:
[ebp-48],eax
0040110C33C0xoreax,eax
0040110E8BCFmovecx,edi
0040111083C104addecx,4
00401113894DB4movdwordptrss:
[ebp-4C],ecx
0040111633C9xorecx,ecx
004011180155BCadd