それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

RubyでWindowsのバイナリ文字列を読めるようにしたい

ruby でHexダンプの16進数を文字に戻したい。

バイナリの16進数文字列がWindowsのレジストリにあるので、コレを元に戻して、何が書いてあるのか見てみたい

hexダンプ文字列

16進数のバイナリのダンプを作る方法。

>> a="Ruby逆引きレシピ"
=> "Ruby\351\200\206\345\274\225\343\201\215\343\203\254\343\202\267\343\203\224"
>> a.unpack('H*')
=> ["52756279e98086e5bc95e3818de383ace382b7e38394"]

ここから16進数のダンプ配列を作ります

>> a.unpack('H*').pop.scan(/[0-9a-f]{2}/).join(",")
=> "52,75,62,79,e9,80,86,e5,bc,95,e3,81,8d,e3,83,ac,e3,82,b7,e3,83,94"

出来た。これで”, ”区切りのバイナリと同じモノが取り出せました

逆にバイトのダンプ文字列から文字を作ります

>> b= ["52756279e98086e5bc95e3818de383ace382b7e38394"].pack('H*')
=> "Ruby\351\200\206\345\274\225\343\201\215\343\203\254\343\202\267\343\203\224"
>> puts b
Ruby逆引きレシピ

packをunpackすればバイナリストリングから文字列を作れる

packテンプレートの解説

Hexダンプの16進数文字列を作る

>> "GTD".split(/ */).map{|c| format "%x", c[0]  }.join(' ')
=> "47,54,44"

ただし、これは 0 が00 にならなかったり

00 と 0 は16進数的には同じモノですが,HEXダンプの場合、バイト格納値を示すので、ちょっと問題

Windowsのレジストリにある日本語を取出す

ネットで見つけたレジストリのサンプルを日本語にする

>Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Landscape]
"Domain"="sonic64.com"
"description"=hex(7):a8,30,f3,30,b8,30,cb,30,a2,30,6e,30,e1,30,e2,30,02,30,d7,\
  30,ed,30,b0,30,e9,30,df,30,f3,30,b0,30,01,30,cd,30,c3,30,c8,30,ef,30,fc,30,\
  af,30,01,30,c7,30,fc,30,bf,30,d9,30,fc,30,b9,30,01,30,4c,00,69,00,6e,00,75,\
  00,78,00,01,30,75,00,6e,00,69,00,78,00,01,30,b2,30,fc,30,e0,30,01,30,f3,97,\
  7d,69,01,30,2c,67,01,30,99,65,06,74,01,30,ca,8e,01,30,5d,30,6e,30,d6,4e,e5,\
  65,38,5e,6e,30,e1,30,e2,30,6a,30,69,30,02,30,00,00,00,00
"title"="Landscape - エンジニアのメモ"
"link"="http://sonic64.com/"

description は「複数行文字列値」のためエンコードされている。ちなみに、description に指定した文字列は「エンジニアのメモ。プログラミング、ネットワーク、データベース、Linuxunix、ゲーム、音楽、本、料理、車、その他日常のメモなど。」という当サイト Landscape の説明

http://sonic64.com/2006-02-16.html

デコードしてみた

>>a="a8,30,f3,30,b8,30,cb,30,a2,30,6e,30,e1,30,e2,30,02,30,d7,30,ed,30,b0,30,e9,30,df,30,f3,30,b0,30,01,30,cd,30,c3,30,c8,30,ef,30,fc,30,af,30,01,30,c7,30,fc,30,bf,30,d9,30,fc,30,b9,30,01,30,4c,00,69,00,6e,00,75,00,78,00,01,30,75,00,6e,00,69,00,78,00,01,30,b2,30,fc,30,e0,30,01,30,f3,97,7d,69,01,30,2c,67,01,30,99,65,06,74,01,30,ca,8e,01,30,5d,30,6e,30,d6,4e,e5,65,38,5e,6e,30,e1,30,e2,30,6a,30,69,30,02,30,00,00,00,00"
>>str=a.delete(",").to_a.pack('H*') ##出来た
>> puts NKF.nkf("-w -W16L",str)
エンジニアのメモ。プログラミング、ネットワーク、データベース、Linux、unix、ゲーム、音楽、本、料理、車、その他日常のメモなど。

デコードして文字列になったよ

文字列はUTF16で文字列をバイトにして格納するっぽい

レジストリに入ってる文字列は,UTF-16 のLEだった