前提・実現したいこと
Windows APIのWinExec関数を用いたプロセスの起動を捕捉したいと思い,Detoursを用いてWinExec関数をhookしたいと考えました.
しかし,WinExec関数をhookしようとするとエラーが出てきます.
またDetours hook自体が動くか確認用に実装したMessageBoxW関数は正常にhookできます.
発生している問題・エラーメッセージ
Run-Time Check Failure #0 - The value of ESP was no 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.
該当のソースコード
プログラムの構成は「コードを注入するファイル(detours_hook_1113.exe)」と「Detoursを使用した注入されるdllファイル(Dll1.dll)」です.
c++
1#include <Windows.h> 2#include <tchar.h> 3#include <tlhelp32.h> 4#include <stdio.h> 5 6 7#define TARGET_EXE "APIapp1.exe"//対象プロセス 8#define DLL_FILE "Dll1.dll" 9#define MY_PROCESS "detours_hook_1113.exe" 10 11 12 13int APIlog() { 14 //WCHAR* success_procName[1024]; 全体フック用 15 //WCHAR* fault_procName[1024]; 全体フック用 16 int success_num = 0; 17 int fault_num = 0; 18 //get dll path 19 TCHAR dllPath[256]; 20 GetModuleFileName(NULL, dllPath, sizeof(dllPath)); 21 int dllPathLen = (lstrlen(dllPath) + 1) * sizeof(TCHAR); 22 23 _tcscpy_s(_tcsrchr(dllPath, _T('\')) + 1, dllPathLen, _T(DLL_FILE)); 24 25 DWORD targetProcId = -1; //target process id 26 27 //search target process 28 HANDLE hSnapShot; 29 if ((hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)) == INVALID_HANDLE_VALUE) { 30 //CreateToolhelp32Snapshot Error 31 MessageBox(NULL, _T("CreateToolhelp32Snapshot"), _T("Error"), MB_OK); 32 return -1; 33 } 34 35 PROCESSENTRY32 pEntry; 36 pEntry.dwSize = sizeof(pEntry); 37 BOOL result = Process32First(hSnapShot, &pEntry); 38 39 40 41 ////////////////対象のみ////////////////////// 42 while (result) { 43 if (lstrcmp(_T(TARGET_EXE), pEntry.szExeFile) == 0) { 44 targetProcId = pEntry.th32ProcessID; 45 break; 46 } 47 result = Process32Next(hSnapShot, &pEntry); 48 } 49 50 if (targetProcId == -1) { 51 MessageBox(NULL, _T("Process Not Found."), _T("Error"), MB_OK); 52 return -1; 53 } 54 55 //open target process 56 HANDLE hTargetProc; 57 if ((hTargetProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, targetProcId)) == NULL) { 58 //OpenProcess Error 59 MessageBox(NULL, _T("OpenProcess"), _T("Error"), MB_OK); 60 return -1; 61 } 62 63 //VirtualAlloc 64 PWSTR memAddr; 65 if ((memAddr = (PWSTR)VirtualAllocEx(hTargetProc, NULL, dllPathLen, MEM_COMMIT, PAGE_READWRITE)) == NULL) { 66 //VirtualAllocEX Error 67 MessageBox(NULL, _T("VirtualAllocEx"), _T("Error"), MB_OK); 68 return -1; 69 } 70 71 //WriteProcessMemory 72 if (WriteProcessMemory(hTargetProc, memAddr, (PVOID)dllPath, dllPathLen, NULL) == 0) { 73 //WriteProcessMemory Error 74 MessageBox(NULL, _T("WriteProcessMemory"), _T("Error"), MB_OK); 75 return -1; 76 } 77 78 FARPROC LoadLibFunc; 79 if ((LoadLibFunc = GetProcAddress(GetModuleHandle(_T("Kernel32")), "LoadLibraryW")) == NULL) { 80 //GetProcAddress Error 81 MessageBox(NULL, _T("LoadLibraryW_GetProcAddress"), _T("Error"), MB_OK); 82 return -1; 83 } 84 85 //CreateRemoteThread 86 HANDLE hThread; 87 if ((hThread = CreateRemoteThread(hTargetProc, NULL, 0, (PTHREAD_START_ROUTINE)LoadLibFunc, memAddr, 0, NULL)) == NULL) { 88 //CreateRemoteThread Error 89 MessageBox(NULL, _T("CreateRemoteThread"), _T("Error"), MB_OK); 90 return -1; 91 } 92 93 WaitForSingleObject(hThread, INFINITE); 94 //////////////end/////////////////////////////////////// 95 96 printf("Success1\n"); 97 printf("キーを押すとアンロード\n"); 98 getchar(); 99 FARPROC FreeLibFunc; 100 if ((FreeLibFunc = GetProcAddress(GetModuleHandle(_T("Kernel32")), "FreeLibrary")) == NULL) { 101 //GetProcAddress Error 102 MessageBox(NULL, _T("FreeLibrary_GetProcAddress"), _T("Error"), MB_OK); 103 return -1; 104 } 105 106 WaitForSingleObject(hThread, INFINITE); 107 108 printf("Success2\n"); 109 getchar(); 110 CloseHandle(hSnapShot); 111 return 0; 112} 113//////////////////////APIend/////////////////////////////////////////// 114 115int main(void) 116{ 117 APIlog(); 118}
c++
1 2#include <windows.h> 3#include <tchar.h>//_Tマクロの設定 4#include <dbghelp.h>//デバッグのやつ? 5#include <detours.h>//detours hookのやつ 6#include<stdio.h> 7#include <winternl.h>//nt系の話? 8#include <psapi.h>//getmodulename() 9#include<fstream>//出力系 10#include<iostream>//出力系? 11#include <time.h>//時刻 12//#include <string> 13 14 15//#include <stdlib.h> 16//#include <locale.h> 17 18#include "header.h" 19#include <tlhelp32.h> 20 21#pragma comment(lib,"ntdll.lib") 22#pragma comment(lib, "detours.lib") 23 24 25const char* logfilename = "C:\logfile.txt"//ログファイル名 26 27bool Hookfunc_flag = FALSE; 28using Type1 = decltype(MessageBoxW); 29Type1* PureMessageBoxW = &MessageBoxW; 30using Type2 = decltype(WinExec); 31Type2* PureWinExec = &WinExec; 32 33 34///////////////実装されているAPIリスト/////////////////////////////////////////////////// 35int WINAPI HookMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType); 36UINT HookWinExec(LPCSTR lpCmdLine,UINT uCmdShow); 37//////////////////////////////////////////////////////////////////////////////////////////////////////////// 38 39BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) 40{ 41 BOOL bResult = FALSE; 42 43 switch (ul_reason_for_call) 44 { 45 case DLL_PROCESS_ATTACH: 46 { 47 DetourRestoreAfterWith(); 48 DetourTransactionBegin(); 49 DetourUpdateThread(GetCurrentThread()); 50 DetourAttach(&(PVOID&)PureMessageBoxW, HookMessageBoxW); 51 DetourAttach(&(PVOID&)PureWinExec, HookWinExec); 52 DetourTransactionCommit(); 53 printf("ATTACH"); 54 getchar(); 55 } 56 57 break; 58 59 case DLL_PROCESS_DETACH: 60 { 61 DetourTransactionBegin(); 62 DetourUpdateThread(GetCurrentThread()); 63 DetourDetach(&(PVOID&)PureMessageBoxW, HookMessageBoxW); 64 DetourDetach(&(PVOID&)PureWinExec, HookWinExec); 65 DetourTransactionCommit(); 66 printf("DETTACH"); 67 getchar(); 68 } 69 break; 70 71 default: 72 break; 73 } 74 return TRUE; 75} 76 77 78/////////////////////フック関数群//////////////////////////////////// 79///////////////////messageboxW-begin//////////////////////////////////// 80int WINAPI HookMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType) 81{ 82 if (Hookfunc_flag) { 83 return PureMessageBoxW(hWnd, lpText, lpCaption, uType); 84 } 85 Hookfunc_flag = TRUE; 86 87 printf("mesW_dbg\n"); 88 89 TCHAR procName[MAX_PATH] = TEXT("<unknown>"); 90 GetModuleBaseName(GetCurrentProcess(), 0, procName, sizeof(procName) / sizeof(TCHAR)); 91 time_t timer; 92 struct tm local_time; 93 timer = time(NULL); 94 localtime_s(&local_time, &timer); 95 96 std::wofstream outputfile(logfilename, std::ios::app); 97 outputfile << local_time.tm_year + 1900; 98 outputfile << "/"; 99 outputfile << local_time.tm_mon + 1; 100 outputfile << "/"; 101 outputfile << local_time.tm_mday; 102 outputfile << " "; 103 outputfile << local_time.tm_hour; 104 outputfile << ":"; 105 outputfile << local_time.tm_min; 106 outputfile << ":"; 107 outputfile << local_time.tm_sec; 108 outputfile << " "; 109 outputfile << procName; 110 outputfile << "->MessageBoxW:"; 111 outputfile << lpText; 112 outputfile << "\n"; 113 outputfile.close(); 114 Hookfunc_flag = FALSE; 115 return PureMessageBoxW(NULL, L"hook_W", L"hook_W", MB_OK); 116} 117/////////////messageboxW-end//////////////////////////////////// 118 119////////////WinExec//////////////////////////// 120UINT HookWinExec( 121 LPCSTR lpCmdLine, 122 UINT uCmdShow 123) 124{ 125 if (Hookfunc_flag) { 126 return PureWinExec( 127 lpCmdLine, 128 uCmdShow 129 ); 130 } 131 Hookfunc_flag = TRUE; 132 133 printf("win_dbg\n"); 134 135 TCHAR procName[MAX_PATH] = TEXT("<unknown>"); 136 GetModuleBaseName(GetCurrentProcess(), 0, procName, sizeof(procName) / sizeof(TCHAR)); 137 printf("ProcessName:%ws",procName); 138 time_t timer; 139 struct tm local_time; 140 timer = time(NULL); 141 localtime_s(&local_time, &timer); 142 143 std::wofstream outputfile(logfilename, std::ios::app); 144 outputfile << local_time.tm_year + 1900; 145 outputfile << "/"; 146 outputfile << local_time.tm_mon + 1; 147 outputfile << "/"; 148 outputfile << local_time.tm_mday; 149 outputfile << " "; 150 outputfile << local_time.tm_hour; 151 outputfile << ":"; 152 outputfile << local_time.tm_min; 153 outputfile << ":"; 154 outputfile << local_time.tm_sec; 155 outputfile << " "; 156 outputfile << procName; 157 outputfile << "->WinExec->"; 158 outputfile << lpCmdLine; 159 160 outputfile << "\n"; 161 outputfile.close(); 162 Hookfunc_flag = FALSE; 163 return PureWinExec(lpCmdLine, uCmdShow); 164} 165/////////////WinExec-end////////////////////////////////////
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/06/28 07:53