Ruby 如何用 ruby 分析二进制文件,有可能不知道里面的数据结构

stephen · 2012年02月20日 · 最后由 skandhas 回复于 2012年02月22日 · 10273 次阅读

如何用 ruby 分析二进制文件,有可能不知道里面的数据结构!

程序?数据?

这个我做过,ruby 不擅长这个。用那个东西。。。不好意思我忘了,@hooopo 应该知道。。

@jinleileiking 用 python 么?不要忘记哦···哭!

分析里面的数据!

你要分析什么?既然不知道里面的数据结构,那这和用神马语言关系不大了吧。属于逆向范畴了都。

@skandhas 分析股票软件保存在本地的二进制文件,求思路

先用弄清里面存的的是啥东东,知道结构的情况下,就好继续往下分析。 比如说,你要分析一个 ELF 文件,你必须先把 ELF 格式本身要了解吧。然后在此基础上对这个文件再进行进一步的分析。

@skandhas 都是 dat 文件,结构网上还是有的,不过是旧的,

#8 楼 @stephen 网上的有相关信息,虽然旧点,只要不是旧的离谱,还是有参考价值的。 最根本的办法是 逆向那个股票软件,找到它读写 dat 文件的相关代码,根据代码来分析它是如何使用 dat 文件的,这样就能得到这个文件的基本结构了。 不过,这样做,工作量是比较大一点。

@hooopo 在么? @skandhas 我先参考下旧的,分析下!

@skandhas 如果知道数据结构,跟着操作思路如何?

ruby 对二进制数据分析的能力差一些,但是也是能分析的,就是麻烦,好像没有现成的库。这块 C 比较顺手。。。。 ruby 要用到内置的一个比较恶心,难懂的函数。。。我忘记是什么了。。。。-_-####

@jinleileiking 呵呵,看来要拿起 c 来了

#11 楼 @stephen 如果知道这个文件的数据结构,那么说明对这个文件进行分析就不是什么难事了。 主要看你是想对这个文件做什么样的分析。至于用什么语言,就看你的习惯了。

Ruby 分析二进制文件也有许多 gem 来辅助,不是什么难事。可以用 FFI,FFI::Struct 可以对 C 的 struct 进行完整的描述。我也写了个 gem: cstruct,也是用来辅助二进制操作的。类似的 gem 还有 binstruct,rstruct 等。

@skandhas 你的 gem 有上传到 github,求地址

#13 楼 @stephen

这个东东 skandhas 是行家,他写的那个 CStruct 很好用。

#15 楼 @stephen CStruct 的地址: https://github.com/skandhas/cstruct/ 你可以直接 gem install CStruct 的 align 目前支持 1 种,后续会增加其它的支持。 FFI 现在发展的很不错了。我个人觉得 FFI::Struct 描述结构体不是很直观。可以 FFI 和 CStruct 联用。像上面的例子。FFI 的功能十分强大,是 Ruby 调用 native 代码,分析二进制代码的利器,十分推荐使用。

想起来了:@skandhas @stephen 我当初用的是这个: http://rubygems.org/gems/bit-struct

写了点代码,能够将 C 的.h 文件自动转化为 bit-struct 的格式供 ruby 使用。一般的结构体都能解析。鉴于为公司做的,不敢开源。。。

#19 楼 @jinleileiking 恩,我以前也用 bit-struct. bit-struct 支持的功能很多,只是觉得它对 struct 的写法不是很直观,当时又不没找到合适的 gem,就自己又造了一个轮子,写了个 cstruct :( <也许我有心理强迫症> 哈哈

#20 楼 @skandhas 我那阵的想法是给 bit-struct 加个 wrapper。

@jinleileiking @skandhas 好似我记得,如果结构体有嵌套,就是没用了

@jinleileiking @skandhas @hhuai 是结构体嵌套结构体!

@jinleileiking @skandhas @hhuai 哈哈,看文档看到了

#21 楼 @skandhas 我改成http://hhuai.github.com, 发现还方便一些。

#23 楼 @stephen 结构嵌套,bit-struct 能搞,我用过

@skandhas 有点问题请教 如果里面有 c++ 的类型呢?__time32_t

对于c++来说直接用__time32_t类型直接出来就是日期(vs2005中,这个代表32位时间类型值,在vc6中直接用time_t即可【vc2005中time_t代表64位时间值】)

#30 楼 @stephen 其实~ __time32_t 在 32 位系统下就是个 long. 在 CStruct 下,用 int32 定义即可。

然后再用 ctime 函数把__time32_t 转成可读的日期字符串。ctime 函数可以用 FFI 来调用

看了以上诸位的讨论,我只有默默的将此贴加入收藏夹...

@skandhas

起止地址 数据内容 数据含义 数据类型 
18 - 21 31 41 30 30 30...FF 证券代码 Char[10] 
22 - 25 B0 09 00 00 日线记录数 Integer 
26 - 57 16 00 17 00...FF FF 记录块号 Word[25] 

struct INDEX_DATA
 {
 char code[10];
 int dayrecordnum;
 unsigned short int reocrd[25];
 };

我用 cstruct 代码如下

class INDEXDATA < CStruct
      char :codes, [10]      #18 - 21 31 41 30 30 30...FF 证券代码 Char[10]
      int32 :dayrecordnum   #22 - 25 B0 09 00 00 日线记录数 Integer
      uint16 :records, [25] #26 - 57 16 00 17 00...FF FF 记录块号 Word[25]
end

读取后,这个 codes 要怎样输出呢,

#33 楼 @stephen 你写个小程序,将.h 翻译成 ruby 的 class,省得手输入了,(如果多的话)

类似编译原理的 lexer

@jinleileiking 我没 h 文件的,我只有用来保存数据的二进制文件,这些数据结构,是在网上找的

#36 楼 @stephen 这样吧,如果不涉及商业机密的话,你可以把格式说明及这个 dat 文件发给我吗?我帮你看看。我对 Ruby 二进制解析比较感兴趣。我的 mail:[email protected]

#33 楼 @stephen 是大智慧的日线数据格式吗?

#36 楼 @stephen 哦,那你应该解决了吧。

@skandhas @jinleileiking 不涉及什么,就是大智慧的日线数据,以发!

@skandhas @jinleileiking http://blog.macd.cn/2149104/viewspace-49051 别人研究的数据结构,大智慧的日线文件太大了,或者请前辈们安装一个大智慧!

@skandhas

uint16 :record, [25] 

这里数组转换成整型,to_i,Integer 都报错,请教,cstruct 有内置函数嘛?我在文档找不到

#42 楼 @stephen uint16 :record, [25] 在 CStruct 内部已经做了处理。你可以按照 ruby 的 Array 来处理它。像我中午给你例子里:

index_data.reocrd.reject{|e| e== 0xffff }

还有,像下面这样也可以,因为 record 给你返回来一个 Ruby Array 对象嘛。

index_data.reocrd.each do |e|
   p e
end

或是通过 [] 来访问其元素。不需要 to_i 之类的函数

需要 登录 后方可回复, 如果你还没有账号请 注册新账号