# 24-移动或复制shellcode总结

移动或复制shellcode是shellcode注入中的第二步，相对于第一步和第二步它的重要性没有那么高，杀软也不会在这里投入过多的关注，究其原因是我们可以自实现逐字节复制，AV/EDR想监控都无从下手。

在本节中我只介绍最基本也最常用的几个方法，分别是 `RtlMoveMemory`、`memcpy`、`逐字节复制`

**⚠注意**：

1. 在shellcode注入中一定要分清是注入本进程还是远程进程。
2. 这里并不讨论使用Nt或Zw类型的API，也不讨论系统调用。

## 一、RtlMoveMemory

官方文档：[rtlMoveMemory 宏 (wdm.h) - Windows drivers | Microsoft Learn](https://learn.microsoft.com/zh-cn/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlmovememory)

`RtlMoveMemory`：函数可以将源内存块的内容复制到目标内存块。这也是在windows编程，特别是免杀中用的比较多的一个函数，相对来说免杀效果差一点。

语法

```go
void RtlMoveMemory(
   void*       Destination,
   const void* Source,
   size_t      Length
);
```

## 二、memcpy

官方文档：[cplusplus.com/reference/cstring/memcpy/?kw=memcpy](https://cplusplus.com/reference/cstring/memcpy/?kw=memcpy)

`memcpy` 将shellcode复制到指定内存区域。

语法

```go
void * memcpy ( void * destination, const void * source, size_t num );
```

## 三 、逐字节复制

由于逐字节复制实在太过简单，直接看代码吧

```go
BOOL mymemcpy(void* dst, void* src, SIZE_T size) {

	// 参数有效性校验
	if (!dst || !src || size == 0) {
		SetLastError(ERROR_INVALID_PARAMETER);
		return FALSE;
	}

	// 转换成BYTE* 类型的指针，这样可以按字节复制
	PBYTE Dst = (PBYTE)dst;
	PBYTE Src = (PBYTE)src;

	// 逐字节复制
	for (size_t i = 0; i < size; ++i) {
		Dst[i] = Src[i];
	}

	return TRUE;
}
```
