- UID
- 3825
- 积分
- 2760
- 精华
- 贡献
-
- 威望
-
- 活跃度
-
- D豆
-
- 在线时间
- 小时
- 注册时间
- 2002-4-14
- 最后登录
- 1970-1-1
|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
×
老了,搜到的:
AutoCAD LISP文件的加密保护
水利部能源部天津勘测设计院(300222) 耿振云
--------------------------------------------------------------------------------
LISP语言是AutoCAD支持的一种高级语言,以其功能强,易于使用,并可方便地扩充AutoCA
D功能而深受广大用户喜爱。然而美中不足的是,LISP语言程序是标准ASCII码文件,不能象
其它高级语言如C、PASCAL那样能够编译成EXE或COM执行文件,因此软件无法得到保护。笔
者用Turbo C编制了一个小程序,可以把LISP文件加密,加密后的文件仅仅是一些毫无意义的
符号,但却可以在Auto CAD中正常运行,这样就对LISP文件起到了一定的保护作用。请读者
注意,LISP源程序库中注释部分即分号以后直到行尾的部分应在加密前去掉。也可以对原程
序做少许改动,增加注释行自动识别处理功能,使这个加密程序更加完善。
/*AutoCAD LISP文件加密程序*/
#include
main()
{
FILE*fi,*fo;
register char zf1,zf2;
char fin[30],fou[30];
int kz;
printf("Enter source file name:");
scanf ("%s",fin);
printf("Enteh newfile name");
scanf("%s",fou);
fi=fopen(fin,"rb");
if(fi==NULL)
{
printf("can not open file %s\n",fi);
exit(1);
}
fo=fopen(fou,"wb");
fputs("AutoCAD PROTECTED LISP file\n",fo);
fputc(26,fo);
fputc("a",fo)
fputc("I",fo);
zf2=fgetc(fi);
zf1=73;
while((zf2=fgetc(fi))!=ox1a)
{
if (zf1>127) zf1=zf1-256;
if (zf2==0x0d) zf2=fgetc(fi);
if (zf2>127) zf2=zf2-256;
zf1=zf1<0?(0x01|(zf1<<1)):zf1<<1;
zf1=zf1^zf2;
if((zf1==0x1a))||(zf1==0x0d)) zf1=zf2;
if(zf1!=0x1a) fputc(zf1,fo);
}
fputc(26,fo);
fclose(fi);
fclose(fo);
}
======================================================
加 密 保 护AutoLISP 文 件
(南 京 化 工 大 学 热 管 研 究 院 叶 迎 海 210009)
---- 摘 要: 本 文 详 细 分 析 了AutoLISP 保 护 文 件 的 格 式 及 其 加 密、 解 密 的 原 理, 同 时 验 证 这 一 保 护 原 理 双 向 转 换 的 正 确 性, 并 为 普 通 文 本 文 件 的 加 密 保 护 提 供 一 种 通 用 方 法。 关 键 词: 加 密 解 密 AutoLISP
一、 引 言
---- 熟 悉AutoLISP 的 读 者 都 知 道, 与C、PASCAL 等 编 译 器 不 同 的 是,AutoLISP 的 主 系 统 是 命 令 解 释 器, 对 指 令 的 处 理 就 象DOS 处 理BATCH 文 件 一 样。 这 一 特 点 使 得AutoLISP 文 件, 不 但 有 着 较 好 的 可 读 性 能, 而 且 修 改 起 来 也 更 为 方 便、 快 捷。 当 然, 其 缺 点 是 任 何 人 用 最 常 用 的EDIT、TYPE 等DOS 命 令, 即 可 使 程 序 原 代 码 一 览 无 疑。 为 了 保 护AutoLISP 的 原 代 码, 我 们 想 到: 最 好 有 一 种 方 法, 将TEXT 的 文 本 文 件 加 密, 使 之 成 为 保 护 格 式 的 文 件。
---- 带 来 的 问 题 是AutoCAD 能 否 认 识 该 保 护 格 式 的 文 件 呢 ?
二、AutoLISP 保 护 文 件 的 格 式
---- AutoCAD 虽 然 没 有 提 供 加 密、 解 密AutoLISP 的 工 具 软 件, 但 其 本 身 却 可 以 接 收 两 种 格 式 的LISP 文 件, 一 种 是 保 护 格 式 的; 另 一 种 是 文 本 格 式 的。 读 入 文 件 后,AutoCAD 首 先 会 作 出 判 断, 一 旦 确 定 文 件 是 保 护 格 式 的, 则 在 加 载 该 程 序 前, 自 动 将 加 密 文 件 代 码 予 以 还 原, 然 后 再 读 入 命 令 解 释 器。 我 们 只 需 按 一 定 格 式 完 成 加 密, 剩 下 的 工 作 交 给AutoCAD 去 完 成 就 可 以 了, 而 且AutoCAD 在 处 理 两 种 格 式 的 文 件 时, 用 户 不 会 觉 得 存 在 任 何 差 别。 下 面 我 们 来 看 看AutoLISP 保 护 格 式 文 件 的 格 式。
---- 起 始 地 址 及 终 止 地 址(Bytes):
---- 0 —29 : 保 护 文 件 的 标 识 字 符 串 计30 Bytes, 及“AutoCAD PROTECTED LISP file\0x0D\0x0A\0x1A”。
---- 30 : 密 码 字 符, 只 有 一 个 字 节。
---- 31 起 : 已 加 密 的 程 序 码。
---- 其 中 前30 个 字 节 用 户 不 得 改 动; 第30 位 是 密 码 字 母, 用 户 可 以 任 意 给 定, 譬 如 字 母‘A’;
---- 第31 位 起 可 由 附 录 程 序 经 过 加 密 计 算 后 写 入 文 件。
三、 加 密 与 解 密 的 原 理
---- 加 密 与 解 密 的 一 个 重 要 工 具 是“ 按 位 异 或(^) 运 算”, 其 作 用 是 判 断 两 运 算 量 相 应 位 的 值 是 否“ 相 异”, 若 为 异, 则 为1, 否 则 为0, 即:0^0=0 ;0^1=1;1^0=1;1^1=0。
---- 因 其 具 有 双 向 转 换、 还 原 的 能 力, 故 在 密 码 学 上 得 到 广 泛 应 用。 让 我 们 来 看 看:
A | 0100 0001 8 | 0011 1000
^y | 0111 1001 ^A | 0100 0001
— — — — — — — — — — — — — —
8 | 0011 1000 y | 0111 1001
---- 上 式 中0x41='A'、0x79='y'、0x38='8','A' ^ 'y' = '8';'8' ^ 'A' = 'y';'y' ^ '8' ='A'。 可 以 看 出 按 位 异 或 运 算 具 有 双 向 转 换、 还 原 的 能 力。AutoCAD 在 加 密、 解 密 时, 除 了 运 用 上 述 方 法 外, 另 外 还 使 用 了 一 个 技 巧, 就 是 移 位 运 算, 将 被 转 换 字 符 的8 个 位 全 部 左 移 一 位, 相 当 于 将 该 整 数 乘 以2, 若 最 高 位 是1( 移 位 后>256), 则 将 溢 出 位1 移 至 最 末 位, 否 则 用0 代 替 末 位, 这 样 就 保 证 了 加 密 码 与 原 代 码 一 一 对 应。 我 们 假 设 用 函 数F 表 示 这 一 运 算 过 程。
---- 字 符0x96, 二 进 制 为1001 0110, 则F(0x96)= F(1001 0110)= 0010 1101 = 0x2D。
---- 我 们 用 下 面 两 个 算 式, 来 说 明 加 密、 解 密 的 具 体 过 程, 式 中 各 符 号 的 意 义:A0->B = A ^B ;A —B = F(A) ^ B;A / B = F(A) ^ B;' || ' = ' = '。 各 字 符 均 以16 进 制 表 示, 假 设 密 码 字 母 是'A' (0x41)。
原 始 程 序 码 为:
(PRINC)
(GETWORD)
加 密 过 程 如 下:
---- ( P R I N C ) ( G E T W O R D ) 41->28 70 72 69 6E 63 29 0D 0A 28 67 65 74 77 6F 72 64 29 0D 0A
---- || / || / || / || … …( 依 次 类 推)
---- 结 果 69 A2 37 7 60 A3 6E D6 85 6C BD 0F 69 BD 9 76 C5 81
具 体 过 程 为:
1、0x41 ^ 0x28 = 0x69; ( 按 位 异 或)
2、F(0x69)= 0xD2; ( 移 位 运 算)
3、0xD2 ^ 0x70 = 0xA2; … …
解 密 过 程 如 下:
---- 41->69 — A2 — 37 — 7 60 A3 6E D6 85 6C BD 0F 69 BD 9 76 C5 81
---- || || || || … …( 依 次 类 推)
---- 28 70 72 69 6E 63 29 0D 0A 28 67 65 74 77 6F 72 64 29 0D 0A 结 果 ( P R I N C ) ( G E T W O R D )
具 体 过 程 为:
1、0x41 ^ 0x69 = 0x28;( 字 符 '(')
2、F(0x69)= 0xD2;
3、0xD2 ^ 0xA2 = 0x70;( 字 符'P') … …
四、 小 结
---- 在 加 密 与 解 密 过 程 中, 读 者 可 以 改 变 函 数F, 比 如 说 改 为 左 右 四 位 对 调(WPS 文 件 的 密 码 编 制 用 到 该 种 方 法)、 右 移 一 位(F(x)=x / 2)、 左 移 两 位(F(x)=4*x) 等 等, 或 许 您 还 有 其 他 的 方 法, 但 必 须 注 意:
---- 1、 转 换 函 数 必 须 是 单 调 函 数, 即 变 量 值 与 函 数 值 必 须 一 一 对 应( 本 文 相 当 于F(x)=2*x);
---- 2、 加 密 程 序 与 解 密 程 序 必 须 使 用 同 一 套 函 数;
---- 3、AutoCAD 不 会 接 受 其 他 公 式 产 生 的 加 密 文 件, 因 此 在 加 密AutoLISP 文 本 文 件 时, 我 们 只 能 用 左 移 一 位 这 一 函 数;
---- 4、 不 要 改 动AutoLISP 保 护 文 件 的 文 件 格 式。
---- 对 于3、4 两 点, 除 非 你 毫 无 意 义 地 花 些 时 间 去 改 变 系 统, 重 新 定 义 一 个load 函 数 来 加 载AutoLISP, 否 则 还 是 遵 守 这 两 条 规 则 为 好。 由 于 篇 幅 问 题, 本 文 未 提 供 解 密 程 序, 只 是 给 出 了 一 个 解 密 的 例 子。 附 一PRO_LISP.C 是 用 作 加 密 的, 该 程 序 在Borland C++ 4.5 上 运 行 通 过, 有 兴 趣 的 读 者 可 以 对PRO_LISP.C 稍 加 改 动, 即 可 获 得 解 密 程 序RES_LISP.C。
附 一 PRO_LISP.C
#include < stdio.h >
#include < stdlib.h >
#define LISP_ID "AutoCAD PROTECTED \
LISP file\0x0D\0x0A\0x1A" // 标 识 字 符 LISP_ID
void main (int argc,char *argv[])
{
FILE *in_file ,*out_file;
unsigned char pass_ch,old_ch,new_ch;
unsigned int i;
printf ("Protect AutoLISP file.\n");
if (argc != 4){
printf("Usage:PRO_LISP < Input-file > < Pass-letter > < Output-file >.\n");
exit (1);
}
if ((in_file = fopen (argv[1],"rb"))== NULL){
printf("Cannot open the input file: %s.\n", argv[1]);
exit (1);
}
if ((out_file =fopen (argv[3],"wb"))== NULL){
printf("Cannot open the output file: %s.\n", argv[3]);
exit (1);
}
printf ("Protect %s to %s ... \n",argv[1],argv[3]);
fputs(LISP_ID,out_file);
pass_ch = argv[2][0];
putc(pass_ch,out_file);
while (! feof (in_file)){
old_ch=fgetc(in_file);
if (old_ch == 0x1A) break;
// 文 件 结 束 中 断 循 环
if (old_ch == 0x0D) continue;
// 若 为 回 车 继 续 循 环
new_ch = pass_ch ^ old_ch;
// 异 或 运 算
if ((new_ch == 0x0D)||(new_ch == 0x1A))
new_ch=old_ch;// 用 上 一 密 码 字 符
if (new_ch == 0x0A) putc (0x0D,out_file);
// 若 为 换 行, 则 加 回 车
putc(new_ch,out_file);
// 写 入 已 加 密 字 符
i=new_ch; i = i<<1;
// 左 移 一 个 位, 相 当 于 乘2
if (i>255) i=i-255;
// 溢 出 位1 加 到 末 位
pass_ch = (unsigned char) i;
// 产 生 新 的 密 码 字 符
}
fclose (in_file);
putc(0x1A,out_file);
fclose (out_file);
printf ("%s Protected !\n",argv[1]);
}
================================================================ |
|