执行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_WRITE和PROCESS_VM_OPERATION访问权限。 - lpBaseAddress:指向目标进程中的内存地址的指针,该地址是数据将被写入的起始位置。
- lpBuffer:指向包含要写入目标进程内存的数据的缓冲区的指针。
- nSize:要写入目标进程的字节数。
- lpNumberOfBytesWritten:指向一个变量的指针,该变量接收实际写入目标进程的字节数。这个参数是可选的,如果为NULL,则忽略。
返回值
- 如果函数成功执行,返回值为非零值(TRUE)。
- 如果函数失败,返回值为零(FALSE)。此时,可以通过调用
GetLastError函数来获取详细的错误代码。

浙公网安备 33010602011771号