ring3实现进程保护

    Ring3下Hook进程有多种方法,其中有消钩子(Msg Hook)、线程注入(Insert Thread)和ShellCode等,前两种最为常见。以前用VB只能用shellcode,原因是VB不支持标准DLL,而VC则完全不成问题,下面说一下方法。消息注入是通过SetWindowsHookEx安装一个钩子(比如WH_GETMESSAGE)然后将DLL注入系统所有GUI进程,这样,大部分进程都会自动加载这个DLL,然后自己通过事先写好的DLL代码来获取其它进程的控制权,但对控制台程序(Console)不支持。第二种远程线程注入则更灵活,但早已被杀毒软件列为木马之列,调用CreateRemoteThread(创建远程线程)基本上杀软都会拦截。远线程方法基本可注入任意进程,但比较麻烦,一次只能注入一个进程,当有新进程启动后,不会自己加载你的DLL,所以得重新注入。

    要保护进程就要Hook掉与进程有关的API,如kernel32库中的OpenProcess(打开进程)、OpenThread(打开线程)、TerminateProcess(终止进程),ntdll中的ZwOpenProcess(NtOpenProcess)、ZwTerminateProcess等。hook Nt函数比较麻烦,这里我们Hook OpenProcess,这比hook TerminateProcess彻底。不过ring3下的hook基本没什么用,容易被攻破,这里只是举个例子,真正要保护进程最好还是写个sys,然后Hook SSDT或者inline hook比较靠谱。另外,这种方法只能防止终止进程,例如防止在任务管理器里结束自己,但无法防GUI,GUI保护比较麻烦,ring0下实用,ring3下一般没什么意义。以下代码在xp/sp3和VC++6.0精简版下测试成功。

DLL代码如下:

// hook.cpp : Defines the entry point for the DLL application.

//************************ Win32DLL  hook.dll ************************************

//******************* http://zzmzzff.blog.163.com ********************************

//************* ring3进程保护模块 Hook kernel32.OpenProcess by飞哥 ***************

#include "stdafx.h"
#include "windows.h"
#include "stdio.h"
#include "hook.h"
#define DLL_API extern "C" _declspec(dllexport)

BYTE oldCode[5];  //旧代码
BYTE newCode[5];  //新代码
ULONG mFunAddr;  //hook目标API地址
HHOOK hHook=0;  //msg hook句柄
HANDLE hProcess=0;  //进程句柄
HWND hWndApp=0;  //窗口句柄
HINSTANCE hMod=0;  //模块句柄


BOOL HookStatus(BOOL bHook)
{
    if (hProcess == NULL) return (false);
    if (bHook)
    {
        ::WriteProcessMemory(hProcess, (void *)mFunAddr, newCode, 5, NULL);
    }
    else
    {
        ::WriteProcessMemory(hProcess, (void *)mFunAddr, oldCode, 5, NULL);
    }
}

//回调
HANDLE WINAPI OpenProcessCallback(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
{
    //::MessageBox(NULL,"被拦截了!","test",MB_OK);
    
    if (dwProcessId==GetData() || GetData()==0xffffffff)  //判断如果是目标进程就拦截,否则就让它结束,-1就保护所有进程
    {
        dwDesiredAccess=0; //拒绝访问
        //dwProcessId = 0xffffffff;  //也可改PID
        
        //通知自己将要打开被保护进程的进程ID,即当前进程ID,也就是DLL所在的进程ID,不是自己。如果任务管理器要打开进程,那它就是taskmgr的PID。
        //::SendMessage(hWndApp, WM_USER, GetCurrentProcessId(), NULL);
    }
    
    HookStatus(false);
    HANDLE ret=::OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
    HookStatus(true);
    
    return (ret);
}

BOOL InitHook()  //初始化hook
{
    hProcess = GetCurrentProcess();  
    //HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, GetCurrentProcessId());

    //hWndApp = FindWindow(NULL, "Hook OpenProcess"); //自己的窗口,用于接收通知

    // 将原API的入口前个字节代码保存到OldCode[]
    mFunAddr = (ULONG)GetProcAddress(LoadLibrary("kernel32.dll"),"OpenProcess");
    memcpy(oldCode,(void *)mFunAddr,5);
    newCode[0] = 0xE9;  //jmp,跳转到自己的函数
    ULONG JmpAddr = (ULONG)OpenProcessCallback - mFunAddr - 5;
    memcpy(&newCode[1],&JmpAddr,sizeof(ULONG));
    
    HookStatus(true); //立即hook
    return (true);
}


BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    hMod = (HINSTANCE)hModule;
    switch (ul_reason_for_call)
    {
        case DLL_PROCESS_ATTACH:
            InitHook();
            break;
        case DLL_THREAD_ATTACH:
            break;
        case DLL_THREAD_DETACH:
            break;
        case DLL_PROCESS_DETACH:
            HookStatus(false);
            //CloseHandle(hProcess);
            break;
    }

    
    return TRUE;
}

//导出,功能是将DLL注入到所有GUI进程
extern "C" __declspec(dllexport) BOOL UnloadHook(){
    return(UnhookWindowsHookEx(hHook));
}

LRESULT CALLBACK HookProc(int nCode,WPARAM wParam,LPARAM lParam){
    return(CallNextHookEx(hHook,nCode,wParam,lParam));
}

extern "C" __declspec(dllexport) BOOL StartHook(DWORD dwProcessId){
    SetData (dwProcessId);  //保存要保护的PID
    hHook = SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)HookProc, hMod, 0);
    
    if (hHook) return TRUE;
    return FALSE;
}

//共享
#pragma data_seg("SharedDataInDll")
    //初始化为 0

    DWORD data_pid=0;

#pragma data_seg()

//这里还需要告诉链接器表明 SharedDataInDll 数据段为可读可写可共享
#pragma comment(linker, "/SECTION:SharedDataInDll,RWS")

//返回共享数据
DWORD GetData()
{
    return data_pid;
}


//设置共享数据
void SetData(DWORD tmpData)
{
    data_pid = tmpData;
}





//hook.h,声明共享数据
/*********************************************************/

#ifndef SHARED_DLL

#define SHARED_DLL


//在 DLL 项目中设置 DLL_API 为导出类型 extern "C" _declspec(dllimport)

//在 Test 项目中则无需设置该 DLL_API , 直接使用这个 CalculateDLL.h 文件即可


#ifdef DLL_API

#else

#define DLL_API extern "C" _declspec(dllimport)

#endif


DLL_API void SetData(DWORD tmpData);

DLL_API DWORD GetData();

#endif

'VB中调用,以下是VB代码
'*******************************************************
'Form1 调用DLL测试
Option Explicit

Private Declare Function StartHook Lib "hook.dll" (ByVal dwProcessId As Long) As Boolean
Private Declare Function UnloadHook Lib "hook.dll" () As Boolean
Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
Private Declare Function CreateToolhelp32Snapshot Lib "kernel32" (ByVal lFlags As Long, ByVal lProcessID As Long) As Long
Private Declare Function Process32First Lib "kernel32" (ByVal hSnapshot As Long, uProcess As PROCESSENTRY32) As Long
Private Declare Function Process32Next Lib "kernel32" (ByVal hSnapshot As Long, uProcess As PROCESSENTRY32) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long

Private Const MAX_PATH = 260
Private Const TH32CS_SNAPPROCESS = &H2

Private Type PROCESSENTRY32
        dwSize As Long
        cntUsage As Long
        th32ProcessID As Long
        th32DefaultHeapID As Long
        th32ModuleID As Long
        cntThreads As Long
        th32ParentProcessID As Long
        pcPriClassBase As Long
        dwFlags As Long
        szExeFile As String * MAX_PATH
End Type

Private Sub Form_Load()
        App.TaskVisible = False
        Command2.Enabled = False
        EnumProcess
        Dim i%
        For i = 0 To cbProcess.ListCount - 1
                If Val(cbProcess.List(i)) = GetCurrentProcessId Then cbProcess.ListIndex = i: Exit For
        Next i
End Sub

Private Sub Command1_Click()
        StartHook Val(cbProcess.Text) '保护
        Command1.Enabled = False
        Command2.Enabled = True
End Sub

Private Sub Command2_Click()
        UnloadHook '取消
        Command1.Enabled = True
        Command2.Enabled = False
End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
        If Command2.Enabled Then Command2_Click
End Sub

'枚举进程
Public Function EnumProcess()
        Dim proc                As PROCESSENTRY32
        Dim lRet                As Long
        Dim hSnapshot           As Long
        hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
        If hSnapshot = 0 Then Exit Function
        proc.dwSize = Len(proc)
        lRet = Process32First(hSnapshot, proc)
        cbProcess.Clear
        Do While lRet <> 0
                cbProcess.AddItem proc.th32ProcessID & " (" & TrimNull(proc.szExeFile) & ")"
                lRet = Process32Next(hSnapshot, proc)
        Loop
        CloseHandle hSnapshot
        cbProcess.AddItem "-1  所有进程"
End Function

'删除空字符
Private Function TrimNull(strString As String) As String
        Dim n As Long
        n = InStr(strString, Chr$(0))
        If n <> 0 Then
                TrimNull = Left$(strString, n - 1)
        Else
                TrimNull = strString
        End If
End Function
'**************************** 结束 ******************************
http://pan.baidu.com/s/1o8jLtrk

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值