MFC/VC++进程自我保护(通过远程线程注入或HOOK)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MFC/VC++进程自我保护(通过远程线程注入或HOOK)相关的知识,希望对你有一定的参考价值。

就是令进程本身无法被关闭或者一关闭就重启,请知道的大侠们不吝赐教,写过的同学把代码贴给小弟看看,谢谢

//dll 代码:
#include <windows.h>

char pNew[8] = 0;
char pOld[8] = 0;

HMODULE hModu = NULL;
DWORD dwOldApi = 0;

void HookApiOn(char* pDllName, char* pApiName,FARPROC pFunc)

DWORD dwOld = 0;
DWORD flag = 0;
hModu = LoadLibrary(pDllName);
dwOldApi = (DWORD)GetProcAddress(hModu,pApiName);

VirtualProtect((LPVOID)dwOldApi,5,PAGE_READWRITE,&dwOld);

char*p = (char*)dwOldApi;
DWORD dd = (DWORD)pFunc - dwOldApi -5 ; //jmp lebel:5个字节
pNew[0] = 0xE9;
*(DWORD*)&(pNew[1]) = dd;
ReadProcessMemory(GetCurrentProcess(),(LPVOID)dwOldApi,(LPVOID)pOld,5,&flag);
//memcpy((void*)pOld,(const void*)dwOldApi,5);

WriteProcessMemory(GetCurrentProcess(),(LPVOID)dwOldApi,(LPVOID)pNew,5,&flag);
VirtualProtect((LPVOID)dwOldApi,5,dwOld,NULL);
return ;


void HookApiOff()


DWORD dwOld = 0;
DWORD flag = 0;

VirtualProtect((LPVOID)dwOldApi,5,PAGE_READWRITE,&dwOld);
WriteProcessMemory(GetCurrentProcess(),(LPVOID)dwOldApi,(LPVOID)pOld,5,&flag);
VirtualProtect((LPVOID)dwOldApi,5,dwOld,NULL);

return ;


void _stdcall my_MessageBoxW( HWND hWnd ,LPCWSTR lpText,LPCWSTR lpCaption,UINT uType)

HookApiOff();
if(IDNO == MessageBoxW(NULL,L"程序非法调用了MessageBoxW函数,是否阻止?",L"提示",MB_YESNO))
MessageBoxW(hWnd,lpText,lpCaption,uType);
HookApiOn("user32.dll","MessageBoxW",(FARPROC)my_MessageBoxW);


void InstallAllHook()

HookApiOn("user32.dll","MessageBoxW",(FARPROC)my_MessageBoxW);

return ;


BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)


switch(ul_reason_for_call)

case DLL_PROCESS_ATTACH:
InstallAllHook();
break;


return TRUE;

//.exe实现进程注入的代码:<此处注入到任务管理器中>
#include <windows.h>
#include <stdio.h>

#define Dll_Name "F:\\workspqce\\Jmp_Hook\\Debug\\jmp_dll.dll"

BOOL EnablePrivilege()

HANDLE hToken = NULL;

if(OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&hToken))

TOKEN_PRIVILEGES tkp= 0;

LookupPrivilegeValue( NULL,SE_DEBUG_NAME,&tkp.Privileges[0].Luid );//修改进程权限
tkp.PrivilegeCount=1;
tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges( hToken,FALSE,&tkp,sizeof tkp,NULL,NULL );//通知系统修改进程权限

return( (GetLastError()==ERROR_SUCCESS) );



return FALSE;


BOOL InjectDll(DWORD dwProcessId)

HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwProcessId);
if(!hProcess)
return FALSE;

LPVOID pszDllName = VirtualAllocEx(hProcess,NULL,strlen(Dll_Name)+1,MEM_COMMIT,PAGE_READWRITE);
if(!pszDllName)
return FALSE;

if(!WriteProcessMemory(hProcess,pszDllName,Dll_Name,strlen(Dll_Name),NULL))
return FALSE;

PTHREAD_START_ROUTINE tsr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")),"LoadLibraryA");
if(!tsr)
return FALSE;

HANDLE hRemote = CreateRemoteThread(hProcess,NULL,0,tsr,pszDllName,0,NULL);
if(!hRemote)
return FALSE;

WaitForSingleObject(hRemote,INFINITE);
VirtualFreeEx(hProcess,pszDllName,strlen(Dll_Name)+1,MEM_RELEASE);

return true;


int main()

DWORD dwProcessId = 0;

HWND hWindow = FindWindow(NULL,"Windows 任务管理器");
GetWindowThreadProcessId(hWindow,&dwProcessId);

if(EnablePrivilege())
InjectDll(dwProcessId);
return 0;
参考技术A 使用全局钩子, 勾住ExitProcess/TerminateProcess API 。 判断进程ID,使之无效就可以了。 参考技术B 给进程设定看门狗

mfc HackerTools远程线程注入

在一个进程中,调用CreateThread或CreateRemoteThreadEx函数,在另一个进程内创建一个线程(因为不在同一个进程中,所以叫做远程线程)。创建的线程一般为Windows API函数LoadLibrary,来加载一个动态链接库(DLL),从而达到在另一个进程中运行自己所希望运行的代码的目的。

步骤:

  1. 打开目标进程
  2. 在目标进程中申请空间
  3. 将要注入的Dll路径写入刚申请的空间中
  4. 获取LoadLibrary函数地址
  5. 在目标进程中创建线程,线程回调函数就是LoadLibrary函数,回调函数参数就是要注入的Dll路径
  6. 等待线程结束
  7. 清理环境
BOOL CInject::ZwCreateThreadExInjectDll(DWORD dwProcessId, char* pszDllFileName)
{
    HANDLE hProcess = NULL;
    SIZE_T dwSize = 0;
    LPVOID pDllAddr = NULL;
    FARPROC pFunProcAddr = NULL;
    HANDLE hRemoteThread = NULL;
    DWORD dwStatus = 0;

    //打开目标进程 获取句柄
    hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
    if (hProcess==NULL)
    {
        m_TipMsg += L"打开进程失败
";
        return FALSE;
    }
    else
    {
        m_TipMsg += L"打开进程成功
";
    }

    //在注入的进程中申请内存
    dwSize = strlen(pszDllFileName) + 1;
    pDllAddr = VirtualAllocEx(hProcess, NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
    if (pDllAddr==NULL)
    {
        m_TipMsg += L"申请内存失败
";
        return FALSE;
    }
    else
    {
        m_TipMsg += L"申请内存成功
";
    }

    //向申请的内存中写入数据
    BOOL bIsSucess = WriteProcessMemory(hProcess, pDllAddr, pszDllFileName, dwSize, NULL);
    if (bIsSucess==FALSE)
    {
        m_TipMsg += L"写入内存失败
";
        return FALSE;
    }
    else
    {
        m_TipMsg += L"写入内存成功
";
    }

    //加载ntdll.dll
    HMODULE hNtdll = LoadLibraryA("ntdll.dll");
    if (hNtdll==NULL)
    {
        m_TipMsg += L"加载ntdll失败
";
        return FALSE;
    }
    else
    {
        m_TipMsg += L"加载ntdll成功
";
    }

    //获取LoadLibraryA函数地址
    pFunProcAddr = GetProcAddress(GetModuleHandleA("Kernel32.dll"), "LoadLibraryA");
    if (pFunProcAddr==NULL)
    {
        m_TipMsg += L"加载LoadLibraryA函数地址失败
";
        return FALSE;
    }
    else
    {
        m_TipMsg += L"加载LoadLibraryA函数地址成功
";
    }

    //获取ZwCreateThread函数地址  ZwCreateThread在64位和32位下的函数声明不一样
#ifdef _WIN64
    typedef DWORD(WINAPI *typedef_ZwCreateThreadEx)(
        PHANDLE ThreadHandle,
        ACCESS_MASK DesiredAccess,
        LPVOID ObjectAttributes,
        HANDLE ProcessHandle,
        LPTHREAD_START_ROUTINE lpStartAddress,
        LPVOID lpParameter,
        ULONG CreateThreadFlags,
        SIZE_T ZeroBits,
        SIZE_T StackSize,
        SIZE_T MaximumStackSize,
        LPVOID pUnkown);
#else
    typedef DWORD(WINAPI *typedef_ZwCreateThreadEx)(
        PHANDLE ThreadHandle,
        ACCESS_MASK DesiredAccess,
        LPVOID ObjectAttributes,
        HANDLE ProcessHandle,
        LPTHREAD_START_ROUTINE lpStartAddress,
        LPVOID lpParameter,
        BOOL CreateSuspended,
        DWORD dwStackSize,
        DWORD dw1,
        DWORD dw2,
        LPVOID pUnkown);
#endif
    typedef_ZwCreateThreadEx ZwCreateThreadEx = (typedef_ZwCreateThreadEx)GetProcAddress(hNtdll, "ZwCreateThreadEx");
    if (ZwCreateThreadEx==NULL)
    {
        m_TipMsg += L"加载ZwCreateThreadEx函数地址失败
";
        return FALSE;
    }
    else
    {
        m_TipMsg += L"加载ZwCreateThreadEx函数地址成功
";
    }
    //使用ZwCreateThreadEx函数创建远程线程 实现DLL注入
    dwStatus = ZwCreateThreadEx(&hRemoteThread, THREAD_ALL_ACCESS, NULL,
    hProcess, (LPTHREAD_START_ROUTINE)pFunProcAddr, pDllAddr, 0, 0, 0, 0, NULL);
    if (hRemoteThread==NULL)
    {
        m_TipMsg += L"远程线程注入失败
";
        return FALSE;
    }
    else
    {
        m_TipMsg += L"远程线程注入成功
";
    }

    //关闭句柄
    CloseHandle(hProcess);
    FreeLibrary(hNtdll);
    return TRUE;

}
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "header.h"

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        MessageBoxA(0,"注入成功","恭喜",0);
        break;
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

 

以上是关于MFC/VC++进程自我保护(通过远程线程注入或HOOK)的主要内容,如果未能解决你的问题,请参考以下文章

VC/MFC啥是逻辑坐标

求exe程序进程自我保护功能不被系统自带的任务管理器结束掉

Windows NT/系统进程的隐藏技术

VC/MFC怎样给菜单项添加勾啊

VC6.0的程序结束后进程不自动结束,如何解决?

基于VC/MFC 的UDP广播,我怎么接受返回的数据包