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

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

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

共收到 43 条回复

程序?数据?

这个我做过,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 好似我记得,如果结构体有嵌套,就是没用了

@hhuai 在看@skandhas 的cstruct

@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: skandhas@163.com

#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之类的函数

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