/ 最近 .rdf 追記 編集 設定 本棚

脳log[20141016] gdipp_loader_32.exe



2014年10月16日 (木)

最終更新: 2014-10-17T00:06+0900

gdipp_loader_32.exe

以前書いた不満を解消するべく慣れないことをした。

gdipp_loader_32.exeが、引数として与えられたプロセスが終了するまで終了しなくなってる。WaitForSingleObject(pi.hProcess, INFINITE);してるんだから必要なことなんだろうけど残念。

gdipp_loader_32.exeは第一引数(任意の exeファイル名)のディレクトリをカレントにして exeを起動するけど、そのせいで exeに渡される二番目以降の引数が相対パスだったときにファイルを見つけられない。例えば

検索しもってちなみにたどり着いた手順。

  1. >SetEnv.Cmd
    >dumpbin /all /disasm gidpp_loader_32.exe
  2. 出力を読む。CreateProcessW関数は KERNEL32.DLLからインポートする関数として3番目に列挙されていて、KERNEL32.DLLの Import Address Tableの位置は 408000となっているので、408000,408004,408008,...の3番目(408008)を覚えておく。
  3. 出力を読む。コードは .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)に書き替えることにする。

  4. 書き替える範囲は 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で表示すると目当てのバイト列があったので書き替えた。

  5. 同じ要領で WaitForSingleObjectの呼び出しも 90(NOP)で塗り潰した。

すごく時間がかかった。『解析魔法少女美咲ちゃん』を参考にしようとしたが、丁度いいところで OllyDbg便利そうということしかわからなかった。済んでしまえばこの程度のことなのでバイナリエディタだけでなんとかしたいが、PEヘッダとインポート情報を読んでアドレスを変換するのが果てしなく面倒で、また、間違えやすい。アドレスもそこから読み取る値も同じバイト列だからか、すぐに区別がつかなくなる。

ちなみに 最初の検索ワードが「disasm」で次が「ディスアセンブラ」それから「逆アセンブラ」「Ordinal Hint」「インポートテーブル」「dumpbin」と変わっていった。並行して、eXeScopeを実行したり bcc55と VCの binディレクトリに dasm.exeみたいな名前(※ildasmからの類推)のファイルを探したりしていた。tdump.exe / dumpbin.exeがそうだとは気付かなかった。