fox 表单和类库的加密及修复[转帖]
fox 表单和类库的加密及修复
ZHAOYF 的 vfpdecoder 是一个划时代的工具,它把 fox 的解密技术提高到了一个新的高度.许多传统的加密工具加密的程序在它面前都原型毕露了.首先祝贺ZHAOYF.向他致敬!
由于 vfpdecoder 可以得到大多数 fox 程序的原代码,因此,对于一些用 vfpdecoder 得到的表单和类库,多数人不得不面对这样一个现实:如何处理这些不能反编译和修改的表单和类库?
要正确修复表单和类库,我们需要知道表单和类库的结构及相应的加密方法.
表单和类库的结构
表单和类库实际上都是标准的 Visual FoxPro 表,一个表单由两个文件组成: .scx 和 .sct,而一个类库也是由两个文件组成: .vcx 和 .vct. 其中,scx 和 vcx 相当于标准的 dbf 文件, 而 sct 和 vct 则相当于标准的 fpt 文件.因此, 你可以在
Visual FoxPro 的开发环境中用以下命令来打开并查看表单和类库的内容:
要查看表单内容:
Ues C:\test\foo.scx
brow
要查看类库内容:
Ues C:\test\foo.vcx
brow
在以上示例中,假定你的表单或类库是在 C:\test 目录中,你的表单或类库名的 foo.scx 或 foo.vcx 通常,我们在表单设计器和类设计器中看到一个个对象,都对应于 scx 和 vcx 中的一条或多条记录.
表单和类库文件在结构上是完全相同的.下面简要说明一下表单和类库的字段和含意:
字段名 字段类型 说明
PLATFORM C 说明此文件运行的平台,在 VFP 中,总是 WIndows
UNIQUEID C 此字段的一个唯一标识
TIMESTAP N 该对象的时间印
CLASS M 此对象的类名
CLASSLOC M 此对象所在的类库名
BASECLASS M 此类的基类
OBJNAME M 该对象的对象名
PARENT M 该类的父类名
PROPERTIES M 该对象的属性代码
PROTECTED M 此字段只对类库有效,用于说明此类中的哪些对象是受保护的
METHODS M 此对象的方法代码,对于去掉调试信息编译的表单或类库,此字段的内容为空
OBJCODE M 此对象的方法代码编译后的代码,它的内容相当于一个 fxp 文件
RESERVED1 M 通常,表单和类库的第一条记录的此字段内容用于说明此文件的版本
或说明此记录是一个自定义类
RESERVED2 M 说明此类中包含的对象数
RESERVED3 M 说明此类中包含的自定义方法及其名称
RESERVED6 M 说明此类中包含的对象使用的显示单位
RESERVED8 M 说明此类使用到的包含文件名
USER M 是给用户使用的,用户可以保存任何信息到此字段中
DBF 表头结构
DBF 字段结构
DBF 数据
FPT 文件头结构
FPT 数据结构
备注字段的结构
表单和类库中的主要内容是保存在备注字段中的,因此有必说明一下备注字段的结构.在 scx 和 vcx 文件中,备注字段的内容只是一个四字节长的指针(DWORD 型),它指向相应的备注文件中的相应的位置,换句话说,备注字段的值就是该字段内容在 sct 或 vct 文件中的偏移值.用户是没有办法用一般的方法来修改这个指针值的.在 scx 和 vcx 文件中的备注字段所指向的 sct 或 vct 的位置,开始四字节用于说明此备注字段的类型,它可能是以下值:
0 – 图片(图片字段类型)
1 – 文本(备注字段类型)
2 – 对象
对于 scx 和 vcx 文件来说,此值只能是 1
接下来的四字节是备注长度,再接下来才是备注字段的真正的内容.
因此,可以按以下方法来读取一个备注字段的内容:
从 dbf 中(也就是 scx 和 vcx 文件)中读取此字段在 .fpt 文件中的偏移
从该偏移中读四字段来判断此备注字段的类型
读取接下来的四字节以确定此字段内容的长度
根据此字段的长度来读取相应长度的内容
对表单和类库进行加密的目的是让解密者不能编辑和修改加密后的表单和类库,所采用的方法主要是采用修改备注字段的指针,标志和长度.
由于 VFP 的表单和类库在运行时,并不会全面检查该表单和类库的结构是否正确.对于没有使用到的字段它是不去理会的.因此加密者可以任意修改 VFP 没有使用到的备注字段的结构和内容.其次, VFP 似乎具有很强的容错性,对于要用到的字段,即使有些信息不正确,它也会进一步采用其它方法来得到正确的信息.
对于一个表单和类库的备注字段的俱体加密方式是:
修改 scx 或 vcx 中的备注字段指针值.如果此字段是 VFP 未用到的, 则可以把此指针值修改为一非法值。所谓非法值是指:一个合法的备注字段指针值必须大于 512,512 是 fpt 文件头大小,第一个备注字段的内容总是开始于 512 字节处,另外,合法的备注字段指针值还必须小于 FPT 文件本身大小(严格地说是应该小于此备注字段内容起始偏移到 fpt 文件尾的大小).因此,无论在任何情况下,只要备注字段指针小于 512 或大于 FPT 文件本身长度就可以认为这是一个非法指针.当然,也可以把此指针修改来指向一个大于 512 且小于 FPT 文件大小的位置, 反正 VFP 也不会用到此字段内容,因而也不会造成运行时的错误.
修改 FPT 文件中的备注字段类型和长度,修改备注字段类型并没有太大意义,但这可能这会造成重新编译表单时提示备注文件无效。修改备注字段长度就可以说是很能恶毒了,它会造成重新编译表单时的假死机和编辑表单类库存盘时产生巨大的临时文件把硬盘占满。俱体方法是根据 scx 或 vcx 中的指针值,修改备注文件中相应偏移的内容。 scx 或 vcx 中的指针直接指向 sct 或 vct 中此备注内容的备注字段类型,备注字段类型是四字节长,接下来的四字节就是备注字段长度了,通常可以把备注字段长度修改为一个很大的数。
修改备注字段的内容.这种方法主要用于修改 OBJCODE 字段内容,因为 OBJCODE 字段中保存着编译后的代码的内容,实际上可以把它的内容当成一个 fxp 文件来看待(编译后的 prg 文件),修改它的内容可以使反编译程序在反编译时失败。最常用的方法是修改开始五字节的标识字节。VFP 产生的 OBJCODE 内容的前五个字节总是 FE F2 FF 20 02, 大概可以把它们随意修改成其它的内容,从而让反编译程序识别失败。另外在也可以象前面所述那样同时修改此备注备注字段的长度,但此长度不能修改为零,可以改为从 1 到 DWORD 所允许的任何正值,VFP 会在运行时动态检查确定此字段的真正长度而不会造成错误。另外,熟悉 fxp 文件结构的人还可以进一步修改 OBJCODE 字段的内容来达到使反编译失败的目的,俱体方法在此就不多谈了。
修改 FPT 文件的长度(向 FPT 文件尾添加垃圾)和 FPT 文件开始四字节处的内容,这种修改可以造成重新修改后不能存盘的错误发生。
修改 scx 或 vcx 的字段类型,这种修改并不多见,且可修改的字段也不多,大概只能把 TIMESTAP 字段从字符型修改为数字型,并且只限于 VFP 8.0 及以上版本才可进行此种修改。
另一个要注意的问题是哪些字段的内容可以修改,那些不能修改.并非所有字段的内容都是可以修改的.一般地讲,METHODS,USER 字段是可以修改的,表单的 PROTECTED 字段是可以修改的(类库的 PROTECTED 字段要看你的类库中有没有特殊属性的对象,如受保护的和隐藏的对象),如果有这样的对象则不要修改,还有,如果你的表单和类库没有使用 .h 文件,则 RESERVED8 字段也是可以修改的,而且对于不同的字段,修改的方式也是不一样的.俱体哪些字段可以修改,你可以参考一下本文附件中的 foo.scx 和 foo.vcx 等文件.有一个原则,原备注字段中有值的,一般不要修改(objcode 字段除外).
表单和类库的修复
表单和类库的修复是加密的逆过程,在修复时尽可能不要修改 sct 和 vct 文件内容。因为可能有多个字段交叉引用到相同的 sct/vct 内容,也就是说一个数据块可能对于一个字段来说是无效的,但对于另一个记录的另一个字段确是正确的。因此在修复时,一般只修改 scx 和 vcx 中的指针,只对 OBJCODE 对象的修改需要对 sct 和 vct 内容进行修改,在修复时需要逐记录逐字段地进行检查和修复。在修复时,还要注意一个问题就是写入块大小时,一定要注意 sct 文件头中的块大小信息。虽然在通常情况下,块大小的值为 1 ,但是此值为其它非 1 值的也不少见。备注字段的真正长度应该是备注头中的块数乘上块大小.
为什么修复后的表单和类库仍然不能修改呢?
最常见的原因如下:
原程序是用较高版本的 VFP 编译的
正在编辑的表单引用到了其它类库中的对象,而此类库不存在或不能被 VFP 识别(未经修复)
正在编辑的表单引用到了某一 ActiveX 控件,此 ActiveX 控件在你的系统中没有注册
你正在编辑的表单是不带 Debug 信息编译的,此类表单通常可以打开,但只要一存盘, OBJCODE 中的内容就会丢失,因此你必须在编辑前用ReFox 或 Foxtools 等工具来恢复它们的原始代码
在编辑一个表单和类库前,必须保证它是带有代码的,而且最好是不打开它地编译它一次.
关于随附程序的说明
附件中的程序是一个简单的表单/类库修复器及其源代码,分别用 C++6.0 及 MASM 实现了检查及修复功能.它们只能检查和修复表单和类库,没有反编译代码的功能.修复后的表单和类库必须用 refox 或 foxtools 反编译出它们的代码才能在 VFP 中重新编辑它们.
如果你遇到有不能修复的表单或类库请在这里告诉我,我会检查原因并及时修正程序.
|