Derive Your Dreams

23:41 06/11/30

べくたー

GreenPad - 新着ソフトレビュー だそうです。 ソフト作者からひとこと、という欄を書きました。 今時のエディタなら GreenPad でできてる程度の多言語混在はできるんじゃないかと思うので、 ポイントというほどポイントかなーとかちょっと思ってしまったりもしつつ。

ひとことに書いたように、あれは 「既存のエディタコンポーネントを一切使わずに『テキストエディタ』を作るのって、 どうやるんだろう?」 が自分的には全てですね。作ってて、エディタの作り方という よりは、"この機能のこの実装って実は死ぬほど重くない?だいじょぶ?でも あとはこれを定数倍のチューニングするしか思いつかないんだけど" と行き詰まったときは 大抵その実装で十分うまく回るのでどんどん作っちゃえばOK、ということを経験的に 学びました。特に車輪の再実装をしてる時は。今の自分ならならもっと小賢しく計算量を 見積もっちゃったりするんですけど、なんというか、その辺の感覚が、こう。

紅白

德  永  英  明 (初)

ktkr!! なに歌うんだろう?

20:07 06/11/29

マンガマンガ

「VC++8でビルドしたアプリはWin95だと動かないよ」 → 「CRTがIsDebuggerPresent APIを呼ばないようにすればいいらしいよ」 → 「Express Edition に CRT のソースついてない!!」 という流れで .NET 2003 再インストールしてました。 頑張ればなんとでもなりそうな気もするのですけどめんどい。

西田メソッド - 2006/11 14 tue. でお勧めされた『イキガミ』 をついに買ってしまいました。ひねくれた言い方をすると、1000人に1人は、自分が死ぬ24時間 前にそのことがわかるようになった仮想の世界の話…と。24時間後に死ぬことがわかった人は どう生きてどう最期を迎えるか。自分だったらどうするかなあと考えると、ここを 適当に30回くらい更新して終わりそうです。この先ひたすらいい話を並べるだけでは 終われないテーマだと思うけれど、どうなるのかな。気になります。

死亡フラグつながりと思ってカウンターでおすすめ返したはずの 『未来日記』 もつい買っちゃいました。イキガミが "生活維持省" とすれば、こちらは "湖で" でしょうか。今色々な意味で間違った気がしますが。 こういう、親切・丁寧・狂気がモットーですという雰囲気と、徹底的にB級たらんとした感じの 勢いは嫌いでないのです。

22:20 06/11/27

マンガ

池袋に用事があったついでにジュンク堂によったら、 『not simple』 完全版が売られてたので即購入。一月前くらいに出ていたらしい…不覚。 最初にこの作品を知ったときも、そういえば同じ場所でした。

改めて考えると、ストーリーももちろんだけれど、やっぱり絵が好きなのかなあ、とも 思えます。この独特なタッチの絵が漫画として見事に"動"いていて、Amazonのレビューにも 幾つかあるように、それが、この絵じゃないと違う話になる、と思えるくらいの効果を 上げているのが印象的です。

00:31 06/11/24

Binary Hacks

Binary Hacks』、読んだら感想書こうと 思ってたのでした。

思ったより、思ったよりとかいうと失礼かもしれないんですけど、 実際に役に立ちそうな知識が手に入った、という印象です。 そもそもそっち方面の基本的なツール等全然知らない状態で読み始めたので、 addr2line やら statifier やら、うおーこれ便利!と思いながら読んでました。 あと、gccでCの関数の間をC++の例外で抜けようとするときは気をつけなきゃいかんとか、 知りませんでした。昔知らずにこれでハマったことがあるような気がする…。 こういう話題が一カ所にまとまってる本、ていうのは貴重ですね。楽しめました。

わりと Linux 寄りなので、普段 Windows 使いな人としては、つい Windows版Hacks などを妄想してしまう。

  1. Image Help Library で PE ファイルの情報を表示する
  2. 共有ライブラリ関数の呼び出しを実行時にフックする
  3. Cygwin の fork() の実装を理解する
  4. Win32 構造化例外入門
  5. C言語でCOMクライアントを作る
  6. CreateRemoteThread で実行中のプロセスにコードを注入・実行する
  7. walign でプログラムを高速化する (ちょい話題が古いか)
  8. ...

みたいな。ちなみに先日晒してみた BlueWoW では #6 と #2 が役に立ちました。

18:10 06/11/19

おー

おめでとーございます!

The last name

DEATH NOTE の映画 を見てきました。アリかアリかで言えばアリでした。かなり面白かったです。 原作のいろんな要素をひっくるめてうまいこと "最後まで" 話をおさめてるのも 楽しかったし、"最後" も、なるほどこう解決したかーと、わりと 納得させられてしまいました。

続 PE Golf

先日のPE Golfについて文脈がわからんと突っ込まれたので説明すると、 「Linuxの標準的な実行バイナリ形式であるELFで、 極限まで小さい "Hello, world!" プログラムを作る」 という大変頭のおkすばらしい挑戦をされている かた がた の様子をみて、 Windowsの実行バイナリ形式であるPEでもしてみんとてするなり。

[MZ]........................................................
............................................................
............................................................
.............................................[PE Header Loc]
............... executable code ............................
............................................................
[PE\0\0]....................................................
........[SectionTable Offset]...............................
.............................[EntryPointAddr]...............
............................................................
............................................................
............................................................
............................................................
.............................................[Subsystem]....
............................................................
(中略)
[SectionTable] × Section の個数
以下、.text とか .data とか 各セクションが続く

PE形式の概要。とりあえず頭に、まるまる1個DOS用の実行バイナリが入ります。 DOSで実行すると "これはWindows用だからWindowsで動かしてね!!" と メッセージ出してすぐ終了するのが普通。互換性互換性。

Windowsから動かすときは、先頭が"MZ"になってることのチェックを除いて、 DOS部分は基本的にさっくり無視されます。ただし、0x3C .. 0x3F バイト目に "PEヘッダ" の Offset が入ることになっているので、そこだけ注意。

DOSの実行ファイルの後ろに、やっと、Windows実行形式としての情報を色々格納した 「PEヘッダ」が現れます。その後ろに、.textや.dataや.bssなどなど、各種セクションの 情報を入れた「Section Table」が来ます。んで、その後ろにセクションの中身の データが続きます。

PEヘッダは4バイト境界からスタートしている必要があって、 PEヘッダの93バイト目の「サブシステム番号」には 0 でない特定の値を入れないと いけません。なので、97バイトがPE形式で実現できる最小値とされているらしいです。

Hello, World

DWORD tmp;
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "Hello, world!\n", 14, &tmp, NULL);

が一番短いんじゃないかと思っています。WriteFile と GetStdHandle は Kernel32.dll の API で、これは同じ環境ではすべてのプロセスで同じアドレスに ロードされてるはずなので、import table を使わずに直接callするとimport情報を 実行ファイルに入れなくてよくなっていい感じです。ただし移植性は全然ないです。 誰かインポート情報つきのHelloWorld作ってください。

あと、引数として即値をpushするよりレジスタをpushした方がx86のマシン語としては 短くなります。で、WinNT系列では、起動時に eax=0, ebx=PEBのアドレス となってるらしいので、これを利用したりしました。

まとめる

PEヘッダには何も入れても実行にはあまり関係ないゾーンが多数あるので、 Hello World の実行コードはその辺に適当に埋めていけば収まってしまいました。 "Hello, world!" という文字列データを埋めるのはあきらめてしまったので、 現状、109 バイトです。

; yasm -f bin -o hello.exe helloPE.asm

BITS 32
ORG  0
GetStdHandle equ 0x7D4EFBC2 ; Varies depending on environments
WriteFile    equ 0x7D4EAAE9 ; Varies depending on environments
ImageBase    equ 0x00400000

	dw "MZ"
hello:	db "Hello, world!", 10
pe_hdr:	db "PE", 0, 0	; Signature
	dw 0x014C		; CPU: i386
	dw 1		; Number of Sections
code1:	  push eax
	  push ebx
	  push -11
	  call GetStdHandle - (ImageBase + 5 + 0x1C)
	  jmp  code2
	db 0
	dw sectbl-($+4)	; Offset for SectionTable
	dw 0x0103		; Characteristics: RELOCS_STRIPPED|EXECUTABLE|32BIT
	dw 0x010B		; Magic
code2:	  push 14
	  push ImageBase+hello
	  push eax
	  call WriteFile - (ImageBase + 5 + 0x32)
	  ret
	dd code1		; EntryPoint
	dd pe_hdr
	dd 0
	dd ImageBase	; ImageBase Address
sectbl:	dd 0x1000		; Section Alignment   ; Section Name(1)
	dd 0x0200		; File Alignment      ;             (2)
	dd 0		                      ; Virtual Size
	dd 0x1000		                      ; Relative Virtual Address
	dw 4		; Subsys Major Ver    ; Physical Size
	dw 0		                      ; Physical Offset
	dd 0		                      ;
	dd 0x2000		; Size Of Image       ;
	dd 0x0200		; Size Of Headers     ;
	dd 0		                      ; Section Flags
	db 3		; Subsystem:console

Section Table はヘッダに適当に重ねてあります。

Future Work

17:32 06/11/17

PE Golf

標準出力に "Hello, world!"。挑戦してみたのですけど、 Tiny PE を参考にしただけっちゅーか、参考にすらしきれていない感じです。 セクションの整列境界を512バイトより下げる方法が、どうも動かない。

4D 5A 48 65 6C 6C 6F 2C 20 77 6F 72 6C 64 21 00     MZHello, world!\0
6A F5 B8 C2 FB 4E 7D FF D0 6A 00 6A 00 6A 0D 68
02 00 40 00 50 B9 E9 AA 4E 7D FF D1 C3 00 00 00     (*)
50 45 00 00 4C 01 01 00 35 44 5D 45 30 00 00 00     PE\0\0...
00 00 00 00 00 00 03 01 0B 01 08 00 00 00 00 00
00 00 00 00 00 10 00 00 10 00 00 00 00 00 00 00
00 20 00 00 00 00 40 00 00 10 00 00 00 02 00 00
04 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00
00 20 00 00 00 02 00 00 00 00 00 00 03              03=/subsystem:console

*) WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "Hello, world!", 13, 0, 0);

Kernel32.dll の API は固定アドレスで叩けるはずなので、と適当に。 お手元の環境に合わせて C2 FB 4E 7D を &GetStdHandle の値、 E9 AA 4E 7D を &WriteFile の値に修正しないと動かんかもです。 しかしコードも Hello, world もヘッダに埋め込める気がしないんですが...。

参考にしたもの: Tiny PEELF Golfid:firewoodさん。

追記: nasm で書いた。こう見るとまだスカスカかなあ。

01:29 06/11/16

gcc4 と TR1

ICPC 方面でBoostの話を振られるたびについこの話をしてしまっている気がするので、 なんとなくメモってみる。

前回から gcc のバージョン は 4 となっていて、で、gcc4 には最初から次期C++標準ライブラリの TR1 の一部が実装されています。役に立つ場面が実際あるかどうかはともかく、 使うと面白いんじゃないかなーと無責任に思っているので、軽くご紹介をば。 今のところ使えるのは以下の通り。あ、名前空間は全部 std::tr1 です。

#include <tr1/unordered_set>
#include <tr1/unordered_map>
using namespace std::tr1;

  ...
  unordered_set<int, char> m;
  m[100] = 'A';
  m[200] = 'B';

ハッシュベースの unordered_(map|multimap|set|multiset)。 基本型かstd::stringをキーにする場合はhash関数も同時に提供されているので、 普通のmap等を使うのとまったく同じ気分で使えます。木構造ベースのmapでは駄目で ハッシュがどうしても必要…という場面はなかなかないので、出番は少なめかもしれません。

#include <tr1/functional>
using namespace std::tr1;
using namespace std::tr1::placeholders;

...
int gcd(int x, int y) { while(x){y%=x; swap(x,y);} return y; }

  function<int(int)> f = bind(&gcd, _1, 100);
    // f は、第一引数と100の最大公約数を返す関数オブジェクト
  assert( f(12) == 4 );

ほぼ Boost の function, bind, mem_fn, ref です。汎用の関数オブジェクト型と、 関数の部分適用。コーディングスタイルにもよると思いますが、 標準アルゴリズムを思いっきり活用したい人には少なくともbindは必須です(断言)。 アルゴリズムに渡す関数オブジェクトのための構造体のコンストラクタを長々と書いてて むなしくなった経験のある方はぜひぜひ。

#include <tr1/memory>

サンプル書くのが面倒になってきました。 おおむね Boost の shared_ptr と weak_ptr です。参照カウンタつきポインタです。ツリーやDAGのリンクを 激しく付け替えるような課題は ICPC だとあんまり見ませんが、Javaと違ってガベコレの ないC++に、出題側が配慮してしまっているのではないかという気がちょっとしています。 だとすると面白くないので、shared_ptr が入ったことで何か変わらないかなーとか 思っています。

#include <tr1/tuple>
#include <tr1/utility>
#include <tr1/array>
#include <tr1/type_traits>

tuple<int,char,double> tup( 12, '3', 4.5 );

わりと Boost の tuplearraytype_traits っぽい感じです。詳細略。 CVS版だと、さらに <tr1/random> まで実装が完了しているそうで、 つまり要するにメルセンヌツイスターで乱数が作れたり、正規分布などなど分布を指定したり できます。

22:16 06/11/14

Binary Hacks

Binary Hacks』 が Amazon から届きました。わーい。明日読みます。 ちなみに バイナリアン度チェック は60点でした。わからなかった問題は 3, 7, 8, 11, 13, 14 で、 POSIX とか Linux とか興味ないしーなどと苦しい言い訳をしている今日この頃なのですが、 特に 13 あたりは言い訳のしようもございません。SjLj ってなんだったけとか、ダメダメです。 本読んで修行しますー。

00:50 06/11/10

GreenPad 1.07

やっと Visual C++ を入れ直したので GreenPadバグ修正です。指摘いただいたり自分で見つけたりしてから1年近く放置していた色々を 一応片付けた気になっています。けど、何か忘れているかも。あとはYz1.dllとNoahとcaldixを 何とかしなくてはいけないらしい。

それと、掲示板の方には書いてないですが、最近の windres が日本語リソースを 通せることを知ったので、他のリソースコンパイラなしの MinGW だけ環境でも 一応ビルドできるようにしときました。

22:16 06/11/06

IE7

グループポリシーで検索ボックスは消せるようです (情報元)。 ばんざい。

ICPC

結果は相変わらず上海つえー!!ですね。 横で見てると、楽しそうすぎて羨ましいなあ、っというか。 この手のチーム戦の短時間勝負コンテスト、年齢制限なしで誰か開いてくれませんか。 今年の問題も結構面白いのが多くて、E, F, I 辺り問題自体はシンプルなんですけど、 全然解き方思いつかんかったです。 すぐに公開されると思いますので、皆様ぜひぜひ挑戦を。 (追記: 問題が公開されました!)

18:16 06/11/03

Internet Explorer 7

IE7 正式版が出たらしいので入れてみました。メニューバーなしの画面デザインが標準 ってことで、それはコンパクトで素晴らしい、と思ってたんですが、結論として 他のところがコンパクトじゃなさすぎる。

アドレスバーの横に検索ボックスが置かれるようになってまして、まずこれの消し方が わからない…。Google以外でブラウザのUIから直接使いたいような検索エンジンは無いので、 Googleツールバー(普通の検索)と、アドレスバーに直打ち(Feeling Lucky)さえあれば 事足りてるので余計なものは要らんのですが…。逆に Google ツールバーの方を消す、という 案は却下でして、[Internet] [Explorer] [7] ていうボタンでページ内検索できるのが いいところなので、これを外すわけにはいかない。

あと、最下段の左の2つのボタン「お気に入りセンター」と「お気に入りに追加」ですが、 これも消し方がわからない。一番左のは使うからいいんですけど、「追加」は Ctrl+D しか 使わないから要らないのだけど。うむむ。

さらにアドレスバーが一番上、標準のツールバー(コマンドバー)が一番下、 間にカスタムでツールバー、という順番は固定で動かせないっぽい。消すこともできなそう。 アドレスバーはおそらくフィッシング対策で、絶対意地でも最上段に張り付かせると決めた んでしょうから、仕方ないのかもしれませんが…。しかし自分には関係ないですが、 「メニューバーはやっぱり欲しい」と思ったときにメニューバーを最上段にできないのは 微妙じゃないかなあ。

コマンドバーが最下段固定なのは、タブバーも兼ねているから表示領域と離せなくなっちゃった という理由ぽいですね。タブはタブで独立させればいいのに。

んで、まあ、アドレスバーが一番上、コマンドバーが一番下で動かせないのは 百歩ゆずって認めるとしても、その最上段or最下段に他のツールバーを並べることが できないのが許し難い。つまりその、

こうコマンドバーの横にGoogleツールバー置きたいじゃないですか。 このスクリーンショットはここに載せるためにだいぶ縮めて撮ったのでキツキツに 見えますけど、実際は十分に二つ収まるサイズで使うので。これができないっぽい。 最下段はコマンドバー"しか"置けなくなっている。IE6 だと3列だったのを、 メニューバーが消えて2列にできる!と思ったけど無理なんでしょうか。うむむむ。

…という愚痴でした。

「いやいやそれはこうすればできるよ!」 みたいな突っ込みお待ちしております。 そもそも素IE使い自体、あんまりいなそうですが…。

ACM/ICPC

明日から 横浜大会 だそうで。観戦お手伝いに行ってきます。 参加者の方がんばって下さい。

00:04 06/11/03

D言語

Variadic Templates ってまたデカい機能追加がサクッと来ましたね。 色々遊べそうです。

void print()() {}
void print(T, A...)(T t, A a) { writefln(t); print(a); }

これができるなら

template List() {}
template List(T, A...) {
	alias T        car;
	alias List!(A) cdr;
}

alias List!(int, char[], double, ireal) t;
t.cdr.car x;

これもできるかな、と思って試してみたら Assertion failure でコンパイラが 落ちました。むぅ。

今のところtupleを明示的な型として入れるつもりはないとWalter氏はおっしゃってますが、結局 Boost.Fusion 相当のものを 言語レベルで導入してしまった方がかえって簡単なんじゃないかという気も。 値タプルだけじゃなくて、型タプルの上をforeachで回りたいです。 C++のVariadic Templates も試してみないとなあ。

03:24 06/11/02

『時をかける少女』のテーマソングを聴いた日に、それまではTEPCOひかりの人っていう 認識だけだった奥華子の歌が好きになったので、Amazonのウィッシュリストに 『やさしい花の咲く場所』 を放り込んでおきました。で、先日いろいろ買ったついでに購入。そういえばAmazon、 いつからか買った商品がウィッシュリストから消えてくれるようになって便利です。

正直、どれも似たような歌が並んでるかな…という感想を持ってしまったのは否めない のですが、こういうのが嫌いでないことも否めないので万事OK。 ひとつ目立って好きなのが、3曲目の "月のそばで眠りたい"。 時折出てくる「あ」の音からはじまる歌詞が、「Ah...」に混じって不意打ち的に来るのが なんだか印象的。

Java Puzzlers

なんかホントに色々買ったんですが、他には 『Java Puzzlers』 など。 あろはさんとこで名著と言っておきながら実は自分は立ち読みしたっきりだったので、ちゃんとじっくり 読んでおかねば、と思いまして。 名前のシャドウイング関連のパズルがいまだに難しすぎて面白いです。

「このJavaコードはどう動くでしょう?」というパズルがひたすら続く本です。 本当にうっかり書いてしまいそうな間違いを題材にした役に立つパズルもあり、 「どーなるか知らんがどうみてもヤバいそんなコード書かないよ!」なコードを 実際どう動くかちょっと考えてみようか的なマゾいパズルもあり。特に後者が楽しいわけですが。 この本のいい所は、「だからこういうコードは書かないようにしましょう」で 終わるのではなくて、「そういうコードを書かせないようにするために、言語/API設計者は どうすべきだったか?」を毎回提示して締めているところですね。

presented by k.inaba (kiki .a.t. kmonos.net) under CC0