Microsoft Word5.0中文版文件解密初探
摘 要:Word5.0中文版文件忘记口令后的解密
关键词:Word5.0中文版 口令 解密
1.引言
随着Microsoft Word5.0 for Windows 中文版作为新一代字处理软件在中国的推广,它的优异性能已经得到了越来越多中国用户的喜爱,它在“所见即所得”,“软件易用性”和“功能集成”等方面给用惯了诸如:WPS、CCED、PE、王码等中文字处理软件的中国用户留下了极为深刻的印象。
随着使用的增多,为实现保密起见,许多用户都可以为自己的文档加口令,但随着口令的增多、变化,有些用户可能过一段时间将自己的某些口令忘记了,导致自己加密的文件自己也打不开,有时,甚至得重新录入、排版,浪费了大量的宝贵时间,以致于有些用户干脆不再加口令了。为此,本人通过对WORD文件的认真分析研究,用Turbo C++1.0(或Turbo C2.0均可)编制了解密程序WORDCODE.C ,在Compaq 4/33计算机上实现了对WORD文件的解密工作,从此再无丢失口令的麻烦。只要对此解密文件适当保存即可,以免失去加密之本意,在此奉献给各位同事。
2.实现原理
通过对加密文件的分析,发现在文件偏移量000E— 0011处存放着密钥,此密钥是经过某种处理由输入的口令转化而成,而加密处理是从文件偏移量0024处开始进行的,处理的方法是,以某一行全00数据的加密后值为基准,通过行间XOR异或处理而成。
因此解密至少有以下两种方法:
一、是根据转换后的密钥反演出原口令,然后在WORD中输入正确的口令即可;
二、是根据加密处理的特点,通过选取适当的样本值,用再XOR的方法实现解密,生成另一个已解密的文件。比较理想的方法是第一种方法,但在无任何资料的情况下,实现起来比较困难。本人根据实际情况选择了第二种解密方法,通过对大量文件的分析,发现了行之有效的手段,在文件偏移量0040、0150、0160、0170处开始的每一个十六字节中数据均为00,每一个文件都一样,以上四个地址中的任何一个都可以作为样本值,用于解密处理。
3.有关资料
以下为对WORD文件用PCTOOLS查看的结果:
未加密的文件(第一扇区):
0000(0000) 96 A6 30 00 15 A0 09 04 - 00 00 00 00 2D 00 00 00
0016(0010) 00 00 00 00 00 00 00 00 - 80 01 00 00 89 01 00 00
0032(0020) 0E 08 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0048(0030) 00 00 00 00 09 00 00 00 - 00 00 00 00 00 00 00 00
0064(0040) 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0080(0050) 00 00 00 00 00 00 00 00 - 00 06 00 00 27 00 00 06
0096(0060) 00 00 27 00 27 06 00 00 - 00 00 27 06 00 00 00 00
0112(0070) 27 06 00 00 00 00 27 06 - 00 00 00 00 27 06 00 00
0128(0080) 0E 00 35 06 00 00 12 00 - 47 06 00 00 00 00 47 06
0144(0090) 00 00 00 00 47 06 00 00 - 00 00 47 06 00 00 00 00
0160(00A0) 47 06 00 00 0A 00 51 06 - 00 00 0A 00 47 06 00 00
0176(00B0) 00 00 5B 06 00 00 40 00 - 9B 06 00 00 00 00 9B 06
0192(00C0) 00 00 00 00 9B 06 00 00 - 00 00 9B 06 00 00 00 00
0208(00D0) 9B 06 00 00 00 00 9B 06 - 00 00 00 00 9B 06 00 00
0224(00E0) 00 00 9B 06 00 00 00 00 - 9B 06 00 00 02 00 9D 06
0240(00F0) 00 00 00 00 9D 06 00 00 - 00 00 9D 06 00 00 00 00
0256(0100) 9D 06 00 00 00 00 9D 06 - 00 00 00 00 9D 06 00 00
0272(0110) 1E 00 BB 06 00 00 34 01 - EF 07 00 00 1F 00 BB 06
0288(0120) 00 00 00 00 27 06 00 00 - 00 00 00 00 00 00 00 00
0304(0130) BB 06 00 00 00 00 BB 06 - 00 00 00 00 00 00 01 00
0320(0140) 02 00 01 00 01 00 00 00 - 00 00 00 00 00 00 00 00
0336(0150) 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0352(0160) 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0368(0170) 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0384(0180) 61 61 61 20 62 62 62 0D - 0A 18 8B 83 2E 8C C2 41
0400(0190) 8D 6E 04 8E 6E 04 8F 6E - 04 90 6E 04 73 04 00 74
0416(01A0) 04 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0432(01B0) 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0448(01C0) 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0464(01D0) 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0480(01E0) 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0496(01F0) 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
加密后的文件(第一扇区):
0000(0000) 96 A6 30 00 15 A0 09 04 - 00 00 00 01 2D 00 28 CE
0016(0010) 82 C7 00 00 00 00 00 00 - 80 01 00 00 89 01 00 00
0032(0020) 0E 08 00 00 1C 1C BE 3F - 01 E3 1E 64 41 3C C6 E3
0048(0030) D9 3E BE 1C 15 1C BE 3F - 01 E3 1E 64 41 3C C6 E3
0064(0040) D9 3E BE 1C 1C 1C BE 3F - 01 E3 1E 64 41 3C C6 E3
0080(0050) D9 3E BE 1C 1C 1C BE 3F - 01 E5 1E 64 66 3C C6 E5
0096(0060) D9 3E 99 1C 3B 1A BE 3F - 01 E3 39 62 41 3C C6 E3
0112(0070) FE 38 BE 1C 1C 1C 99 39 - 01 E3 1E 64 66 3A C6 E3
0128(0080) D7 3E 8B 1A 1C 1C AC 3F - 46 E5 1E 64 41 3C 81 E5
0144(0090) D9 3E BE 1C 5B 1A BE 3F - 01 E3 59 62 41 3C C6 E3
0160(00A0) 9E 38 BE 1C 16 1C EF 39 - 01 E3 14 64 06 3A C6 E3
0176(00B0) D9 3E E5 1A 1C 1C FE 3F - 9A E5 1E 64 41 3C 5D E5
0192(00C0) D9 3E BE 1C 87 1A BE 3F - 01 E3 85 62 41 3C C6 E3
0208(00D0) 42 38 BE 1C 1C 1C 25 39 - 01 E3 1E 64 DA 3A C6 E3
0224(00E0) D9 3E 25 1A 1C 1C BE 3F - 9A E5 1E 64 43 3C 5B E5
0240(00F0) D9 3E BE 1C 81 1A BE 3F - 01 E3 83 62 41 3C C6 E3
0256(0100) 44 38 BE 1C 1C 1C 23 39 - 01 E3 1E 64 DC 3A C6 E3
0272(0110) C7 3E 05 1A 1C 1C 8A 3E - EE E4 1E 64 5E 3C 7D E5
0288(0120) D9 3E BE 1C 3B 1A BE 3F - 01 E3 1E 64 41 3C C6 E3
0304(0130) 62 38 BE 1C 1C 1C 05 39 - 01 E3 1E 64 41 3C C7 E3
0320(0140) DB 3E BF 1C 1D 1C BE 3F - 01 E3 1E 64 41 3C C6 E3
0336(0150) D9 3E BE 1C 1C 1C BE 3F - 01 E3 1E 64 41 3C C6 E3
0352(0160) D9 3E BE 1C 1C 1C BE 3F - 01 E3 1E 64 41 3C C6 E3
0368(0170) D9 3E BE 1C 1C 1C BE 3F - 01 E3 1E 64 41 3C C6 E3
0384(0180) B8 5F DF 3C 7E 7E DC 32 - 0B FB 95 E7 6F B0 04 A2
0400(0190) 54 50 BA 92 72 18 31 51 - 05 73 70 60 32 38 C6 97
0416(01A0) DD 3E BE 1C 1C 1C BE 3F - 01 E3 1E 64 41 3C C6 E3
0432(01B0) D9 3E BE 1C 1C 1C BE 3F - 01 E3 1E 64 41 3C C6 E3
0448(01C0) D9 3E BE 1C 1C 1C BE 3F - 01 E3 1E 64 41 3C C6 E3
0464(01D0) D9 3E BE 1C 1C 1C BE 3F - 01 E3 1E 64 41 3C C6 E3
0480(01E0) D9 3E BE 1C 1C 1C BE 3F - 01 E3 1E 64 41 3C C6 E3
0496(01F0) D9 3E BE 1C 1C 1C BE 3F - 01 E3 1E 64 41 3C C6 E3
解密后的文件(第一扇区):
0000(0000) 96 A6 30 00 15 A0 09 04 - 00 00 00 00 2D 00 00 00
0016(0010) 00 00 00 00 00 00 00 00 - 80 01 00 00 89 01 00 00
0032(0020) 0E 08 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0048(0030) 00 00 00 00 09 00 00 00 - 00 00 00 00 00 00 00 00
0064(0040) 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0080(0050) 00 00 00 00 00 00 00 00 - 00 06 00 00 27 00 00 06
0096(0060) 00 00 27 00 27 06 00 00 - 00 00 27 06 00 00 00 00
0112(0070) 27 06 00 00 00 00 27 06 - 00 00 00 00 27 06 00 00
0128(0080) 0E 00 35 06 00 00 12 00 - 47 06 00 00 00 00 47 06
0144(0090) 00 00 00 00 47 06 00 00 - 00 00 47 06 00 00 00 00
0160(00A0) 47 06 00 00 0A 00 51 06 - 00 00 0A 00 47 06 00 00
0176(00B0) 00 00 5B 06 00 00 40 00 - 9B 06 00 00 00 00 9B 06
0192(00C0) 00 00 00 00 9B 06 00 00 - 00 00 9B 06 00 00 00 00
0208(00D0) 9B 06 00 00 00 00 9B 06 - 00 00 00 00 9B 06 00 00
0224(00E0) 00 00 9B 06 00 00 00 00 - 9B 06 00 00 02 00 9D 06
0240(00F0) 00 00 00 00 9D 06 00 00 - 00 00 9D 06 00 00 00 00
0256(0100) 9D 06 00 00 00 00 9D 06 - 00 00 00 00 9D 06 00 00
0272(0110) 1E 00 BB 06 00 00 34 01 - EF 07 00 00 1F 00 BB 06
0288(0120) 00 00 00 00 27 06 00 00 - 00 00 00 00 00 00 00 00
0304(0130) BB 06 00 00 00 00 BB 06 - 00 00 00 00 00 00 01 00
0320(0140) 02 00 01 00 01 00 00 00 - 00 00 00 00 00 00 00 00
0336(0150) 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0352(0160) 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0368(0170) 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0384(0180) 61 61 61 20 62 62 62 0D - 0A 18 8B 83 2E 8C C2 41
0400(0190) 8D 6E 04 8E 6E 04 8F 6E - 04 90 6E 04 73 04 00 74
0416(01A0) 04 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0432(01B0) 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0448(01C0) 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0464(01D0) 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0480(01E0) 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
0496(01F0) 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
根据对WORD加密后的文件与加密前的文件的比较,总结了以下表中内容。
*.DOC *.DOT 文件结构 (本文除特殊标明外,所写数据均为十六进制数)
偏移量 |
长度 |
内 容 |
| 0000— 0001 | 2 |
WORD 文件标识 固定为96 A6 |
| 0002— 000A | 9 |
未知 |
| 000B— 000B | 1 |
文件加密标志 00:未加密;01:已加密。 |
| 000C— 000D | 2 |
未知 |
| 000E— 0011 | 4 |
由口令转换而成的密码 |
| 0012— 0017 | 6 |
未知 |
| 0018— 001B | 4 |
指向正文开始的偏移量 固定为01 80 |
| 001C— 001F | 4 |
指向正文结束+1处 |
| 0020— 0023 | 4 |
文件长度,低字在前,高字在后,此值不是文件正文的长度,而是整个文件的长度,以0A 0E为最小单位,即文档、模板文件最小长度为2062字节。 |
| 0024— 0033 | 16 |
未知 可能为保留字,值为0 |
| 0034— 0037 | 4 |
文件正文长度+2(2为0D 0A之长度) |
| 0038— 003F | 8 |
未知 |
| 0040— 004F | 16 |
未知 固定为0,可作取样标本,供解密之用。 |
| 0050— 014F | 未知 |
|
| 0150— 015F 0160— 016F 0170— 017F |
16 16 16 |
固定为0值,可作取样标本,供解密之用。 |
| 0180— | 正文开始 |
4.源程序清单:
/* Filename:WORDCODE.C
Program by ZhangHongLiang 1995/06/08
*/
#include <stdio.h>
#define EXAMPLE_LINE 5 /*5,22,23,24*/
struct word_file_head
{
char line1[16];
char line2[16];
char line3[16];
}filehead;
main(int argc,char*argv[])
{
FILE *fp1,*fp2;
char buffer[16],Standard_00[16];
int i;
if (argc!=3)
{
printf("\nUsage:WORDCODE Source.DOC Destination.DOC\n\7\7\7");
exit(0);
}
if ((fp1=fopen(argv[1],"rb"))==NULL)
{
printf("Cannot Open %s!\n\7",argv[1]);
exit(0);
}
if ((fp2=fopen(argv[2],"wb"))==NULL)
{
printf("Cannot Open %s!\n\7",argv[2]);
exit(0);
}
printf("Transfer %s to %s \nPlease wait...\n",argv[1],argv[2]);
for(i=0;i<EXAMPLE_LINE;i++) fread(Standard_00,16,1,fp1);
/* read example line */
rewind(fp1);
fread(&filehead,sizeof(struct word_file_head),1,fp1);
filehead.line1[11]=0; /* clear password flag */
filehead.line1[14]=0; filehead.line1[15]=0; /* clear password */
filehead.line2[0]=0; filehead.line2[1]=0;
for(i=4;i<16;i++)
filehead.line3[i]=filehead.line3[i]^Standard_00[i];
fwrite(&filehead,sizeof(struct word_file_head),1,fp2);
while(!feof(fp1))
{
fread(buffer,16,1,fp1);
for(i=0;i<16;i++) buffer[i]=buffer[i]^Standard_00[i];
fwrite(buffer,16,1,fp2);
}
fclose(fp1);
fclose(fp2);
printf("The %s processed.\n\7",argv[1]);
return 0;
}
4.使用方法
在DOS提示符下打入:Wordcode 欲解密文件名 解密后文件名<CR>即可将源加密文件转化为已去除口令的文件。
注:⑴本人所写WORD文件结构未参照任何有关资料,系本人的理解,如有误及不详,以Microsoft WORD5.0有关正式资料为准;⑵用WORDCODE解密后的文件可能要比原文件要长几字节(是由于本程序以16BYTE为一个处理单位,对目标文件进行写操作的),对WORD读文件没有任何不良影响,重写后即可恢复原长度。
1995-04