【文章标题】: 一个窗口隐藏工具的注册验证流程分析(二)-RSA补丁与注册机
【文章作者】: FishSeeWater
【软件名称】: 为支持看雪,想研究学习的自己找找吧:)
【软件大小】: 264K
【下载地址】: 自己搜索下载
【加壳方式】: ASPack
【保护方式】: Aspack+RSA
【编写语言】: Delphi
【使用工具】: OllyIce IDA RSATool BigIntCalc
【作者声明】: 只是感兴趣研究密码学保护的程序,没有其他目的,这里也是纯代码演示。失误之处敬请诸位大侠赐教!
同时感谢lingyu的密码学方面大力帮助,没有lingyu的帮助,就没有这篇幅教程了:)
--------------------------------------------------------------------------------
【详细过程】
一款窗口隐藏的工具,可定制性很高,是本人目前见过的窗口隐藏类软件中比较不错的。
(分析过程见:一个窗口隐藏工具的注册验证流程分析(一))
开工前明确一下目标:
目标 :做出目标软件的注册机
需要工具:Delphi7-2007,FGInt库,RSATool,大数计算器 BigIntCalc 。
预备知识:
一个窗口隐藏工具的注册验证流程分析(一)
RSA保护的程序 注册机制作思路总结
首先我们分析一下要实现我们的目标需要做哪些工作:
1、通过前一篇文章的分析我们知道软件中用RSA算法保护的,因此 RSA算法中的n,e,d 是不可或缺的。有了这三个参数,
我们就可以做“许可文件”了。
2、同样,前一篇文章我们也分析出了“许可文件”中存放着用户名与授权码的密文,各占一行。我们除了要求出授权码,
还要想办法求出一个用户名,否则通过授权码的验证后,在界面上的授权用户会显示乱码的。
整理一下:
注册机要实现的两个功能(我们给其取个名字叫:“注册机 总纲”):
1、根据机器码生成授权码并转换为密文的功能。
a、找出RSA算法中的n,e,d。
b、如果不能顺利的找出e,那还需要patch软件。
c、用找到的n,e 写授权码生成代码。
2、根据用户名生成用户名密文的功能。
3、将1,2生成的密文保存到文件功能。
首先进行“注册机 总纲” 第1部分:
要做RSA注册机必要的三个元素 n,e,d。通过前面的分析,我们知道在软件中已经有 n,d 的存在了,那么对于RSA的攻击我
们能不能用“2、RSA小指数攻击法”这种方法进行呢?不试试是不会知道的:),那我们先进尝试用“2、RSA小指数攻击法”
这种方法来获取做注册机所需要的e。
我们给这个方案取个名字为 :MakeRSAKeyGen 方案一
为了工作方便,先进行一些前期工作:
1、由于程序中的n,d都是加密后存放的,所以我们先把他自定义的加解密函数提出来。
2、把 n,d 的加密字串提出来备用。
我们先看一下程序的自定义加密函数:
00483B58 <H>/$ 55 push ebp ; subN_222222_Encrypt
00483B59 |. 8BEC mov ebp, esp
00483B5B |. 83C4 F8 add esp, -8
00483B5E |. 53 push ebx
00483B5F |. 56 push esi
00483B60 |. 57 push edi
00483B61 |. 894D F8 mov [local.2], ecx
00483B64 |. 8BF2 mov esi, edx
00483B66 |. 8945 FC mov [local.1], eax
00483B69 |. 8B45 FC mov eax, [local.1]
00483B6C |. E8 3310F8FF call <HideHelp.System::__linkproc__ LStrAddRef(void *)>
00483B71 |. 33C0 xor eax, eax
00483B73 |. 55 push ebp
00483B74 |. 68 EA3B4800 push <HideHelp.loc_483BEA>
00483B79 |. 64:FF30 push dword ptr fs:[eax]
00483B7C |. 64:8920 mov dword ptr fs:[eax], esp
00483B7F |. 8B45 F8 mov eax, [local.2]
00483B82 |. 8B55 FC mov edx, [local.1]
00483B85 |. E8 A20BF8FF call <HideHelp.System::__linkproc__ LStrAsg(void *,void *)>
00483B8A |. 8B45 FC mov eax, [local.1]
00483B8D |. E8 220EF8FF call <HideHelp.__linkproc__ LStrLen_Or_DynArrayLength(void)>
00483B92 |. 8BF8 mov edi, eax
00483B94 |. 85FF test edi, edi
00483B96 |. 7E 3C jle short <HideHelp.loc_483BD4>
00483B98 |. BB 01000000 mov ebx, 1
00483B9D <H>|> 8B45 F8 /mov eax, [local.2] ; 输出
00483BA0 |. E8 6710F8FF |call <HideHelp.InternalUniqueString(void &)>
00483BA5 |. 8B55 FC |mov edx, [local.1] ; 输入
00483BA8 |. 8A541A FF |mov dl, byte ptr ds:[edx+ebx-1] ; 取明文的ASCII码
00483BAC |. 8BCE |mov ecx, esi ; ESI中存放的是一个种子数 0x59F0F3 (从参数中传进来的)
00483BAE |. C1E9 08 |shr ecx, 8 ; 种子数右移8位
00483BB1 |. 32D1 |xor dl, cl ; ASCII码与右移后的值异或
00483BB3 |. 885418 FF |mov byte ptr ds:[eax+ebx-1], dl ; 保存密文
00483BB7 |. 8B45 F8 |mov eax, [local.2]
00483BBA |. 8B00 |mov eax, dword ptr ds:[eax]
00483BBC |. 0FB64418 FF |movzx eax, byte ptr ds:[eax+ebx-1] ; 取密文
00483BC1 |. 03F0 |add esi, eax ; 种子数+密文
00483BC3 |. 69C6 6DCE0000 |imul eax, esi, 0CE6D ; 乘 0x58BF
00483BC9 |. 05 BF580000 |add eax, 58BF
00483BCE |. 8BF0 |mov esi, eax ; 保存种子
00483BD0 |. 43 |inc ebx
00483BD1 |. 4F |dec edi ; 循环
00483BD2 |.^ 75 C9 \jnz short <HideHelp.loc_483B9D>
00483BD4 <H>|> 33C0 xor eax, eax ; loc_483BD4
00483BD6 |. 5A pop edx
00483BD7 |. 59 pop ecx
00483BD8 |. 59 pop ecx
00483BD9 |. 64:8910 mov dword ptr fs:[eax], edx
00483BDC |. 68 F13B4800 push <HideHelp.loc_483BF1>
00483BE1 <H>|> 8D45 FC lea eax, [local.1] ; loc_483BE1
00483BE4 |. E8 EF0AF8FF call <HideHelp.System::__linkproc__ LStrClr(void *)>
00483BE9 \. C3 retn
[COLOR="SeaGreen"]procedure Encrypt(sIn: string; sOut: PUCHAR);
label
H3D;
var
i: Integer;
p1, p2: PUCHAR;
begin
p1 := PUCHAR(sIn);
p2 := PUCHAR(sOut);
i := Length(sIn);
asm
mov ebx,1;
mov esi,$59F0F3;
mov edi,dword ptr i;
H3D:
mov eax,dword ptr p2; //Out
mov edx,dword ptr p1; //In
mov dl, byte ptr ds:[edx+ebx-1] ;
mov ecx, esi;
shr ecx, 8;
xor dl, cl;
mov byte ptr ds:[eax+ebx-1], dl;
mov eax, p2;
movzx eax, byte ptr ds:[eax+ebx-1];
add esi, eax;
imul eax, esi, $0CE6D;
add eax, $58BF;
mov esi, eax;
inc ebx;
dec edi;
jnz H3D;
end;
end;[/COLOR]
00483BF8 <H>/$ 55 push ebp ; subN_111111_Decrypt
00483BF9 |. 8BEC mov ebp, esp
00483BFB |. 83C4 F8 add esp, -8
00483BFE |. 53 push ebx
00483BFF |. 56 push esi
00483C00 |. 57 push edi
00483C01 |. 894D F8 mov [local.2], ecx
00483C04 |. 8BF2 mov esi, edx
00483C06 |. 8945 FC mov [local.1], eax
00483C09 |. 8B45 FC mov eax, [local.1]
00483C0C |. E8 930FF8FF call <HideHelp.System::__linkproc__ LStrAddRef(void *)>
00483C11 |. 33C0 xor eax, eax
00483C13 |. 55 push ebp
00483C14 |. 68 883C4800 push <HideHelp.loc_483C88>
00483C19 |. 64:FF30 push dword ptr fs:[eax]
00483C1C |. 64:8920 mov dword ptr fs:[eax], esp
00483C1F |. 8B45 F8 mov eax, [local.2]
00483C22 |. 8B55 FC mov edx, [local.1]
00483C25 |. E8 020BF8FF call <HideHelp.System::__linkproc__ LStrAsg(void *,void *)>
00483C2A |. 8B45 FC mov eax, [local.1]
00483C2D |. E8 820DF8FF call <HideHelp.__linkproc__ LStrLen_Or_DynArrayLength(void)>
00483C32 |. 8BF8 mov edi, eax
00483C34 |. 85FF test edi, edi
00483C36 |. 7E 3A jle short <HideHelp.loc_483C72>
00483C38 |. BB 01000000 mov ebx, 1
00483C3D <H>|> 8B45 F8 /mov eax, [local.2] ; loc_483C3D
00483C40 |. E8 C70FF8FF |call <HideHelp.InternalUniqueString(void &)>
00483C45 |. 8B55 FC |mov edx, [local.1]
00483C48 |. 8A541A FF |mov dl, byte ptr ds:[edx+ebx-1]
00483C4C |. 8BCE |mov ecx, esi
00483C4E |. C1E9 08 |shr ecx, 8
00483C51 |. 32D1 |xor dl, cl
00483C53 |. 885418 FF |mov byte ptr ds:[eax+ebx-1], dl
00483C57 |. 8B45 FC |mov eax, [local.1]
00483C5A |. 0FB64418 FF |movzx eax, byte ptr ds:[eax+ebx-1]
00483C5F |. 03F0 |add esi, eax
00483C61 |. 69C6 6DCE0000 |imul eax, esi, 0CE6D
00483C67 |. 05 BF580000 |add eax, 58BF
00483C6C |. 8BF0 |mov esi, eax
00483C6E |. 43 |inc ebx
00483C6F |. 4F |dec edi
00483C70 |.^ 75 CB \jnz short <HideHelp.loc_483C3D>
00483C72 <H>|> 33C0 xor eax, eax ; loc_483C72
00483C74 |. 5A pop edx
00483C75 |. 59 pop ecx
00483C76 |. 59 pop ecx
00483C77 |. 64:8910 mov dword ptr fs:[eax], edx
00483C7A |. 68 8F3C4800 push <HideHelp.loc_483C8F>
00483C7F <H>|> 8D45 FC lea eax, [local.1] ; loc_483C7F
00483C82 |. E8 510AF8FF call <HideHelp.System::__linkproc__ LStrClr(void *)>
00483C87 \. C3 retn
[COLOR="SeaGreen"]procedure Decrypt(sIn: string; sOut: PUCHAR);
label
H3D;
var
i: Integer;
p1, p2: PUCHAR;
begin
p1 := PUCHAR(sIn);
p2 := PUCHAR(sOut);
i := Length(sIn);
asm
mov ebx,1;
mov esi,$59F0F3;
mov edi,dword ptr i;
H3D:
mov eax,dword ptr p2; //Out
mov edx,dword ptr p1; //In
mov dl, byte ptr ds:[edx+ebx-1];
mov ecx, esi;
shr ecx, 8;
xor dl, cl;
mov byte ptr ds:[eax+ebx-1], dl;
mov eax,dword ptr p1; // [local.1] ;
movzx eax, byte ptr ds:[eax+ebx-1];
add esi, eax;
imul eax, esi, $0CE6D;
add eax, $58BF;
mov esi, eax;
inc ebx;
dec edi;
jnz H3D;
end;
end;[/COLOR]
[COLOR="SeaGreen"]var //这里做几个全局变量备用
gStrN , gStrE , gStrD , gStrUserName , gStrUserLicNum: string;
var
strD, strN, str: string;
retPD, retPN : array[0..2048] of UCHAR;
strD := 'yW08F8H4TKwt6GOtDBSNRGO3XnVgWp=QwyuRhgxWcYyMP5pkcU4GoNSvqDbXZZ10+JRSPozkMPm3BV=yDI18ZlYnLlEZjBodicFLn1GLB28O99ulXhQuaGUV9M' +
'P8rVf1agDMfOWQIewfDR4pJ=SnyqK7IRbEPjHI=fZ+SM24bE22f2diTZ4uB=+BEt7BMGsHS8q6DMZfhwgE9a+2BfmNAvP2eLASj1XU50+rhCy3QJjuqLX5WRgu' +
'81oRB447Y3he0FnLyfSwTUEpQcNR1QppIB83Fh+jRdze5C53TZF=iYIpoL0xPCdPmLOpz2lorYh9aKB=vtWfE4OJOFuxGO2cgMuqndkgqp15OBgZNBBPGtV+au' +
'AEt7r0ZHOmSTeEmPRkk8BFdTSat2sYhHXOiwNBwtJ61KN2CNKF3rG7mZwBI1oM5r1o++ryh5p6wsS=yLWeO1IjA+OEjG9gresLOmK36P3REMaJaw3MbwfiqbhF' +
'7TxT1BVIkeXpQG+xmmjZi8KHGXCHSbByoZExm9m=CUBH4H1i1kXroxB6dm9RbZnfEjjRQgscRzBid1cke4mg58=InsD+WufkFORJqoteVZ8oOC3UEG4mX7dJCr=4O8CYwEm6eHY' +
'HxzM402e5T5QZjToaJi2vThQmK7FXcJoeaDsgKRY7baihvhefHGqTrWZnIPx0wh0GI+jK9sS9tBZ8bcd4E+9bPc7Ms1IT9c2vqqZs1HIAzkj+I04915tCE0dY6WsrfZfzryVqrNoU1BBLZfOPoaAmWq=eY9sus93M5LrQ';
//========================
strN := 'zNznSHe3UsWKxYFSHxsC1vYSC8AR3hUO6hS4COiIaMetdexdSQFc+GZD5p+A5byHZn0oLJIN6V+OLnoz060duZdrZNRNWS7EBIkrqB6nLCjNP+mTDlk4eASn3f' +
'Rfv+g30q+i5ou6upkF7RbT07PxrvAUPF88Dyb4ME6okCPoXAStRrwIIFCi26rt82TX4bNfHXoXxUm=dIh5P+gA9k=CxAmo5DqQwQvKVrZDW9C6n1rTWtXWRyLI' +
'sbafFNKnYL2FUqMLhPzA0S40wcLm5acW4smLSlhAjwXdGekhJf8kaHZK+nqOVFdk7YCAPfUm2=6iL2pRn9OOgQ9mrr2d+F6M+w2TReNA9RyHX1hv5pD+DPAAAf' +
'dUQu5QwLwHX6bOzkIr2TP0+SXZ+HKedbJpZLK+UcoJGZsCJtZy2M=AqF9REI1=SEX4znk1AqLWmoEsFN8QWD4i3JKgnrI12nOF=DxhfVvhMQfCIxkCa2Z3ypbx' +
'erlKeFD9pnrg9Awpwmoafg6ZC+MqC0fCROUiaTtiUdIuntUvt+Tj+k1WEveVZp0RKMX7zvCh6OUkKQGQILE=k=htdWVejSAmBvFKOWjOi5iQ6OCOnwqR3rtFi=5bCxeBbFto0EpZk' +
'ima63sQrvI6+cIEmWfZaf0x6eBiBlGz1LqwMADqeKX5SFZjNWNn9dg0xSA2cB5yMea5OqB3DboYV+w=zM+IwErztyHuU2PsPZfo=vDQZQWsLEhADGRXn4UT1lm+NZJamWK3IHzfIfb8awzCofXXU=weO5yuJOSztkFf';[/COLOR]
[COLOR="SeaGreen"]ZeroMemory(@retPD[0], 2048);
ZeroMemory(@retPN[0], 2048);
ConvertBase64to256(strD, str);
Decrypt(str, @retPD[0]);
gStrD := StrPas(@retPD[0]);
ConvertBase64to256(strn, str);
Decrypt(str, @retPN[0]);
gStrN := StrPas(@retPN[0]);[/COLOR]
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!