binspect

http://shinh.skr.jp/dat_dir/binspect.tgz

ずっと放置するよりは…と思って出すことに。JVM Golf をやった時に作った、汎用バイナリフォーマット解析コマンド&ライブラリ、を作りたかったものです。 binareal 見て 1 年後にちょっと作ってみたものを 2 年してから出すというようなそういう。

% ./binspect.rb hello.gif hello.p

などとすると Ruby の pp で GIF をダンプしたものが出力されます。

[[:fileHdr, [[[:signature, "GIF"], [:version, "89a"]]]],
 [:logicalScreenDescriptor,
  [[[:width, 35],
    [:height, 100],
    [:packed, 128],
    [:bgcolor, 1],
    [:aspect_ratio, 0],
    [:globalColorTable,
     [[[:r, 0], [:g, 0], [:b, 0]], [[:r, 255], [:g, 255], [:b, 255]]]]]]],
 [:data,
  [[[:tag, 33],
    [:extension,
     [[[:label, 254],
       [:commentExtension,
        [[[:commentData,
           [[[:size, 45],
             [:data, "\n;BEGIN{print\"Hello, world!\\n\";exit}\n__END__\n"]],
            [[:size, 0], [:data, ""]]]]]]]]]]],
   [[:tag, 44],
    [:imageDescriptor,
     [[[:left, 0],
       [:top, 0],

こういうのがえんえんと出力される。 -y つければ YAML 。余談ですが YAML 書きやすいって言うけどこういうリストだけの構造は徹底的に書きにくいですね。 XML の方がマシなくらい。

出力されたものを

% ./binspect.rb hello.p hello2.gif

とかすれば元に戻ったりもします。ちゃんと戻るのは GIF だけですが。 pp のダンプの段階で適当にいじれば色々遊べるわけです。コード埋めたりとかですね。

プラグインは今のところ GIFBMP と ELF と class があります。 GIF 以外はヘッダ以外はダンプしないので、見るだけに使うか、ライブラリとして使って内容は自分で加える必要があります。まぁもともとそいう用途を想定してます。

プラグイは、例えば ELF のプログラムヘッダはこんな感じで書けます。

 class Phdr < Binformat
   int :type;
   int :offset;
   addr :vaddr;
   addr :paddr;
   int :filesz;
   int :memsz;
   int :flags;
   int :align;
 end

サイズ情報があってからそのサイズだけバイナリが入ってくる…とかいうフォーマットは多いのですが、そういうのはこんなかんじ。

 class PascalString < Binformat
   int :size
   byte :buf, :size
 end

サイズに計算結果を入れることもできます。

 class NullTerminatedPascalString < Binformat
   int :size
   byte :buf, proc {size + 1}
 end

タグによって union 的に型が変わったり、ターミネータがあるまで繰り返し…っていうようなものは、

class GIFData < Binformat
  byte :tag
  some {
    case tag
    when 0x2c
      struct GIFImageDescriptor, :imageDescriptor
    when 0x21
      struct GIFExtension, :extension
    when 0x3b
      struct GIFTrailer, :trailer
    else
      raise "Unknown separator: #{tag}"
    end
  }
end

class GIF < Binformat
  struct GIFFileHeader, :fileHdr
  struct GIFLogicalScreenDescriptor, :logicalScreenDescriptor

  repeat GIFData, :data, proc{|data|
    data.assoc(:tag)[1] == 0x3b
  }
end

とかそんな感じ。

ライブラリとして使うサンプルとしては、 bmp にコードを埋めてみた、下記みたいなものがあります。

require 'bmp'

fileHdr = [:fileHdr,
           [[
             [:type, "BM"],
             [:size, 35 + 256],
             [:reserved1, 0],
             [:reserved2, 0],
             [:offbytes, 160],
            ]]]

infoHdr = [:infoHdr,
           [[
             [:size, 40],
             [:width, 16],
             [:height, 16],
             [:planes, 1],
             [:bits, 4],
             [:compression, 0],
             [:sizeImage, 128],
             [:xPixPerMeter, 2834],
             [:yPixPerMeter, 2834],
             [:clrUsed, 2],
             [:clrImportant, 2],
            ]]]

palette = [:palette,
           [
            [[:r, 0], [:g, 0], [:b, 0], [:unused, 0]],
            [[:r, 255], [:g, 255], [:b, 255], [:unused, 0]],
           ]]

bmp = [fileHdr, infoHdr, palette]

bin = BMP.new.dump(bmp)

bin += %Q(
BEGIN{puts'Hello, world!';exit}
__END__
).ljust(98)

128.times{|i|
  bin << i
}
bin << 0
bin << 0
bin << 0

print bin

jsdmkun

http://shinh.skr.jp/jsdmkun/jsdmkun.html

V8 速いなぁもう canvasBulletML 動くんじゃね、と作ってみました。ううむプラグイン無しでも弾幕が普通に見られる時代に。 sdmkun 作ってた時は Pen 133MHz とかで、当時より速いんじゃないかなぁコレ。

適当に書いたけど Safari でもそれなりに動くなぁ… Firefox はちょっとつらい…

あとまぁ FPS カウンタがあからさまにおかしいとか、 accel が無いとか、速度が違うから想定通りに動いてない弾幕があるとか、 horizontal が無いとか、そもそも当たり判定がないとか、色々未実装です。

まぁそいうもげもげよりは、 BulletML をちゃんと JS にコンパイルしてから動作するようにしたいです。そのへんきっちりやれば Firefox でもまともにいける気がする。

JS しっかり書くのとかたぶん始めてなんですが、1000行程度書いてみた感じでは、まぁ割と書けるもんだなぁ的な。一番欲しいのは Ruby の sub(){} とか Perl の s///g とか。

sevilwm 0.9.7

またも id:mtkh さんにいただいた再起動時に window の位置を保存する機能を。ありがとうございます。

http://shinh.skr.jp/sevilwm/

WID わかるようになったついでに、 PID とかもわかるといいんですけど、なんか window の中で動いてるプロセス ID を適当に取得する方法とかなかったっけ…

sevilwm-0.9.5

http://shinh.skr.jp/sevilwm/

id:mtkh さんに再起動時に引数保持するパッチをいただいたので。ていうか 0.9.3 とかも全然アナウンスしてないみたいだ。 ignore を腐らせてたのを mtkh さんに教えていただいて修正したのが 0.9.3 で、 click focus 時のリサイズ時にフォーカス変わっちゃう問題を修正していただいたのを取り込んだのが 0.9.4 みたいだ。非常に助かってます。ありがとうございます。

sevilwm 0.9.2

http://shinh.skr.jp/sevilwm/

なんか ignores あたりに少しヘンなメモリ触ってるとかリークとかあったのでいじっておきました。ついでに ev_handler.c が構造体がうまいことパックされることを前提としてる感じだったので(まぁメンバ2つともポインタだしたぶん大丈夫だろうけど)、一応修正しておきました。

なにかあれば下記メールアドレスへ。
shinichiro.hamaji _at_ gmail.com
shinichiro.h