执行PE节中的Shellcode

下面以文件inject.exe分析为例。

1、打开宿主进程,获取进程句柄。

 

 

 

 

 

 

OpenProcess用于打开一个已存在的进程对象,并返回该进程的句柄。该函数的原型如下:

HANDLE OpenProcess(

  DWORD dwDesiredAccess,

  BOOL bInheritHandle,

  DWORD dwProcessId

);

dwDesiredAccess:指定希望获得的访问权限。这是一个位掩码,可以指定一个或多个访问权限。常见的权限包括PROCESS_ALL_ACCESS(授予对所有进程对象的访问权限)、PROCESS_VM_READ(允许读取进程内存)、PROCESS_VM_WRITE(允许写入进程内存)和SYNCHRONIZE(允许等待进程终止)。

bInheritHandle:指定句柄是否可由子进程继承。如果此参数为TRUE,则子进程可以继承该句柄;如果为FALSE,则子进程不能继承该句柄。

dwProcessId:指定要打开的进程的进程标识符。这个标识符是唯一的,用于标识系统中的每一个进程。

如果函数执行成功,它会返回指定进程的句柄。如果函数失败,它会返回NULL,并且可以通过调用GetLastError函数来获取失败的原因。

2、申请内存空间

VirtualAllocEx用于在指定进程的虚拟地址空间中分配内存。该函数的原型如下:

LPVOID VirtualAllocEx(

  HANDLE hProcess,

  LPVOID lpAddress,

  SIZE_T dwSize,

  DWORD flAllocationType,

  DWORD flProtect

);

hProcess:目标进程的句柄。这个句柄标识了需要分配内存的进程。句柄必须拥有对目标进程的适当访问权限。

lpAddress:指向要分配的内存区域的起始地址的指针。如果此参数为NULL,则系统决定分配区域的起始地址。

dwSize:要分配的内存区域的大小,以字节为单位。实际分配的内存大小通常是系统内存页大小的整数倍。

flAllocationType:内存分配类型。这个参数可以是一个或多个分配类型的组合,如MEM_COMMIT(提交分配)和MEM_RESERVE(保留分配)。常见的组合是仅使用MEM_COMMIT,它表示同时分配并保留内存。

flProtect:内存保护属性。这个参数指定了内存区域的访问权限,如PAGE_READWRITE(可读可写)、PAGE_EXECUTE_READWRITE(可执行、可读可写)等。

如果函数成功,返回指向分配的内存区域的起始地址的指针。如果函数失败,返回NULL。可以通过调用GetLastError函数来获取具体的错误代码。

3、

WriteProcessMemory函数是Windows API中的一个重要函数,它允许一个进程将数据写入到另一个进程的地址空间中。这个函数在需要对其他进程进行内存操作(如调试、注入代码等)时非常有用。以下是关于WriteProcessMemory函数的详细解析:

函数原型

在C++中,WriteProcessMemory函数的原型通常如下所示(注意,参数类型可能因不同的资料来源而略有不同,但基本含义相同):

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

  • hProcess:目标进程的句柄。这个句柄必须是通过OpenProcess函数获得的,并且具有对目标进程的PROCESS_VM_WRITEPROCESS_VM_OPERATION访问权限。
  • lpBaseAddress:指向目标进程中的内存地址的指针,该地址是数据将被写入的起始位置。
  • lpBuffer:指向包含要写入目标进程内存的数据的缓冲区的指针。
  • nSize:要写入目标进程的字节数。
  • lpNumberOfBytesWritten:指向一个变量的指针,该变量接收实际写入目标进程的字节数。这个参数是可选的,如果为NULL,则忽略。

返回值

  • 如果函数成功执行,返回值为非零值(TRUE)。
  • 如果函数失败,返回值为零(FALSE)。此时,可以通过调用GetLastError函数来获取详细的错误代码。

posted @ 2024-07-30 20:53  无事闲逛  阅读(72)  评论(0)    收藏  举报