VB+delphi实现进程保护  
官方Delphi 学习QQ群: 682628230(三千人)
频道

VB+delphi实现进程保护


学学delphi做点东东玩玩吧。

还是老思路不过是换了DLL看守了。

           1.DLL注入。

          2.创建线程。

          3.检测被守护进程是否存在。

          4.不存在就启动。

DLL

检测进程是否存在我用的是枚举进程然后取得路径

调用函数 EnumProcesses-枚举进程。然后调用 OpenProcess 打开进程获取句柄,然后用

GetModuleFileNameEx来获取文件位置。

不存在的话调用WinExec来启动进程。

然后延时100毫秒,以节省系统资源。

最后重新循环以上代码。。。。。。

EXE

调用就比较简单了。

先寻找被注入的进程。我就用Explorer.exe来测试。

先用CreateToolhelp32Snapshot获取进程快照,然后用Process32First,Process32Next来

寻找Explorer.exe的Pid。用OpenProcess打开进程,权限为PROCESS_ALL_ACCESS(&H1F0FFF)

Inject这个函数是我从网上找到,啥意思我估计我也看不太懂了

应该就是把GetProcAddress,GetModuleHandle,LoadLibrary。移到别的进程上来执行。

就是这么简单。。。

我发下所有代码。

DLL

library ProtectMe;
uses
SysUtils,
windows,
PsApi;
function GetSystemPath():String;stdcall;
var
SysDir:array[0..255] of char;
begin
GetSystemDirectory(@SysDir,255);
GetSystemPath:=String(SysDir);
end;

procedure ProtectProcess();
const
n = 512;
var
pHandle:Cardinal;
IDArr: array[0..n-1] of DWORD;
size,i: DWORD;
buf: array[0..MAX_PATH] of Char;
isLive:Boolean;
label BeginScan;
begin
BeginScan:FillChar(buf, n, #0); {这样可避免乱码}
EnumProcesses(@IDArr, n, size);
for i := 0 to size div SizeOf(DWORD) - 1 do
begin
    pHandle := OpenProcess(PROCESS_ALL_ACCESS, False, IDArr[i]);
    GetModuleFileNameEx(pHandle, 0, buf, Length(buf)*SizeOf(buf[0]));
    CloseHandle(pHandle);
    if SameText(String(buf),String('C:\ProtectMe.exe'))=True then
      begin
        isLive:=True;
        Break;
      end
    else
      begin
        isLive:=False;
    end;
end;
if isLive=False then Begin
    WinExec(PChar('C:\ProtectMe.exe'),5);
end;
Sleep(100);
Goto BeginScan;
end;


procedure DllMain(Reason: Integer);
var
hThread:Cardinal;
hThreadID:Cardinal;
begin
    if reason=DLL_PROCESS_ATTACH then begin
      hThread:= CreateThread(nil,0,@ProtectProcess, nil, 0, hThreadID);
    end;
    if reason=DLL_PROCESS_DETACH then begin
      TerminateThread(hThread,0);
      CloseHandle (hThread);
    end;
end;

exports
DllMain;
begin
DLLProc := @DllMain;
DllMain(DLL_PROCESS_ATTACH);
end.

EXE

MOD:

Option Explicit
Public Declare Function VirtualAllocEx Lib "kernel32" (ByVal hProcess As Long, _
          ByVal lpAddress As Long, ByVal dwSize As Long, ByVal flAllocationType As Long, _
          ByVal flProtect As Long) As Long
Public Declare Function VirtualFreeEx Lib "kernel32" (ByVal hProcess As Long, _
          ByVal lpAddress As Long, ByVal dwSize As Long, _
          ByVal dwFreeType As Long) As Long
Public Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, _
          ByVal lpProcName As String) As Long
Public Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" _
          (ByVal lpModuleName As String) As Long
Public Declare Function OpenProcess Lib "kernel32" _
          (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, _
            ByVal dwProcessId As Long) As Long
Public Declare Function CloseHandle Lib _
            "kernel32" (ByVal hObject As Long) As Long
Public Declare Function WriteProcessMemory Lib "kernel32" _
          (ByVal hProcess As Long, ByVal lpBaseAddress As Long, lpBuffer As Any, _
           ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Public Declare Function CreateRemoteThread Lib "kernel32" _
          (ByVal hProcess As Long, ByVal lpThreadAttributes As Long, _
            ByVal dwStackSize As Long, ByVal lpStartAddress As Long, _
            ByVal lpParameter As Long, ByVal dwCreationFlags As Long, _
            lpThreadId As Long) As Long
Public Declare Function WaitForSingleObject Lib "kernel32" _
          (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Public Declare Function GetExitCodeThread Lib "kernel32" _
          (ByVal hThread As Long, lpExitCode As Long) As Long
Public Declare Function CreateToolhelp32Snapshot Lib _
            "kernel32" _
            (ByVal lFlags As Long, ByVal lProcessID As Long) As Long
Public Declare Function Process32First Lib "kernel32" _
            (ByVal hSnapshot As Long, uProcess As PROCESSENTRY32) As Long
Public Declare Function Process32Next Lib "kernel32" (ByVal hSnapshot As Long, _
            uProcess As PROCESSENTRY32) As Long
Public Declare Function RtlAdjustPrivilege Lib _
            "ntdll.dll" (ByVal Privilege As Long, _
            ByVal Enable As Boolean, ByVal Client As Boolean, _
            WasEnabled As Long) As Long
Public Const MEM_COMMIT = 4096
Public Const PAGE_READWRITE = 4

Public 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 * 260
End Type

Public Function Inject(ByVal ProcessHandle As String, ByVal MyDllFileName As String) As Boolean
Dim MyDllFileLength         As Long   'dll文件名长度
Dim MyDllFileBuffer         As Long   '写入dll文件名的内存地址
Dim MyReturn                As Long
Dim MyResult                As Long
Dim MyAddr                   As Long   '执行远程线程代码的起始地址。这里等于LoadLibraryA的地址

        'dll文件路径
        MyDllFileLength = LenB(StrConv(MyDllFileName, vbFromUnicode)) + 1
        '这里把dll文件名从Unicode转换成Ansi,否则英文字母是2个字节。 _
         顺便说一下,学过C的应该知道字符串要以/0标志结尾,所以dll文件名长度要加上1个字节存放Chr(0)

        '得到进程的句柄
        If ProcessHandle = 0 Then Inject = False

        MyDllFileBuffer = VirtualAllocEx(ProcessHandle, 0, MyDllFileLength, MEM_COMMIT, PAGE_READWRITE)
        '在目标进程中申请分配一块空白内存区域。内存的起始地址保存在MyDllFileBuffer中。 _
         这块内存区域我们用来存放dll文件路径,并作为参数传递给LoadLibraryA。
        If MyDllFileBuffer = 0 Then Inject = False

        MyReturn = WriteProcessMemory(ProcessHandle, MyDllFileBuffer, ByVal (MyDllFileName), MyDllFileLength, 0)
        '在分配出来的内存区域中写入dll路径径。注意第二个参数传递的是MyDllFileBuffer的内容, _
         而不是MyDllFileBuffer的内存地址?
        If MyReturn = 0 Then Inject = False

        MyAddr = GetProcAddress(GetModuleHandle("Kernel32"), "LoadLibraryA")
        '得到LoadLibraryA函数的起始地址。他的参数就是我们刚才写入的dll路径。但是LoadLibraryA本身是不知道参数在哪里的。 _
         接下来我们就用CreateRemoteThread函数告诉他参数放在哪里了?
        If MyAddr = 0 Then Inject = False

        MyResult = CreateRemoteThread(ProcessHandle, 0, 0, MyAddr, MyDllFileBuffer, 0, 0)

        '好了,现在用CreateRemoteThread在目标进程创建一个线程,线程起始地址指向LoadLibraryA, _
         参数就是MyDllFileBuffer中保存的dll路径?
        If MyResult = 0 Then
            Inject = False
        Else
            Inject = True
        End If
        '接下来你可以使用WaitForSingleObject等待线程执行完毕。 _
         并用GetExitCodeThread得到线程的退出代码,用来判断时候正确执行了dll中的代码。
        CloseHandle MyResult
        CloseHandle ProcessHandle
        '扫地工作
End Function
Public Function GetProcessID(ByVal sProcess As String) As Long
Dim i As Long
Dim Proc As PROCESSENTRY32
Dim snap As Long
Dim theloop As Long
    snap = CreateToolhelp32Snapshot(&H2&, 0)
    Proc.dwSize = Len(Proc)
    theloop = Process32First(snap, Proc)
    i = 0
    While theloop <> 0
        If LCase$(sProcess) = LCase$(Left(Proc.szExeFile, InStr(1, Proc.szExeFile, Chr(0)) - 1)) Then
            GetProcessID = Proc.th32ProcessID
        End If
        DoEvents
        i = i + 1
        theloop = Process32Next(snap, Proc)
    Wend
    CloseHandle snap
End Function

FORM

Option Explicit

Private Sub Command1_Click()
    Call Inject(OpenProcess(&H1F0FFF, False, GetProcessID("Explorer.exe")), App.Path & "\ProtectMe.dll")
End Sub
---------------------------------------------------

以上代码都通过测试。

编译后把DLL和EXE放在 C:\ 下面运行单击Command1按钮

即可,然后结束进程,发现进程被结束,但是立刻又被启动。这样就可以达到“防杀”的效果了。

需要注意的是,注入系统进程的话,Dll请小心使用,以免出现错误,使系统进程崩溃,

还有,系统服务执行Winexec的时候,被启动进程是无任何界面的。


推荐分享
图文皆来源于网络,内容仅做公益性分享,版权归原作者所有,如有侵权请告知删除!
 

Copyright © 2014 DelphiW.com 开发 源码 文档 技巧 All Rights Reserved
晋ICP备14006235号-8 晋公网安备 14108102000087号

执行时间: 0.075001001358032 seconds