• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

WinAPI【远程注入】hook注入Delphi实例一

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

(okwary) 小叹的学习园地

线程注入实例:

 

我们知道在NT及以上操作系统提供了一个函数VirtualAllocEx,利用这个函数我们可以在其它进程中申请一块内存,其定义如下:

function VirtualAllocEx(  //在其它进程中申请一块内存

hProcess: THandle;// hProcess为要申请内存的进程的句柄

lpAddress: Pointer;// lPAddress为地址指针,指向需要分配的某地址范围内的页面的起始地址,可以设为nil,由系统确定分配空间的地址.

dwSize:dword; //分配内存区域的大小.

flAllocationType: DWORD; //flAllocationType为分配类型,在这儿我们设为MEM_COMMIT.

flProtect: DWORD//flProtect为新分配内存的存取保护类型,可设为PAGE_EXECUTE_READWRITE来定义其为可执行可读写.

): Pointer; stdcall;//函数执行成功后,将会返回所分配页面的基址.

 

其中,可以用如下方法得到指定的窗口所属的进程的进程句柄.

Function GetProcessHandle: THandle;

var


WndHandle, PID: THandle;


begin


WndHandle := FindWindow(nil, '窗口名');//得到其进程和线程ID

GetWindowThreadProcessId(WndHandle, PID);//以完全访问权限打开进程句柄

Result := OpenProcess(PROCESS_ALL_ACCESS, False, PID);


end;


看下面的例子:

unit unit1;

interface

uses

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls;

const

WM_HOOKED = WM_USER + 3221; //Hook安装成功的消息

type

TThreadProVarList = record //变量列表

SendMessage: DWORD;

ExitProcess: DWORD;

ExitThread: DWORD; //上面用来保存API真实地址

WndHandle: DWORD;

end;

TForm1 = class(TForm)

Button1: TButton;

Button2: TButton;

procedure Button1Click(Sender: TObject);

procedure Button2Click(Sender: TObject);

private

ThreadAdd: Pointer;//在目标进程中申请的内存地址

PID, PHandle: DWORD; //目标窗口进程ID,句柄和线程ID

ThreadHandle, ThreadID: Thandle; //新的远程线程的ID和句柄

procedure WMHOOKED(var Msg: TMessage);message WM_HOOKED;

public

// Public declarations

end;

var

Form1: TForm1;

implementation

//$R *.dfm

procedure ThreadPro;

var

VarList: TThreadProVarList;

begin

asm


mov eax, $FFFFFFFF //到$FFFFFFFF的偏移是7

mov VarList.SendMessage, eax

mov eax, $FFFFFFFF //这个$FFFFFFFF是在上一个偏移位置加8

mov VarList.WndHandle, eax

mov eax, $FFFFFFFF

mov VarList.ExitProcess, eax

mov eax, $FFFFFFFF

mov VarList.ExitThread, eax

push 0

push 0

push 4245 //4245就是自定义的WM_HOOKED

push VarList.WndHandle

call VarList.SendMessage

push 0

call VarList.ExitThread

end;

end;

procedure TForm1.Button1Click(Sender: TObject);

var

WndHandle, TmpHandle: THandle;//要注入线程的窗口句柄和临时存放的句柄.

DllModule, SendPro, WriteCount: DWORD;

ExitPro, ExitTPro: DWORD;

begin

WndHandle := FindWindow(nil, '记事本');//先查找到要注入远程线程的窗口

GetWindowThreadProcessId(WndHandle, PID);//得到其进程和线程ID

PHandle := OpenProcess(PROCESS_ALL_ACCESS, False, PID);//以完全访问权限打开进程句柄

ThreadAdd := VirtualAllocEx(PHandle, nil, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);//在目标进程中分配内存

WriteProcessMemory(PHandle, ThreadAdd, @ThreadPro, 4096, WriteCount);//把自定义函数写入到目标进程中

ThreadHandle := createRemoteThread(PHandle, nil, 0, ThreadAdd, nil, create_SUSPENDED, ThreadID);//以挂起方式建立远端线程,以便修改

DllModule := LoadLibrary('User32.dll');//得到API真实的地址

SendPro := DWORD(GetProcAddress(DllModule, 'SendMessageW'));

DllModule := LoadLibrary('Kernel32.dll');

ExitPro := DWORD(GetProcAddress(DllModule, 'ExitProcess'));

ExitTPro := DWORD(GetProcAddress(DllModule, 'ExitThread'));

//把API真实地址和数据写入到在目标进程中的函数中

TmpHandle := Self.Handle;

WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+7), @SendPro, SizeOf(DWORD), WriteCount);

WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+15), @TmpHandle, SizeOf(DWORD), WriteCount);

WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+23), @ExitPro, SizeOf(DWORD), WriteCount);

WriteProcessMemory(PHandle, Pointer(LongInt(ThreadAdd)+31), @ExitTPro, SizeOf(DWORD), WriteCount);

ResumeThread(ThreadHandle);//开始运行远端线程

CloseHandle(ThreadHandle);//

end;

procedure TForm1.Button2Click(Sender: TObject);

begin

VirtualFreeEx(PHandle, ThreadAdd, 4096, MEM_DECOMMIT);//释放在目标进程中分配的内存

CloseHandle(PHandle);//关闭不用的句柄

end;

procedure TForm1.WMHOOKED(var Msg: TMessage);

begin

MessageBox(self.Handle, '建立远端线程成功', '!!!', MB_OK);

end;

end.{---END---}


要在线程函数中新定义变量的话,在TThreadProVarList类型中添加就可以了,然后再添加一条类似于

mov eax, $FFFFFFFF

mov VarList.ExitProcess, eax

的指今,并用WriteProcessMemory写入新变量的值就可以了.

如果是在var中申请变量的话,到函数第一条指今的偏移地址会改变,源程序也要相应改变,可以利用CPU窗口来查看。

注意:

此方法不适用于9x系统.

在线程函数中调用VCL函数也会有问题,因为指向的是自己的进程中的函数地址.

如果使用Pchar类型的字串的话,必须先用VirtualAllocEx函数申请内存,再用WriteProcessMemory写字串到目标进程中并保存下来字串地址,再按传送API地址的方法传送给线程函数就可以使用了.

最后记得使用VirtualFreeEx函数来释放在目标进程中分配的内存.

利用VirtualAllocEx函数还可以实现不需要DLL文件的HOOK技术等.
 
 
 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
安装MATLAB(已经下载安装包)发布时间:2022-07-18
下一篇:
MATLAB 关于马尔科夫计算转移概率矩阵发布时间:2022-07-18
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap