`
eyesye
  • 浏览: 20271 次
最近访客 更多访客>>
社区版块
存档分类
最新评论

进程防杀的实现

    博客分类:
  • arp1
阅读更多

在WINDOWS操作系统下,当我们无法结束或者不知道怎样结束一个程序的时候,或者是懒得去找“退出”按钮的时候,通常会按“CTRL+ALT+DEL”呼出任务管理器,找到想结束的程序,点一下“结束任务”就了事了,呵呵,虽然有点粗鲁,但大多数情况下都很有效,不是吗?

设想一下,如果有这么一种软件,它所要做的工作就是对某个使用者在某台电脑上的活动作一定的限制,而又不能被使用者通过“结束任务”这种方式轻易地解除限制,那该怎么做?无非有这么三种方法:1.屏蔽“CTRL+ALT+DEL”这个热键的组合;2.让程序不出现在任务管理器的列表之中;3.让任务管理器无法杀掉这个任务。对于第一种方法,这样未免也太残酷了,用惯了“结束任务”这种方法的人会很不习惯的;对于第二种方法,在WINDOWS 9X下可以很轻易地使用注册服务进程的方法实现,但是对于WINDOWS NT架构的操作系统没有这个方法了,进程很难藏身,虽然仍然可以实现隐藏,但实现机制较为复杂;对于第三种方法,实现起来比较简单,我的作品:IPGate 网址过滤器 就是采用的这种方式防杀的,接下来我就来介绍这种方法。

任务管理器的“结束任务”实际上就是强制终止进程,它所使用的杀手锏是一个叫做TerminateProcess()的Win32 API函数,我们来看看它的定义:

BOOL TerminateProcess(
HANDLE hProcess; // 将被结束进程的句柄
UINT uExitCode; // 指定进程的退出码
);

看到这里,是不是觉得不必往下看都知道接下来要做什么:Hook TerminateProcess()函数,每次TerminateProcess()被调用的时候先判断企图结束的进程是否是我的进程,如果是的话就简单地返回一个错误码就可以了。真的是这么简单吗?先提出一个问题,如何根据hProcess判断它是否是我的进程的句柄?答案是:在我的进程当中先获得我的进程的句柄,然后通过进程间通讯机制传递给钩子函数,与hProcess进行比较不就行了?错!因为句柄是一个进程相关的值,不同进程中得到的我的进程的句柄的值在进程间进行比较是无意义的。

怎么办?我们来考察一下我的hProcess它是如何得到的。一个进程只有它的进程ID是独一无二的,操作系统通过进程ID来标识一个进程,当某个程序要对这个进程进行访问的话,它首先得用OpenProcess这个函数并传入要访问的进程ID来获得进程的句柄,来看看它的参数:

HANDLE OpenProcess(
DWORD dwDesiredAccess, // 希望获得的访问权限
BOOL bInheritHandle, // 指明是否希望所获得的句柄可以继承
DWORD dwProcessId // 要访问的进程ID
);

脉络渐渐显现:在调用TerminateProcess()之前,必先调用OpenProcess(),而OpenProcess()的参数表中的dwProcessId是在系统范围内唯一确定的。得出结论:要Hook的函数不是TerminateProcess()而是OpenProcess(),在每次调用OpenProcess()的时候,我们先检查dwProcessId是否为我的进程的ID(利用进程间通讯机制),如果是的话就简单地返回一个错误码就可以了,任务管理器拿不到我的进程的句柄,它如何结束我的进程呢?

至此,疑团全部揭开了。由Hook TerminateProcess()到Hook OpenProcess()的这个过程,体现了一个逆向思维的思想。其实我当初钻进了TerminateProcess()的死胡同里半天出也不来,但最终还是蹦出了灵感的火花,注意力转移到了OpenProcess()上面,实现了进程防杀。喜悦之余,将这心得体会拿出来与大家分享。


windowsNT下的通过截获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
分享到:
评论

相关推荐

    进程防杀 HOOK ,防止任务管理杀死程序

    进程防杀技术主要涉及到计算机系统中的进程管理和保护机制,尤其是如何在面对恶意操作或系统工具如任务管理器的干预时,保持程序的持续运行。在本文中,我们将深入探讨HOOK技术及其在进程保护中的应用。 HOOK是...

    进程防杀hook openprocess[C]

    在IT领域,尤其是在系统安全和恶意软件分析中,"进程防杀"是一个关键的话题,而"hook openprocess"则是这个话题中的一个重要技术手段。这里我们将深入探讨这两个概念以及它们之间的关联。 首先,让我们理解什么是...

    加载驱动进程防杀的软件源码

    【加载驱动进程防杀的软件源码】是一个与系统安全和程序防护相关的VB源码集合。这个主题涉及到计算机操作系统中的核心组件,特别是驱动程序管理和进程保护。在Windows系统中,驱动程序是操作系统与硬件交互的关键,...

    利用hook OpenProcess实现进程防杀的DLL源码

    总之,hook `OpenProcess`是实现进程防杀的一种有效方法,它通过对关键系统函数的监控和控制,增强了系统的保护能力。然而,这种技术也存在潜在的风险,如误报或破坏其他合法程序的运行,因此在实际应用中需要谨慎...

    进程防杀 Hook OpenProcess

    进程防杀技术是一种在计算机安全领域中用于保护恶意软件或合法程序免受反病毒软件和其他安全工具检测和清除的方法。Hook OpenProcess是其中一种常用的技术手段,它涉及到系统调用拦截和过程注入。 OpenProcess是...

    完整版进程防杀模块.rar

    进程防杀模块是计算机安全领域中的一个重要组成部分,主要用于保护系统免受恶意软件的侵害,特别是那些试图通过控制或隐藏进程来实现自身隐藏和持久化的行为。这个“完整版进程防杀模块.rar”压缩包文件很可能包含了...

    6种进程防杀方案和源码.rar

    优点:ring3实现的进程防杀,无驱动无hook,原理及代码都较为简单,能防止任务管理器杀掉进程 缺点:只能下xp下有效(与xp打的补丁也有关,有的xp系统会失败)防杀能力有限,例如不能防住IceSword等工具 该方法是参考了csdn一...

    Hook+-+进程防杀

    《Hook进程防杀技术解析与应用》 在计算机软件领域,Hook是一种强大的技术,它允许开发者拦截并处理特定系统调用或API函数,以便在原始功能执行前后进行自定义操作。"Hook+进程防杀"是指通过Hook技术来防止反病毒...

    易语言进程防杀、防结束模块

    易语言进程防杀模块的实现原理可能包括以下几个方面: 1. **权限提升**:通过获取更高的系统权限,如管理员权限,使得程序在运行时拥有更大的控制权,从而能更有效地防止被低权限的进程结束。 2. **钩子技术**:...

    进程防杀C++实例源代码

    C++实现进程防杀实例源代码.....支持C#外部调用...[DllImport("NoKillDll.dll", EntryPoint = "Init")] private extern static void Init(); //调用 Init();

    VS 2017 C++ 防杀进程

    "VS 2017 C++ 防杀进程"是一个利用Visual Studio 2017的C++编程语言编写的程序,旨在使自身免受NTSD、WMIC、TASKKILL等常见进程结束工具的影响,同时也包括任务管理器。这个程序特别针对64位Windows操作系统设计,以...

    ring3实现的进程防杀

    在IT安全领域,"ring3实现的进程防杀"是一个重要的技术话题,它涉及到系统级保护和反恶意软件策略。Ring3是CPU操作模式之一,通常指用户模式,与Ring0(内核模式)相对。在用户模式下运行的代码不能直接访问硬件资源...

    ring3实现任务管理器的进程防杀

    "ring3实现任务管理器的进程防杀"是指在用户模式下编写程序来防止其他进程被任务管理器或其他类似工具结束。这种方法主要用于保护关键进程的安全,使其免受恶意软件或未经授权的操作影响。 C++是实现这一目标的常用...

    意天进程防杀保护开发包(进程防杀组件) 1.0.0.1

    6. **dll**:动态链接库文件,这些文件包含了实际的进程防杀功能实现,开发者在编译时需要链接这些库才能使用开发包的功能。 7. **demo**:演示或示例程序,用于展示如何在实际项目中应用开发包,是学习和理解开发...

    易语言进程防杀模块下载的快来

    易语言进程防杀模块是一种专为易语言编程环境设计的安全技术组件,用于增强程序的自我保护能力,防止恶意软件分析、篡改或杀死程序进程。这个模块通过一系列的技术手段,如进程隐藏、反调试、内存保护等,为易语言...

    delphi进程防杀例子

    在Delphi中实现进程防杀,主要涉及以下几个技术点: 1. **隐藏进程**:通过修改进程属性,如隐藏进程窗口、改变进程名称等,使得其他程序难以发现进程的存在。 2. **注入代码**:将自定义代码注入到其他进程中,以...

    C++双进程防杀屏蔽键盘钩子程序

    《C++实现双进程防杀与键盘钩子技术解析》 在计算机编程领域,尤其是在系统级编程中,有时我们需要对特定的系统行为进行监控或控制,例如捕获键盘输入、防止自身进程被杀死等。本篇文章将深入探讨如何利用C++实现...

    意天进程保护开发包(进程防杀组件)

    意天 进程保护 开发包( 进程防杀 组件)是意天软件推出的一款 进程保护 开发包,用该 进程保护 开发包主要可使开发人员保护自己的进程不被 taskmanager等工具杀掉实现 进程保护 功能,同时taskmanager等工具也无法获得...

    hook 任务管理器 进程防杀

    在IT领域,尤其是系统安全和恶意软件防护方面,“hook 任务管理器 进程防杀”是一个关键的技术点。这个标题暗示了一种技术手段,即通过hook(钩子)技术来防止目标进程被任务管理器或其他类似工具结束,从而增强程序...

    2个相互守护防杀的进程.两个进程互相守护防杀

    标题和描述中提到的"2个相互守护防杀的进程"是一种设计模式,用于确保两个关键进程在对方被意外终止时能够互相启动对方,从而提高系统的稳定性和可靠性。这种机制常用于安全软件或者管理系统中,确保核心服务不会...

Global site tag (gtag.js) - Google Analytics