當前位置:編程學習大全網 - 源碼下載 - C語言 如何讓任務管理器無法結束進程

C語言 如何讓任務管理器無法結束進程

HOOK TerminateProcess()這個API函數

我這裏有源代碼,要的話留郵箱

我先把主要的自定義類貼出來:

/////////////////////////////////////////////////////////

// APIHook.h文件

#ifndef __APIHOOK_H__

#define __APIHOOK_H__

#include <windows.h>

class CAPIHook

{

public:

CAPIHook(LPSTR pszModName,

LPSTR pszFuncName, PROC pfnHook, BOOL bExcludeAPIHookMod = TRUE);

virtual ~CAPIHook();

operator PROC() { return m_pfnOrig; }

// 實現

private:

LPSTR m_pszModName; // 導出要HOOK函數的模塊的名字

LPSTR m_pszFuncName; // 要HOOK的函數的名字

PROC m_pfnOrig; // 原API函數地址

PROC m_pfnHook; // HOOK後函數的地址

BOOL m_bExcludeAPIHookMod; // 是否將HOOK API的模塊排除在外

private:

static void ReplaceIATEntryInAllMods(LPSTR pszExportMod, PROC pfnCurrent,

PROC pfnNew, BOOL bExcludeAPIHookMod);

static void ReplaceIATEntryInOneMod(LPSTR pszExportMod,

PROC pfnCurrent, PROC pfnNew, HMODULE hModCaller);

// 下面的代碼用來解決其它模塊動態加載DLL的問題

private:

// 這兩個指針用來將所有的CAPIHook對象連在壹起

static CAPIHook *sm_pHeader;

CAPIHook *m_pNext;

private:

// 當壹個新的DLL被加載時,調用此函數

static void WINAPI HookNewlyLoadedModule(HMODULE hModule, DWORD dwFlags);

// 用來跟蹤當前進程加載新的DLL

static HMODULE WINAPI LoadLibraryA(PCSTR pszModulePath);

static HMODULE WINAPI LoadLibraryW(PCWSTR pszModulePath);

static HMODULE WINAPI LoadLibraryExA(PCSTR pszModulePath, HANDLE hFile, DWORD dwFlags);

static HMODULE WINAPI LoadLibraryExW(PCWSTR pszModulePath, HANDLE hFile, DWORD dwFlags);

// 如果請求已HOOK的API函數,則返回用戶自定義函數的地址

static FARPROC WINAPI GetProcAddress(HMODULE hModule, PCSTR pszProcName);

private:

// 自動對這些函數進行掛鉤

static CAPIHook sm_LoadLibraryA;

static CAPIHook sm_LoadLibraryW;

static CAPIHook sm_LoadLibraryExA;

static CAPIHook sm_LoadLibraryExW;

static CAPIHook sm_GetProcAddress;

};

#endif // __APIHOOK_H__

//////////////////////////////////////////////////////////////

// APIHook.cpp文件

#include "APIHook.h"

#include "Tlhelp32.h"

#include <ImageHlp.h> // 為了調用ImageDirectoryEntryToData函數

#pragma comment(lib, "ImageHlp")

// CAPIHook對象鏈表的頭指針

CAPIHook* CAPIHook::sm_pHeader = NULL;

CAPIHook::CAPIHook(LPSTR pszModName, LPSTR pszFuncName, PROC pfnHook, BOOL bExcludeAPIHookMod)

{

// 保存這個Hook函數的信息

m_bExcludeAPIHookMod = bExcludeAPIHookMod;

m_pszModName = pszModName;

m_pszFuncName = pszFuncName;

m_pfnHook = pfnHook;

m_pfnOrig = ::GetProcAddress(::GetModuleHandle(pszModName), pszFuncName);

// 將此對象添加到鏈表中

m_pNext = sm_pHeader;

sm_pHeader = this;

// 在所有當前已加載的模塊中HOOK這個函數

ReplaceIATEntryInAllMods(m_pszModName, m_pfnOrig, m_pfnHook, bExcludeAPIHookMod);

}

CAPIHook::~CAPIHook()

{

// 取消對所有模塊中函數的HOOK

ReplaceIATEntryInAllMods(m_pszModName, m_pfnHook, m_pfnOrig, m_bExcludeAPIHookMod);

CAPIHook *p = sm_pHeader;

// 從鏈表中移除此對象

if(p == this)

{

sm_pHeader = p->m_pNext;

}

else

{

while(p != NULL)

{

if(p->m_pNext == this)

{

p->m_pNext = this->m_pNext;

break;

}

p = p->m_pNext;

}

}

}

void CAPIHook::ReplaceIATEntryInOneMod(LPSTR pszExportMod,

PROC pfnCurrent, PROC pfnNew, HMODULE hModCaller)

{

// 取得模塊的導入表(import descriptor)首地址。ImageDirectoryEntryToData函數可以直接返回導入表地址

ULONG ulSize;

PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)

::ImageDirectoryEntryToData(hModCaller, TRUE,

IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize);

if(pImportDesc == NULL) // 這個模塊沒有導入節表

{

return;

}

// 查找包含pszExportMod模塊中函數導入信息的導入表項

while(pImportDesc->Name != 0)

{

LPSTR pszMod = (LPSTR)((DWORD)hModCaller + pImportDesc->Name);

if(lstrcmpiA(pszMod, pszExportMod) == 0) // 找到

break;

pImportDesc++;

}

if(pImportDesc->Name == 0) // hModCaller模塊沒有從pszExportMod模塊導入任何函數

{

return;

}

// 取得調用者的導入地址表(import address table, IAT)

PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)(pImportDesc->FirstThunk + (DWORD)hModCaller);

// 查找我們要HOOK的函數,將它的地址用新函數的地址替換掉

while(pThunk->u1.Function)

{

// lpAddr指向的內存保存了函數的地址

PDWORD lpAddr = (PDWORD)&(pThunk->u1.Function);

if(*lpAddr == (DWORD)pfnCurrent)

{

// 修改頁的保護屬性

DWORD dwOldProtect;

MEMORY_BASIC_INFORMATION mbi;

::VirtualQuery(lpAddr, &mbi, sizeof(mbi));

::VirtualProtect(lpAddr, sizeof(DWORD), PAGE_READWRITE, &dwOldProtect);

// 修改內存地址 相當於“*lpAddr = (DWORD)pfnNew;”

::WriteProcessMemory(::GetCurrentProcess(),

lpAddr, &pfnNew, sizeof(DWORD), NULL);

::VirtualProtect(lpAddr, sizeof(DWORD), dwOldProtect, 0);

break;

}

pThunk++;

}

}

void CAPIHook::ReplaceIATEntryInAllMods(LPSTR pszExportMod,

PROC pfnCurrent, PROC pfnNew, BOOL bExcludeAPIHookMod)

{

// 取得當前模塊的句柄

HMODULE hModThis = NULL;

if(bExcludeAPIHookMod)

{

MEMORY_BASIC_INFORMATION mbi;

if(::VirtualQuery(ReplaceIATEntryInAllMods, &mbi, sizeof(mbi)) != 0)

hModThis = (HMODULE)mbi.AllocationBase;

}

// 取得本進程的模塊列表

HANDLE hSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ::GetCurrentProcessId());

// 遍歷所有模塊,分別對它們調用ReplaceIATEntryInOneMod函數,修改導入地址表

MODULEENTRY32 me = { sizeof(MODULEENTRY32) };

BOOL bOK = ::Module32First(hSnap, &me);

while(bOK)

{

// 註意:我們不HOOK當前模塊的函數

if(me.hModule != hModThis)

ReplaceIATEntryInOneMod(pszExportMod, pfnCurrent, pfnNew, me.hModule);

bOK = ::Module32Next(hSnap, &me);

}

::CloseHandle(hSnap);

}

// 掛鉤LoadLibrary和GetProcAddress函數,以便在這些函數被調用以後,掛鉤的函數也能夠被正確的處理

CAPIHook CAPIHook::sm_LoadLibraryA("Kernel32.dll", "LoadLibraryA",

(PROC)CAPIHook::LoadLibraryA, TRUE);

CAPIHook CAPIHook::sm_LoadLibraryW("Kernel32.dll", "LoadLibraryW",

(PROC)CAPIHook::LoadLibraryW, TRUE);

CAPIHook CAPIHook::sm_LoadLibraryExA("Kernel32.dll", "LoadLibraryExA",

(PROC)CAPIHook::LoadLibraryExA, TRUE);

CAPIHook CAPIHook::sm_LoadLibraryExW("Kernel32.dll", "LoadLibraryExW",

(PROC)CAPIHook::LoadLibraryExW, TRUE);

CAPIHook CAPIHook::sm_GetProcAddress("Kernel32.dll", "GetProcAddress",

(PROC)CAPIHook::GetProcAddress, TRUE);

void WINAPI CAPIHook::HookNewlyLoadedModule(HMODULE hModule, DWORD dwFlags)

{

// 如果壹個新的模塊被加載,掛鉤各CAPIHook對象要求的API函數

if((hModule != NULL) && ((dwFlags&LOAD_LIBRARY_AS_DATAFILE) == 0))

{

CAPIHook *p = sm_pHeader;

while(p != NULL)

{

ReplaceIATEntryInOneMod(p->m_pszModName, p->m_pfnOrig, p->m_pfnHook, hModule);

p = p->m_pNext;

}

}

}

HMODULE WINAPI CAPIHook::LoadLibraryA(PCSTR pszModulePath)

{

HMODULE hModule = ::LoadLibraryA(pszModulePath);

HookNewlyLoadedModule(hModule, 0);

return(hModule);

}

HMODULE WINAPI CAPIHook::LoadLibraryW(PCWSTR pszModulePath)

{

HMODULE hModule = ::LoadLibraryW(pszModulePath);

HookNewlyLoadedModule(hModule, 0);

return(hModule);

}

HMODULE WINAPI CAPIHook::LoadLibraryExA(PCSTR pszModulePath, HANDLE hFile, DWORD dwFlags)

{

HMODULE hModule = ::LoadLibraryExA(pszModulePath, hFile, dwFlags);

HookNewlyLoadedModule(hModule, dwFlags);

return(hModule);

}

HMODULE WINAPI CAPIHook::LoadLibraryExW(PCWSTR pszModulePath, HANDLE hFile, DWORD dwFlags)

{

HMODULE hModule = ::LoadLibraryExW(pszModulePath, hFile, dwFlags);

HookNewlyLoadedModule(hModule, dwFlags);

return(hModule);

}

FARPROC WINAPI CAPIHook::GetProcAddress(HMODULE hModule, PCSTR pszProcName)

{

// 得到這個函數的真實地址

FARPROC pfn = ::GetProcAddress(hModule, pszProcName);

// 看它是不是我們要hook的函數

CAPIHook *p = sm_pHeader;

while(p != NULL)

{

if(p->m_pfnOrig == pfn)

{

pfn = p->m_pfnHook;

break;

}

p = p->m_pNext;

}

return pfn;

}

如果妳對HOOK API有壹頂的了解m就可以用這個類來實現妳的程序:

最重要的2個接口:

static void ReplaceIATEntryInAllMods(LPSTR pszExportMod, PROC pfnCurrent,

PROC pfnNew, BOOL bExcludeAPIHookMod);

HOOK所有模塊

static void ReplaceIATEntryInOneMod(LPSTR pszExportMod,

PROC pfnCurrent, PROC pfnNew, HMODULE hModCaller);

HOOK 指定模塊

妳只要能使所有進程都HOOK所有模塊,就能達到妳的目的

<很明顯利用全局鉤子嘛>

把妳要HOOK的代碼放到DLL裏面,讓所有進程加載,就能實現了

  • 上一篇:號角專精哪個技能
  • 下一篇:Pos免費獲得源代碼
  • copyright 2024編程學習大全網