弯路:防止通过另一个软件杀死我的软件的任务

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 视频中所示)。并考虑用您的最新进展更新问题...如果其他人(知识渊博)看到您正在努力工作,他们会提供帮助...

以上是关于弯路:防止通过另一个软件杀死我的软件的任务的主要内容,如果未能解决你的问题,请参考以下文章

如何防止任务管理器杀死我的 pythonw 脚本?

用任务管理器杀死时如何防止内存泄漏[重复]

防止从任务管理器中杀死进程,反转

Delphi 7 - 防止用户在任务管理器中杀死进程

防止iOS在几分钟后杀死App

防止任务(反恶意软件程序)被结束