远程注入手段 及 内存操作

来源:互联网 发布:cf冰龙刷枪软件 编辑:程序博客网 时间:2024/06/05 16:13
有两个函数可以用来实现上述功能:VirtualAllocEx和CreateRemoteThread。这两个函数都只能在Windows NT下使用。
VirtualAllocEx函数可以用来在其他进程的地址空间内申请内存,当然申请到的内存也是位于目标进程的地址空间内的,将这个函数和WriteProcessMemory函数配合就可以在目标进程的地址空间中“造”出任何东西来。

VirtualAllocEx函数是VirtualAlloc的扩充,相比之下,VirtualAllocEx函数多了一个参数hProcess,其他参数定义和使用的方法都和VirtualAlloc函数相同,新增的hProcess参数用来指定要申请内存的进程句柄,如果需要在目标进程中使用VirtualAllocEx函数,那么必须对进程拥有PROCESS_VM_OPERATION权限。

如果内存申请成功,函数返回一个指针,指向申请到的内存块,当然这个指针是针对目标进程的地址空间的。如果内存申请失败,函数返回NULL。

CreateRemoteThread函数用来在其他进程内创建一个线程,当然创建的线程是运行于目标进程的地址空间内的,它和目标进程自己创建的线程并没有什么区别。


该函数是CreateThread函数的扩充,与CreateThread相比,CreateRemoteThread函数多了一个hProcess参数,其他所有参数的定义和用法都与CreateThread的参数相同。hProcess用来指定要创建线程的目标进程句柄。注意:lpStartAddress指向的线程函数的地址是位于目标进程的地址空间内的。如果需要在目标进程中使用CreateRemoteThread函数,那么必须对进程拥有PROCESS_CREATE_THREAD权限。

使用VirtualAllocEx和CreateRemoteThread函数,再配合WriteProcessMemory函数,就能够让一段代码在其他进程中运行,由于远程线程是属于目标进程的,所以在任务管理器中不会产生新的进程,事实上,谁也不会发现列出的某个进程中会多了一个不属于它自己控制的线程。整个实现的过程归纳如下:


(1)使用VirtualAllocEx函数在目标进程中申请一块内存,内存块的长度必须能够容纳线程使用的代码和数据,内存块的属性应该是PAGE_EXECUTE_READWRITE,这样拷贝到内存块中的代码就可以被执行。


(2)使用WriteProcessMemory函数将需要在远程线程中执行的代码(包括它使用的数据)拷贝到第(1)步申请到的内存块中。


(3)使用CreateRemoteThread函数创建远程线程。



下面再记录下一个部分内容:

ReadProcessMemory与WriteProcessMemory

首先介绍一个函数VirtualProtectEx,它用来改变一个进程的虚拟地址中特定页里的某一区域的保护属性,这句话有些咬嘴,直接从MSDN中翻译过来的,简单来说就是改变某一进程中虚拟地址的保护属性,如果以前是只读的,那改变属性为PAGE_EXECUTE_READWRITE后,就可以更改这部分内存了。


具体看它的实现


BOOL WINAPI VirtualProtectEx(
  __in   HANDLE hProcess,
  __in   LPVOID lpAddress,
  __in   SIZE_T dwSize,
  __in   DWORD flNewProtect,
  __out  PDWORD lpflOldProtect
);


第一个参数是进程的句柄,这个句柄可以使用由CreateProcess()函数得到的PROCESS_INFORMATION结构中的hProcess成员,CreateProcess()这个函数相信大家用的很多了,我就不详细介绍了。如果仅仅知道hProcess的ID,那么可以通过OpenProcess()函数得到,OpenProcess()有三个参数,最后一个参数就是进程的ID,它的返回值为进程的句柄。如果想得到线程的句柄,同样可以采用这两种方式,利用结构体PROCESS_INFORMATION重的hThread成员或使用函数OpenThread()。


第二个参数lpAddress就是页中要改变保护属性的地址。第三个参数dwSize改变保护属性区域的大小,以字节为单位。通过这两个变量就可以确定要改变包括属性的区域了。


第四个参数fNewProtect是要改变的保护属性。包含PAGE_EXECUTE_READWRITE,PAGE_READONLY等,但先看第五个参数lpfOldProtect,是用来保存为改变之前的内存区域的保护属性,也就是说我们可以先备份之前的保护属性,然后将属性更改为PAGE_EXECUTE_READWRITE,然后对内存区域进行一些操作,然后再将内区域更改回来。


 


接下来看ReadProcessMemory()函数


BOOL WINAPI ReadProcessMemory(
  __in   HANDLE hProcess,
  __in   LPCVOID lpBaseAddress,
  __out  LPVOID lpBuffer,
  __in   SIZE_T nSize,
  __out  SIZE_T *lpNumberOfBytesRead
);


第一个参数hProcess为进程的句柄,第二个参数lpBaseAddress为要读取内容的基地址,当然你事先要了解你要读取内容的基地址。第三个参数lpBuffer为接收所读取内容的基地址。第四个参数为要读取内容的大小,以字节为单位。最后一个参数lpNumberOfBytesRead为接收读取内容的buffer中收到的字节数。一般都设为NULL,这个该参数将被忽略掉。


使用ReadProcessMemory()函数,可以获得该进程内存空间中的信息,或是用于监测进程的执行情况,或是将进程内的数据备份,然后调用writeProcessMemory()进行修改,必要时再还原该进程的数据。


BOOL WINAPI WriteProcessMemory(
  __in   HANDLE hProcess,
  __in   LPVOID lpBaseAddress,
  __in   LPCVOID lpBuffer,
  __in   SIZE_T nSize,
  __out  SIZE_T *lpNumberOfBytesWritten
);


该函数与readProcessMemory的参数基本相同,只不过第三个参数lpBuffer为要写入进程的内容。


将内存的内容更改后,别忘了调用VirtualProtectEx()恢复内存原来的保护属性。

0 0
原创粉丝点击