最終更新: 2014-10-17T00:06+0900
以前書いた不満を解消するべく慣れないことをした。
gdipp_loader_32.exeが、引数として与えられたプロセスが終了するまで終了しなくなってる。WaitForSingleObject(pi.hProcess, INFINITE);してるんだから必要なことなんだろうけど残念。
gdipp_loader_32.exeは第一引数(任意の exeファイル名)のディレクトリをカレントにして exeを起動するけど、そのせいで exeに渡される二番目以降の引数が相対パスだったときにファイルを見つけられない。例えば
検索しもってちなみにたどり着いた手順。
>SetEnv.Cmd >dumpbin /all /disasm gidpp_loader_32.exe
出力を読む。コードは .textセクションに含まれている。/disasmオプションを付けたのでニーモニックで読める。さっき覚えておいた 408008で検索すると次の行(だけ)がヒットした。
004010B3: FF 15 08 80 40 00 call dword ptr ds:[00408008h]
呼び出し規約の違いは知らないが、callにそなえて末尾の引数から順番に pushしてるぽいところから推測する。
CreateProcessW(argv[0], lpCmdLine, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, working_dir, &si, &pi);
004010B2: 52 push edx 00401094: 8D 8D F4 FD FF FF lea ecx,[ebp+FFFFFDF4h] 0040109A: 51 push ecx (これがきっと working_dirに違いない) 0040109B: 6A 00 push 0 (NULL) 0040109D: 6A 04 push 4 (たぶん CREATE_SUSPENDED) 0040109F: 6A 00 push 0 (FALSE) 004010A1: 6A 00 push 0 (NULL) 004010A3: 6A 00 push 0 (NULL)
51(push ecx)を 6A 00(push 0)に書き替えることはサイズが違ってできないので、その前の準備段階を含めた 8D 8D F4 FD FF FF 51(lea ecx,[ebp+FFFFFDF4h]; push ecx)を 90 90 90 90 90 6A 00(NOP;NOP;NOP;NOP;NOP; push 0)に書き替えることにする。
書き替える範囲は 00401094からの7バイトだが Stirlingで開いた gdipp_loader_32.exeにそんなアドレスはない。dumpbinが出力した .textセクションの情報を見る。
68EA virtual size 1000 virtual address (00401000 to 004078E9) 6A00 size of raw data 400 file pointer to raw data (00000400 to 00006DFF)
virtual sizeと size of raw dataの微妙な違いが気になるが、00401094-00401000+00000400 = 494のアドレスを Stirlingで表示すると目当てのバイト列があったので書き替えた。
すごく時間がかかった。『解析魔法少女美咲ちゃん』を参考にしようとしたが、丁度いいところで OllyDbg便利そうということしかわからなかった。済んでしまえばこの程度のことなのでバイナリエディタだけでなんとかしたいが、PEヘッダとインポート情報を読んでアドレスを変換するのが果てしなく面倒で、また、間違えやすい。アドレスもそこから読み取る値も同じバイト列だからか、すぐに区別がつかなくなる。
ちなみに 最初の検索ワードが「disasm」で次が「ディスアセンブラ」それから「逆アセンブラ」「Ordinal Hint」「インポートテーブル」「dumpbin」と変わっていった。並行して、eXeScopeを実行したり bcc55と VCの binディレクトリに dasm.exeみたいな名前(※ildasmからの類推)のファイルを探したりしていた。tdump.exe / dumpbin.exeがそうだとは気付かなかった。
最終更新: 2015-01-12T01:26+0900
ifが値を返さないとか条件演算子がないとか*、エラーを nilと比較することはできるけど || や && のオペランドにはならないとか⁑、配列の最後の要素の後ろにカンマを置かずに改行するとカンマがないって理由でコンパイルエラーになるとか⁂、ああ、この独善的融通の利かなさ、Rubyではないな googleだから Pythonがこうなのか?という感想。
ベースは /shjs/lang/sh_javascript.js。
ミクロな感想
>go get "github.com/..."
に失敗した。手コピインストール……ただのデータファイルなので言語の勉強にはならないよね……。フレイバーの違いライブラリの違いに足を取られるのがわずらわしいしもどかしい。CLRと MSIL?
* つまり、if (cond) return A else return B みたいな冗長性(returnの繰り返し)と無駄な構造化を強制されるわけ。
⁑ 何かを true/falseと比較することはもちろん nullと比較することもまずしたことがない。そうする理由は、trueが falseではないすべての値であったりする Cのことや、null(それと NaN)は nullであること/ないことをテストすることはできても二つの nullが同じものであることがありえない SQLのことが念頭にあるからだ。そして、Goだからこういう書き方で OKなんだというような考え方はしない(http://vvvvvv.sakura.ne.jp/ds14050/diary/20140815.html)。信じられない仕様を強制するもんだ。
⁂ なぜ余計な物を強制されるのか。ケツカンマは便利だからと許容されているもの(だが俺は嫌いだ)であって、強制するというならそれは削除させる方向に向かうべきものだ。
参考 [[サクラエディタふぁんくらぶ part14|http://anago.2ch.net/test/read.cgi/software/1294526851/656-663]]
[...]*3
について、プレースホルダを %1$s
にすれば 1つの引数を使い回せるのに。