弯路:防止通过另一个软件杀死我的软件的任务
Posted
技术标签:
【中文标题】弯路:防止通过另一个软件杀死我的软件的任务【英文标题】:Detours: Prevent task kill of my software via another software 【发布时间】:2015-11-04 01:49:39 【问题描述】:我发现了一个代码,它承诺拦截和绕过对TerminateProcess
函数的调用,从而防止我的软件被其他程序直接杀死。
但是这段代码不起作用,我仍然可以通过其他程序杀死我的进程。
这是我在this YouTube video 中找到的代码的最后一次尝试:
PS:victim.exe 是杀手级程序。
DLL
// DllRedirectAPI.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include <Windows.h>
BYTE MOV[10] = 0x48, 0xB8, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 ;
BYTE JMP_RAX[2] = 0xFF, 0xE0 ;
#define BuffSizeX64 (sizeof(MOV) + sizeof(JMP_RAX))
BOOL Hook_Det_x64(char LibName[], char API_Name[], LPVOID NewFun)
DWORD OldProtect;
DWORD64 OrgAddress = (DWORD64)GetProcAddress(LoadLibraryA(LibName), API_Name);
if (OrgAddress == NULL) return 0;
memcpy(&MOV[2], &NewFun, 8);
VirtualProtect((LPVOID)OrgAddress, BuffSizeX64, PAGE_EXECUTE_READWRITE, &OldProtect);
memcpy((LPVOID)OrgAddress, MOV, sizeof(MOV));
memcpy((LPVOID)(OrgAddress + sizeof(MOV)), JMP_RAX, sizeof(JMP_RAX));
VirtualProtect((LPVOID)OrgAddress, BuffSizeX64, OldProtect, &OldProtect);
return 1;
int WINAPI MessageBoxAX(
HWND hWnd,
LPCSTR lpText,
LPCSTR lpCaption,
UINT uType)
MessageBoxExA(0, "Hooked ...", "Mahmoud", 0, 0);
return 999;
BOOL WINAPI DllMain(HMODULE hModule, DWORD Call_Reason, LPVOID lpReserved)
switch (Call_Reason)
case DLL_PROCESS_ATTACH:
Hook_Det_x64("Kernel32.dll", "TerminateProcess", MessageBoxAX);
return 1;
注射器
// Injector.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <tlhelp32.h>
#include <shlwapi.h>
#include <conio.h>
#include <stdio.h>
#include <comdef.h>
#define WIN32_LEAN_AND_MEAN
#define CREATE_THREAD_ACCESS (PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ)
BOOL Inject(DWORD pID, const char * DLL_NAME);
DWORD GetTargetThreadIDFromProcName(const char * ProcName);
int main(int argc, char * argv[])
//############### CHANGE HERE ONLY ###################
char *Target_Process = "victim.exe"; //###
//#######################################################
char *buf;
DWORD pID = GetTargetThreadIDFromProcName(Target_Process);
buf = "DllRedirectAPI.dll";
if (!Inject(pID, buf))
printf("DLL Not Loaded!");
else
printf("DLL is Injected in torget Process");
_getch();
return 0;
BOOL Inject(DWORD pID, const char * DLL_NAME)
HANDLE Proc;
char buf[50] = 0 ;
LPVOID RemoteString, LoadLibAddy;
if (!pID)
return false;
Proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
if (!Proc)
sprintf_s(buf, "OpenProcess() failed: %d", GetLastError());
printf(buf);
return false;
LoadLibAddy = (LPVOID)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "LoadLibraryA");
RemoteString = (LPVOID)VirtualAllocEx(Proc, NULL, strlen(DLL_NAME), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
WriteProcessMemory(Proc, (LPVOID)RemoteString, DLL_NAME, strlen(DLL_NAME), NULL);
CreateRemoteThread(Proc, NULL, NULL, (LPTHREAD_START_ROUTINE)LoadLibAddy, (LPVOID)RemoteString, NULL, NULL);
CloseHandle(Proc);
return true;
DWORD GetTargetThreadIDFromProcName(const char * ProcName)
PROCESSENTRY32 pe;
HANDLE thSnapShot;
BOOL retval, ProcFound = false;
thSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (thSnapShot == INVALID_HANDLE_VALUE)
printf("Error: Unable create toolhelp snapshot!");
return false;
pe.dwSize = sizeof(PROCESSENTRY32);
retval = Process32First(thSnapShot, &pe);
while (retval)
if (_bstr_t(pe.szExeFile) == _bstr_t(ProcName))
return pe.th32ProcessID;
retval = Process32Next(thSnapShot, &pe);
return 0;
谁能帮助我,告诉我哪里出错了?
我的系统是 Windows 7 Ultimate 64 位。
提前致谢。
【问题讨论】:
你确定TaskManager甚至使用TerminateProcess()
吗? Windows 内置的许多功能不使用 kernel32,而是直接使用本机 API(在本例中为 NtTerminateProcess()
。)
AFAIK:在 Windows 中,如果应用程序被杀死,您无法阻止它被关闭
您可能也对此感兴趣:security.stackexchange.com/questions/30985/…。简短的回答是他们不会阻止自己在代码中被杀死。
您的挂钩仅适用于(假设它甚至像宣传的那样工作)由加载它的进程对TerminateProcess
的调用。您没有将其加载到任务管理器中,因此它不会影响任务管理器。
你在写病毒吗?否则 - 为什么你会阻止用户终止你的进程???
【参考方案1】:
(想写评论,但是写的有点长……)
正如@AndrewMedico 在评论中所说:您需要挂钩任务管理器进程的TerminateProcess
,以防止任务管理器终止任何事情。
我建议你以下方法:
尝试简单的 DLL 注入
a/ 创建一个 DLL,在其 DllMain
中打印一些文本,例如printf("I am here\n"); fflush(stdout);
b/ 尝试使用 process hacker 的 Miscellaneous>Inject DLL...
将其注入其他命令行进程c/ 通过检查它的标准输出来验证你的 DLL 是否在目标进程中执行
尝试一个简单的 API 挂钩:
a/ 创建一个命令行应用程序,它等待一个键,然后使用TerminateProcess(GetCurrentProcess(), 1);
的一些变体自行终止。在TerminateProcess
调用之后添加代码以打印一些文本。
b/ 运行此应用程序以验证调用TerminateProcess
后的文本是否未打印。
c/ 在等待使用密钥之前先钩住TerminateProcess
,例如mhook。在替换函数中打印一些文本,然后返回。此处请勿调用原TerminateProcess
。
d/ 运行此应用程序以验证钩子内的文本是否已打印,并且 TerminateProcess
调用之后的文本也已打印(即验证进程终止被抑制)。
结合前面步骤的结果来实现您的目标:
a/ 将第 2 步中的挂钩代码放入第 1 步中的 DLL 中
b/ 在等待密钥时将其从第 2b 步(即没有钩子的应用程序)注入应用程序,并在打印TerminateProcess
后验证文本。
c/ 享受(或调试/责备我)
祝你好运!
编辑>
好的,这是我对这里的看法:
问题中的代码:
(与我在“2b”中建议的应用非常相似)
挂钩TerminateProcess
并改为显示一个消息框。
执行时应该显示一个消息框
(貌似只有32位版本)
YouTube video
显示一个应用程序“Terminate process.exe”,它会终止由名称给出的进程
执行“Injector.exe”后,应用程序停止终止进程并显示一个消息框(恕我直言,“Injector.exe”将“DllFile.dll”注入正在运行的“终止进程”。 exe")
Source code for the injector in the YouTube comments
此代码将 DLL“C:\DllRedirectAPI.dll”注入它找到的第一个名为“victim.exe”的进程
(不注入“Terminate process.exe”,不使用“DllFile.dll”)
Source code for the DLL in the YouTube comments
此代码挂钩函数MessageBoxA
,它改为显示不同的消息框。值得注意的是,钩子代码本身调用了原来的MessageBoxA
,并采取了恢复钩子时所做的修改,调用原来的函数,然后重新应用钩子的方法。
(它根本不挂钩“TerminateProcess”)
(貌似只有32位版本)
64-bit version excerpts
MessageBoxA
的破坏性钩子(即不备份原始代码)
钩子使用MessageBoxExA
(原封不动)来显示不同的消息框(即它不使用覆盖的MessageBoxA
)
(它根本不挂钩“TerminateProcess”)
(是64位版本)
免责声明:100% 确定我不是很精通该主题,请随时纠正/澄清我。
对于实际的挂钩,我个人建议使用mhook library,它对我有用。它的文档也值得一读。
参见例如this 一些替代品(我没有尝试过)...
编辑>
这个适用于我在 VirtualBox 中的 Win XP 上:
#include <windows.h>
#include <stdio.h>
#include <mhook.h>
static BOOL WINAPI
(*_TerminateProcess)(
_In_ HANDLE hProcess,
_In_ UINT uExitCode
) = NULL;
BOOL WINAPI
TerminateProcessImpl(
_In_ HANDLE hProcess,
_In_ UINT uExitCode)
printf("\nBlocked\n"); fflush(stdout);
return 0;
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD Reason, LPVOID Reserved)
if(Reason==DLL_PROCESS_ATTACH)
printf("\nDLL attached!\n"); fflush(stdout);
HMODULE h = LoadLibrary("Kernel32");
if(h!=NULL)
printf("\nGot Kernel32!\n"); fflush(stdout);
_TerminateProcess=(void*)GetProcAddress(h,"TerminateProcess");
if(_TerminateProcess!=NULL)
printf("\nAbout to hook...\n"); fflush(stdout);
if(Mhook_SetHook((void*)&_TerminateProcess, &TerminateProcessImpl))
printf("\nHooked OK!\n"); fflush(stdout);
else
printf("\nHook failed!\n"); fflush(stdout);
return TRUE;
【讨论】:
@vip,好的。关于上面我留下链接的 Youtube 视频,为 Autor 进行的注入仅在TaskMgr.exe
或两个进程中('calc.exe' 和 TaskMgr.exe
)?我不明白这个。
@Cloud.NET 我会说它进入了Terminate Process.exe
。源代码可能不同于用于视频的源代码。 (顺便说一句,可能不适用于 64 位系统,给定 32 位指针)。
@vip,是的,我上面留下的代码与视频不同,是我在另一个站点上捕获的其他代码。但是这个视频的作者也在cmets中留下了一个x64的代码,大概你看到了。我还测试了 x64 代码,但没有成功。如果可以的话,你也可以测试并告诉我测试结果吗?可能是我走错了一步。
我已经测试了autor留在Youtube Video cmets中的Detour_x64.h
,将dll注入Windows的Task Manager.exe
(victim.exe)(在我的情况下为x64),但仍然是这种方式没用。你认为 Windows 的Task Manager
对这种技术有一些保护吗?我对kernel32.dll
和api 函数TerminateProcess
的代码进行了所有修改。是的,我会去测试 MHook 库。
你是如何注入 dll 的?也许使用您自己的进程杀手程序进行测试会更容易(如 YouTube 视频中所示)。并考虑用您的最新进展更新问题...如果其他人(知识渊博)看到您正在努力工作,他们会提供帮助...以上是关于弯路:防止通过另一个软件杀死我的软件的任务的主要内容,如果未能解决你的问题,请参考以下文章