-
-
NneWell's KeygenMe
-
2004-5-18 17:07 5917
-
NneWell's KeygenMe
点击下载:附件!
这个kegenme脱壳,虽说包了三层壳,但都未做特殊处理,还是比较容易脱壳的,此处就不说了,只简单说一下算法流程
(1) 对用户名的变换
对“用户名Team.FreeWingS” 进行查表运算,这里有两张表
"2WqvCprbgHBcKLRfmD0x6V5TyX4n3QuIz987JEOoliZUsMjkAt1eNahYSFdPGw"
查的用户名索引 然后对串每一字节与索引值运算后,循环查"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"
运算所得串存放在ds:dword_4137D8
(2) 对注册码的变换
注册码32字节,转换为大写存放在ds:dword_4137D0
(3)SHA及RSA运算
按下确定按钮后
核心运算啦
进来看看
核心其实就是
RSA(注册码变换串串) == SHA(用户名变换串) 里面稍有些小变化而已
感觉算法还算明了,就是中间加了些类似下面这些代码,显得Call调用比较多,其实核心部分还是比较简明的
RSA(N=82BD850DAD84C36128C4BC43DD764DF9,E=0E401C1B)
容易得到解密d = 1BF0778D89CFE1B26DE4D0E9FAA9720B
用计算器算了一个注册码:
Name: yesky1
Code: 9E0930D8B48D2956E78870303949B69C
这个keygenme总的说来不算难,注册机部分主要是字符串变换,最好的办法就是在这个keygenme上进行diy来做出一个注册机,就不需要对字符
串变换重新实现,而且因为RSA算法是对成算法,而SHA为单向算法都可直接应用keygenme中的代码,有兴趣的不妨一试,也让我学习一下,:)。当然也可拷贝出asm码来,c中嵌入汇编也是比较好实现的。
好久没玩破解了,还望大伙指正:D 。
by yesky1
点击下载:附件!
这个kegenme脱壳,虽说包了三层壳,但都未做特殊处理,还是比较容易脱壳的,此处就不说了,只简单说一下算法流程
(1) 对用户名的变换
对“用户名Team.FreeWingS” 进行查表运算,这里有两张表
"2WqvCprbgHBcKLRfmD0x6V5TyX4n3QuIz987JEOoliZUsMjkAt1eNahYSFdPGw"
查的用户名索引 然后对串每一字节与索引值运算后,循环查"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"
运算所得串存放在ds:dword_4137D8
seg000:0040E19B push ds:dword_4137D8 ; 保存输出:根据用户名所得变换字串 形如"YHPI1Po7Gk.NN55ExcF6" seg000:0040E1A1 lea eax, [ebp+var_9C6] ; 形如"yesky1Team.FreeWingS" seg000:0040E1A7 push eax seg000:0040E1A8 lea eax, [ebp+var_BC] ; "2WqvCprbgHBcKLRfmD0x6V5TyX4n3QuIz987JEOoliZUsMjkAt1eNahYSFdPGw" seg000:0040E1AE push eax seg000:0040E1AF lea eax, [ebp+var_7C] ; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890" seg000:0040E1B2 push eax seg000:0040E1B3 call sub_40D563 ; 用户名字符串变换函数
(2) 对注册码的变换
注册码32字节,转换为大写存放在ds:dword_4137D0
seg000:0040DF81 lea eax, [ebp+var_FC6] seg000:0040DF87 push eax seg000:0040DF88 call sub_40C76D ; 注册码每个DWORD高低字位互换 seg000:0040DA91 call sub_40D4B5 ; 对注册码进行简单ROR+ADD XOR变换
(3)SHA及RSA运算
按下确定按钮后
核心运算啦
seg000:0040DFF9 lea eax, [ebp+var_1C78] ; 输入:‘%.8X%.8X%.8X%.8X’ seg000:0040DFFF push eax seg000:0040E000 lea eax, [ebp+var_FE4] ; 输出:用来最终比较 SHA运算输出 seg000:0040E006 push eax seg000:0040E007 lea eax, [ebp+var_518] ; 输出:由用户名串变换而来,用于进行RSA后再进行最终比较 seg000:0040E00D push eax seg000:0040E00E lea eax, [ebp+var_1C64] ; 输入:用户名变换结果 字符串 seg000:0040E014 push eax seg000:0040E015 lea eax, [ebp+var_FC6] ; 输入:变换后注册码 seg000:0040E01B push eax seg000:0040E01C call sub_40DA5C ; SHA160变换
进来看看
seg000:0040DA5C push ebp seg000:0040DA5D mov ebp, esp seg000:0040DA5F push ebx seg000:0040DA60 push esi seg000:0040DA61 push edi seg000:0040DA62 xor eax, eax seg000:0040DA64 or ecx, 0FFFFFFFFh seg000:0040DA67 mov edi, [ebp+arg_4] seg000:0040DA6A repne scasb seg000:0040DA6C not ecx seg000:0040DA6E dec ecx seg000:0040DA6F mov ds:dword_413658, ecx seg000:0040DA75 call sub_40C2FA ; 监测调试器 seg000:0040DA7A push offset dword_413658 seg000:0040DA7F push [ebp+arg_4] seg000:0040DA82 call sub_40D686 ; 对用户名变换串进行SHA160变换,结果保存再unk_413074 seg000:0040DA87 mov ds:byte_413088, 0 seg000:0040DA8E push [ebp+arg_0] seg000:0040DA91 call sub_40D4B5 ; 对注册码进行简单ROR+ADD XOR变换 seg000:0040DA96 mov ecx, 0Ch ; 取SHA160变换结果前12字节 seg000:0040DA9B mov ds:dword_41364C, ecx ; 保存长度 seg000:0040DAA1 mov esi, offset unk_413074 ; 保存SHA160结果 seg000:0040DAA6 mov edi, [ebp+arg_C] seg000:0040DAA9 rep movsb seg000:0040DAAB call sub_40C4DF ; 监测调试器 seg000:0040DAB0 mov esi, offset unk_413074 ; 保存SHA160结果 seg000:0040DAB5 mov edi, [ebp+arg_C] ; 下面对SHA前12字节与后8字节进行xor变换 seg000:0040DAB8 mov eax, [esi+10h] seg000:0040DABB xor [edi], eax seg000:0040DABD mov eax, [esi+0Ch] seg000:0040DAC0 xor [edi+8], eax seg000:0040DAC3 mov eax, [edi] seg000:0040DAC5 xor [edi+4], eax seg000:0040DAC8 mov edi, [ebp+arg_0] ; 注册码变换HEX串 seg000:0040DACB push dword ptr [edi] seg000:0040DACD push dword ptr [edi+4] seg000:0040DAD0 push dword ptr [edi+8] seg000:0040DAD3 push dword ptr [edi+0Ch] seg000:0040DAD6 push [ebp+arg_10] seg000:0040DAD9 push [ebp+arg_8] ; 输出:用于RSA变换输入 seg000:0040DADC call ds:dword_4137B6 ; wsprintf seg000:0040DAE2 pop edi seg000:0040DAE3 pop esi seg000:0040DAE4 pop ebx seg000:0040DAE5 leave seg000:0040DAE6 retn 14h seg000:0040DAE6 sub_40DA5C endp seg000:0040E026 lea eax, [ebp+var_518] ; 输入待变换M串 seg000:0040E02C push eax seg000:0040E02D lea eax, [ebp+var_EC6] ; 保存RSA输出结果 C seg000:0040E033 push eax seg000:0040E034 lea eax, [ebp+var_2C] ; E='E401C1B' seg000:0040E037 push eax seg000:0040E038 lea eax, [ebp+var_22] ; N='82BD850DAD84C36128C4BC43DD764DF9' seg000:0040E03B push eax seg000:0040E03C call sub_40DAE9 ; RSA运算 seg000:0040E041 call sub_40E331 ; 监测调试器? seg000:0040E046 lea eax, [ebp+var_FE4] seg000:0040E04C push eax seg000:0040E04D lea eax, [ebp+var_EC6] ; rsa计算结果 seg000:0040E053 push eax seg000:0040E054 call sub_40DBB7 ; 进行最终比较,比较12字节 seg00059 and eax, eax seg000:0040E05B jz short loc_40E07C ; 不等则跳出错对话框
核心其实就是
RSA(注册码变换串串) == SHA(用户名变换串) 里面稍有些小变化而已
感觉算法还算明了,就是中间加了些类似下面这些代码,显得Call调用比较多,其实核心部分还是比较简明的
call sub_40C69D ; 解码字符串函数 call sub_40D886 ; 内存数据搬运工 将用户名变换串和注册码HEX串搬来搬去诚心找事干啊,:) call sub_40D4F2 ; 类似这种,制造SEH来添乱
RSA(N=82BD850DAD84C36128C4BC43DD764DF9,E=0E401C1B)
容易得到解密d = 1BF0778D89CFE1B26DE4D0E9FAA9720B
用计算器算了一个注册码:
Name: yesky1
Code: 9E0930D8B48D2956E78870303949B69C
这个keygenme总的说来不算难,注册机部分主要是字符串变换,最好的办法就是在这个keygenme上进行diy来做出一个注册机,就不需要对字符
串变换重新实现,而且因为RSA算法是对成算法,而SHA为单向算法都可直接应用keygenme中的代码,有兴趣的不妨一试,也让我学习一下,:)。当然也可拷贝出asm码来,c中嵌入汇编也是比较好实现的。
好久没玩破解了,还望大伙指正:D 。
by yesky1
阿里云助力开发者!2核2G 3M带宽不限流量!6.18限时价,开 发者可享99元/年,续费同价!
赞赏
他的文章
看原图