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字节,我也没试小一点会怎么样。
貌似搞错了,其实不用具体文件也行,但需要自己设置具体大小。
#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 = CreateFileMappingA(INVALID_HANDLE_VALUE,NULL,PAGE_EXECUTE_READWRITE,0,24,"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);
}
因为要可执行,所以必须要是已经存在的文件。这里面各种配置属性很多,主要还是参考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里面的汇编代码。
需要注意的就是:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通