#実現したいこと
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
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/11/02 07:00
2020/11/02 07:16
2020/11/02 08:24 編集
2020/11/02 08:27
2020/11/04 03:13 編集
2020/11/04 05:12 編集
2020/11/04 07:08 編集
2020/11/04 08:34 編集
2020/11/05 04:51
2020/11/05 05:30
2020/11/05 05:42
2020/11/05 06:40 編集
2020/11/06 07:16
2020/11/16 06:03 編集
2020/11/16 08:16 編集
2020/11/17 08:07
2020/11/17 09:23
2020/11/19 07:34 編集
2020/11/19 08:07
2020/11/20 03:57
2020/11/20 06:07
2020/11/20 06:39
2020/11/20 06:59
2020/11/20 07:08
2020/11/20 07:36
2020/11/20 09:01 編集
2020/11/20 08:56
2020/11/20 08:57
2020/11/20 08:57
2020/11/24 04:19
2020/11/24 07:24
2020/11/26 03:17
2020/11/26 05:17
2020/11/27 04:14
2020/11/27 08:09
2020/11/30 07:07
2021/05/12 05:44 編集