前 言
出于各种各样的目的,软件开发人员经常会面对结构未知的数据文件,这可能是原于受客户委托,对第三方开发的软件功能进行有限扩展或二次开发;也可能原于学习和提高的目的;但更多的时候可能纯粹出于好奇。
分析数据文件需要一些相关的知识和技能,包括对数据文件的基本结构和存储方式的理解。
数据文件结构分析方法的任务:数据结构与数据表达内涵的分析。
本书不涉及通常意义上的数据加密、数据解密等相关问题。
基本数据类型。在第一部分中,将给以简单的介绍。
对于分析复杂的数据文件,除了基本的知识和技能外,还需要强大的分析工具。在第二、三、四部分,介绍了Fexplorer软件强大的数据分析功能和方便、灵活的操作。
在面对实际问题时,分析数据文件可能需要更多的知识和背景。在第五部分通过实例演示了一个完整的数据文件的破解过程。
需要特别说明的是,尽管数据文件分析技术有可能被一些人用于非法目的,但本书的著者强烈要求读者,在理解和使用本书的过程中,严格遵守国际、国内软件保护、知识产权等相关的法律、法规,这也是著者编写本书的出发点。
数据文件是整个软件的一部分,存储软件的输入、输出数据,通常以磁盘文件的形式保存在存储介质中。 有时软件并不需要数据文件,比如大家常用的WINDOWS提供的计算器。但多数,特别是大型应用软件,都需要有数据文件。如数据库管理软件、文字处理软件、绘图软件、股票分析软件等,都有自己的数据文件。 软件的文件包括程序文件和数据文件两类,程序文件主要包含软件的可执行代码,负责对用户输入的数据进行计算、分析,并将计算分析结果以数据文件的形式保存到数据文件中。 从功能上,数据文件可分为输入数据文件、输出数据文件和临时数据文件。输入数据文件负责初始化软件的运行环境,存储被加工的数据原料。输出数据文件存储经过软件分析、计算的结果。临时数据文件存储软件计算过程中生成的临时数据或中间结果,这类数据在软件运行结束后一般由软件自动删除。 从存储格式上,数据文件可分为文本数据文件和二进制数据文件。文本数据文件可由文本编辑器打开。常见的文本数据文件有批处理文件(*.bat)、配置文件(*.ini或*.CFG)、DXF文件。 二进制数据文件不能被文本编辑器打开,只能通过WINDOWS提供的底层文件操作指令访问。由于二进制数据文件的存储效率和访问效率较高,几乎所有规模较大的数据文件全为二进制数据文件。 由于文本数据文可直接用文本编辑器查看,所以数据文件分析中所设计的数据文件类型主要是二进制数据文件。 数据文件可以看成是一个由各种基本的数据类型构成的数据集合,基本的数据类型有整型数据、浮点型数据、字符型数据。 整型数据有单字节整数(8位)、双字节整数(16位)、四字长整数(32位)。单字节整数只占1个byte,表示数据的范围从0-255或-125到125。双字节整数占2个byte,表示数据的范围从0-65535或-32767到32767。四字长整数占4个byte,表示数据的范围从0-4294967295或-2147483647到2147483647。 逻辑型数据也由单字节整数表示,占1个byte(8位),其中0表示“否”,0表示“是”。随着计算机计算能力的提高,计算器处理数据的范围不断扩大,整型数据范围也在增加。目前64位整数、128位整数在部分机器或系统中已经成为基本数据类型。 浮点数有单精度浮点数、双精度浮点数两中基本类型。单精度浮点数占4个byte(32位),表示数据的范围从0-255或-125到125。双精度浮点数占8个byte(64位),表示数据的范围从0-255或-125到125。 字符型数据分两类,字符和字符串。字符型数据占1个byte(8位),表示“0”-“9”、“A”-“Z”、“a”-“z”、“!”-“+”、“{”、“}”、“[”、“]”、“|”、“、”、“:”、“;”、“’”、“<”、“>”、“,”、“。”、“?”、“/”等。 字符串数据由字符组成。根据存储方式的差异,字符串分为静态字符串和动态字符串。静态字符串存储时包含一个表示字符串长度的字节,称为长度字节,位于存储的第一个字节。因此,静态字符串最大容纳255个字符。 动态字符串没有长度的字节,字符串是以“0#”结尾。所以动态字符串又称为“零结尾字符串”(Null-terminated String)。动态字符串没有长度限制,但一般机器或系统中,动态字符串长度小于4GB。 结构数据(STRUCTURE),有时又称记录(RECORD),是由若干基本数据类型构成。以下是两个简单的结构数据,分别表示二维空间点和三维空间点。 T2DPoint=Record X,Y:Real; end; T3DPoint=Record X,Y,Z:Real; end; 结构可以变得很复杂,实际上每一个数据文件可以看作一个结构。下面是一个表示文件头信息的结构数据,不仅包含大量的基本数据类型、也包括预定义的结构数据类型,既嵌套结构数据。简单的嵌套结构数据只有两层,复杂的嵌套结构数据只有三层甚至更多。 HeaderType=Record OBjNum:Word; XYOffset:LongInt; XYSize:Longint; IndexOffset:LongInt; IndexSize:LongInt; AttrOffset:LongInt; AttrSize:LongInt; Addr:Longint; XYAddrIndex:Array of AddrIndexType; AttrAddrIndex:Array of AddrIndexType; ISubGrInfo:ISubGrInfoType; IStrInfo:IStrInfoType; ILineInfo:ILnInfoType; Num1,Num2:SmallInt; XYRange:RangeType; ScreenType:Record ScrWid,ScrHei:single;end; AttrIndexOffset,AttrIndexSize:Longint; RangeOffset,rangeSize:LongInt; end; 结构是数据文件最常见的数据类型,是构成数据文件的基本框架。分析数据文件所花费的时间多数用在从大量的数据流中分离出一个个结构数据。 长度超过1个字节的数据,在存储数据时,有存放顺序的问题。对于两字节整数,低位字节在前,高位字节在后,如整数5689,十六进制的存储格式为“$3916”。四字节整数,最低位字节在前,高位字节在后,如整数20060520,十六进制的存储格式为“$68193201”。 静态字符串数据占n+1个字节,n为字符串的个数(不含结尾的0#)。第一个字节为长度字节,数值为n以后按顺序为各字符。 动态字符串占n+1个字节,n为字符串的长度,第一个字符占第一位,以后按顺序占据位置,最后一位为结束标志0#。 数据文件一般包含文件头和数据两部分,部分数据文件可能还包含索引表。因此分析数据文件的第一步是弄清数据文件的基本框架,然后按照文件头、索引表、数据三部分依次分析、破解。 文件头一般在数据文件的开始。通常包含文件类型标识、所有者、版本信息、创建时间、文件大小。 文件头中最重要的信息是文件的大小,它可以帮助程序员方便地访问整个数据文件。通常文件的大小由四字节的一个长整数表示。 在分析数据文件时,由于文件的大小是可知的(通过WINDOWS的GetFileSize进程取得),因此可以从分析文件的大小入手。 [例]:文件长度 索引表存放组成数据文件各部分的偏移地址、大小等相关信息,利用索引表可以方便地对数据文件的各部分进行。通常文件各部分的偏移地址和大小由四字节长整数表示。 有些情况下,索引表与文件头是一起的。 数据部是数据文件的主题,通常在文件中占据大部分存储空间。一般情况下,数据部由相对独立的数据块组成,每一个数据块表示不同的数据内容。分析数据部的第一步是将数据部分为若干数据块。 数据块的内容和格式由数据块表达的内容决定,简单的数据块直接由最基本的数据类型构成,这种情况比较少见。通常情况下,数据块比较复杂,不仅有简单的基本数据类型,更多的是由结构数据类型或嵌套结构数据类型构成。 例如表示空间离散点位置的数据通常是一组实数对,其中表示二维空间的实数对由两个实数X、Y构成、表示三维平面空间的实数对由三个实数X、Y、Z构成。这种数据块可以用Array of T2Dpoint或Array of T3Dpoint表示。 表示一组色彩的数据块,根据颜色生成方式,可以有三种数据形式:RGB三色、CMKY四色、长整数,其中RGB三色、CMKY四色分别由3字节和4字节组成,分别依次存放R、G、B和C、M、K、Y色谱数据,每个色谱数据占1个字节。长整数直接代表一个颜色,WINDOWS系统采用此类颜色表示方法。这种数据筷仍然属于简单数据块,它可以用类似Array of RGB或Array of CMKY或Array of LongInt表示。 下组结构数据是用来描述矢量图中线图元数据块的,属于三层嵌套结构数据。 LnInfoType=record ID:String[40]; //ID编号 LinesNum, LType, AddedType, Color:Integer; //线段数/线型/辅助线型/颜色 Wid:Single; //线宽 AddedColor, Layer, Attr:Integer; //辅助颜色/所在图层号/属性 Range:RangeType; //范围 PointNum:Integer; //总点数 Title:String[128]; //名称 end; LDotsType=^LdLink; LdLink=Record Next,Pre:LDotsType; xy:TRPoint; End; LineSegType=^LSegLink; LSegLink=Record Next:LineSegType; PHead,PEnd:LDotsType; End; ArgLineType=^LLink; LLink=Record Next:ArgLineType; Info:LnInfoType; SHead,SEnd:LineSegType; End; 数据文件的基本分析方法包括基于数据流的分析方法、基于基本数据类型的分析方法和基于结构数据的分析方法。 基于数据流的分析方法也可以称为基于字节的数据分析方法。基于数据流的分析方法的任务是将字节流组成基本数据类型。 在计算机硬件层次上,所有数据的存储格式都是二进制数码,形如000100001000010000100010的bit流。对于软件工程师,通常不需要处理这样的数据,除非直接与硬件打交道。一般情况下,软件工程师仅需要在字节层次或更高的层次上处理数据,也就是将二进制数据按照每8位一个单位进行处理,将上述bit流看成如下的byte流 00010000 10000100 00100010。基于数据流的分析方法实际上是将数据文件按照字节的方式读出来,然后再由一个个字节组成基本数据类型。 如何由字节组成基本数据类型,没有固定的方法,需要多方面尝试。但有些基本原则可以参考,第一是构成基本数据数值大小,第二是常用的数据类型。 利用字节构成基本数据的数值大小可以判定分析是否成功,例如,表示字符串长度的长度字节,其数值的大小应等于其后的字符串的长度。表示文件大小的长整数,其数值应等于文件的大小或相近数值*。表示空间位置坐标的实数,其大小应在实际表示的空间范围之内。表示金额的实数,小数位不能超过两位。 利用常用的数据类型可以帮助确定哪些数据类型更有可能。例如,表示文件大小、偏移地址、日期等一般是长整数,表示名称、注释的必须是字符型数据,表示空间位置坐标、费率的数据一般是实数。表示逻辑关系、字符串长度的,一般是字节数据。 基于基本数据类型的分析方法的任务是将基本数据类型组成结构数据类型,这是数据文件分析的重点,也是分析工作成功与否的关键。 Fexplorer软件主要是用来解决如何将基本数据类型组成复杂的结构数据类型的,为分析人员提供一个方便的分析手段。但是,还应该意识到,仅凭Fexplorer软件是不能够解决一切问题的。更重要的需要分析员更宽广的知识面、软件开发经历等。当然,有一定的数据文件分析的经历,毫无疑问增加分析的成功率。从这一点将,多一些尝试、多一些积累,才是从事分析工作人员的最根本的分析法宝。 基于结构数据类型的分析方法是利用上述分析工作得到的结构数据类型还原整个数据文件。对于整个分析工作而言,在从事这部分工作时,应当有在迷茫探索和疲惫的拼搏之后承受丰收喜悦的感觉。 在Fexplorer软件的高级操作部分,将给读者展示基于结构数据类型分析方法的强大功能,以及由此带来的震撼。 1 基本知识
1.1 数据文件
1.2 数据文件类型
1.3 数据类型
1.3.1 整型数据
1.3.2 浮点数据
1.3.3 字符型数据
1.3.4 结构数据
1.4 数据的存放顺序
1.5 数据文件结构
1.5.1 文件头
1.5.2 索引表
1.5.3 数据部
1.6 数据文件基本分析方法
1.6.1 基于数据流的分析方法
1.6.2 基于基本数据类型的分析方法
1.6.3 基于结构数据的分析方法