1. 程式人生 > 其它 >Windows下檔案對映共享記憶體執行ShellCode測試

Windows下檔案對映共享記憶體執行ShellCode測試

記錄學習Windows下檔案對映來共享記憶體

目的:探究共享記憶體區域是否可執行shellcode(讓程式在共享記憶體以後彈出一個資訊框)

實驗過程:

1.獲取MessageBox和ExitProcess的地址。

避免程式彈出資訊框後崩潰或者中斷。

程式碼:

#include<iostream>
#include<windows.h>
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,<kernel32.ExitProcess>                               |
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<iostream>
#include<windows.h>
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<<fileMap<<endl;
	LPVOID address = MapViewOfFile(fileMap,FILE_MAP_ALL_ACCESS|FILE_MAP_EXECUTE,0,0,0);
	
	memcpy(address,shellcode,sizeof(shellcode));
	cout<<address<<endl;
	for(int i=0;i<sizeof(shellcode);i++)
	{
		printf("%x ",(*(unsigned char*)(address + i)));
	}
	while(1);
}

需要注意的是,1.txt一定要是存在的檔案,最好大小超過24位元組,我也沒試小一點會怎麼樣。

因為要可執行,所以必須要是已經存在的檔案。這裡面各種配置屬性很多,主要還是參考MSDN

4.另一個執行ShellCode的程式

#include<iostream>
#include<windows.h>
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 都要用一樣的才行。