質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

1555閲覧

DLLインジェクションがうまくいかない

katahiromz

総合スコア186

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

2クリップ

投稿2017/11/28 04:24

編集2017/11/28 11:46

こんにちは。

64ビットのWindows 10で、DLLインジェクションをしようとしています。
https://github.com/katahiromz/SimpleDLLInjection

CMakeLists.txtファイルがあるので、CMakeでビルドして下さい。

64ビットプログラムから64ビットアプリへのインジェクションは成功するのですが、
32ビットプログラムから32ビットアプリへのインジェクションが失敗します。

原因がわかりません。失敗したときの出力は以下の通りです。

text

1$ ./build/injector32.exe -e pictbear.exe 2dll_path: C:\Users\katahiromz\Documents\Dev\SimpleDLLInjection\build\payload32.dll 3LoadLibraryA failed: 0, 0 4DllInjectByPid failed 5failed

GetLastErrorの戻り値は、ゼロになりました。

ソースはこちらです。
https://github.com/katahiromz/SimpleDLLInjection/blob/master/payload/payload.cpp
https://github.com/katahiromz/SimpleDLLInjection/blob/master/injector/injector.cpp

この中に間違いがあると思われます。
よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yohhoy

2017/11/28 06:35

最低限、GetLastErrorで取得できるエラーコードを確認されてはいかがでしょう。
katahiromz

2017/11/28 06:40

32ビットのPictBearというプログラムに対して、コマンドプロンプトからinjectorを起動しましたが、前述のように失敗しました。
katahiromz

2017/11/28 06:56

エラーコードはゼロでした。
guest

回答2

0

ベストアンサー

私の環境では
・セキュリティ的には何も特別なことをやってない、自分が以前作成した32bitのEXEファイルを直接ダブルクリックで起動してターゲットにする
・MSYS2の32bit向けシェルからSimpleDLLInjectionをビルドしてinjector32.exeを実行する
でもインジェクション失敗しました。

仮説:
・payload32.dllが、特定のDLL(例えば、libgcc_s_dw2-1.dll)を必要としている
かつ
・pictbear.exeからはlibgcc_s_dw2-1.dllの場所がわからない
なので、「pictbear.exeからpayload32.dllをロードできない」ということなのでは。

実験:
・injector32.exeを実行する前に、同じシェルからpictbear.exeを実行しておく
ではどうでしょうか。
これでインジェクション成功するのであれば、仮説の信憑性が高まります。
私の環境では、これでインジェクション成功したように見えました。

libgcc_s_dw2-1.dllだけが問題だとすれば、
・payload32.dllがlibgcc_s_dw2-1.dllを必要としないようにする
または
・pictbear.exeからlibgcc_s_dw2-1.dllの場所がわかるようにする
が対策でしょうか。

ついでに。
今は全プロセスでkernel32.dllのアドレスが同じみたいだけど、将来的にも保証されているのかどうかが気になります。

投稿2017/11/30 13:21

okrt

総合スコア366

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

katahiromz

2017/12/01 11:54

回答ありがとうございます。 「injector32.exeを実行する前に、同じシェルからpictbear.exeを実行しておく ではどうでしょうか」 これは成功しました。現在、検証中です。
katahiromz

2017/12/01 12:03 編集

解決いたしました。やはりDLLの依存関係が問題でした。injectorが「libgcc_s_dw2-1.dll」に依存していたようです。 set(CMAKE_C_FLAGS "-static -static-libgcc -static-libstdc++") set(CMAKE_CXX_FLAGS "-static -static-libgcc -static-libstdc++")
okrt

2017/12/05 14:00

今更ですが、書き忘れていたことがあった(けど回答そのものではない)のでコメントを追加します。 確か、私の環境では最初の段階で ・MSYS2の32bit向けシェルからビルドしたtargetprog.exeをエクスプローラーから直接ダブルクリックすると「libgcc_s_dw2-1.dll が見つからないため、コードの実行を続行できません。」で実行できない ・MSYS2の32bit向けシェルからtargetprog.exeを実行することは可能 という現象があったので、 「targetprog.exeもpayload32.dllも共通する部分があるだろうなあ」ということから仮説や実験に繋がりました。 あとは、 Visual Studioのコマンドプロンプトが使えれば、そこから DUMPBIN /DEPENDENTS (パス)\payload32.dll MSYS2にBinutilsが入っているのであれば objdump -p (パス)/payload32.dll | grep -i dll または objdump -x (パス)/payload32.dll | grep -i dll (もっと適切な方法があるかもしれませんが、そこは広い心で見てやって下さい) で簡易調査。
guest

0

こちらではうまくいきました。
相手側プロセスでLoadLibraryAは実行されているのでしょうか?

こちらではWindbgを使用して以下のように実行されていることを確認できました。
引数の値はマスクしています。
とりあえずインジェクト先のプロセスにデバッガをアタッチして確認してみてください。

0:005> x KERNEL32!LoadLi* ~省略~ 0:005> x KERNELBASE!LoadLi* ~省略~ //とりえあえず両方ともブレークポイントを仕掛けておく 0:005> bp KERNELBASE!LoadLibraryA 0:005> bp KERNEL32!LoadLibraryAStub 0:005> g ---------------- ここで injector32.exe -e DF.exe ---------------- //ブレークした Breakpoint 1 hit eax=88ef99bc ebx=025e0000 ecx=75025980 edx=75025980 esi=75025980 edi=75025980 eip=75025980 esp=04beff84 ebp=04beff94 iopl=0 nv up ei pl zr na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246 KERNEL32!LoadLibraryAStub: 75025980 8bff mov edi,edi //引数を確認 0:005> kv # ChildEBP RetAddr Args to Child 00 04beff80 75028654 025e0000 75028630 88ef99bc KERNEL32!LoadLibraryAStub (FPO: [Non-Fpo]) 01 04beff94 77e24a47 025e0000 974d2a9c 00000000 KERNEL32!BaseThreadInitThunk+0x24 (FPO: [Non-Fpo]) 02 04beffdc 77e24a17 ffffffff 77e49ed8 00000000 ntdll!__RtlUserThreadStart+0x2f (FPO: [SEH]) 03 04beffec 00000000 75025980 025e0000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo]) //引数を表示。想定したものがセットされている 0:005> da 025e0000 025e0000 "C:\Users\XXXXXXXXXXXXXXXXXXXXXX" 025e0020 "XXXXXXXXXXXXXXXXX\SimpleDLLInje" 025e0040 "ction-master\build\Debug\payload" 025e0060 "32.dll"

もう少し簡単な方法を記載しておきます。
okrtさんの記載している仮説も調べられると思います。

Process Monitorというツールがあってこれを使用するとスレッド開始やDLLのロードの結果を調べられます。

Filterから
Process Name is PictBear.exe
をIncludeとして設定します。
フィルター
キャプチャを開始して、
injector32.exe -e PictBear.exe
とします。
そうすると以下のようにDLLのロードが実施され成功しているのかが分かります。
なお、私の環境ではPictBearでも成功しました。
ログ

投稿2017/11/28 13:06

編集2017/12/01 11:45
hmmm

総合スコア818

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

katahiromz

2017/11/28 13:43

LoadLibraryAStubなんて初めて見ました。どうやら、PictBear.exeにはDLL注入を妨害する機構があるようです。後でWinDbgを試してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問