どうやって他のプロセスに殺されるのを防ぐの?


プロセス防殺の実現
WINDOWSのオペレーティングシステムの下で、私达がどのようにプログラムを终えることができない时、あるいはどのように1つのプログラムを终えることが分からない时、あるいは“退出”ボタンを探すのがおっくうな时、通常“CTRL+ALT+DEL”を押してタスクマネージャを呼び出して、终わりたいプログラムを探し当てて、“任务を终える”をクリックして事を终えて、ほほほ、少し乱暴ですが、しかし大多数の情况の下ですべてとても有効で、そうじゃないですか.
想定すると、あるユーザーのパソコンでの活動を一定の制限し、ユーザーに「タスクを終了する」という方法で簡単に制限を解除されないようにするソフトウェアがあれば、どうすればいいのでしょうか.3つの方法があるにほかならない.「CTRL+ALT+DEL」というホットキーの組み合わせをブロックします.2.タスクマネージャのリストにプログラムを表示させない.3.タスクマネージャがこのタスクを殺すことができないようにします.第一の方法については、これはあまりにも残酷で、「任務を終わらせる」という方法に慣れている人は慣れません.第2の方法については、WINDOWS 9 Xの下で登録サービスプロセスを簡単に使用する方法で実現できるが、WINDOWS NTアーキテクチャのオペレーティングシステムにはこの方法がなく、プロセスは身を隠すことが難しく、依然として隠蔽を実現することができるが、実現メカニズムは複雑である.第3の方法については、実現が簡単ですが、私の作品:IPGateウェブサイトフィルタはこのような方法で防殺されています.次に、この方法を紹介します.
タスクマネージャの「タスクの終了」は、実際にはプロセスの強制終了であり、TerminateProcess()というWin 32 API関数を使用しています.定義を見てみましょう.
BOOL TerminateProcess(
HANDLE hProcess;//プロセスを終了するハンドル
UINT uExitCode;//プロセスの終了コードの指定
);
ここを見て、下を見なくても次に何をするかがわかるような気がしますか:Hook TerminateProcess()関数は、TerminateProcess()が呼び出されるたびに、意図的に終了したプロセスが私のプロセスかどうかを判断し、そうであれば簡単にエラーコードを返すことができます.本当に簡単ですか?まず、hProcessに基づいて私のプロセスのハンドルであるかどうかを判断する方法を提案します.答えは:私のプロセスの中でまず私のプロセスのハンドルを得て、それからプロセス間の通信メカニズムを通じてフック関数に伝達して、hProcessと比較すればいいのではないでしょうか.間違いだ!ハンドルはプロセスに関連する値であるため、異なるプロセスで得られた私のプロセスのハンドルの値をプロセス間で比較することは意味がありません.
どうしよう?私のhProcessがどのように得たのかを考察してみましょう.1つのプロセスはそのプロセスIDだけがユニークで、オペレーティングシステムはプロセスIDを通じて1つのプロセスを識別し、あるプログラムがこのプロセスにアクセスする場合、まずOpenProcessという関数を使用してアクセスするプロセスIDを入力してプロセスのハンドルを取得し、そのパラメータを見てみましょう.
HANDLE OpenProcess(
DWORDdwDesiredAccess,//希望アクセス権
BOOL bInheritHandle,//取得したハンドルを継承したいかどうかを示す
DWORDdwProcessId//アクセスするプロセスID
);
脈絡が徐々に現れる:TerminateProcess()を呼び出す前にOpenProcess()を呼び出す必要があり、OpenProcess()のパラメータテーブルのdwProcessIdはシステム範囲内で唯一決定される.Hookの関数はTerminateProcess()ではなくOpenProcess()で、OpenProcess()を呼び出すたびに、dwProcessIdが私のプロセスのIDであるかどうかを確認し(プロセス間通信メカニズムを利用して)、そうであれば簡単にエラーコードを返すことができ、タスクマネージャは私のプロセスのハンドルを手に入れることができず、どのように私のプロセスを終了しますか?
これで,疑念団はすべて明らかになった.Hook TerminateProcess()からHook OpenProcess()へのこの過程は、逆思考の思想を体現している.実は私は当初TerminateProcess()の袋小路に潜り込んで半日も出てこなかったのですが、結局インスピレーションの火花が飛び出し、OpenProcess()に注意力が移り、プロセス防殺を実現しました.喜びのあまり、この心得を出してみんなと分かち合います.
Windows NTでのOpenProcess関数のキャプチャによる本プロセスの終了を禁止するVCコードは以下の通りである.
StickyApp32.cppファイル
#include 
#include "HookAPI.h"

typedef HANDLE (__stdcall *OPENPROCESS_PROC)(DWORD, BOOL, DWORD);

OPENPROCESS_PROC pOpenProcess = NULL;

HANDLE __stdcall OpenProcess_Handler(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
{
HANDLE RetValue = NULL;
HWND hWnd;
DWORD ProcessId;

hWnd = FindWindow("ThunderRT5Form", "StickyApp32";

GetWindowThreadProcessId(hWnd, &ProcessId);

if (dwProcessId != ProcessId)
RetValue = pOpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);

return RetValue;
}


__declspec(dllexport) LRESULT CALLBACK HookFunction(int code, WPARAM wParam, LPARAM lParam)
{
if (pOpenProcess == NULL)
pOpenProcess = (OPENPROCESS_PROC)HookAPIFunction(GetModuleHandle(NULL), "KERNEL32.DLL", "OpenProcess", (PROC)OpenProcess_Handler);

return false;
}


BOOL WINAPI DllMain(HANDLE hInst, ULONG dwReason, LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:

DisableThreadLibraryCalls(hInst);

break;
}

return true;
}

HOOKAPI.cppファイル
// ----------
// HOOKAPI - Matt Pietrek 1995
// ----------

#include 
#include "HookAPI.h"

// Macro for adding pointers/DWORDs together without C arithmetic interfering

#define MakePtr(cast, ptr, addValue) (cast)((DWORD)(ptr)+(DWORD)(addValue))

PROC HookAPIFunction(HMODULE hFromModule,
PSTR pszFunctionModule,
PSTR pszFunctionName,
PROC pfnNewProc)
{
PROC pfnOriginalProc;
PIMAGE_DOS_HEADER pDosHeader;
PIMAGE_NT_HEADERS pNTHeader;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
PIMAGE_THUNK_DATA pThunk;

DWORD dwProtectionFlags;
DWORD dwScratch;

// Verify that a valid pfn was passed

if (IsBadCodePtr(pfnNewProc)) return 0;

// First, verify the the module and function names passed to use are valid

pfnOriginalProc = GetProcAddress(GetModuleHandle(pszFunctionModule), pszFunctionName);

if (!pfnOriginalProc) return 0;

pDosHeader = (PIMAGE_DOS_HEADER)hFromModule;

// Tests to make sure we're looking at a module image (the 'MZ' header)

if (IsBadReadPtr(pDosHeader, sizeof(IMAGE_DOS_HEADER))) return 0;

if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) return 0;

// The MZ header has a pointer to the PE header

pNTHeader = MakePtr(PIMAGE_NT_HEADERS, pDosHeader, pDosHeader->e_lfanew);

// More tests to make sure we're looking at a "PE" image

if (IsBadReadPtr(pNTHeader, sizeof(IMAGE_NT_HEADERS))) return 0;

if (pNTHeader->Signature != IMAGE_NT_SIGNATURE) return 0;

// We know have a valid pointer to the module's PE header.
// Now go get a pointer to its imports section

pImportDesc = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, pDosHeader,
pNTHeader->OptionalHeader.
DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].
VirtualAddress);

// Bail out if the RVA of the imports section is 0 (it doesn't exist)

if (pImportDesc == (PIMAGE_IMPORT_DESCRIPTOR)pNTHeader) return 0;

// Iterate through the array of imported module descriptors, looking
// for the module whose name matches the pszFunctionModule parameter

while (pImportDesc->Name)
{
PSTR pszModName = MakePtr(PSTR, pDosHeader, pImportDesc->Name);

if (stricmp(pszModName, pszFunctionModule) == 0) break;

// Advance to next imported module descriptor

pImportDesc++;
}

// Bail out if we didn't find the import module descriptor for the
// specified module. pImportDesc->Name will be non-zero if we found it.

if (pImportDesc->Name == 0) return 0;

// Get a pointer to the found module's import address table (IAT)

pThunk = MakePtr(PIMAGE_THUNK_DATA, pDosHeader, pImportDesc->FirstThunk);

// Blast through the table of import addresses, looking for the one
// that matches the address we got back from GetProcAddress above.

while (pThunk->u1.Function)
{
if (pThunk->u1.Function == (PDWORD)pfnOriginalProc)
{
dwProtectionFlags = PAGE_READWRITE;

VirtualProtect(&pThunk->u1.Function, 4096, dwProtectionFlags, &dwScratch);

// We found it! Overwrite the original address with the
// address of the interception function. Return the original
// address to the caller so that they can chain on to it.

pThunk->u1.Function = (PDWORD)pfnNewProc;

return pfnOriginalProc;
}

// Advance to next imported function address

pThunk++;
}

// Function not found

return 0;
}

Hookapi.hファイル
#ifndef HOOKAPI_H
#define HOOKAPI_H

PROC HookAPIFunction(HMODULE hFromModule,
PSTR pszFunctionModule,
PSTR pszFunctionName,
PROC pfnNewProc);

#endif