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

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

新規登録して質問してみよう
ただいま回答率
85.35%
Win32 API

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

C++

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

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

1回答

1768閲覧

Ntdll.dllに存在するNtUnmapViewOfSectionのフックを行い,NtUnmapViewOfSectionを行ったプロセスの特定を行いたいです.

sitsumon_jirou

総合スコア5

Win32 API

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

C++

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

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

2クリップ

投稿2020/10/08 08:17

編集2020/11/11 03:19

#実現したいこと
Ntdll.dllに存在するAPI「NtUnmapViewOfSection」のフックを行い,NtUnmapViewOfSectionを呼び出したプロセスを特定しようとしています.
notepad.exeをJavaコードをかけない体に改造するを参考にしています.
自分の以前の質問と似たような質問ですが,変更点,エラー内容が違っているので回答お願いします.
#悩んでいること
1.rewriteファンクション内でNtdll.dllの参照を行うが参照できず「アプリケーションが正しく動作しませんでした」と表示される.他のdll(kernel32.dllなど)では参照,フックを行うときにそのようなエラーは出なかった.アドレスの問題と推測しているが不明.
2.GetModuleFileName(GetModuleHandle(NULL), fileNameBuf, MAX_PATH) > 0)でAPIを呼び出したプロセスを特定できるのか?
HookedNtUnmapViewOfSection()内でOutputDebugString(fileNameBuf);としているがこれで正しいのかわからない.

コード

自作dll(WaruiDll)の作成部分とdllファイルばらまき部分に分かれています.
##自作dllファイルの作成
dllmainでdllファイルのエントリポイントの作成とrewriteファンクションの呼び出しを行います.
このコードによって作成されるdllファイルはプロセスがアタッチされたときに実行されます.
rewriteファンクションはrewrite.cppの中で定義されています.

dllmain

1// dllmain.cpp : DLL アプリケーションのエントリ ポイントを定義します。 2#include "stdafx.h" 3#include "rewrite.h" 4#include <windows.h> 5#include <stdio.h> 6 7fp_NtUnmapViewOfSection NtUnmapViewOfSectionPtr = NULL; 8TCHAR fileNameBuf[MAX_PATH]=("not complete"); 9 10NTSTATUS 11WINAPI 12HookedNtUnmapViewOfSection( 13 HANDLE ProcessHandle, 14 PVOID BaseAddress 15) 16{ 17 OutputDebugString(fileNameBuf); 18 OutputDebugString(TEXT("HookedNtUnmapViewOfSection!\n")); 19 return NtUnmapViewOfSectionPtr(ProcessHandle,BaseAddress); 20} 21 22 23void APIHook() { 24 if (GetModuleFileName(GetModuleHandle(NULL), fileNameBuf, MAX_PATH) > 0) { 25 NtUnmapViewOfSectionPtr = (fp_NtUnmapViewOfSection)RewriteFunction("Ntdll.dll", "NtUnmapViewOfSection", HookedNtUnmapViewOfSection); 26 } 27} 28 29BOOL APIENTRY DllMain( HMODULE hModule, 30 DWORD dwReason, 31 LPVOID lpReserved 32 ) 33{ 34 if (dwReason == DLL_PROCESS_ATTACH) 35 { 36 DisableThreadLibraryCalls(hModule); 37 APIHook(); 38 } 39 return TRUE; 40}

rewriteの中でrewriteファンクションを定義しています.
rewriteファンクションでは,第一引数にフックを行いたいAPIが含まれるdllファイル名,第二引数にフックを行いたいAPI名,第三引数にフックを行った時の挙動を記したファンクションのポインタを渡します.
dllファイルのハンドルを求め,NULLチェックをしたのちに,dllファイル内を全探索して第二引数のAPI名を探し,見つかったら第三引数のファンクションに置き換える.

rewrite

1#include "stdafx.h" 2#include <stdlib.h> 3#include <imagehlp.h> 4#include "rewrite.h" 5#pragma comment(lib,"imagehlp.lib") 6 7void* RewriteFunctionImp(const char* szRewriteModuleName, const char* szRewriteFunctionName, void* pRewriteFunctionPointer) 8{ 9 for (int i = 0; i < 2; i++) { 10 // ベースアドレス 11 intptr_t pBase = 0; 12 if (i == 0) { 13 if (szRewriteModuleName) { 14 pBase = (intptr_t)::GetModuleHandleA(szRewriteModuleName); 15 } 16 } 17 else if (i == 1) { 18 pBase = (intptr_t)GetModuleHandle(NULL); 19 } 20 if (!pBase)continue; 21 22 // イメージ列挙 23 ULONG ulSize; 24 PIMAGE_IMPORT_DESCRIPTOR pImgDesc = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData((HMODULE)pBase, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize); 25 for (; pImgDesc->Name; pImgDesc++) { 26 const char* szModuleName = (char*)(intptr_t)(pBase + pImgDesc->Name); 27 // THUNK情報 28 PIMAGE_THUNK_DATA pFirstThunk = (PIMAGE_THUNK_DATA)(intptr_t)(pBase + pImgDesc->FirstThunk); 29 PIMAGE_THUNK_DATA pOrgFirstThunk = (PIMAGE_THUNK_DATA)(intptr_t)(pBase + pImgDesc->OriginalFirstThunk); 30 // 関数列挙 31 32 for (; pFirstThunk->u1.Function; pFirstThunk++, pOrgFirstThunk++) { 33 if (IMAGE_SNAP_BY_ORDINAL(pOrgFirstThunk->u1.Ordinal))continue; 34 PIMAGE_IMPORT_BY_NAME pImportName = (PIMAGE_IMPORT_BY_NAME)(intptr_t)(pBase + (intptr_t)pOrgFirstThunk->u1.AddressOfData); 35 if (!szRewriteFunctionName) { 36 // 表示のみ 37 printf("Module:%s Hint:%d, Name:%s\n", szModuleName, pImportName->Hint, pImportName->Name); 38 } 39 else { 40 // 書き換え判定 41 if (stricmp((const char*)pImportName->Name, szRewriteFunctionName) != 0)continue; 42 43 // 保護状態変更 44 DWORD dwOldProtect; 45 if (!VirtualProtect(&pFirstThunk->u1.Function, sizeof(pFirstThunk->u1.Function), PAGE_READWRITE, &dwOldProtect)) 46 return NULL; // エラー 47 //OutputDebugString(pImportName->Name); 48 // 書き換え 49 void* pOrgFunc = (void*)(intptr_t)pFirstThunk->u1.Function; // 元のアドレスを保存しておく 50 WriteProcessMemory(GetCurrentProcess(), &pFirstThunk->u1.Function, &pRewriteFunctionPointer, sizeof(pFirstThunk->u1.Function), NULL); 51 pFirstThunk->u1.Function = (intptr_t)pRewriteFunctionPointer; 52 53 // 保護状態戻し 54 VirtualProtect(&pFirstThunk->u1.Function, sizeof(pFirstThunk->u1.Function), dwOldProtect, &dwOldProtect); 55 return pOrgFunc; // 元のアドレスを返す 56 } 57 } 58 } 59 } 60 return NULL; 61} 62 63void* RewriteFunction(const char* szRewriteModuleName, const char* szRewriteFunctionName, void* pRewriteFunctionPointer) 64{ 65 //OutputDebugString(TEXT("Rewrite1!\n")); 66 return RewriteFunctionImp(szRewriteModuleName, szRewriteFunctionName, pRewriteFunctionPointer); 67}

Inject()の中でSetWindowsHookEx()を呼び出す.

WaruiDll

1#include "stdafx.h" 2 3LRESULT WINAPI HookProc(int code, WPARAM wParam, LPARAM lParam) { 4 return NULL; 5} 6 7void Inject() { 8 //OutputDebugString(TEXT("Inject!\n")); 9 SetWindowsHookEx(WH_CALLWNDPROC, HookProc, GetModuleHandle(__TEXT("WaruiDll")), 0); 10}

#dllばらまき部分
メインの中で自作したdllファイルをばらまくInject()を呼び出す.

main

1#include "stdafx.h" 2 3int main() 4{ 5 Inject(); 6 printf("I am WaruiApp!\n"); 7 getchar(); 8 return 0; 9} 10

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

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

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

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

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

guest

回答1

0

ベストアンサー

まず、Native API の Hook に SetWindowsHookEx は無意味です。
なぜなら、DLL Injection の対象が GUI アプリに限定されてしまうから。
NtUnmapViewOfSection() は CUI (コンソール) アプリでも利用可能なので、SetWindowsHookEx では対応できません。

不特定のプロセスに対して NtUnmapViewOfSection() をフックしたいのであれば、まずプロセスの Create / Terminate を監視する機能が必要です。
プロセスの Create / Terminate を監視は色々と方法がありますが、一番ベストな方法はカーネル モード ドライバを作成し、その中で PsSetCreateProcessNotifyRoutine (あるいは PsSetCreateProcessNotifyRoutineEx) で新規プロセス生成を監視する実装です。

PsSetCreateProcessNotifyRoutineEx
https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-pssetcreateprocessnotifyroutineex

ただしカーネル モード ドライバは、ユーザ モード側で動作する一般的なアプリやサービスとは全く異なる知識が必要になるので、それなりに難易度は高いです。
それ以外としては、EnumProcessModules() で定期的にプロセスの増減を監視する方法もありますが、CPU リソースを無駄に消費するのでパフォーマンス的に難があり、かつ一部のサービス プロセスに対しては検出することができないという制限もあります。

で、とにかくプロセスの Create / Terminate を監視する機能が実現出来たら、OpenProcess(), VirtualAllocEx(), WriteProcessMemory(), CreateRemoteThreadEx() の各API を組み合わせて、外部プロセスから対象 DLL を Injection します。

LoadLibrary,CreateRemoteThreadを使ったDLL Injectionをやってみる
https://snoozy.hatenablog.com/entry/2019/12/22/195234

DLL Injection に成功したら、その DLL 内から Hook Routine を仕掛けます。
質問に提示されているコードは PEHeader 内の IAT 書き換えによる実装方法ですが、これも意味がないです。
対象プロセス内に、GetProcAddress() により自前で NtUnmapViewOfSection() ルーチン アドレスを取得しているモジュールが存在する場合、IAT に NtUnmapViewOfSection() ルーチン アドレスは存在しないので、Catch することもできません。
(さらに言えば、IAT による Hook では、そのプロセス内にロードされているすべてのモジュールの PEHeaser をチェックする必要があるので、とても面倒なのに上記のような「落ち」がある。)
漏れなく監視したいのであれば、NtUnmapViewOfSection() ルーチンの prologue code を改ざんする必要があります。
(お手軽に実現したいなら "Detours" がお勧め。)

メモリパッチによるAPIフックコードの実装をやってみる
https://snoozy.hatenablog.com/entry/2020/02/29/093033

投稿2020/10/28 08:47

Bego

総合スコア69

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

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

sitsumon_jirou

2020/11/02 07:00

回答ありがとうございます. さらに質問なのですが,DetoursなどメモリパッチによるAPIフックであってもIAT書き換えのようにすべてのモジュールを把握する必要がありますよね?
Bego

2020/11/02 07:16

> さらに質問なのですが,DetoursなどメモリパッチによるAPIフックであっても > IAT書き換えのようにすべてのモジュールを把握する必要がありますよね? いえ、必要ありません。 先の返信で書きましたが、IAT の書き換えで Hook できるのは、モジュール ビルド時にリンカにより解決された外部参照だけです。 LoadLibrary() / GetProcAddress() 経由で呼び出される API コールに対しては、IAT の書き換えは意味を持ちません。 IAT 書き換えによる Hook とは異なり、Detours では Hook 対象 API の prologue code を書き換えます。 つまり Hook 対象 API の先頭が、Hook Routine への jump 命令に書き換えられるので、IAT Hook のような同一プロセス内にロードされている他のモジュールを気にする必要はありません。 しかも IAT Hook よりも確実です。
sitsumon_jirou

2020/11/02 08:24 編集

素早い回答ありがとうございます. 以下のサイトのコードを用いて早速Detoursを使ってみました. https://gazee.net/develop/detours-visual-studio-2015-usage/ このコード内のMessageBoxAはフックをすることができました. ですが,このプログラムをgetchar()で待機させ,その間に他のアプリケーションによってMessageBoxAを呼び出したのですが,他のアプリケーションの方はフックできませんでした. 私の認識では,プログラム実行中はMessageBoxAの先頭が書き換わっている認識だったので,うまくいくと思ったのですがどのような問題があるのでしょうか? 何度も質問すいません.
Bego

2020/11/02 08:27

UNICODE バージョンで Build してませんか? UNICODE バージョンで Build している場合、MessageBoxA ではなく MessageBoxW を Hook する必要があります。 Hook Routine を仕掛ける対象アプリが、MessageBoxA あるいは MessageBoxW のどちらを使用しているかは、その exe の IAT を確認すればわかります。 (あるいはデバッガ上から対象アプリを起動させ、MessageBoxA および MessageBoxW にブレークポイントをセットした状態で実行させれば、どっちがコールされたかが確認できます。)
sitsumon_jirou

2020/11/04 03:13 編集

試行錯誤したのですが,うまくいきませんでした. 私の認識は, 1.DetoursによってHook対象のAPIを探す. 2.対象のAPIの先頭部分を,自分のしたい命令のアドレスへのjump命令に書き換える 3.そのため,どんなプロセスが対象のAPIを呼び出しても,Detoursによって書き換えられている間やりたい命令が行われる. です. また,実装したコードは以下の通りです. 1.Detoursのコード #include <Windows.h> #include <detours.h> #include<stdio.h> #pragma comment(lib, "detours.lib") using Type1 = decltype(::MessageBoxW); Type1* PureMessageBoxW = &::MessageBoxW; int WINAPI HookMessageBoxW(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) { return PureMessageBoxW(NULL, L"hook_W", L"hook_W", MB_OK); } using Type2 = decltype(::MessageBoxA); Type2* PureMessageBoxA = &::MessageBoxA; int WINAPI HookMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) { return PureMessageBoxA(NULL, "hook_A", "hook_A", MB_OK); } int main() { MessageBoxW(NULL, L"before_W", L"before_W", MB_OK); MessageBoxA(NULL, "before_A", "before_A", MB_OK); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(&(PVOID&)PureMessageBoxW, HookMessageBoxW); DetourAttach(&(PVOID&)PureMessageBoxA, HookMessageBoxA); if (DetourTransactionCommit() == NO_ERROR) OutputDebugString(TEXT("MessageBoxA() detoured successfully")); getchar(); MessageBoxW(NULL, L"after_W", L"after_W", MB_OK); MessageBoxA(NULL, "after_A", "after_A", MB_OK); return 0; } 2.MessageBoxを出すだけのプログラム int main() { MessageBoxW(NULL, L"abcdあいう", L"abcdあいう", MB_OK); MessageBoxA(0, "test", "title", MB_OK); } 長文で申し訳ないですが,間違っているところを教えていただけたら幸いです.
Bego

2020/11/04 05:12 編集

一点確認ですが、この1のサンプルで、MessageBoxA() への Hook は成功しているですよね? で、HookMessageBoxW() のパラメータ定義が間違っています。 int WINAPI HookMessageBoxW(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) ではなく、 int WINAPI HookMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType) です。 (MessageBoxA は LPCSTR ですが、MessageBoxW は LPCWSTR です。) それでもダメなら。。。 プロジェクト一式をどこかのオンラインストレージにアップしてもらえるなら、私の方でデバッグします。 ----------------------------------------------- 無料でおすすめのオンラインストレージ5選 https://imitsu.jp/list/online-storage/free-recommended/ -----------------------------------------------
sitsumon_jirou

2020/11/04 07:08 編集

やはりうまくいきません. オンラインストレージを作成しました. 1.Detoursのプログラム https://mega.nz/folder/Z9xTjA6D#qBUGqZeL9IuYNyX52xyegg 2.MessageBoxを出すだけのプログラム https://mega.nz/folder/xhongSAb#x-DKYNJuhaIqZbInlWKusg 以前述べたように1を実行中に2を実行することでフックの確認を行いました. 1内のAPI,messageboxはAもWもフックできますが,2内のAPIフックはできません. よろしくお願いします.
Bego

2020/11/04 08:34 編集

> 以前述べたように1を実行中に2を実行することでフックの確認を行いました. これ↑の意味が、よくわからないのですが。。。。 先のサンプルの1と2は別プロセスとして実行されるので、1を実行していようとも、2が Hook されることはありません。 各ユーザー モード プロセスのユーザー モード空間は、個々のプロセス毎に完全に独立しています。 つまり ntdll.dll や kernelbase.dll, kernel32.dll 等すべての DLL は、個々のプロセスの仮想メモリ空間に「個別」にロードされます。 ですので、プロセス A のユーザー モード空間にロードされた DLL がプロセス B で参照されることはありませんし、利用されることもありません。 だから、一番初めの返信で説明したように、新規プロセス生成を監視する必要があるのです。 (新規プロセスの生成を検出したら、そのタイミングで外部プロセスからその新規プロセスに対して DLL Injection を行い、その Injection した DLL が対象とする API に対して Hook Routine を仕掛ける。。。ということ。) この部分の理解は大丈夫ですか? P.S. > 3.そのため,どんなプロセスが対象のAPIを呼び出しても, > Detoursによって書き換えられている間やりたい命令が行われる. この認識↑が間違いですね。。。。
sitsumon_jirou

2020/11/05 04:51

とても勘違いしていました. 私はDetoursを使うことで,プロセスによってロードされる前のdll内の対象API部分を書き変えるもの(プロセスとか関係なく)だと思っていました. 大元のDLL内を書き換えることが手っ取り早いのかなと思ったのですがこれは現実的ではないですか? 結局すべてのプロセスを把握してDLLインジェクションするということは必須ということですね. 返答ありがとうございます.
Bego

2020/11/05 05:30

> 大元のDLL内を書き換えることが手っ取り早いのかなと思ったのですが > これは現実的ではないですか? まだ勘違いしているような。。。。 Detours は、仮想メモリ上にロードされた大元の API を書き換えます。 Word.exe や Excel.exe 等すべてのプロセスのユーザ モード空間は、個別に独立しています。 そのユーザ モード空間に ntdll.dll や kernelbase.dll、kernel32.dll といった各種 DLL がロードされるわけですが、それら DLL 群が異なるプロセス間で共有されることはありません。 「大元のDLL内を書き換える」というのが何を意味しているのかよくわかりませんが、"%WinDir%\System32" フォルダ内の ntdll.dll ファイルを書き換えるという意味ならば、荒唐無稽です。 そんなことをしたら、Windows システムが起動できなくなります。 IAT Hook でも Detours での Hook でも、書き換えられるのは「仮想メモリ上にロードされたモジュール」に対してです。
sitsumon_jirou

2020/11/05 05:42

ntdll.dll ファイルを書き換えるという意味でとらえていました. DLLの変更についてデリケートな部分だということは承知してましたが,ちょっとした変更すら無理だということは理解していませんでした.すいません. 現在はPsSetCreateProcessNotifyRoutineを用いてすべてのプロセスを把握しようとしています.ですが,教えてくださったようにカーネルモードドライバは難しそうです.
Bego

2020/11/05 06:40 編集

> カーネルモードドライバは難しそうです. 世の中には、こんなサンプルも転がってます。 ------------------------------------- Kernel Mode Extensions Driver https://github.com/OSRDrivers/kmexts ------------------------------------- ただし、カーネル モード側で動作するドライバは、ちょっとでもバグがあると即ブルースクリーンです。 つまり上記サンプルをちょっと変更しただけで簡単にブルースクリーンになる可能性があり、最悪 PC が起動できなくなることすらあり得ます。 ブルースクリーンと格闘するだけの「根性」が無いのであれば、カーネル モード ドライバには手を出さない方が幸せに過ごせます。
sitsumon_jirou

2020/11/06 07:16

ここまで丁寧に説明していただきありがとうございました. 大変そうですが頑張ってみます.
sitsumon_jirou

2020/11/16 06:03 編集

今,全体ではなく対象のプロセスだけに対して Detoursを用いて,ntunmapviewofsectionのフックを行っています. ですが,指摘してただいた通りntunmap~は自前でアドレスを取得するため,MessageBoxとは仕様が違い悩んでいます. 見にくくてすいませんがどのようにしたらいいでしょうか? 以下コード #include <windows.h> #include <tchar.h> #include <dbghelp.h> #include <detours.h> #include<stdio.h> #include <winternl.h> #include <psapi.h> #include<fstream> #include<iostream> #pragma comment(lib,"ntdll.lib") #pragma comment(lib, "detours.lib") typedef NTSTATUS(WINAPI* _NtUnmapViewOfSection)( HANDLE ProcessHandle, PVOID BaseAddress ); HMODULE hNTDLL = GetModuleHandleA("ntdll"); FARPROC fpNtUnmapViewOfSection = GetProcAddress(hNTDLL, "NtUnmapViewOfSection"); _NtUnmapViewOfSection NtUnmapViewOfSection =(_NtUnmapViewOfSection)fpNtUnmapViewOfSection; using Type1 = decltype(MessageBoxW); Type1* PureMessageBoxW = &MessageBoxW; int WINAPI HookMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType) { TCHAR procName[MAX_PATH] = TEXT("<unknown>"); GetModuleBaseName(GetCurrentProcess(), 0, procName, sizeof(procName) / sizeof(TCHAR)); OutputDebugString(procName); return PureMessageBoxW(NULL, L"hook_W", L"hook_W", MB_OK); } using Type2 = decltype(MessageBoxA); Type2* PureMessageBoxA = &MessageBoxA; int WINAPI HookMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) { TCHAR procName[MAX_PATH] = TEXT("<unknown>"); GetModuleBaseName(GetCurrentProcess(), 0, procName, sizeof(procName) / sizeof(TCHAR)); //OutputDebugString(procName); std::wofstream outputfile("test.txt"); outputfile << procName; outputfile.close(); return PureMessageBoxA(NULL, "hook_A", "hook_A", MB_OK); } using Type3 = decltype(NtUnmapViewOfSection); Type3* PureNtUnmapViewOfSection = &NtUnmapViewOfSection; int WINAPI HookNtUnmapViewOfSection(HANDLE ProcessHandle,PVOID BaseAddress ){ TCHAR procName[MAX_PATH] = TEXT("<unknown>"); GetModuleBaseName(GetCurrentProcess(), 0, procName, sizeof(procName) / sizeof(TCHAR)); OutputDebugString(procName); return PureNtUnmapViewOfSection(ProcessHandle,BaseAddress); } BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: DetourRestoreAfterWith(); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(&(PVOID&)PureMessageBoxW, HookMessageBoxW); DetourAttach(&(PVOID&)PureMessageBoxA, HookMessageBoxA); DetourAttach(&(PVOID&)PureNtUnmapViewOfSection, HookNtUnmapViewOfSection); DetourTransactionCommit(); break; } return TRUE; }
Bego

2020/11/16 08:16 編集

ntdll.dll に実装されている NtUnmapViewOfSection() は、ZwUnmapViewOfSection() と同義になります。 デバッガで NtUnmapViewOfSection() と ZwUnmapViewOfSection() のエントリポイントを確認すれば、同じであることが分かります。 ----------------------------------- 0:007> x ntdll!??UnmapViewOfSection 00007ffd`eb5cc2d0 ntdll!ZwUnmapViewOfSection (ZwUnmapViewOfSection) 00007ffd`eb5cc2d0 ntdll!NtUnmapViewOfSection (NtUnmapViewOfSection) ----------------------------------- ZwUnmapViewOfSection function (wdm.h) https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-zwunmapviewofsection NTSTATUS ZwUnmapViewOfSection( HANDLE ProcessHandle, PVOID BaseAddress ); ----------------------------------- なので、上記 ZwUnmapViewOfSection() サイトで説明されているパラメータに従い、MessageBoxA/MessageBoxW と同様に Hook Routine を仕掛ければいいだけです。 大体こんな感じ↓。 (脳内なんちゃってコードなので、動くかどうかはわかりません。) //-------------------------- // Function prototypes //-------------------------- #define MY_DLL_MODULE "MyDll" HMODULE g_hNtdll = NULL; typedef NTSTATUS (*PFN_NtUnmapViewOfSection)( HANDLE ProcessHandle, PVOID BaseAddress ); PFN_NtUnmapViewOfSection PureNtUnmapViewOfSection = NULL; NTSTATUS MyZwUnmapViewOfSection ( HANDLE ProcessHandle, PVOID BaseAddress ) { NTSTATUS ntStatus = STATUS_UNSUCCESSFUL; OutputDebugStringA( (("[%s] MyZwUnmapViewOfSection Routine(%x, %x) \n"), MY_DLL_MODULE, ProcessHandle, BaseAddress) ); // DebugBreak(); ntStatus = PureNtUnmapViewOfSection( ProcessHandle, BaseAddress ); return ntStatus; } // End of MyZwUnmapViewOfSection(). BOOL APIENTRY DllMain ( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { BOOL bResult = FALSE; switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: g_hNtdll = GetModuleHandleA( "ntdll" ); if( g_hNtdll ) { PureNtUnmapViewOfSection = (PFN_NtUnmapViewOfSection)GetProcAddress( g_hNtdll, "NtUnmapViewOfSection" ); if( PureNtUnmapViewOfSection ) { DetourRestoreAfterWith(); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(&(PVOID&)PureNtUnmapViewOfSection, MyZwUnmapViewOfSection); DetourTransactionCommit(); } } break; case DLL_PROCESS_DETACH: if( PureNtUnmapViewOfSection ) { DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourDetach(&(PVOID&)PureNtUnmapViewOfSection, MyZwUnmapViewOfSection); DetourTransactionCommit(); } break; default: break; } return TRUE; }
sitsumon_jirou

2020/11/17 08:07

返答ありがとうございます. 教えていただいた通りにしましたら,対象のプロセスに対して,フックを行うことができました. しかし今度は,対象のプロセスをフックし,対象のプロセスがntunmapviewofsectionを実行するとエラーを起こしてしまいました. 「Run-Time Check Failure #0 - The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention.」 のように出ており,呼び出し規約に問題があると出てしまいました. どこまでうまくいっているのか確かめてみてMyZwUnmapViewOfSection関数のreturnで問題が起こっていることがわかりました. しかし,呼び出し規約を変えてみたり,_stdcallをつけてみたりしましたが,エラーは治りませんでした.また,対象のプロセス(https://github.com/m0n0ph1/Process-Hollowing)との関係でエラーが出たのかと思いいじったりもしました. 以下コード #define MY_DLL_MODULE "MyDll" HMODULE g_hNtdll = NULL; typedef NTSTATUS (_stdcall *PFN_NtUnmapViewOfSection)( HANDLE ProcessHandle, PVOID BaseAddress ); PFN_NtUnmapViewOfSection PureNtUnmapViewOfSection=NULL ; NTSTATUS MyZwUnmapViewOfSection ( HANDLE ProcessHandle, PVOID BaseAddress ) { NTSTATUS ntStatus = FALSE;    ntStatus = PureNtUnmapViewOfSection(ProcessHandle, BaseAddress);    std::wofstream outputfile("test.txt");    outputfile << procName;    outputfile.close(); //////ここまでうまく動作(出力成功) return ntStatus; } // End of MyZwUnmapViewOfSection(). BOOL APIENTRY DllMain(HANDLE hModule,DWORD ul_reason_for_call,LPVOID lpReserved) { BOOL bResult = FALSE; switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: g_hNtdll = GetModuleHandleA("ntdll"); if (g_hNtdll) { PureNtUnmapViewOfSection = (PFN_NtUnmapViewOfSection)GetProcAddress(g_hNtdll,"NtUnmapViewOfSection"); if (PureNtUnmapViewOfSection) { DetourRestoreAfterWith(); DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(&(PVOID&)PureNtUnmapViewOfSection, MyZwUnmapViewOfSection); DetourTransactionCommit(); } } break; case DLL_PROCESS_DETACH: if (PureNtUnmapViewOfSection) { DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourDetach(&(PVOID&)PureNtUnmapViewOfSection, MyZwUnmapViewOfSection); DetourTransactionCommit(); } break; default: break; } return TRUE; }
Bego

2020/11/17 09:23

下記サイト参考に WER の設定を行い、エラー発生時のプロセス ダンプを採取できないか、確認してみてください。 +++++++++++++++++++++++++++++++++++++++ Windowsエラー報告(WER)機能を使ってアプリケーションのクラッシュダンプ(ユーザーダンプ)を作成する方法 https://support.citrix.com/article/CTX119302 +++++++++++++++++++++++++++++++++++++++
sitsumon_jirou

2020/11/19 07:34 編集

クラッシュダンプを取得することができ,Windbgで解析まで行いました. ですが結構調べてみましたが,解析結果の見方がわかりませんでした. どのように見ればよいのでしょうか?
Bego

2020/11/19 08:07

そのダンプ ファイルと、exe と dll に対応するシンボル ファイル (.pdb) と、公開可能なソースコードをどこかのオンライン ストレージにアップしてもらえますか? ----------------------------------------------- 無料でおすすめのオンラインストレージ5選 https://imitsu.jp/list/online-storage/free-recommended/ -----------------------------------------------
Bego

2020/11/20 06:07

"ProcessHollowing.exe" のシンボルファイルはないのでしょうか?
Bego

2020/11/20 06:39

"ProcessHollowing.pdb" が無いのまともな解析が出来ないのですが、Hook Routine は正常にセットされているようです。 0:000> u ntdll!NtUnmapViewOfSection l3 ntdll!NtUnmapViewOfSection: 772918c0 e9abff2b00 jmp Dll1+0x11870 (77551870) 772918c5 ba70712a77 mov edx,offset ntdll!Wow64SystemServiceCall (772a7170) 772918ca ffd2 call edx ですがが。。。 "Dll1.pdb" がタイムスタンプが合っていません。 0:000> lmDvm ProcessHollowing Browse full module list start end module name 000f0000 00100000 ProcessHollowing C (no symbols) Loaded symbol image file: ProcessHollowing.exe Image path: Z:\Process-Hollowing-master\sourcecode\Debug\ProcessHollowing.exe Image name: ProcessHollowing.exe Browse all global symbols functions data Timestamp: Tue Nov 17 16:34:53 2020 (5FB37D1D) CheckSum: 00000000 ImageSize: 00010000 Translations: 0000.04b0 0000.04e4 0409.04b0 0409.04e4 Information from resource tables: 0:000> lmDvm Dll1 Browse full module list start end module name 77540000 7757a000 Dll1 C (no symbols) Loaded symbol image file: Dll1.dll Image path: C:\Users\Security\Desktop\detours_hook_1113\detours_hook_1113\Debug\Dll1.dll Image name: Dll1.dll Browse all global symbols functions data Timestamp: Wed Nov 18 13:18:06 2020 (5FB4A07E) CheckSum: 00000000 ImageSize: 0003A000 Translations: 0000.04b0 0000.04e4 0409.04b0 0409.04e4 Information from resource tables: ビルドし直したものをアップしていませんか? ビルドし直したものでは意味がありません。 ダンプを採取したしたときに使用した exe や dll 同じタイムスタンプ。。。つまりビルド時に生成されたシンボル ファイルをアップしてもらわないと、解析できません。 (同じソース コードからビルドしても、バイナリは毎回異なるので、シンボルファイルも異なることになります。) 「結構調べてみましたが」って、シンボル ファイルを同期させないで、どーやって調べたんですか?
sitsumon_jirou

2020/11/20 06:59

ProcessHollowing.exeを含んだファイルです. https://mega.nz/folder/c4BxXKiC#Mk6MYqAACveaBST3_XOb9A 最終的にHelloWorldを表示するだけのプログラムなので悪意のあるコードは実行されませんが,プロセスハロウィングのコードが含まれているため,WindowsDefenderを切った状況でないと削除される可能性があります. コードはhttps://github.com/m0n0ph1/Process-Hollowingまんまです.
sitsumon_jirou

2020/11/20 07:08

ビルドしなおしたものをあげていました. 同じタイムスタンプのものではありませんでした. あげなおすので少しお待ちください. すいません. 「結構調べた」というのは自分の知識が浅いため,解析をどのように行うのか,解析をどのように見ればいいのか調べたということです.
Bego

2020/11/20 09:01 編集

svchost プロセスを生成しようとしているみたいだけど、このプロセスがどー言うプロセスかちゃんと勉強しましたか? これはサービス用のホスト プロセスです。 サービス プロセスは特殊な User Process なので、一般的な方法ではダメかも。 いきなり svchost プロセスへの API Hook なんて無謀です。
Bego

2020/11/20 08:56

0:000> !analyze -v ******************************************************************************* * * * Exception Analysis * * * ******************************************************************************* KEY_VALUES_STRING: 1 Key : Analysis.CPU.mSec Value: 921 Key : Analysis.DebugAnalysisProvider.CPP Value: Create: 8007007e on NMORI-10X64-001 Key : Analysis.DebugData Value: CreateObject Key : Analysis.DebugModel Value: CreateObject Key : Analysis.Elapsed.mSec Value: 2164 Key : Analysis.Memory.CommitPeak.Mb Value: 83 Key : Analysis.System Value: CreateObject Key : Timeline.OS.Boot.DeltaSec Value: 14751 Key : Timeline.Process.Start.DeltaSec Value: 7 Key : WER.OS.Branch Value: vb_release Key : WER.OS.Timestamp Value: 2019-12-06T14:06:00Z Key : WER.OS.Version Value: 10.0.19041.1 ADDITIONAL_XML: 1 OS_BUILD_LAYERS: 1 NTGLOBALFLAG: 0 PROCESS_BAM_CURRENT_THROTTLED: 0 PROCESS_BAM_PREVIOUS_THROTTLED: 0 APPLICATION_VERIFIER_FLAGS: 0 CONTEXT: (.ecxr) eax=00000001 ebx=010febd4 ecx=6e37ccbb edx=00000004 esi=00751bf2 edi=00756072 eip=0075393c esp=010febb8 ebp=010ffa00 iopl=0 nv up ei pl zr na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246 ProcessHollowing!failwithmessage+0x1ec: 0075393c cc int 3 Resetting default scope EXCEPTION_RECORD: (.exr -1) ExceptionAddress: 0075393c (ProcessHollowing!failwithmessage+0x000001ec) ExceptionCode: 80000003 (Break instruction exception) ExceptionFlags: 00000000 NumberParameters: 1 Parameter[0]: 00000000 PROCESS_NAME: ProcessHollowing.exe ERROR_CODE: (NTSTATUS) 0x80000003 - { O} u [ N | C g u [ N | C g B B EXCEPTION_CODE_STR: 80000003 EXCEPTION_PARAMETER1: 00000000 STACK_TEXT: 010ffa00 00753579 00751bf2 00000001 00000000 ProcessHollowing!failwithmessage+0x1ec 010ffa18 00752acf 00751bf2 00000000 010ffcdc ProcessHollowing!_RTC_Failure+0x29 010ffa3c 00751bf2 000000fc 00440000 010ffdd0 ProcessHollowing!_RTC_CheckEsp+0x1f 010ffcdc 007527ab 00758e48 0123e6d0 00751109 ProcessHollowing!CreateHollowedProcess+0x262 010ffdd0 00752fa3 00000001 01236e78 01236fa0 ProcessHollowing!wmain+0x9b 010ffdf0 00752df7 08840b2d 00751109 00751109 ProcessHollowing!invoke_main+0x33 010ffe4c 00752c8d 010ffe5c 00753028 010ffe6c ProcessHollowing!__scrt_common_main_seh+0x157 010ffe54 00753028 010ffe6c 766cfa29 00ec1000 ProcessHollowing!__scrt_common_main+0xd 010ffe5c 766cfa29 00ec1000 766cfa10 010ffec8 ProcessHollowing!wmainCRTStartup+0x8 010ffe6c 76f175f4 00ec1000 49070952 00000000 kernel32!BaseThreadInitThunk+0x19 010ffec8 76f175c4 ffffffff 76f3733f 00000000 ntdll!__RtlUserThreadStart+0x2f 010ffed8 00000000 00751109 00ec1000 00000000 ntdll!_RtlUserThreadStart+0x1b FAULTING_SOURCE_LINE: d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\rtc\error.cpp FAULTING_SOURCE_FILE: d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\rtc\error.cpp FAULTING_SOURCE_LINE_NUMBER: 213 FAULTING_SOURCE_CODE: No source found for 'd:\agent\_work\3\s\src\vctools\crt\vcstartup\src\rtc\error.cpp' SYMBOL_NAME: ProcessHollowing!failwithmessage+1ec MODULE_NAME: ProcessHollowing IMAGE_NAME: ProcessHollowing.exe STACK_COMMAND: ~0s ; .ecxr ; kb FAILURE_BUCKET_ID: BREAKPOINT_80000003_ProcessHollowing.exe!failwithmessage OS_VERSION: 10.0.19041.1 BUILDLAB_STR: vb_release OSPLATFORM_TYPE: x86 OSNAME: Windows 10 FAILURE_ID_HASH: {3fe0017a-14d7-365a-c1fa-0b13cc94d5c1} Followup: MachineOwner ---------
Bego

2020/11/20 08:57

0:000> ~*kvn . 0 Id: 9c0.2f84 Suspend: 0 Teb: 00ec4000 Unfrozen # ChildEBP RetAddr Args to Child 00 010fe27c 764a9823 00000003 010fe4b0 00000001 ntdll!NtWaitForMultipleObjects+0xc (FPO: [5,0,0]) 01 010fe410 764a9708 00000003 010fe4b0 00000000 KERNELBASE!WaitForMultipleObjectsEx+0x103 (FPO: [SEH]) 02 010fe42c 76715a26 00000003 010fe4b0 00000000 KERNELBASE!WaitForMultipleObjects+0x18 (FPO: [Non-Fpo]) 03 010fe4d8 76715657 00000000 00000000 010fe5cc kernel32!WerpReportFaultInternal+0x3b7 (FPO: [Non-Fpo]) 04 010fe4f4 766eaf19 010fe59c 7654dda0 010fe5cc kernel32!WerpReportFault+0x9d (FPO: [Non-Fpo]) 05 010fe4fc 7654dda0 010fe5cc 00000001 60d683c7 kernel32!BasepReportFault+0x19 (FPO: [Non-Fpo]) 06 010fe59c 76f54d07 010fe5cc 76f25c32 010ffec8 KERNELBASE!UnhandledExceptionFilter+0x290 (FPO: [Non-Fpo]) 07 010ffec8 76f175c4 ffffffff 76f3733f 00000000 ntdll!__RtlUserThreadStart+0x3d742 08 010ffed8 00000000 00751109 00ec1000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo]) 1 Id: 9c0.1e24 Suspend: 1 Teb: 00ec7000 Unfrozen # ChildEBP RetAddr Args to Child 00 0142f7b4 76f01030 000000b0 0123d368 00000010 ntdll!NtWaitForWorkViaWorkerFactory+0xc (FPO: [5,0,0]) 01 0142f974 766cfa29 01232f90 766cfa10 0142f9e0 ntdll!TppWorkerThread+0x2a0 (FPO: [Non-Fpo]) 02 0142f984 76f175f4 01232f90 494a0e7a 00000000 kernel32!BaseThreadInitThunk+0x19 (FPO: [Non-Fpo]) 03 0142f9e0 76f175c4 ffffffff 76f3733f 00000000 ntdll!__RtlUserThreadStart+0x2f (FPO: [SEH]) 04 0142f9f0 00000000 76f00d90 01232f90 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo]) 2 Id: 9c0.18b4 Suspend: 1 Teb: 00ecd000 Unfrozen # ChildEBP RetAddr Args to Child 00 0307f94c 76f01030 00000058 012a0da8 00000010 ntdll!NtWaitForWorkViaWorkerFactory+0xc (FPO: [5,0,0]) 01 0307fb0c 766cfa29 012307c0 766cfa10 0307fb78 ntdll!TppWorkerThread+0x2a0 (FPO: [Non-Fpo]) 02 0307fb1c 76f175f4 012307c0 4b0f0ce2 00000000 kernel32!BaseThreadInitThunk+0x19 (FPO: [Non-Fpo]) 03 0307fb78 76f175c4 ffffffff 76f3733f 00000000 ntdll!__RtlUserThreadStart+0x2f (FPO: [SEH]) 04 0307fb88 00000000 76f00d90 012307c0 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo]) 3 Id: 9c0.2dd8 Suspend: 1 Teb: 00ed0000 Unfrozen # ChildEBP RetAddr Args to Child 00 031cfbe8 76f01030 00000058 012a75b0 00000010 ntdll!NtWaitForWorkViaWorkerFactory+0xc (FPO: [5,0,0]) 01 031cfda8 766cfa29 012307c0 766cfa10 031cfe14 ntdll!TppWorkerThread+0x2a0 (FPO: [Non-Fpo]) 02 031cfdb8 76f175f4 012307c0 4b14098e 00000000 kernel32!BaseThreadInitThunk+0x19 (FPO: [Non-Fpo]) 03 031cfe14 76f175c4 ffffffff 76f3733f 00000000 ntdll!__RtlUserThreadStart+0x2f (FPO: [SEH]) 04 031cfe24 00000000 76f00d90 012307c0 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])
Bego

2020/11/20 08:57

0:000> ~0s eax=00000000 ebx=00000000 ecx=6e37ccbb edx=00000004 esi=00000003 edi=00000003 eip=76f21bdc esp=010fe280 ebp=010fe410 iopl=0 nv up ei pl nz ac po nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000212 ntdll!NtWaitForMultipleObjects+0xc: 76f21bdc c21400 ret 14h 0:000> .ecxr eax=00000001 ebx=010febd4 ecx=6e37ccbb edx=00000004 esi=00751bf2 edi=00756072 eip=0075393c esp=010febb8 ebp=010ffa00 iopl=0 nv up ei pl zr na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246 ProcessHollowing!failwithmessage+0x1ec: 0075393c cc int 3 0:000> kvn *** Stack trace for last set context - .thread/.cxr resets it # ChildEBP RetAddr Args to Child 00 010ffa00 00753579 00751bf2 00000001 00000000 ProcessHollowing!failwithmessage+0x1ec (FPO: [Non-Fpo]) (CONV: cdecl) [d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\rtc\error.cpp @ 213] 01 010ffa18 00752acf 00751bf2 00000000 010ffcdc ProcessHollowing!_RTC_Failure+0x29 (FPO: [Non-Fpo]) (CONV: cdecl) [d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\rtc\error.cpp @ 234] 02 010ffa3c 00751bf2 000000fc 00440000 010ffdd0 ProcessHollowing!_RTC_CheckEsp+0x1f (FPO: [Non-Fpo]) (CONV: cdecl) [d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\rtc\stack.cpp @ 43] 03 010ffcdc 007527ab 00758e48 0123e6d0 00751109 ProcessHollowing!CreateHollowedProcess+0x262 (FPO: [Non-Fpo]) (CONV: cdecl) [C:\Users\Security\Downloads\Process-Hollowing-master (2)\Process-Hollowing-master\sourcecode\ProcessHollowing\ProcessHollowing.cpp @ 78] 04 010ffdd0 00752fa3 00000001 01236e78 01236fa0 ProcessHollowing!wmain+0x9b (FPO: [Non-Fpo]) (CONV: cdecl) [C:\Users\Security\Downloads\Process-Hollowing-master (2)\Process-Hollowing-master\sourcecode\ProcessHollowing\ProcessHollowing.cpp @ 298] 05 010ffdf0 00752df7 08840b2d 00751109 00751109 ProcessHollowing!invoke_main+0x33 (FPO: [Non-Fpo]) (CONV: cdecl) [d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 90] 06 010ffe4c 00752c8d 010ffe5c 00753028 010ffe6c ProcessHollowing!__scrt_common_main_seh+0x157 (FPO: [Non-Fpo]) (CONV: cdecl) [d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 288] 07 010ffe54 00753028 010ffe6c 766cfa29 00ec1000 ProcessHollowing!__scrt_common_main+0xd (FPO: [Non-Fpo]) (CONV: cdecl) [d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl @ 331] 08 010ffe5c 766cfa29 00ec1000 766cfa10 010ffec8 ProcessHollowing!wmainCRTStartup+0x8 (FPO: [Non-Fpo]) (CONV: cdecl) [d:\agent\_work\3\s\src\vctools\crt\vcstartup\src\startup\exe_wmain.cpp @ 17] 09 010ffe6c 76f175f4 00ec1000 49070952 00000000 kernel32!BaseThreadInitThunk+0x19 (FPO: [Non-Fpo]) 0a 010ffec8 76f175c4 ffffffff 76f3733f 00000000 ntdll!__RtlUserThreadStart+0x2f (FPO: [SEH]) 0b 010ffed8 00000000 00751109 00ec1000 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo]) 0:000> .frame 04 04 010ffdd0 00752fa3 ProcessHollowing!wmain+0x9b [C:\Users\Security\Downloads\Process-Hollowing-master (2)\Process-Hollowing-master\sourcecode\ProcessHollowing\ProcessHollowing.cpp @ 298] 0:000> dv/V 010ffdd8 <virtual frame 10ffdd0>+0x0008 argc = 0n1 010ffddc <virtual frame 10ffdd0>+0x000c argv = 0x01236e78 010ffdc8 <virtual frame 10ffdd0>-0x0008 pPath = 0x0123e6d0 "C:\Users\Security\Downloads\Process-Hollowing-master (2)\Process-Hollowing-master\sourcecode\Debug\helloworld.exe" 0:000> .frame 03 03 010ffcdc 007527ab ProcessHollowing!CreateHollowedProcess+0x262 [C:\Users\Security\Downloads\Process-Hollowing-master (2)\Process-Hollowing-master\sourcecode\ProcessHollowing\ProcessHollowing.cpp @ 78] 0:000> dv/V 010ffce4 <virtual frame 10ffcdc>+0x0008 pDestCmdLine = 0x00758e48 "svchost" 010ffce8 <virtual frame 10ffcdc>+0x000c pSourceFile = 0x0123e6d0 "C:\Users\Security\Downloads\Process-Hollowing-master (2)\Process-Hollowing-master\sourcecode\Debug\helloworld.exe" 010ffcd4 <virtual frame 10ffcdc>-0x0008 pStartupInfo = 0x012404f8 010ffcc8 <virtual frame 10ffcdc>-0x0014 pProcessInfo = 0x012374e0 010ffc8c <virtual frame 10ffcdc>-0x0050 pBuffer = 0x01435040 "MZ???" 010ffc74 <virtual frame 10ffcdc>-0x0068 pSourceImage = 0x0123e940 010ffc80 <virtual frame 10ffcdc>-0x005c dwBytesRead = 0xcf600 010ffc5c <virtual frame 10ffcdc>-0x0080 hNTDLL = 0x76eb0000 010ffcbc <virtual frame 10ffcdc>-0x0020 pPEB = 0x012418a0 010ffc98 <virtual frame 10ffcdc>-0x0044 dwSize = 0xcf600 010ffc50 <virtual frame 10ffcdc>-0x008c fpNtUnmapViewOfSection = 0x76f218c0 010ffb68 <virtual frame 10ffcdc>-0x0174 dwBreakpoint = 0xcccccccc 010ffc2c <virtual frame 10ffcdc>-0x00b0 pRemoteImage = 0xcccccccc 010ffca4 <virtual frame 10ffcdc>-0x0038 hFile = 0x00000104 010ffc44 <virtual frame 10ffcdc>-0x0098 NtUnmapViewOfSection = 0x76f218c0 010ffb5c <virtual frame 10ffcdc>-0x0180 dwEntrypoint = 0xcccccccc 010ffcb0 <virtual frame 10ffcdc>-0x002c pImage = 0x01245ab0 010ffc38 <virtual frame 10ffcdc>-0x00a4 dwResult = 0xcccccccc 010ffb50 <virtual frame 10ffcdc>-0x018c pContext = 0xcccccccc 010ffc20 <virtual frame 10ffcdc>-0x00bc dwDelta = 0xcccccccc 010ffc68 <virtual frame 10ffcdc>-0x0074 pSourceHeaders = 0x01435138
sitsumon_jirou

2020/11/24 04:19

このプログラムでは,対象のプロセスに対してのみAPI Hookを行っていて,今回の対象プログラムはprocess hollowing.exeだけで,svchost.exeはprocess hollowing.exeによってprocess hollowingされていますが,API Hookの対象ではないと思っていました. Detoursを使った方法では,APIHookを行ったプロセスが作成したプロセスに対してのAPIHookが行われるということですか? それともAPIHookを行った引数として,svchostに関する情報が含まれているからエラーが出るということでしょうか?
Bego

2020/11/24 07:24

> それともAPIHookを行った引数として, > svchostに関する情報が含まれているからエラーが出るということでしょうか? 先の返信では、hollowing.exe のコードをきちんと読まず、テキトーなことを書いてしました。 申し訳ありません。 ですが。。。。 これ、よくよく眺めてみたら、Process Injection の常套手段ぢゃん。 目的はなんですか? もしかして目的は Process Hacking?
sitsumon_jirou

2020/11/26 03:17

NtUnmap~に限らず様々なAPIの利用履歴を監視,ログとして出力することで,悪意のあるマルウェアなどと悪意のない実行ファイルの違いを調べることが目的です.
Bego

2020/11/26 05:17

だったらなぜ、わざわざ Process Injection のサンプルをベースにするのですか? マルウェア検出に Process Injection は必要無いと思うのですが。。。。 Process Injection をベースにする理由が明確にならない限りは、コメントできません。 (下手にコメントして、犯罪の片棒を担いでしまった。。。なんてことになったら大変なので。)
sitsumon_jirou

2020/11/27 04:14

マルウェアの中でも主にprocess hollowingの機能を持ったマルウェアの検知をしたいためです.process hollowingの検知を行うとなったら,まず最初に思いついたのがAPIの中でもNtUnmap~の使用履歴を把握することでした.NtUnmap~がどのくらい端末内で呼び出されているのかまず調べるつもりです.
Bego

2020/11/27 08:09

その方法だと、NtUnmapViewOfSection が呼び出されるちゃんとした頻度を把握することはできません。 なぜなら、ntdll.dll 内の NtUnmapViewOfSection() Hook では、Session 0 以外の、かつ User Mode 側で発生した NtUnmapViewOfSection() しか検知できないから。 つまり、Session 0 で動作している各種 Service Process や Kernel Mode 側から発行された NtUnmapViewOfSection() は検出できないけど、NtUnmapViewOfSection() を呼び出す頻度は、Session 0 で動作している各種 Service Process や Kernel Mode 側からの方が圧倒的に多いから、一般的な API Hook 方法ではまともな呼び出し頻度を把握することはできません。 NtUnmapViewOfSection の呼び出し頻度を調べたいなら、WinDbg をカーネル デバッグ接続して、NT カーネル側の NtUnmapViewOfSection および ZwUnmapViewOfSection に Breakpoint を張れば、すべての Call を Catch できます。 (軽く確認しただけでも1秒間に数十回のコールが発生していましたが、そのすべてが System Process と Service Process からでした。なので API Hook での確認は意味がない。) なお、マルウェアが NtUnmapViewOfSection() をコールするとすれば、Kernel Mode 側もしくは Session 0 で動作する Service Process から。 一般の User Mode Process から NtUnmapViewOfSection() をコールするなんて、セキュリティ ソフトに「私を見つけて!!」って言ってるようなもんです。
sitsumon_jirou

2020/11/30 07:07

ご指摘ありがとうございます. WinDbgを使用して試してみようと思います. API Hookの使用については吟味します.
Bego

2021/05/12 05:44 編集

間違えました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問