您好,欢迎访问三七文档
超星PDG转换(10千字)安全中国更新时间:2007-09-2718:35:52责任编辑:池天热点:======================================“超星读书卡”持卡用户可以通过Internet下载超星数字图书馆中的数字图书。令很多用户困扰的是在一台机器上下载的文件,在另一台机器上无法直接阅读。虽然可以通过获取离线注册码的方式解决,但总感觉不尽方便,能否妥善解决?也许我们注意到在线阅读时是不分那台机器的,可以想象其PDG文件在从网上传到机器内时是不具备机器识别特征的,这些文件是下载到本地时在本地加密后存盘的。因此我们有可能在分析出其本地加密算法,然后推演出其逆算法,将其还原成原始文件,那么就可以实现自由的离线阅读了。经过算法分析,证明此方法是可行的,并做出这个demo版的小工具:1.此工具暂没有批量转换功能,一次只能转换一个选定文件2.我只做了不全面的简单测试,不一定适用于所有的PDG文件3.我用的是SSReader3.6及以前版下载的PDG文件,通过测试4.现在SSReader3.7的加密方式已经改变,肯定不支持,有待以后分析======================================以下论述是我跟踪分析的大致结果,表述不是很精确,有些是猜测所有分析是基于3.6版的,新版的格式可能会增加内容或有所改变,我的分析是针对于两种主要类型(格式)的,其实也是目前绝大部分图书所采用的类型,一种是我们在线阅览的那种pdgtype=02h另一种是下载存储到本地硬盘文件的那种pdgtype=10h因此以下描述的结构只能保证对这两种文件有效,其它类型的还需进一步的分析验证.==========================================================================================1.PDG文件的大致结构:PDG2_fileSTRUCTHH_headeroptionalheaderPDG_dataPDG2_fileENDSHH_headerSTRUCTdw4848h;超星文件特征标志db02h;PDG_VERSION=2db00h;我见到的PDG2这里都是0,就算默认吧dd?;不知道,对我们似乎没有价值ddoffset_optional_header;optional_header在文件中的偏移地址,应该等于0Ch吧HH_headerENDSoptional_headerSTRUCTdb80h,00h,00h;没什么好说的,算是标志吧dbpdgtype;文档类型,我只分析02h和10h两种类型dwx_pix;扫描图像的横向参数dwy_pix;扫描图像的纵向参数db01h,00h,00h,00h;按默认算吧ddoffset_PDG_data;扫描图像数据在文件中的偏移地址,大概都是8Ch吧ddsize_PDG_data;扫描图像数据的字节数dd8dup(?);作用可能不大,把它们添上0不影响页面的显示key_datadb1Chdup(?);作用可能不大,把它们添上0不影响页面的显示optional_headerENDSkey_dataSTRUCTdb1Ehdup(?);这里有时是一个有关超星公司字符信息,有时为空(全0)dw?;我不清楚什么含义db8dup(?);可能有几处默认是0ddSS_user_key;重要的数据,可用于解码还原x_pix和y_pixdd?;key_dataENDS==========================================================================================2.我所想象的图书阅览管理过程(基于简单的分析,未必准确,仅供参考)超星图书服务器上所存储的图书是扫描生成的(废话,大家都知道),是按pdgtype=02h存储的,文件结构与上述结构相符,单其扫描数据PDG_data是经过加密的,加密过程如下:30h字节长的key_data经过md5运算得到128位即16字节的数据,此16字节的数据作为密钥,采用一种分组加密算法以16字节为单位进行加密运算,直到数据结束,此分组加密算法我根据手头的不多的密码学算法比较,我没有识别出来,我暂且称之为encode_sub,我将它放在后面了,大家有兴趣的可以帮忙看一下,有知道可以的告诉我,万分感谢.当我们在线阅览时,ssreader.exe中的相对应decode_sub将数据解码后,就可以显示出来了.在下载到本地硬盘时,文件存储成pdgtype=10h类型的了,PDG_data扫描数据是用解码后的原始数据存储的,但它把optional_header中部分数据加密了,加密过程如下:跟据每台机器的硬盘C:分区的卷序列号和空间大小对应此机器的SS机器码,由SS机器码可以算出一个word值,暂时称为SS_w,这段算法我没去分析,对我们用处也不大.在下载存盘时还需要一个随机word值RANDOM_w,RANDOM_w实际就作为SS_user_key的高16位,由SS_w和RANDOM_w再算出一个word值作为SS_user_key的低16位,因其算法可逆,所以可以用SS_user_key还原出原来的SS_w,这也是原程序用来检测当前硬盘的SS_w和下载文件的SS_w是否一致的方法,不一致则提示你用户不对不是无法阅读.接下来用SS_user_key(用SS_w和RANDOM_w算法稍变也可以)算出两个word值,分别去减x_pix和y_pix,最后把pdgtype添上10h.这样与我们有用的处理就算结束了,存盘后就可以了.==========================================================================================3.我们需要做的工作我们只要把pdgtype=10h的文件转变成pdgtype=02h的文件,就可以实现不受硬盘的限制脱机自由阅读了.过程大致这样吧,大家也应该可以想到了,我用语言描述很费尽的,因此这里用汇编代码描述吧:下面这段算法在pdg2.dll可以找到,我贴的稍有调整,并去掉了SS_w的检测movebp,SS_user_keyshreax,10hxoredx,edxmovesi,1FFhdivesimovecx,edxmoveax,ebpshreax,10hxoredx,edxmovesi,0DBhdivesiimulecx,edxleaedx,dwordptr[ecx-000050EEh]movebx,ebpsubebx,edxandebx,0000FFFFhshrebp,10hmoveax,ebxxoredx,edxmovecx,000003FBhmovedi,00000083hdivecximulebx,ebpmoveax,ebpmovecx,edxxoredx,edxdivedimoveax,edxsubeax,ebxsubeax,ecxsubecx,ebxsubecx,edxaddx_pix,ax;还原x_pixaddy_pix,cx;还原y_pix为了看起来干净利索,我们把key_data区域都清0,不这样也没问题,不过有几处可能不要乱数leaedi,key_datamovecx,30hxoreax,eaxrepstosb然后对30h字节长度的key_data进行一次md5,md5我就不贴在这里了,太费篇幅了,大家都可以找到,我们下面要用到这128位(16字节)的结果作为分组加密算法的密钥,实际上我们的key_data已经是清0的了,结果也是固定不变的了,也可以直接用现成的结果.我假设结果存在key_128处.为转成pdgtype=02h文件,PDG_data要用encode_sub加密movedi,size_PDG_data;数据长度cmpedi,10hjldata_encode_endmovebx,key_128movesi,offsetPDG_datashredi,4@@:pushebx;密钥指针pushesi;数据指针,加密结果也存储在这里callsub_encode;分组算法,每次加密10h字节addesp,8addesi,10hdecedijnz@Bdata_encode_end:;处理结束;下面是完整的分组加密算法,在********.exe中可以找到;其中注释是我分析时加的,不尽准确,本想删去,后来一想算了,献丑也罢,只当交流了;开始看时感觉上有点象RC5族算法,但越看越不象,资料有限,还是确认不了,望高手指教encode_subprocnearvar_2C=dwordptr-2Chvar_28=dwordptr-28hvar_24=dwordptr-24hvar_20=dwordptr-20hvar_1C=dwordptr-1Chvar_18=dwordptr-18hvar_14=dwordptr-14hvar_10=dwordptr-10hvar_C=dwordptr-0Chvar_8=dwordptr-8var_4=dwordptr-4arg_0=dwordptr8;pDataarg_4=dwordptr0Ch;pKeypushebpmovebp,espaddesp,0FFFFFFD4hmoveax,[ebp+arg_0];pDatamovedx,[eax];Amov[ebp+var_4],edx;sa=Amovedx,[eax+4];Bmov[ebp+var_8],edx;sb=Bmovedx,[eax+8];Cmov[ebp+var_C],edx;sc=Cmovedx,[eax+0Ch];Dmov[ebp+var_10],edx;sd=Dmoveax,[ebp+arg_4];pKeymovedx,[eax];kamov[ebp+var_14],edx;kamovedx,[eax+4];kbmov[ebp+var_18],edx;kbmovedx,[eax+8];kcmov[ebp+var_1C],edx;kcmovedx,[eax+0Ch];kdmov[ebp+var_20],edx;kdxoredx,edx;c1mov[ebp+var_24],edx;c1mov[ebp+var_28],9E3779B9h;c0mov[ebp+var_2C],10h;r@@:movecx,[ebp+var_28];c0add[ebp+var_24],ecx;c1+c0moveax,[ebp+var_8];sbshleax,4;sb4addeax,[ebp+var_14];sb4+kamovedx,[ebp+var_8];sbaddedx,[ebp+var_24];sb+c1xoreax,edx;(sb4+ka)xor(sb+c1)movecx,[ebp+var_8];sbshrecx,5;sb5addecx,[ebp+var_18];sb5+kbxoreax,ecx;(sb4+ka)xor(sb+c1)xor(sb5+kb)add[ebp+var_4],eax;sa=sa+[(sb4+ka)xor(sb+c1)xor(sb5+kb)]moveax,[ebp+var_C];scshleax,4;sc4addeax,[ebp+var_1C];sc4+kcmovedx,[ebp+var_C];scaddedx,[ebp+var_24];sc+c1xoreax,edx;(sc4+kc)xor(sc+c1)movecx,[ebp+var_C];scshrecx,5;sc5addecx,[ebp+var_20];sc5+kdxoreax,ecx;(sc4+kc)xor(sc+c1)xor(sc5+kd)add[ebp+var_8],eax;sb=sb+[(sc4+kc)xo
本文标题:超星PDG格式分析
链接地址:https://www.777doc.com/doc-4671651 .html