标签:分析 SS MOV 地址 EBP 简单 BYTE PTR 溢出
简单分析栈以及栈溢出
目标代码
#include<iostream>
#include<cstring>
bool IsPasswordOkay(void)
{
char Password[12] = {0,1,2,3,4,5,7,8,9,10,11};//直接将数组填满
for(int i=12;i<20;i++)//覆盖EBP和ESP所指向的返回地址
{
printf("NO.%d\t",i);
scanf("%x",&Password[i]);
printf("NO.%d put in hex is %c\n",i,Password[i]);
}
return 0==strcmp(Password,"goodpass");
}
int main()
{
bool PwStatus;
puts("Enter");
PwStatus = IsPasswordOkay();
if(PwStatus == false){
puts("denied");
exit(-1);
}
else puts("Access Granted");
}
这里将输入密码的地方直接用0~11填满,直接进行后面的覆盖。
由于EBP指针和ESP指向的地址都是8位16进制
在OD中可以看到存储Password数组的内容都是MOV BYTE PTR SS:[LOCAL.3]
其翻译过来是MOV BYTE PTR SS:[EBP-0C],0
,表示把0赋值给距离EBP指针12(16进制为0C)的一个byte,那么装满了12个元素的字符数组Password的最后一个元素的地址[EBP-01]和EBP相邻。
CPU Disasm
地址 十六进制转储 命令 注释
00401048 |. C645 F4 00 MOV BYTE PTR SS:[LOCAL.3],0
0040104C |. C645 F5 01 MOV BYTE PTR SS:[LOCAL.3+1],1
00401050 |. C645 F6 02 MOV BYTE PTR SS:[LOCAL.3+2],2
00401054 |. C645 F7 03 MOV BYTE PTR SS:[LOCAL.3+3],3
00401058 |. C645 F8 04 MOV BYTE PTR SS:[LOCAL.2],4
0040105C |. C645 F9 05 MOV BYTE PTR SS:[LOCAL.2+1],5
00401060 |. C645 FA 07 MOV BYTE PTR SS:[LOCAL.2+2],7
00401064 |. C645 FB 08 MOV BYTE PTR SS:[LOCAL.2+3],8
00401068 |. C645 FC 09 MOV BYTE PTR SS:[LOCAL.1],9
0040106C |. C645 FD 0A MOV BYTE PTR SS:[LOCAL.1+1],0A
00401070 |. C645 FE 0B MOV BYTE PTR SS:[LOCAL.1+2],0B
而在堆栈中,可以看到程序中的存储情况。临时变量(指这里的数组Password)存储在栈中,并且最后一个元素的地址与EBP的地址相邻。
程序返回时ESP所指向的返回地址指向值是函数ISpasswordOkay的下一句的地址
那么我们可以通过覆盖EBP指针和返回地址改变程序的返回,从而控制程序下一步的执行。
这里的控制方法是使用循环输入EBP和返回地址的值。
for(int i=12;i<20;i++)//覆盖EBP和ESP所指向的返回地址
{
printf("NO.%d\t",i);
scanf("%x",&Password[i]);
printf("NO.%d put in hex is %c\n",i,Password[i]);
}
EBP和返回地址分别占用4个字节故使用8次输入一个字节的内容。
目标为
CPU Disasm
地址 十六进制转储 命令 注释
0040117D |> \68 50304300 PUSH OFFSET 00433050 ; ASCII "Access Granted"
输入内容为
Enter
NO.12 30
NO.12 put in hex is 0
NO.13 ff
NO.13 put in hex is
NO.14 19
NO.14 put in hex is
NO.15 00
NO.15 put in hex is
NO.16 7d
NO.16 put in hex is }
NO.17 11
NO.17 put in hex is
NO.18 40
NO.18 put in hex is @
NO.19 00
NO.19 put in hex is
Access Granted
这里EBP指针是main函数的EBP,返回地址是0040117D
即将"Access Granted"入栈准备输出的地址
在函数ISpasswordOkay进行返回时
CPU Disasm
地址 十六进制转储 命令 注释
004010F6 |. 8BE5 MOV ESP,EBP
004010F8 |. 5D POP EBP
004010F9 \. C3 RETN
MOV ESP,EBP:EBP的值会给到ESP,然后会将存储在栈中的main的EBP指针的值取出(这里进行的操作的结果就是在程序返回后,ESP的值改成了我们写入的0019FF30
(其实原来就是这个值,只是象征性的写一下,意思就是ISpasswordOkay的EBP存储main的EBP地址,而main的EBP存储的是win32内核的EBP指针的地址)
POP EBP :会把之前存储在栈中的ISpasswordOkay的EBP的值取出,并且将栈顶弹出,栈顶弹出后(ESP指向返回地址
!!!!!!)
EBP的值不对的话会使程序崩溃。(当然是试过了)
RETN 基于ESP现在指向的地址进行返回
结果就是成功的返回到输出Access Granted的地方。
标签:分析,SS,MOV,地址,EBP,简单,BYTE,PTR,溢出 来源: https://blog.csdn.net/witwitwiter/article/details/122398882
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。