• 全部
  • VC综合技术
  • 互联网技术
  • MFC AppLauncher
  • .NET 技术
  • 界面
  • 进程
  • 算法
  • 硬件/系统
  • 数据库
  • VC++技术资源

一个软件保护方案!!

Terark-CTO-雷鹏 奇简软件(北京)有限公司 CTO  2002-05-08 08:55:01
俺毕业设计做的是 "软件保护技术及实现" 也就是做一个加壳软件 ,
把一个 EXE 文件的代码(或者你想要加密的其它部分)进行加密 , 运行时先运行俺的壳
程序 , 然后才跳转到原程序入口执行 .

壳程序对文件(该被加了壳的 EXE 文件)进行完整性检验----用安全散列算法进
行检验 , 如果不合法 , 则认为程序中毒 , 或者被解密者改过 !!

接下来 , 我检验本地主机是否已被授权(通过检查硬件信息) , 如果未被授权 , 责
提示这是一个盗版!!

软件的授权是这样的 : 我的整个软件中(除了一个把我的 shield 程序 merge 到客
户程序的套件)还有另外两个套件 , 一个服务器程序 , 在客户软件开发者网站上运行 .
一个注册程序 , 在客户端运行 .

服务器对开发者卖出的软件进行授权----当然他的软件是用我的软件保护过了的 .

注册程序从该软件拷贝取得序列号SN(serial number) , 再取得本地主机的硬件信息 ,
计算该硬件信息的散列值 H . 将它发送给服务器 , 服务器从数据库中查找这个 SN 对应的解
密密钥 , 如果找到 , 并且这个序列号的拷贝已经注册 , 并且 它收到的 H 和以前注册的 H
相同 , 就把解密密码发给客户 , ----一个拷贝可以在一台被授权的计算机上多次安装/注册 ----- 且以将它发给客户 ,
如果未找到 , 提示客户端 , 可能有错误 , 请求重发 , 多次错误之后认为是对服务器的恶意
攻击 , 不在理会从这台客户机上发来的信息 . 如果这个序列号的拷贝未注册 , 只是简单的将
解密密码发给客户即可 . 并将随 SN 一起发来的 H 存入数据库 , 待以后再验证这台计算机 .

注册程序收到服务器返回的解密密码之后 , 我们暂且把这个解密密码设为 K1 , 用一个密码
算法把这个 K1 解调 , 同时用 刚才得到的本地主机硬件信息的散列值 H 再对原软件进行加密 ,
在这个过程中 , 使用了本人设计的一个算法 , 可以保证在解掉 K1 并 加上 H 的过程中原程序
的明文不出现在内存中 . 以防止解密者在这个过程中 dump 内存 .

最后注册程序计算软件的信息检验码 , 存入壳程序中的一个地方 .

现在一切 OK 了!!

合法用户运行软件时 , 我的壳程序先运行 , 软件的信息检验码验证一般会通过(除非中毒) , 然后验证硬件信息 ,
当然也通过 . 再用该硬件信息的散列 H 解密客户程序部分 , 然后跳入客户程序入口执行 .

壳程序的主要技术 :

1 . 因为壳程序中对API 的调用 , 编译器产生一个 jmp [xxxx] 指令 , 那个 xxxx 在编译时就确定了 , 但壳程序的代码和数据的地址随客户程序的不同而不同 即那个 xxxx 随客户程序而变 . 这样加壳时我就要把这些 jmp [xxxx]指令中的 xxxx 修改为对应于客户程序 的 yyyy , 这样似乎也不是很难 , 但是 , 壳程序中一般难免使用静态数据 , C 语言中的全局数据就是静态数据 , 还有用引号引起来的字符串 , 也是全局数据 , 对这些全局数据及 jmp [xxxx] 都进行修改----代价太大了! 所以我只能想出另一个折衷的方案 , 见下.

2 . 我在壳程序中不直接调用系统函数 , 如winapi , C 语言标准库函数 , 因为使用这些函数 , 就要把我的壳程序和和系统的库进行链接 , 而我的壳程序的框架是用 Assembly 写的 , 必须自己设计壳程序中要使用的 winapi import , 这些就是壳程序框架的内容 .


3 . 壳程序主体是用 C/C++ 写 , 在这个 C/C++ 程序中 , 也仅能使用在壳程序框架中导入的 winapi .

4 . 还有一个麻烦就是----编译时要先把 C/C++ 代码编译成 Assembly , 再插入用 Assembly 写的框架中 , ----因为它不能和库进行链接 . 原因上面已述 !

5 . 壳程序中 , 反跟踪指令是必须的 !! 所以我还设计了许多反跟踪 , 加密客户程序入口地址 , 等等许多防破解的代码 .


6 . 壳程序框架的元代码俺在另一篇文章中列出 !!

俺准备俺的这个软件商业化 !! 有同仁请帮忙推广 !! 估计 20 天之后就可以推出版本了!!----因为那时候要验收毕业设计 !!

到目前为止 , 我还没有发现有什么对我这个设计的有力的攻击 ,
----也是因为没有人对这个协议进行攻击!!

那我就先说说对几种可预见的攻击的防护!

如果 解密者把 K1 存储起来 , 然后安装软件时不向开发者发送请求 , 也可能解密 !! ----没关系 !!

我的壳程序在运行过几次 如 每10 次 , 或每次运行 , 都向开发者网站发送 SN 及机器信息的散列----发散列而不发真实的机器信息可防止某些苛刻的顾客埋怨开发者侵犯了他的隐私权!!----如果机器信息不对!!哼!!后果难以想象!!


有人又要说了 , 那我把你的壳脱掉 , 也没关系 !!
----我在整个加密过程中还用了 "代码转移 " 技术 , 就是把 客户程序部分的一些代码转移到我的壳程序中 , 而在原来这段代码的开始插入一个 jmp 指令跳到这些被转移的代码在壳程序的那个位置 执行完之后 , 又跳回来 !!

哈哈 !! 如果他把壳给脱了 , 那程序运行那段转移了的代码时会发生什么后果呢?

欢迎大家提出破解方案 !! 督促我改进设计 !!
...全文
33 点赞 收藏 4
写回复
4 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
ckacka(小红帽) :

你说我的加壳使客户的代码失去了后期可维护性?

这从何说起?

客户开发出一个稳定的软件版本之后,用我的软件加壳,然后,下一个稳定版本搞好了,再加一次壳即可 !!哪里来的失去了后期可维护性?还望指明!!
回复
dark_zy(dark_zy) :

我是在通过读取硬盘序列号,厂商信息,CPUID,BIOS厂商,把这些信心综合在一起,进行散列,运行时取得这些信息,再计算散列!!

我想,如果你要在我这个程序外面再做一个 SHELL ,好像可以 ,但是,具体的实现?如何实现?加 hook ? 改变函数调用的地址?

希望你能明确一点 !
回复
ckacka 2002-05-12
同意楼上的!

“而且你的做法很难商业推广,因为你的代码失去了后期的可维护性!”

这只是我的不成熟看法,请指教!
回复
dark_zy 2002-05-12
主机硬件信息哪里来的?从机器/BIOS/SYSTEM/注册表读取?
那我在你的程序外,再做一个SHELL,每次都给你提供假的主机信息。

这只是我的不成熟看法,请指教
回复
相关推荐
发帖
VC/MFC
创建于2007-09-28

1.5w+

社区成员

VC/MFC相关问题讨论
申请成为版主
帖子事件
创建了帖子
2002-05-08 08:55
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……