Windows下文件映射共享内存执行ShellCode测试


记录学习Windows下文件映射来共享内存

目的:探究共享内存区域是否可执行shellcode(让程序在共享内存以后弹出一个信息框)

实验过程:

1.获取MessageBox和ExitProcess的地址。

避免程序弹出信息框后崩溃或者中断。

代码:

#include
#include
using namespace std;
int main()
{
	int num1 = (int)&MessageBox;
	int num2 = (int)&ExitProcess;
	printf("MessageBox addr is %xh\n",num1);
	printf("ExitProcess addr is %xh\n",num2);
}

结果:

MessageBox addr is 76b90f40h
ExitProcess addr is 76f14e10h

不同的电脑,地址可能不同。

2.构造ShellCode

利用masm32编译链接生成机器码。

代码如下:需要根据上一步执行结果进行修改。

	.386
	.model flat,stdcall
	option casemap:none

	.code
start:
	push 0
	push 0
	push 0
	push 0
	mov eax,76B90F40H
	call eax
	push 0
	mov eax,76F14E10H
	call eax
end start

使用OD或者x32dbg调试看看机器码。

00A31000 | 6A 00              | push 0                                                       |
00A31002 | 6A 00              | push 0                                                       |
00A31004 | 6A 00              | push 0                                                       |
00A31006 | 6A 00              | push 0                                                       |
00A31008 | B8 400FB976        | mov eax,76B90F40                                             |
00A3100D | FFD0               | call eax                                                     |
00A3100F | 6A 00              | push 0                                                       |
00A31011 | B8 104EF176        | mov eax,                               |
00A31016 | FFD0               | call eax                                                     |

所以。

unsigned char shellcode[] = {0x6a,0x0,0x6a,0x0,0x6a,0x0,0x6a,0x0,0xb8,0x40,0x0f,0xb9,0x76,0xff,0xd0,0x6a,0x0,0xb8,0x10,0x4e,0xf1,0x76,0xff,0xd0 };
//跟着复制就好了,一共24字节,因为是绝对地址,用call比jmp方便一些

3.一个程序创造文件映射。

代码:

#include
#include
using namespace std;
unsigned char shellcode[] = {0x6a,0x0,0x6a,0x0,0x6a,0x0,0x6a,0x0,0xb8,0x40,0x0f,0xb9,0x76,0xff,0xd0,0x6a,0x0,0xb8,0x10,0x4e,0xf1,0x76,0xff,0xd0 };

int main()
{
	HANDLE file = CreateFile("1.txt",GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE,FILE_SHARE_READ,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0);
	HANDLE fileMap = CreateFileMapping(file,NULL,PAGE_EXECUTE_READWRITE,0,0,"myTest");
	cout<

需要注意的是,1.txt一定要是存在的文件,最好大小超过24字节,我也没试小一点会怎么样。
貌似搞错了,其实不用具体文件也行,但需要自己设置具体大小。

#include
#include
using namespace std;
unsigned char shellcode[] = {0x6a,0x0,0x6a,0x0,0x6a,0x0,0x6a,0x0,0xb8,0x40,0x0f,0xb9,0x76,0xff,0xd0,0x6a,0x0,0xb8,0x10,0x4e,0xf1,0x76,0xff,0xd0 };

int main()
{
//	HANDLE file = CreateFile("1.txt",GENERIC_READ|GENERIC_WRITE|GENERIC_EXECUTE,FILE_SHARE_READ,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0);
	HANDLE fileMap = CreateFileMappingA(INVALID_HANDLE_VALUE,NULL,PAGE_EXECUTE_READWRITE,0,24,"myTest");
	cout<
因为要可执行,所以必须要是已经存在的文件。这里面各种配置属性很多,主要还是参考MSDN

4.另一个执行ShellCode的程序

#include
#include
using namespace std;

int main()
{
	MessageBox(0, "text", "title", MB_OK);//比如让程序加载user32.dll,后面才能有弹窗。
    //当然也可以构造LoadLibrary("user32.dll")的shellCode,但是麻烦了,这里方便一点。
	HANDLE hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS|FILE_MAP_EXECUTE, FALSE, "myTest");
	cout << hMap << endl;
	LPVOID address = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS| FILE_MAP_EXECUTE, 0, 0, 0);
	cout << address << endl;
	__asm {
		mov eax,address
		call eax
	}

	while (1);
}

执行结果,就是,弹出一个代码的信息框,再执行masm32里面的汇编代码。

需要注意的就是:

FILE_MAP_ALL_ACCESS|FILE_MAP_EXECUTE ,后面这个几个 MapViewOfFile 和 OpenFileMapping 都要用一样的才行。