- UID
- 38953
注册时间2007-12-2
阅读权限20
最后登录1970-1-1
以武会友
该用户从未签到
|
【文章标题】: 海天屏幕广播 算法分析 + 注册机代码
【文章作者】: JackyChou
【作者邮箱】: [email protected]
【软件名称】: 海天屏幕广播 V4.1
【软件大小】: 76K
【下载地址】: 自己搜索下载
【加壳方式】: 无壳
【保护方式】: 算法保护
【编写语言】: VC
【使用工具】: OD、PEID
【操作平台】: XP SP2正版
【软件介绍】: 海天屏幕广播软件是将局域网内一台电脑的屏幕画面广播到其他电脑上的软件,采用虚拟显示驱动,实时性好,CPU占用低,在局域网内能取得很好的效果。可以直接广播视频画面。本软件为绿色软件,仅服务端需要安装一个虚拟显示驱动程序,无需设置,操作简单。同时具备语音广播,远程锁定,短消息,电子教鞭,远程关机等功能,可应用于学校,企事业单位教学,培训,演示等场合。
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
前段时间由于项目问题以及杂七杂八的事情,没有什么时间学习算法分析。不过本人算法分析也是相当的菜,难的还
在学习当中,正好遇到一个简单的算法程序,拿来和大家一起分享。网上也好像有内存注册机,不过注册码不对。
算法关键位置查找过程:
1、运行程序,点击【注册】菜单。
注册对话框信息:机器码为【1551133666】。
随便输入注册码【123456】,点击【注册(R)】按钮,没有任何反应。不过程序文件夹内,产生一个文件【sset.ini】。
打开一看,发现注册码是存放在这个文件内的。(regnum=123456)。
尝试了几次,都没有任何提示,所以软件可能是重启验证的。后来发现,如果软件提示注册成功,其实是假注册成功
现象。真正注册成功是没有任何提示,并且软件重新启动才验证的。成功注册后,菜单中不会再出现【注册】菜单项目了。
2、对于INI小型文件,一般用API函数【GetPrivateProfileStringA】进行读取的。如果文件超大,最好自己进行解析。
因为这个API会重复进行文件的打开和关闭,效率较低。
OD载入程序,下断GetPrivateProfileStringA,运行F9。当进行项【regnum】读取时,去除断点,Alt + F9返回。
【返回代码】
---------------------------------------------------------------------------------------------------
00402B41 . 50 push eax ; /IniFileName => "C:\Documents and Settings\zhoujq\",D7,"烂鎈**\**\sset.ini"
00402B42 . 6A 00 push 0 ; |Default = 0
00402B44 . 68 28D34000 push 0040D328 ; |Key = "regnum"
00402B49 . 68 20D34000 push 0040D320 ; |Section = "setting"
00402B4E . FFD3 call ebx ; \GetPrivateProfileIntA
00402B50 . 6A 00 push 0 ; /pFileSystemNameSize = NULL
00402B52 . 6A 00 push 0 ; |pFileSystemNameBuffer = NULL
00402B54 . 8DB5 28010000 lea esi, dword ptr [ebp+128] ; |
00402B5A . 6A 00 push 0 ; |pFileSystemFlags = NULL
00402B5C . 6A 00 push 0 ; |pMaxFilenameLength = NULL
00402B5E . 56 push esi ; |pVolumeSerialNumber
00402B5F . 6A 00 push 0 ; |MaxVolumeNameSize = 0
00402B61 . 6A 00 push 0 ; |VolumeNameBuffer = NULL
00402B63 . 68 1CD34000 push 0040D31C ; |RootPathName = "c:\"
00402B68 . 8BF8 mov edi, eax ; |
00402B6A . FF15 48B04000 call dword ptr [<&KERNEL32.GetVolumeInfo>; \GetVolumeInformationA
00402B70 . 8B0E mov ecx, dword ptr [esi]
00402B72 . 57 push edi
00402B73 . 51 push ecx
00402B74 . E8 77F8FFFF call 004023F0
00402B79 . 8945 74 mov dword ptr [ebp+74], eax
00402B7C . 8B15 28E74000 mov edx, dword ptr [40E728]
00402B82 . 8B3D 2CE74000 mov edi, dword ptr [40E72C]
00402B88 . A1 30E74000 mov eax, dword ptr [40E730]
00402B8D . 83C4 08 add esp, 8
00402B90 . 894424 18 mov dword ptr [esp+18], eax
00402B94 . A1 50E74000 mov eax, dword ptr [40E750]
00402B99 . F7DA neg edx
00402B9B . 1BD2 sbb edx, edx
00402B9D . 23D7 and edx, edi
00402B9F . 33FF xor edi, edi
00402BA1 . 3BC7 cmp eax, edi
00402BA3 . 895424 14 mov dword ptr [esp+14], edx
00402BA7 . 74 11 je short 00402BBA
00402BA9 . C74424 1C 010>mov dword ptr [esp+1C], 1
00402BB1 . 8B48 20 mov ecx, dword ptr [eax+20]
00402BB4 . 894C24 20 mov dword ptr [esp+20], ecx
00402BB8 . EB 08 jmp short 00402BC2
00402BBA > 897C24 1C mov dword ptr [esp+1C], edi
00402BBE . 897C24 20 mov dword ptr [esp+20], edi
00402BC2 > 8B15 3CE74000 mov edx, dword ptr [40E73C]
00402BC8 . 8D4424 14 lea eax, dword ptr [esp+14]
00402BCC . 50 push eax
00402BCD . 895424 28 mov dword ptr [esp+28], edx
00402BD1 . E8 54740000 call <jmp.&HTSAPI.#1>
00402BD6 . 3BC7 cmp eax, edi
00402BD8 . 74 0E je short 00402BE8
00402BDA . 50 push eax
00402BDB . 68 0CD34000 push 0040D30C
00402BE0 . E8 1BF9FFFF call 00402500
00402BE5 . 83C4 08 add esp, 8
00402BE8 > 8B0D 44E74000 mov ecx, dword ptr [40E744]
00402BEE . 51 push ecx
00402BEF . 57 push edi
00402BF0 . 68 28D34000 push 0040D328 ; ASCII "regnum"
00402BF5 . 68 20D34000 push 0040D320 ; ASCII "setting"
00402BFA . FFD3 call ebx ; eax=假码
00402BFC . 8B16 mov edx, dword ptr [esi]
00402BFE . 50 push eax ; 假码
00402BFF . 52 push edx ; 机器码
00402C00 . E8 3BFBFFFF call 00402740 ; 这边出现正码
00402C05 . 83C4 08 add esp, 8
00402C08 . 3BC7 cmp eax, edi
00402C0A . 8945 78 mov dword ptr [ebp+78], eax
00402C0D . 5B pop ebx
00402C0E . 75 31 jnz short 00402C41 ; 注册成功则跳
00402C10 . 8D4424 7C lea eax, dword ptr [esp+7C]
00402C14 . 66:893D 4CE74>mov word ptr [40E74C], di
00402C1B . A3 48E74000 mov dword ptr [40E748], eax
---------------------------------------------------------------------------------------------------
下面代码略
====================================================================================================
【关键CALL代码】
---------------------------------------------------------------------------------------------------
00402740 /$ 8B4C24 04 mov ecx, dword ptr [esp+4] ; ecx=机器码
00402744 |. 64:A1 0000000>mov eax, dword ptr fs:[0]
0040274A |. 69C9 096EBA02 imul ecx, ecx, 2BA6E09 ; ecx=ecx*0x2BA6E09
00402750 |. 6A FF push -1
00402752 |. 68 00A34000 push 0040A300
00402757 |. 50 push eax
00402758 |. B8 25499224 mov eax, 24924925 ; eax=0x24924925
0040275D |. F7E1 mul ecx ; 无符号乘eax*ecx->edx(高位)+eax(低位)
0040275F |. 2BCA sub ecx, edx ; ecx=ecx -edx
00402761 |. 64:8925 00000>mov dword ptr fs:[0], esp
00402768 |. D1E9 shr ecx, 1 ; 逻辑右移1位
0040276A |. 03CA add ecx, edx ; ecx=ecx+edx
0040276C |. 56 push esi
0040276D |. C1E9 02 shr ecx, 2 ; 逻辑右移2位
00402770 |. 8BC1 mov eax, ecx ; eax = ecx
00402772 |. 57 push edi
00402773 |. 69C0 FB3F9702 imul eax, eax, 2973FFB ; eax=eax*0x2973FFB
00402779 |. 8B7C24 1C mov edi, dword ptr [esp+1C] ; edi=假码(123456)
0040277D |. F7D0 not eax ; eax取反
0040277F |. 83C0 2F add eax, 2F ; eax=eax+0x2F
00402782 |. 3BC7 cmp eax, edi
00402784 |. 0F84 AE000000 je 00402838 ; 如果跳则eax=0,因为后面xor eax,eax
0040278A |. 8BF0 mov esi, eax ; esi=eax
0040278C |. 8D4C24 18 lea ecx, dword ptr [esp+18]
00402790 |. 0FAFF0 imul esi, eax ; esi=esi*eax
00402793 |. E8 44740000 call <jmp.&MFC42.#540_CString::CString>
00402798 |. 56 push esi
00402799 |. 8D4424 1C lea eax, dword ptr [esp+1C]
0040279D |. 68 00D24000 push 0040D200 ; ASCII "%u"
004027A2 |. 50 push eax
004027A3 |. C74424 1C 000>mov dword ptr [esp+1C], 0
004027AB |. E8 1C750000 call <jmp.&MFC42.#2818_CString::Format> ; esi值格式化
004027B0 |. 83C4 0C add esp, 0C
004027B3 |. 8D4C24 1C lea ecx, dword ptr [esp+1C]
004027B7 |. 6A 08 push 8
004027B9 |. 51 push ecx
004027BA |. 8D4C24 20 lea ecx, dword ptr [esp+20]
004027BE |. E8 55740000 call <jmp.&MFC42.#4129_CString::Left> ; 取左边8位作为注册码
004027C3 |. 50 push eax
004027C4 |. 8D4C24 1C lea ecx, dword ptr [esp+1C]
004027C8 |. C64424 14 01 mov byte ptr [esp+14], 1
004027CD |. E8 40740000 call <jmp.&MFC42.#858_CString::operator=>
004027D2 |. 8D4C24 1C lea ecx, dword ptr [esp+1C]
004027D6 |. C64424 10 00 mov byte ptr [esp+10], 0
004027DB |. E8 DE730000 call <jmp.&MFC42.#800_CString::~CString>
004027E0 |. 8B5424 18 mov edx, dword ptr [esp+18]
004027E4 |. 52 push edx ; /s
004027E5 |. FF15 F0B24000 call dword ptr [<&MSVCRT.atoi>] ; \字符串到数值的转换
004027EB |. 83C4 04 add esp, 4
004027EE |. 3BC7 cmp eax, edi ; eax(真码)与输入码的比较
004027F0 |. 75 27 jnz short 00402819 ; 跳,eax=0
004027F2 |. 8D4C24 18 lea ecx, dword ptr [esp+18]
004027F6 |. C74424 10 FFF>mov dword ptr [esp+10], -1
004027FE |. E8 BB730000 call <jmp.&MFC42.#800_CString::~CString>
00402803 |. B8 01000000 mov eax, 1 ; eax=1
00402808 |. 8B4C24 08 mov ecx, dword ptr [esp+8]
0040280C |. 64:890D 00000>mov dword ptr fs:[0], ecx
00402813 |. 5F pop edi
00402814 |. 5E pop esi
00402815 |. 83C4 0C add esp, 0C
00402818 |. C3 retn
00402819 |> B8 398EE338 mov eax, 38E38E39
0040281E |. 8D4C24 18 lea ecx, dword ptr [esp+18]
00402822 |. F7E7 mul edi
00402824 |. D1EA shr edx, 1
00402826 |. C74424 10 FFF>mov dword ptr [esp+10], -1
0040282E |. 8D42 03 lea eax, dword ptr [edx+3]
00402831 |. 3BC2 cmp eax, edx
00402833 |. E8 86730000 call <jmp.&MFC42.#800_CString::~CString>
00402838 |> 8B4C24 08 mov ecx, dword ptr [esp+8]
0040283C |. 5F pop edi
0040283D |. 33C0 xor eax, eax ; eax=0
0040283F |. 64:890D 00000>mov dword ptr fs:[0], ecx
00402846 |. 5E pop esi
00402847 |. 83C4 0C add esp, 0C
0040284A \. C3 retn
---------------------------------------------------------------------------------------------------
通过关键CALL的分析,注册码的算法过程应该都明白了。
【注册机代码】
因为算法比较简单,所以用VC写代码时可以偷懒,直接可以嵌入ASM写代码
_asm
{
mov ecx, dwMachine //机器码
imul ecx, ecx, 0x2BA6E09
xor edx, edx
mov eax, 0x24924925
mul ecx
sub ecx, edx
shr ecx, 1
add ecx, edx
shr ecx, 2
mov eax, ecx
imul eax, eax, 0x2973FFB
not eax
add eax, 0x2F
xor edx, edx
mov edx, eax
imul edx, eax
mov eax, edx
mov dwOut, eax // 处理数据
}
sKey.Format("%u", dwOut);
sKey = sKey.Left(8); // 真正注册码
====================================================================================================
好,就分析到这里。文章可能有很多错误的地方,敬请见谅。并给予指出问题。
--------------------------------------------------------------------------------
【经验总结】
算法分析还是从简单的开始分析好,不然对自己的信心会大大打击。
--------------------------------------------------------------------------------
【版权声明】: 本文原创于飘云阁技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2008年09月27日 22:21:46 |
|