为什么C语言的strcpy函数有漏洞(转)[@more@]   前言:研究了几天DOS下的溢出原理,最后明白了其实原理都很简单关键是要懂得为什么C语言的strcpy函数有漏洞,为什么对这个函数的不正常使用会造成溢出。   一节:介绍strcpy函数能看到这篇文章的人可能都知道问题很多是出在它的身上吧呵呵。   先看一看在标准的C语言的string.h中对这个函数的申明char *_Cdecl stpcpy (char *dest, const char *src);对于代码看下面的:(这是微软对这个函数的说明)   (%VC%/vc7/crt/src/intel/strcat.asm)   ;***   ;char *strcpy(dst, src) - copy one string over another   ;Purpose:   ; Copies the string src into the spot specified by   ; dest; assumes enough room.   ;   ; Algorithm:   ; char * strcpy (char * dst, char * src)   ; {   ; char * cp = dst;   ; while( *cp++ = *src++ ); /* Copy src over dst */   ; return( dst );   ; }   ;Entry:   ; char * dst - string over which "src" is to be copied   ; const char * src - string to be copied over "dst"   ;   ;Exit:   ; The address of "dst" in EAX   ;   ;Uses:   ; EAX, ECX   ;   ;Exceptions:   ;**********************************************************************   本来想去掉一些注解,不过觉得还是留着好哈:)   从上面我们可以看到这样的代码有问题有:   1.没有检查输入的两个指针是否有效。   2.没有检查两个字符串是否以NULL结尾。   3.没有检查目标指针的空间是否大于等于原字符串的空间。   好了现在我们知道了对于调用string.h中的这个函数,和我们自已写一个如下的程序没有本质上的区别那么我们就来研究它就可以了.就叫它c4.exe吧.   main(){j();}   j()   {   char a[]={a,b,};   char b[1];   char *c=a;   char *d=b;   while(*d++=*c++);   printf("%sn",b);   }   二节:调试我们的c4.exe   所用工具W32dasm,debug,tcc,tc   第一步我们用TC2编绎生成可执行文件c4.exe.   第二步用TCC -B生成这段C代码的汇编源代码.   第三步用W32dasm和debug对c4.exe进行静态和动态调试   先分析由TCC生成的c4.asm代码如下:   先说明一下由于这是一个完整的包括了MAIN函数的C程序,程序刚开始时数据段和堆栈段还有代码都不在一起但是当,执行到我们的J函数时堆栈和数段就在一起了这要特别注意.   ifndef ??version   ?debug macro   endm   endif   ?debug S "c4.c"   _TEXT segment byte public CODE   DGROUP group _DATA,_BSS   assume cs:_TEXT,ds:DGROUP,ss:DGROUP   _TEXT ends   _DATA segment word public DATA   d@ label byte   d@w label word   _DATA ends   _BSS segment word public BSS   b@ label byte   b@w label word   ?debug C E930A68D2E0463342E63   _BSS ends   _TEXT segment byte public CODE   ; ?debug L 1   _main proc near   ; ?debug L 3   call near ptr _j //这儿执行我们的J函数   @1:   ; ?debug L 4   ret   _main endp   _TEXT ends   _DATA segment word public DATA //最先在数据段中定义我们的源串ab结尾符   db 97   db 98   db 0   _DATA ends   _TEXT segment byte public CODE   ; ?debug L 6   _j proc near   push bp //J函数入口   mov bp,sp   sub sp,6   push si   push di   push ss   lea ax,word ptr [bp-6]   push ax   push ds   mov ax,offset DGROUP:d@ //特别注意这是得到源串在数据段中的偏移   push ax //所有SCOPY@以上的代码的作用是在堆栈中分配源串加目的串那么多个空间   mov cx,3 //cx=3指定要拷贝的字符数   call far ptr SCOPY@ //执行了另一个函数作用是把数据段中的源串拷到栈中   ; ?debug L 10   lea si,word ptr [bp-6]   ; ?debug L 11   lea di,word ptr [bp-2]   ; ?debug L 12   jmp short @3   @5:   @3:   ; ?debug L 12   mov bx,si   inc si   mov al,byte ptr [bx]   mov bx,di   inc di   mov byte ptr [bx],al   or al,al   jne @5   @4:   ; ?debug L 13   lea ax,word ptr [bp-2]   push ax   mov ax,offset DGROUP:s@ //得到printf函数的打印格式参数   push ax   call near ptr _printf   pop cx   pop cx   @2:   ; ?debug L 14   pop di   pop si   mov sp,bp   pop bp   ret   _j endp   _TEXT ends   ?debug C E9   _DATA segment word public DATA   s@ label byte   db 37 //%   db 115 //s   db 10 //换行符:)   db 0   _DATA ends   extrn SCOPY@:far   _TEXT segment byte public CODE   extrn _printf:near   _TEXT ends   public _main   public _j   end   三节:分析W32Dasm得来的静态汇编代码,也就是程序最终的代码同时我们一步步来分析   这时堆栈的情况.   文章写到这儿可能大家一定认识都是些看到就头大的代码吧,没事我先分析一下   这些代码就执行来说可以分为三个部分:   1.从01FE到020B是根据C代码中的定义在堆栈中分配空间例子中分了6个字节,定义多少分多少也没有毛病   2远跳到0000:1395是把数据段中的源串放到堆栈中由于放入个数在cx中所以这儿也没有毛病   3在堆栈中把源串拷到目的串所在的内存单元中问题就在这儿了!   :0001.01FA E80100 call 01FE //执行我们的j函数   :0001.01FD C3 ret   :0001.01FE 55 push bp   :0001.01FF 8BEC mov bp, sp   :0001.0201 83EC06 sub sp, 0006   :0001.0204 56 push si   :0001.0205 57 push di   :0001.0206 16 push ss   :0001.0207 8D46FA lea ax, [bp-06]   :0001.020A 50 push ax   :0001.020B 1E push ds   :0001.020C B89401 mov ax, 0194   :0001.020F 50 push ax   :0001.0210 B90300 mov cx, 0003   :0001.0213 9A95130000 call 0000:1395 //这儿先跳到1395去执行了由于它是在0000所以是远跳   :0001.0218 8D76FA lea si, [bp-06]   :0001.021B 8D7EFE lea di, [bp-02]   :0001.021E EB00 jmp 0220   :0001.0220 8BDE mov bx, si   :0001.0222 46 inc si   :0001.0223 8A07 mov al , [bx]   :0001.0225 8BDF mov bx, di   :0001.0227 47 inc di   :0001.0228 8807 mov [bx], al   :0001.022A 0AC0 or al , al   :0001.022C 75F2 jne 0220   :0001.022E 8D46FE lea ax, [bp-02]   :0001.0231 50 push ax   :0001.0232 B89701 mov ax, 0197   :0001.0235 50 push ax   :0001.0236 E8BC08 call 0AF5 //执行打印输出   :0001.0239 59 pop cx   :0001.023A 59 pop cx   :0001.023B 5F pop di   :0001.023C 5E pop si   :0001.023D 8BE5 mov sp, bp   :0001.023F 5D pop bp   :0001.0240 C3 ret   //下面的就是我们的SCOPY@   0001.1395 55 push bp   :0001.1396 8BEC mov bp, sp   :0001.1398 56 push si   :0001.1399 57 push di   :0001.139A 1E push ds   :0001.139B C57606 lds si, [bp+06]   :0001.139E C47E0A les di, [bp+0A]   :0001.13A1 FC cld   :0001.13A2 D1E9 shr cx, 01   :0001.13A4 F3 repz   :0001.13A5 A5 movsw   :0001.13A6 13C9 adc cx, cx   :0001.13A8 F3 repz   :0001.13A9 A4 movsb   :0001.13AA 1F pop ds   :0001.13AB 5F pop di   :0001.13AC 5E pop si   :0001.13AD 5D pop bp   :0001.13AE CA0800 retf 0008   我们现在开始DEBUG动态调试:   第一步D:turboc2>debug c4.exe   -g 01FE 通过W32DASM中的查找我们直接跳到J入口处执行   AX=0000 BX=0566 CX=000E DX=067F SP=FFE8 BP=FFF4 SI=00D8 DI=054B   DS=13DB ES=13DB SS=13DB CS=129F IP=01FE NV UP EI PL ZR NA PE NC   129F:01FE 55 PUSH BP   -t   AX=0000 BX=0566 CX=000E DX=1193 SP=FFE6 BP=FFF4 SI=00D8 DI=054B   DS=13DB ES=13DB SS=13DB CS=129F IP=01FF NV UP EI PL ZR NA PE NC   129F:01FF 8BEC MOV BP,SP   由于上一条指令是CALL O1FE,所以也就有一条POP 01FD,然后又是一个PUSH BP   -d ss:ffe0   13DB:FFE0 FF 01 9F 12 F3 0B F4 FF-FD 01 1D 01 01 00 F2 FF ................   13DB:FFF0 54 05 F6 FF 00 00 43 35-2E 45 58 45 00 00 FB 00 T.....C5.EXE....   现在就来看看栈的情况   mov bp,sp后BP就成了FFE6   低   FFE0 | ->SUB SP,0006(空了六个字节为源目的串在堆栈   

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/8225414/viewspace-967659/,如需转载,请注明出处,否则将追究法律责任。

0
0
分享到:

上一篇: 缓冲区溢出漏掘之整数范围限制浅析(转)
下一篇: 黑客中级技术--缓冲区溢出攻击(转)

请登录后发表评论 登录

全部评论
<%=items[i].createtime%>

<%=items[i].content%>

<%if(items[i].items.items.length) { %>

<%for(var j=0;j

<%=items[i].items.items[j].createtime%> 回复

<%=items[i].items.items[j].username%>   回复   <%=items[i].items.items[j].tousername%>: <%=items[i].items.items[j].content%>

<%}%> <%if(items[i].items.total > 5) { %>

还有<%=items[i].items.total-5%>条评论 ) data-count=1 data-flag=true>点击查看

<%}%>

<%}%> <%}%>

post0
  • 博文量

    2031

  • 访问量
    7922744

最新文章

  • 微软MTV联手挑战苹果iTunes面临严厉竞争(转)
  • 微软在反垄断案中最后一搏请求美法院介入(转)
  • 智能手机的行业生存(转)
  • 关注软件用户的“知情权”(转)
  • 外电评06年11大发财行业PC制造业榜上有名(转)
  • 北京数字鸿沟问题正逐渐显现呈加速扩大趋势(转)
  • 曹兴诚遭台湾当局起诉辞去联电董事长职位(转)
  • 传密码局欲开放WAPI算法WAPI强制执行迫近?(转)
  • 中国"芯"群体突破我国芯片产业自主创新纪实(转)
  • 科技大会描绘创新型国家愿景专家细解现实差距(转)

支持我们 作者招募 用户协议 FAQ Contact Us

北京盛拓优讯信息技术有限公司. 版权所有  京ICP备09055130号-4  北京市公安局海淀分局网监中心备案编号:11010802021510

广播电视节目制作经营许可证(京) 字第1234号 中国互联网协会会员

转载于:http://blog.itpub.net/8225414/viewspace-967659/

为什么C语言的strcpy函数有漏洞(转)相关推荐

  1. 自定义strcpy函数c语言,c语言编写strcpy函数的方法

    c语言编写strcpy函数的方法 1.搭建基本的C语言程序框架,注意添加#include头文件 2.定义两个字符数组 3.strcpy函数原型:char *strcpy(char *dest, con ...

  2. c语言strcpy函数的漏洞

    函数里的局部变量一般都是按序排放的,并且因为是分配在堆栈之中,它们的地址是向下"增长",即向低地址方向增长.比如下面的程序: int flag=0x12345678;printf( ...

  3. 用C语言实现strcpy函数和strncpy函数

    内容会持续更新,有错误的地方欢迎指正,谢谢! strcpy函数 strcpy是C语言中的一个复制字符串的库函数,手动实现如下: char* strcpy(char* des,const char* s ...

  4. 【C语言】strcpy()函数

    文章目录 一.strcpy()函数的简介 二.strcpy()函数的具体使用 三.使用strcpy()函数的注意事项 一.strcpy()函数的简介 strcpy()函数:是将一个字符串复制到另一块空 ...

  5. C语言编写strcpy函数

    #include<stdio.h> char *strcpy1(char *dest,char *src); int main(int argc, const char *argv[]) ...

  6. linux strcpy函数实现,strcpy(char *dest , char *src)的漏洞

    前言:研究了几天DOS下的溢出原理,最后明白了其实原理都很简单关键是要懂得为什么C语言的strcpy函数有漏洞,为什么对这个函数的不正常使用会造成溢出. 一节:介绍strcpy函数能看到这篇文章的人可 ...

  7. c语言 字符串拷贝函数作用,C语言不使用strcpy函数如何实现字符串复制功能

    Ⅰ )字符串复制函数 字符串复制是字符串操作中比较常用的操作之一.C语言库函数中提供的字符串复制函数是:strcpy函数.该函数的功能为:把源字符数组中的字符串复制到目的字符数组中,字符串结束标志&q ...

  8. C语言strcpy函数的使用

    点击蓝字 关注我们 strcpy简单使用:  #include <stdio.h> #include <string.h>struct Student {int sid;cha ...

  9. c++语言函数strcpy,C++中函数的安全版本的意义及strcpy函数的功能和差别(图)

    C++中函数的安全版本的意义及strcpy函数的功能和差别(图) 我们在进行C/C++编程时,会发现中有些函数在VS中使用时,提示使用_s的函数版本,其实这种_s的函数版本是安全版本,它们完成的任务与 ...

最新文章

  1. 中国九章量子计算机诞生!比最快的超算快一百万亿倍
  2. java读取文件 16进制_Java对文件的16进制读取和操作
  3. 17 WM配置-策略-激活存储区搜索(Storage Section Search)
  4. 208.实现Trie(前缀树)
  5. cdn搭建原理_直播平台如何搭建?
  6. 使用实时摄像头预览的iOS对象检测(六)
  7. Git——撤销和删除操作【git restore / git rm 】
  8. 20165205 2017-2018-2 《Java程序设计》第六周学习总结
  9. 制造业erp整体业务流程
  10. 搭建 Extmail企业邮件服务
  11. 布朗运动 2 | 布朗运动的推广
  12. 谷歌浏览器实现按下按键的脚本_谷歌浏览器快捷键设置方法详解
  13. JsonPath 解析Josn字符串
  14. PM之数据分析与逻辑能力
  15. Unity内截屏实现
  16. 统一社会信用代码校验-JavaScript
  17. 百度百科爬虫爬人物信息
  18. Kong Rate Limiting 插件详解
  19. 学it需要学历吗_低学历者是否适合学IT?IT行业对学历要求高吗
  20. 博士骗领210万元、硕士骗领3万元人才补贴,全被判刑了!

热门文章

  1. uni-app小程序里用echarts-for-wx-uniapp,dispatchAction不起作用
  2. HCIP第十天(BGP实验一)
  3. 图深度学习连载八,入门教程之简化图卷积模型
  4. 欧拉测试网,测试埋伏空投
  5. 蒲公英服务器搭建小程序,wx小程序—— 小程序页面通用模板的使用
  6. 2021安徽大学计算机科学与技术考研科目,2021考研初试科目调整,这些学校给出通知!...
  7. 漫画:顶级高手都擅长“二维四象限”分析法​
  8. 有关JVM类加载器的一点点想法
  9. 知识图谱:小小的入门级综合应用
  10. 《画解数据结构》(0 - 4)- 逻辑结构