ImageVerifierCode 换一换
格式:DOCX , 页数:57 ,大小:45.40KB ,
资源ID:6737979      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/6737979.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(闲着没事整理了一下DLL的N种注入方法.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

闲着没事整理了一下DLL的N种注入方法.docx

1、闲着没事整理了一下DLL的N种注入方法闲着没事整理了一下DLL的N种注入方法,对学习外挂的朋友,应该有用!第一种方法:利用 CreateRemoteThread 远程建立线程的方式注入DLL首先,我们要提升自己的权限,因为远程注入必不可免的要访问到目标进程的内存空间,如果没有足够的系统权限,将无法作任何事下面是这个函数是用来提升我们想要的权限用的function EnableDebugPriv : Boolean;varhToken : THANDLE;tp : TTokenPrivileges;rl : Cardinal;beginresult := false;/打开进程令牌环OpenPr

2、ocessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken);/获得进程本地唯一IDif LookupPrivilegeValue(nil, SeDebugPrivilege, tp.Privileges0.Luid) thenbegin tp.PrivilegeCount := 1; tp.Privileges0.Attributes := SE_PRIVILEGE_ENABLED; /调整权限 result := AdjustTokenPrivileges(hToken, False, tp,

3、 sizeof(tp), nil, rl);end;end;关于 OpenProcessToken() 和 AdjustTokenPrivileges() 两个 API 的简单介绍:OpenProcessToken():获得进程访问令牌的句柄function OpenProcessToken( ProcessHandle: THandle; /要修改访问权限的进程句柄 DesiredAccess: DWORD; /指定你要进行的操作类型 var TokenHandle: THandle): BOOL; /返回的访问令牌指针AdjustTokenPrivileges() :调整进程的权限func

4、tion AdjustTokenPrivileges( TokenHandle: THandle;/ 访问令牌的句柄 DisableAllPrivileges: BOOL; / 决定是进行权限修改还是除能(Disable)所有权限 const NewState: TTokenPrivileges;/ 指明要修改的权限,是一个指向TOKEN_PRIVILEGES结构的指针,该结构包含一个数组,数据组的每个项指明了权限的类型和要进行的操作; BufferLength: DWORD;/结构PreviousState的长度,如果PreviousState为空,该参数应为 0 var PreviousS

5、tate: TTokenPrivileges; / 指向TOKEN_PRIVILEGES结构的指针,存放修改前的访问权限的信息 var ReturnLength: DWORD /实际PreviousState结构返回的大小) : BOOL;远程注入DLL其实是通过 CreateRemoteThread 建立一个远程线程调用 LoadLibrary 函数来加载我们指定的DLL,可是如何能让远程线程知道我要加载DLL呢,要知道在Win32系统下,每个进程都拥有自己的4G虚拟地址空间,各个进程之间都是相互独立的。所我们需要在远程进程的内存空间里申请一块内存空间,写入我们的需要注入的 DLL 的路径

6、需要用到的 API 函数有:OpenProcess():打开目标进程,得到目标进程的操作权限,详细参看MSDNfunction OpenProcess( dwDesiredAccess: DWORD;/ 希望获得的访问权限 bInheritHandle: BOOL;/ 指明是否希望所获得的句柄可以继承 dwProcessId: DWORD / 要访问的进程ID): THandle; VirtualAllocEx():用于在目标进程内存空间中申请内存空间以写入DLL的文件名function VirtualAllocEx( hProcess: THandle;/ 申请内存所在的进程句柄 lpAdd

7、ress: Pointer;/ 保留页面的内存地址;一般用nil自动分配 dwSize,/ 欲分配的内存大小,字节单位;注意实际分 配的内存大小是页内存大小的整数倍 flAllocationType: DWORD; flProtect: DWORD): Pointer; WriteProcessMemory():往申请到的空间中写入DLL的文件名function WriteProcessMemory( hProcess: THandle;/要写入内存数据的目标进程句柄 const lpBaseAddress: Pointer; /要写入的目标进程的内存指针, 需以 VirtualAllocEx

8、() 来申请 lpBuffer: Pointer; /要写入的数据 nSize: DWORD; /写入数据的大小 var lpNumberOfBytesWritten: DWORD /实际写入的大小): BOOL; 然后就可以调用 CreateRemoteThread 建立远程线程调用 LoadLibrary 函数来加载我们指定的DLLCreateRemoteThread()/在一个远程进程中建立线程function CreateRemoteThread( hProcess: THandle;/远程进程的句柄 lpThreadAttributes: Pointer; /线程安全描述字,指向SE

9、CURITY_ATTRIBUTES结构的指针 dwStackSize: DWORD;/线程栈大小,以字节表示 lpStartAddress: TFNThreadStartRoutine;/ 一个TFNThreadStartRoutine类型的指针,指向在远程进程中执行的函数地址 lpParameter: Pointer; /传入参数的指针 dwCreationFlags: DWORD;/创建线程的其它标志 var lpThreadId: DWORD /线程身份标志,如果为0, 则不返回): THandle; 整个远程注入DLL的具体实现代码如下:function InjectDll(const

10、 DllFullPath : string; const dwRemoteProcessId : Cardinal): boolean;varhRemoteProcess, hRemoteThread: THANDLE;pszLibFileRemote : Pointer;pszLibAFilename: PwideChar;pfnStartAddr : TFNThreadStartRoutine;memSize, WriteSize, lpThreadId : Cardinal;beginresult := FALSE;/ 调整权限,使程序可以访问其他进程的内存空间if EnableDebu

11、gPriv thenbegin /打开远程线程 PROCESS_ALL_ACCESS 参数表示打开所有的权限 hRemoteProcess := OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwRemoteProcessId ); try / 为注入的dll文件路径分配内存大小,由于为WideChar,故要乘2 GetMem(pszLibAFilename, Length(DllFullPath) * 2 + 1); / 之所以要转换成 WideChar, 是因为当DLL位于有中文字符的路径下时不会出错 StringToWideChar(DllFullPath

12、, 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(pszL

13、ibFileRemote) then begin /使用WriteProcessMemory函数将DLL的路径名写入到远程进程的内存空间 if WriteProcessMemory(hRemoteProcess, pszLibFileRemote, pszLibAFilename, memSize, WriteSize) and (WriteSize = memSize) then begin lpThreadId := 0; / 计算LoadLibraryW的入口地址 pfnStartAddr := GetProcAddress(LoadLibrary(Kernel32.dll), Load

14、LibraryW); / 启动远程线程LoadLbraryW,通过远程线程调用创建新的线程 hRemoteThread := CreateRemoteThread(hRemoteProcess, nil, 0, pfnStartAddr, pszLibFileRemote, 0, lpThreadId); / 如果执行成功返回True; if (hRemoteThread 0) then result := TRUE; / 释放句柄 CloseHandle(hRemoteThread); end; end; finally / 释放句柄 CloseHandle(hRemoteProcess);

15、 end;end; end;接下来要说的是如何卸载注入目标进程中的DLL,其实原理和注入DLL是完全相同的,只是远程调用调用的函数不同而已,这里要调用的是FreeLibrary代码如下:function UnInjectDll(const DllFullPath : string;const dwRemoteProcessId : Cardinal) : Boolean;/ 进程注入和取消注入其实都差不多,只是运行的函数不同而已varhRemoteProcess, hRemoteThread : THANDLE;pszLibFileRemote : pchar;pszLibAFilename:

16、 PwideChar;pfnStartAddr : TFNThreadStartRoutine;memSize, WriteSize, lpThreadId, dwHandle : Cardinal;beginresult := FALSE;/ 调整权限,使程序可以访问其他进程的内存空间if EnableDebugPriv thenbegin /打开远程线程 PROCESS_ALL_ACCESS 参数表示打开所有的权限 hRemoteProcess := OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwRemoteProcessId ); try / 为注入的

17、dll文件路径分配内存大小,由于为WideChar,故要乘2 GetMem(pszLibAFilename, Length(DllFullPath) * 2 + 1); / 之所以要转换成 WideChar, 是因为当DLL位于有中文字符的路径下时不会出错 StringToWideChar(DllFullPath, pszLibAFilename, Length(DllFullPath) * 2 + 1); / 计算 pszLibAFilename 的长度,注意,是以字节为单元的长度 memSize := (1 + lstrlenW(pszLibAFilename) * sizeof(WCHA

18、R); /使用VirtualAllocEx函数在远程进程的内存地址空间分配DLL文件名空间 pszLibFileRemote := VirtualAllocEx( hRemoteProcess, nil, memSize,MEM_COMMIT, PAGE_READWRITE); if Assigned(pszLibFileRemote) then begin /使用WriteProcessMemory函数将DLL的路径名写入到远程进程的内存空间 if WriteProcessMemory(hRemoteProcess, pszLibFileRemote, pszLibAFilename, me

19、mSize, WriteSize) and (WriteSize = memSize) then begin / 计算GetModuleHandleW的入口地址 pfnStartAddr := GetProcAddress(LoadLibrary(Kernel32.dll), GetModuleHandleW); /使目标进程调用GetModuleHandleW,获得DLL在目标进程中的句柄 hRemoteThread := CreateRemoteThread(hRemoteProcess, nil, 0, pfnStartAddr, pszLibFileRemote, 0, lpThrea

20、dId); / 等待GetModuleHandle运行完毕 WaitForSingleObject(hRemoteThread,INFINITE); / 获得GetModuleHandle的返回值,存在dwHandle变量中 GetExitCodeThread(hRemoteThread, dwHandle); / 计算FreeLibrary的入口地址 pfnStartAddr := GetProcAddress(LoadLibrary(Kernel32.dll), FreeLibrary); / 使目标进程调用FreeLibrary,卸载DLL hRemoteThread := Create

21、RemoteThread(hRemoteProcess, nil, 0, pfnStartAddr, Pointer(dwHandle), 0, lpThreadId); / 等待FreeLibrary卸载完毕 WaitForSingleObject( hRemoteThread, INFINITE ); / 如果执行成功返回True; if hRemoteProcess0 then result := TRUE; / 释放目标进程中申请的空间 VirtualFreeEx(hRemoteProcess, pszLibFileRemote, Length(DllFullPath)+1, MEM_

22、DECOMMIT); / 释放句柄 CloseHandle(hRemoteThread); end; end; finally / 释放句柄 CloseHandle(hRemoteProcess); end;end;end;第二种方法:采用CreateProcess的方法,实现起来比较复杂,但没有上面几种方法的局限性。且可以用其他工具(VC等)调试注入的DLL。下面进行介绍。原理如下:1用CreateProcess(CREATE_SUSPENDED)启动目标进程。2找到目标进程的入口,用ImageHlp中的函数可以实现。3将目标进程入口的代码保存起来。4在目标进程的入口写入LoadLibrar

23、y(MyDll)实现Dll的注入。5用ResumeThread运行目标进程。6目标进程就运行了LoadLibrary(MyDll),实现DLL的注入。7目标进程运行完LoadLibrary(MyDll)后,将原来的代码写回目标进程的入口。8目标进程Jmp至原来的入口,继续运行程序。从原理上可以看出,DLL的注入在目标进程的开始就运行了,而且不是用Debug的方案,这样,就没有上面方案的局限性了。该方案的关键在6,7,8三步,实现方法需要监视进程和DLL合作。下面,结合代码进行分析。在监视进程中,创建FileMapping,用来保存目标进程的入口代码,同时保证DLL中可以访问。在第7步实现将原目

24、标代码写回目标进程的入口。 监视程序和DLL共用的结构体#pragma pack (push ,1) 保证下面的结构体采用BYTE对齐(必须)typedef struct BYTE int_PUSHAD; / pushad 0x60 BYTE int_PUSH; / push &szDLL 0x68 DWORD push_Value; / &szDLL = ApiSpy.dll的path BYTE int_MOVEAX; /move eax &LoadLibrary0xB8 DWORD eax_Value; / &LoadLibrary WORD call_eax; / call eax 0x

25、D0FF(FF D0) (LoadLibrary(ApiSpy.dll); BYTE jmp_MOVEAX; / move eax &ReplaceOldCode0xB8 DWORD jmp_Value; / JMP的参数 WORD jmp_eax; / jmp eax 0xE0FF(FF E0) jmp ReplaceOldCode; char szDLLMAX_PATH; /ApiSpy.dll的FullPathINJECT_LOADLIBRARY_CODE, *LPINJECT_CODE;#pragma pack (pop , 1)上面结构体的代码为汇编代码,对应的汇编为:pushadp

26、ush szDllmov eax, &LoadLibraryAcall eax/ 实现调用LoadLibrary(szDll)的代码mov eax, oldentryjmp eax / 实现在LoadLibrary运行完后, 跳至目标进程的入口继续运行/ FileMaping的结构体typedef struct LPBYTElpEntryPoint; / 目标进程的入口地址 BYTE oldcodesizeof(INJECT_CODE); / 目标进程的代码保存SPY_MEM_SHARE, * LPSPY_MEM_SHARE;准备工作:第一步:用CreateProcess(CREATE_SUSPENDED)启动目标进程。CreateProcessA(0, szRunFile, 0, 0, FALSE, CREATE_SUSPENDED 0, NULL, &stInfo, &m_proInfo) ;/ 用CreateProcess启动一个暂停的目标进程/ 找到目标进程的入口点,函数如下第二步:找到目标进程的入口,用I

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1