第一范文网 - 专业文章范例文档资料分享平台

DLL的11种注入方法

来源:用户分享 时间:2020-06-21 本文由淡若清风 分享 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:xxxxxx或QQ:xxxxxx 处理(尽可能给您提供完整文档),感谢您的支持与谅解。

闲着没事整理了一下DLL的N种注入方法,对学习外挂的朋友,应该有用!

第一种方法:

利用 CreateRemoteThread 远程建立线程的方式注入DLL.

首先,我们要提升自己的权限,因为远程注入必不可免的要访问到目 标进程的内存空间,如果没有足够的系统权限,将无法作任何事.下 面是这个函数是用来提升我们想要的权限用的.

function EnableDebugPriv : Boolean; var

hToken : THANDLE; tp : TTokenPrivileges; rl : Cardinal; begin

result := false;

//打开进程令牌环

OpenProcessToken(GetCurrentProcess(),

TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken);

//获得进程本地唯一ID

if LookupPrivilegeValue(nil, 'SeDebugPrivilege', tp.Privileges[0].Luid) then begin

tp.PrivilegeCount := 1;

tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED; //调整权限

result := AdjustTokenPrivileges(hToken, False, tp, sizeof(tp), nil, rl); end; end;

关于 OpenProcessToken() 和 AdjustTokenPrivileges() 两个 API 的简单介绍:

OpenProcessToken():获得进程访问令牌的句柄.

function OpenProcessToken(

ProcessHandle: THandle; //要修改访问权限的进程句柄 DesiredAccess: DWORD; //指定你要进行的操作类型 var TokenHandle: THandle ): BOOL; //返回的访问令牌指针

AdjustTokenPrivileges() :调整进程的权限. function AdjustTokenPrivileges(

TokenHandle: THandle; // 访问令牌的句柄

DisableAllPrivileges: BOOL; // 决定是进行权限修改还是除 能(Disable)所有权限

const NewState: TTokenPrivileges; // 指明要修改的权限,

是一个指向TOKEN_PRIVILEGES结构的指针,该结构包含一个数组,数 据组的每个项指明了权限的类型和要进行的操作;

BufferLength: DWORD; //结构PreviousState的长度,如果 PreviousState为空,该参数应为 0

var PreviousState: TTokenPrivileges; // 指向

TOKEN_PRIVILEGES结构的指针,存放修改前的访问权限的信息 var ReturnLength: DWORD //实际PreviousState结构返回的大 小

) : BOOL;

远程注入DLL其实是通过 CreateRemoteThread 建立一个远程线程调 用 LoadLibrary 函数来加载我们指定的DLL,可是如何能让远程线程 知道我要加载DLL呢,要知道在Win32系统下,每个进程都拥有自己的 4G虚拟地址空间,各个进程之间都是相互独立的。所我们需要在远程 进程的内存空间里申请一块内存空间,写入我们的需要注入的 DLL 的路径. 需要用到的 API 函数有:

OpenProcess():打开目标进程,得到目标进程的操作权限,详细参 看MSDN

function OpenProcess(

dwDesiredAccess: DWORD; // 希望获得的访问权限

bInheritHandle: BOOL; // 指明是否希望所获得的句柄可以继 承

dwProcessId: DWORD // 要访问的进程ID ): THandle;

VirtualAllocEx():用于在目标进程内存空间中申请内存空间以写入 DLL的文件名

function VirtualAllocEx(

hProcess: THandle; // 申请内存所在的进程句柄

lpAddress: Pointer; // 保留页面的内存地址;一般用nil自 动分配

dwSize, // 欲分配的内存大小,字节单位;注意实际分 配的 内存大小是页内存大小的整数倍 flAllocationType: DWORD; flProtect: DWORD ): Pointer;

WriteProcessMemory():往申请到的空间中写入DLL的文件名 function WriteProcessMemory(

hProcess: THandle; //要写入内存数据的目标进程句柄 const lpBaseAddress: Pointer; //要写入的目标进程的内存指 针, 需以 VirtualAllocEx() 来申请 lpBuffer: Pointer; //要写入的数据 nSize: DWORD; //写入数据的大小

var lpNumberOfBytesWritten: DWORD //实际写入的大小 ): BOOL;

然后就可以调用 CreateRemoteThread 建立远程线程调用 LoadLibrary 函数来加载我们指定的DLL.

CreateRemoteThread() //在一个远程进程中建立线程 function CreateRemoteThread(

hProcess: THandle; //远程进程的句柄

lpThreadAttributes: Pointer; //线程安全描述字,指向 SECURITY_ATTRIBUTES结构的指针

dwStackSize: DWORD; //线程栈大小,以字节表示 lpStartAddress: TFNThreadStartRoutine; // 一个

TFNThreadStartRoutine类型的指针,指向在远程进程中执行的函数 地址

lpParameter: Pointer; //传入参数的指针

dwCreationFlags: DWORD; //创建线程的其它标志

var lpThreadId: DWORD //线程身份标志,如果为0, 则不返回 ): THandle;

整个远程注入DLL的具体实现代码如下:

function InjectDll(const DllFullPath : string; const dwRemoteProcessId : Cardinal): boolean; var

hRemoteProcess, hRemoteThread: THANDLE; pszLibFileRemote : Pointer; pszLibAFilename: PwideChar;

pfnStartAddr : TFNThreadStartRoutine; memSize, WriteSize, lpThreadId : Cardinal; begin

result := FALSE;

// 调整权限,使程序可以访问其他进程的内存空间 if EnableDebugPriv then begin

//打开远程线程 PROCESS_ALL_ACCESS 参数表示打开所有的权限 hRemoteProcess := OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwRemoteProcessId );

try

// 为注入的dll文件路径分配内存大小,由于为WideChar,故要 乘2

GetMem(pszLibAFilename, Length(DllFullPath) * 2 + 1);

// 之所以要转换成 WideChar, 是因为当DLL位于有中文字符 的路径下时不会出错

StringToWideChar(DllFullPath, pszLibAFilename, Length (DllFullPath) * 2 + 1);

// 计算 pszLibAFilename 的长度,注意,是以字节为单元的 长度

memSize := (1 + lstrlenW(pszLibAFilename)) * sizeof (WCHAR);

//使用VirtualAllocEx函数在远程进程的内存地址空间分配 DLL文件名空间

pszLibFileRemote := VirtualAllocEx( hRemoteProcess, nil, memSize, MEM_COMMIT, PAGE_READWRITE);

if Assigned(pszLibFileRemote) then begin

//使用WriteProcessMemory函数将DLL的路径名写入到远程 进程的内存空间

if WriteProcessMemory(hRemoteProcess,

pszLibFileRemote, pszLibAFilename, memSize, WriteSize) and (WriteSize = memSize) then begin

lpThreadId := 0;

// 计算LoadLibraryW的入口地址

pfnStartAddr := GetProcAddress(LoadLibrary ('Kernel32.dll'), 'LoadLibraryW');

// 启动远程线程LoadLbraryW,通过远程线程调用创建新 的线程

hRemoteThread := CreateRemoteThread

(hRemoteProcess, nil, 0, pfnStartAddr, pszLibFileRemote, 0, lpThreadId);

// 如果执行成功返回 True; if (hRemoteThread <> 0) then result := TRUE;

// 释放句柄

CloseHandle(hRemoteThread); end; end; finally

// 释放句柄

CloseHandle(hRemoteProcess); end;

end; end;

接下来要说的是如何卸载注入目标进程中的DLL,其实原理和注入DLL 是完全相同的,只是远程调用调用的函数不同而已,这里要调用的是 FreeLibrary.代码如下:

function UnInjectDll(const DllFullPath : string; const dwRemoteProcessId : Cardinal) : Boolean;

// 进程注入和取消注入其实都差不多,只是运行的函数不同而已 var

hRemoteProcess, hRemoteThread : THANDLE; pszLibFileRemote : pchar; pszLibAFilename: PwideChar;

pfnStartAddr : TFNThreadStartRoutine;

memSize, WriteSize, lpThreadId, dwHandle : Cardinal; begin

result := FALSE;

// 调整权限,使程序可以访问其他进程的内存空间 if EnableDebugPriv then begin

//打开远程线程 PROCESS_ALL_ACCESS 参数表示打开所有的权限 hRemoteProcess := OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwRemoteProcessId );

try

// 为注入的dll文件路径分配内存大小,由于为WideChar,故要

搜索“diyifanwen.net”或“第一范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,第一范文网,提供最新小学教育DLL的11种注入方法 全文阅读和word下载服务。

DLL的11种注入方法 .doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.diyifanwen.net/wenku/1092133.html(转载请注明文章来源)
热门推荐
Copyright © 2018-2022 第一范文网 版权所有 免责声明 | 联系我们
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:xxxxxx 邮箱:xxxxxx@qq.com
渝ICP备2023013149号
Top