精华内容
下载资源
问答
  • (C语言网)入门程序设计竞赛用什么编译器好? 有人肯定说DEV,其实,如果有志向打ACM这些高段位比赛同学应该习惯使用CodeBlocks。 CodeBlocks这款编译器它强大之处在于 跨平台,windows、linux 都可以。 VS...

    C语言网)入门程序设计竞赛用什么编译器好?

    有人肯定说DEV,其实,如果有志向打ACM这些高段位比赛的同学应该习惯使用CodeBlocks

    CodeBlocks这款编译器它的强大之处在于

    1. 跨平台,windows、linux 都可以用。
    2. VS太大,到我的笔记本上跑着太慢,cb是一个比较好的替代品。不使用一些复杂的库,比如说MFC啊啥的,cb完全够用了。
    3. 自带类似Visual Assist一样的工具。
    4. 完全免费,不需要去网上找注册码综上。

    接下来跟大家说说安装办法:

    1,下载 codeblocks:
    https://sourceforge.net/projects/codeblocks/files/Binaries/17.12/Windows/codeblocks-17.12mingw-setup.exe/download

    下载安装后,既可以双击运行,界面如下。

    CodeBlocks16.01

    CodeBlocks的入门使用教程

    首先新建一个.c文件,点击File – New 选择File

    然后选择C/C++ source,Go !

    继续Next!

    然后这个时候再选择C源文件,然后Next

    之后在路径里选择我们这个源码的存放位置,并起一个名字,

    这个大家应该都知道,必须要有C的文件后缀名.c,然后Save。

    CodeBlocks的入门使用教程

    然后最后再点击Finish即可!

    CodeBlocks的入门使用教程

    即可看到多了一个名字为dotcpp.c的文件选项卡,现在可以在这里面写程序了!

    笔者这里觉得字体太小,调大一些,可以在Setttings – editor中选择字体大小

    CodeBlocks的入门使用教程

    接下来就可以编译、运行了。快捷键对应:

    编译->Ctrl+F9

    运行->Ctrl+F10

    编译输出见下方 ,蓝色字体

    CodeBlocks的入门使用教程

    运行效果:

    与其他编译器相比,可以看到主函数返回值以及运行时间,很人性化!

    CodeBlocks的入门使用教程

    怎么样,大家看会了吗,其实各编译器过程都差不多,熟悉即可上手!

    以上就是CodeBlocks编译器的入门教程,希望对大家有用!

    本文来自集OJ+教程+智能梯度刻意练习等功能于一体的C语言网

    展开全文
  • //首先我写了学生信息管理系统的添加数据函数,需要将数据保存在磁盘里,将数据写入文件那一块用的c语言,其他为c++,代码如下: void Add() { char a='Y'; FILE *fp; if((fp=fopen("informations....
  • 所用编译器Devc++编译器 ...“向程序发送命令时出现错误”,是什么问题导致呢?如何解决? 之前都没有这种情况,不知道怎么了。![图片说明](https://img-ask.csdn.net/upload/201707/24/1500910541_943557.png)
  • Trybuild一种测试工具,用于在一组测试用例上调rustc并断言所导致所有错误消息均预期。 此类测试通常用于测试涉及过程宏错误报告。 我们将编写测试用例,以触发宏检测到错误或Rust编译器在生成...
  • clion的配置及使用 相必经常学C或者C++的同学们一定用过dev c++、vc++、VS等等各种编译器,相比...我从入学以来开始学C,学校用的是devc++,VC++等,但我就是想尝尝鲜,在无数次的安装,配置,文件无法运行,愤怒,.

    clion的配置及使用(希望大家看完)

    相必经常学C或者C++的同学们一定用过dev c++、vc++、VS等等各种编译器,相比他们来说,clion还是比较冷门的,为什么?因为它需要配置环境!!!这点老烦人了,而且,你配置好了环境也不一定能运行,那为什么还有很多人用clion?颜值高,手感好,而且还护眼。不得不说,jetbrains的产品,必为精品。

     

    clion和pycharm就像双胞胎一样。我从入学以来开始学C,学校用的是devc++,VC++等,但我就是想尝尝鲜,在无数次的安装,配置,文件无法运行,愤怒,卸载之后(是真的),终于找到了稳定的运行方法!!(第四步是我最想告诉大家都)接下来,就带大家一起研究clion怎么使用。

    第一步,我们去官网下载clion

    这里下载https://www.jetbrains.com/clion/其中有一个让打勾选择的窗口,如果是学生,建议只保留第一个64-bit launcher,其他的可以都不选择。

    第二步,下载MinGW

    链接:https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds

    注意:不要点击绿色的download!

    选择后,点击x86_64-posix-sjlj就可以下载了(可能有点慢),保存到一个喜欢的地址

    第三步,配置

    1,点击file,settings,

    2,找到Toolchains,点击右边的➕

    3,environment选择mingw,点击environment最后面的三个点,选择刚刚下载好保存的mingw文件,其余的系统会自动帮你配置好

    4,完成

    第四步,配置好了,说说怎么用,这是clion的第二个麻烦之处

    新建一个项目,创建一个C文件,命名为zxcv,然后点击CMakeLists.txt,在里面输入add_executable(main2 zxcv.c)  注意:这里的main2是我自己起的名,你可以任意起,但是格式一定要对【add_executable(名字 文件名.c)】,我也不知道为什么,但是不这样,自己创建的文件无法运行!出现了弹窗,点击reload即可。当然,每次创建一个文件,都要重复执行此步骤。

    最后,再说一下中文乱码的问题:

    点击settings,点击editor,然后点击File encodings

    把方框里全部改成UTF-8,然后返回到主屏幕,把这里的UTF-8改成GBK,就可以啦!!

     

    我是大一的学生,非常热爱计算机专业,但自身水平有限,如有错误,请读者指出即可,我会加倍努力的!认同的小伙伴别忘记点个赞,谢谢哈~

     

    展开全文
  • 如题,使用GCC编译器时发现,局部变量的地址总是从低地址向高地址分配,而dev c中局部变量却从高...但是gcc却不是,我用的版本4.8.4. 原因:GCC的堆栈保护技术—— canary的使用。 使用的原因为了防止某些溢

    如题,使用GCC编译器时发现,局部变量的地址总是从低地址向高地址分配,而dev c中局部变量却是从高地址向低地址分配的?

    栈分配的方向是从高地址向低地址分配,但在变量内部地址是从低地址向高地址增长”一直都是这样理解的,以为所有编译器都是按照这种方式来分配变量地址的。但是gcc却不是,我用的版本是4.8.4.

    原因:GCC的堆栈保护技术—— canary的使用。

    使用的原因是为了防止某些溢出的攻击。但是只是溢出时方向发生了改变,并没有起到太大的作用,可能对于传统的一些攻击方法有用。

    下面是一篇canary方法的讲解:

    转载地址:http://www.ibm.com/developerworks/cn/linux/l-cn-gccstack/


    以堆栈溢出为代表的缓冲区溢出已成为最为普遍的安全漏洞。由此引发的安全问题比比皆是。早在 1988 年,美国康奈尔大学的计算机科学系研究生莫里斯 (Morris) 利用 UNIX fingered 程序的溢出漏洞,写了一段恶意程序并传播到其他机器上,结果造成 6000 台 Internet 上的服务器瘫痪,占当时总数的 10%。各种操作系统上出现的溢出漏洞也数不胜数。为了尽可能避免缓冲区溢出漏洞被攻击者利用,现今的编译器设计者已经开始在编译器层面上对堆栈进行保护。现在已经有了好几种编译器堆栈保护的实现,其中最著名的是 StackGuard 和 Stack-smashing Protection (SSP,又名 ProPolice)。

    编译器堆栈保护原理

    我们知道攻击者利用堆栈溢出漏洞时,通常会破坏当前的函数栈。例如,攻击者利用清单 1 中的函数的堆栈溢出漏洞时,典型的情况是攻击者会试图让程序往 name 数组中写超过数组长度的数据,直到函数栈中的返回地址被覆盖,使该函数返回时跳转至攻击者注入的恶意代码或 shellcode 处执行(关于溢出攻击的原理参见《Linux 下缓冲区溢出攻击的原理及对策》)。溢出攻击后,函数栈变成了图 2 所示的情形,与溢出前(图 1)比较可以看出原本堆栈中的 EBP,返回地址已经被溢出字符串覆盖,即函数栈已经被破坏。

    清单 1. 可能存在溢出漏洞的代码
    int vulFunc() {
        char name[10];
        //…
        return 0;
    }
    图 1. 溢出前的函数栈
    溢出前的函数栈
    图 2. 溢出后的函数栈
    溢出后的函数栈

    如果能在运行时检测出这种破坏,就有可能对函数栈进行保护。目前的堆栈保护实现大多使用基于 “Canaries” 的探测技术来完成对这种破坏的检测。

    “Canaries” 探测:

    要检测对函数栈的破坏,需要修改函数栈的组织,在缓冲区和控制信息(如 EBP 等)间插入一个 canary word。这样,当缓冲区被溢出时,在返回地址被覆盖之前 canary word 会首先被覆盖。通过检查 canary word 的值是否被修改,就可以判断是否发生了溢出攻击。

    常见的 canary word:

    • Terminator canaries
    • 由于绝大多数的溢出漏洞都是由那些不做数组越界检查的 C 字符串处理函数引起的,而这些字符串都是以 NULL 作为终结字符的。选择 NULL, CR, LF 这样的字符作为 canary word 就成了很自然的事情。例如,若 canary word 为 0x000aff0d,为了使溢出不被检测到,攻击者需要在溢出字符串中包含 0x000aff0d 并精确计算 canaries 的位置,使 canaries 看上去没有被改变。然而,0x000aff0d 中的 0x00 会使 strcpy() 结束复制从而防止返回地址被覆盖。而 0x0a 会使 gets() 结束读取。插入的 terminator canaries 给攻击者制造了很大的麻烦。
    • Random canaries
    • 这种 canaries 是随机产生的。并且这样的随机数通常不能被攻击者读取。这种随机数在程序初始化时产生,然后保存在一个未被隐射到虚拟地址空间的内存页中。这样当攻击者试图通过指针访问保存随机数的内存时就会引发 segment fault。但是由于这个随机数的副本最终会作为 canary word 被保存在函数栈中,攻击者仍有可能通过函数栈获得 canary word 的值。
    • Random XOR canaries
    • 这种 canaries 是由一个随机数和函数栈中的所有控制信息、返回地址通过异或运算得到。这样,函数栈中的 canaries 或者任何控制信息、返回地址被修改就都能被检测到了。

    目前主要的编译器堆栈保护实现,如 Stack Guard,Stack-smashing Protection(SSP) 均把 Canaries 探测作为主要的保护技术,但是 Canaries 的产生方式各有不同。下面以 GCC 为例,简要介绍堆栈保护技术在 GCC 中的应用。

    GCC 中的堆栈保护实现

    Stack Guard 是第一个使用 Canaries 探测的堆栈保护实现,它于 1997 年作为 GCC 的一个扩展发布。最初版本的 Stack Guard 使用 0x00000000 作为 canary word。尽管很多人建议把 Stack Guard 纳入 GCC,作为 GCC 的一部分来提供堆栈保护。但实际上,GCC 3.x 没有实现任何的堆栈保护。直到 GCC 4.1 堆栈保护才被加入,并且 GCC4.1 所采用的堆栈保护实现并非 Stack Guard,而是 Stack-smashing Protection(SSP,又称 ProPolice)。

    SSP 在 Stack Guard 的基础上进行了改进和提高。它是由 IBM 的工程师 Hiroaki Rtoh 开发并维护的。与 Stack Guard 相比,SSP 保护函数返回地址的同时还保护了栈中的 EBP 等信息。此外,SSP 还有意将局部变量中的数组放在函数栈的高地址,而将其他变量放在低地址。这样就使得通过溢出一个数组来修改其他变量(比如一个函数指针)变得更为困难。

    GCC 4.1 中三个与堆栈保护有关的编译选项

    -fstack-protector:

    启用堆栈保护,不过只为局部变量中含有 char 数组的函数插入保护代码。

    -fstack-protector-all:

    启用堆栈保护,为所有函数插入保护代码。

    -fno-stack-protector:

    禁用堆栈保护。

    GCC 中的 Canaries 探测

    下面通过一个例子分析 GCC 堆栈保护所生成的代码。分别使用 -fstack-protector 选项和 -fno-stack-protector 编译清单2中的代码得到可执行文件 demo_sp (-fstack-protector),demo_nosp (-fno-stack-protector)。

    清单 2. demo.c
    int main() {
        int i;
        char buffer[64];
        i = 1;
        buffer[0] = 'a';
        return 0;
    }

    然后用 gdb 分别反汇编 demo_sp,deno_nosp。

    清单 3. demo_nosp 的汇编代码
    (gdb) disas main
    Dump of assembler code for function main:
    0x08048344 <main+0>:    lea    0x4(%esp),%ecx
    0x08048348 <main+4>:    and    $0xfffffff0,%esp
    0x0804834b <main+7>:    pushl  0xfffffffc(%ecx)
    0x0804834e <main+10>:   push   %ebp
    0x0804834f <main+11>:   mov    %esp,%ebp
    0x08048351 <main+13>:   push   %ecx
    0x08048352 <main+14>:   sub    $0x50,%esp
    0x08048355 <main+17>:   movl   $0x1,0xfffffff8(%ebp)
    0x0804835c <main+24>:   movb   $0x61,0xffffffb8(%ebp)
    0x08048360 <main+28>:   mov    $0x0,%eax
    0x08048365 <main+33>:   add    $0x50,%esp
    0x08048368 <main+36>:   pop    %ecx
    0x08048369 <main+37>:   pop    %ebp
    0x0804836a <main+38>:   lea    0xfffffffc(%ecx),%esp
    0x0804836d <main+41>:   ret    
    End of assembler dump.
    清单 4. demo_sp 的汇编代码
    (gdb) disas main
    Dump of assembler code for function main:
    0x08048394 <main+0>:    lea    0x4(%esp),%ecx
    0x08048398 <main+4>:    and    $0xfffffff0,%esp
    0x0804839b <main+7>:    pushl  0xfffffffc(%ecx)
    0x0804839e <main+10>:   push   %ebp
    0x0804839f <main+11>:   mov    %esp,%ebp
    0x080483a1 <main+13>:   push   %ecx
    0x080483a2 <main+14>:   sub    $0x54,%esp
    0x080483a5 <main+17>:   mov    %gs:0x14,%eax
    0x080483ab <main+23>:   mov    %eax,0xfffffff8(%ebp)
    0x080483ae <main+26>:   xor    %eax,%eax
    0x080483b0 <main+28>:   movl   $0x1,0xffffffb4(%ebp)
    0x080483b7 <main+35>:   movb   $0x61,0xffffffb8(%ebp)
    0x080483bb <main+39>:   mov    $0x0,%eax
    0x080483c0 <main+44>:   mov    0xfffffff8(%ebp),%edx
    0x080483c3 <main+47>:   xor    %gs:0x14,%edx
    0x080483ca <main+54>:   je     0x80483d1 <main+61>
    0x080483cc <main+56>:   call   0x80482fc <__stack_chk_fail@plt>
    0x080483d1 <main+61>:   add    $0x54,%esp
    0x080483d4 <main+64>:   pop    %ecx
    0x080483d5 <main+65>:   pop    %ebp
    0x080483d6 <main+66>:   lea    0xfffffffc(%ecx),%esp
    0x080483d9 <main+69>:   ret    
    End of assembler dump.

    demo_nosp 的汇编代码中地址为 0x08048344 的指令将 esp+4 存入 ecx,此时 esp 指向的内存中保存的是返回地址。地址为 0x0804834b 的指令将 ecx-4 所指向的内存压栈,由于之前已将 esp+4 存入 ecx,所以该指令执行后原先 esp 指向的内容将被压栈,即返回地址被再次压栈。0x08048348 处的 and 指令使堆顶以 16 字节对齐。从 0x0804834e 到 0x08048352 的指令是则保存了旧的 EBP,并为函数设置了新的栈框。当函数完成时,0x08048360 处的 mov 指令将返回值放入 EAX,然后恢复原来的 EBP,ESP。不难看出,demo_nosp 的汇编代码中,没有任何对堆栈进行检查和保护的代码。

    将用 -fstack-protector 选项编译的 demo_sp 与没有堆栈保护的 demo_nosp 的汇编代码相比较,两者最显著的区别就是在函数真正执行前多了 3 条语句:

    0x080483a5 <main+17>:   mov    %gs:0x14,%eax
    0x080483ab <main+23>:   mov    %eax,0xfffffff8(%ebp)
    0x080483ae <main+26>:   xor    %eax,%eax

    在函数返回前又多了 4 条语句:

    0x080483c0 <main+44>:   mov    0xfffffff8(%ebp),%edx
    0x080483c3 <main+47>:   xor    %gs:0x14,%edx
    0x080483ca <main+54>:   je     0x80483d1 <main+61>
    0x080483cc <main+56>:   call   0x80482fc <__stack_chk_fail@plt>

    这多出来的语句便是 SSP 堆栈保护的关键所在,通过这几句代码就在函数栈框中插入了一个 Canary,并实现了通过这个 canary 来检测函数栈是否被破坏。

    %gs:0x14 中保存是一个随机数,0x080483a5 到 0x080483ae 处的 3 条语句将这个随机数放入了栈中 [EBP-8] 的位置。函数返回前 0x080483c0 到 0x080483cc 处的 4 条语句则将栈中 [EBP-8] 处保存的 Canary 取出并与 %gs:0x14 中的随机数作比较。若不等,则说明函数执行过程中发生了溢出,函数栈框已经被破坏,此时程序会跳转到 __stack_chk_fail 输出错误消息然后中止运行。若相等,则函数正常返回。

    调整局部变量的顺序

    以上代码揭露了 GCC 中 canary 的实现方式。仔细观察 demo_sp 和 demo_nosp 的汇编代码,不难发现两者还有一个细微的区别:开启了堆栈保护的 semo_sp 程序中,局部变量的顺序被重新组织了。

    程序中, movl $0x1,0xffffff**(%ebp) 对应于 i = 1;

    movb $0x61,0xffffff**(%ebp) 对应于 buffer[0] = ‘a’;

    demo_nosp 中,变量 i 的地址为 0xfffffff8(%ebp),buffer[0] 的地址为 0xffffffb8(%ebp)。可见,demo_nosp 中,变量 i 在 buffer 数组之前,变量在内存中的顺序与代码中定义的顺序相同,见图 3 左。而在 demo_sp 中,变量 i 的地址为 0xffffffb4 (%ebp),buffer[0] 的地址为 0xffffffb8(%ebp),即 buffer 数组被挪到了变量 i 的前面,见图 3 右。

    图 3. 调整变量顺序前后的函数栈
    调整变量顺序前后的函数栈

    demo_sp 中局部变量的组织方式对防御某些溢出攻击是有益的。如果数组在其他变量之后(图 3 左),那么即使返回地址受到 canary 的保护而无法修改,攻击者也可能通过溢出数组来修改其他局部变量(如本例中的 int i)。当被修改的其他局部变量是一个函数指针时,攻击者就很可能利用这种溢出,将函数指针用 shellcode 的地址覆盖,从而实施攻击。然而如果用图 3 右的方式来组织堆栈,就会给这类溢出攻击带来很大的困难。

    GCC 堆栈保护效果

    以上我们从实现的角度分析了 GCC 中的堆栈保护。下面将用一个小程序 overflow_test.c 来验证 GCC 堆栈保护的实际效果。

    清单 5. 溢出攻击模拟程序 overflow_test.c
    #include <stdio.h>
    #include <stdlib.h>
    char shellcode[] =
        "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"
        "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"
        "\x80\xe8\xdc\xff\xff\xff/bin/sh";
    
    int test()
    {
        int i;
        unsigned int stack[10];
        char my_str[16];
        printf("addr of shellcode in decimal: %d\n", &shellcode);
        for (i = 0; i < 10; i++)
            stack[i] = 0;
    
        while (1) {
            printf("index of item to fill: (-1 to quit): ");
            scanf("%d",&i);
            if (i == -1) {
                break;
            }
            printf("value of item[%d]:", i);
            scanf("%d",&stack[i]);
        }
    
        return 0;
    }
    
    int main()
    {
        test();
        printf("Overflow Failed\n");
    
        return 0;
    }

    该程序不是一个实际的漏洞程序,也不是一个攻击程序,它只是通过模拟溢出攻击来验证 GCC 堆栈保护的一个测试程序。它首先会打印出 shellcode 的地址,然后接受用户的输入,为 stack 数组中指定的元素赋值,并且不会对数组边界进行检查。

    关闭堆栈保护,编译程序

    aktoon@aktoon-thinkpad:~/SCAD/overflow_test$ gcc –fno-stack-protector -o 
    overflow_test ./overflow_test.c

    不难算出关闭堆栈保护时,stack[12] 指向的位置就是栈中存放返回地址的地方。在 stack [10],stack[11],stack[12] 处填入 shellcode 的地址来模拟通常的溢出攻击:

    aktoon@aktoon-thinkpad:~/SCAD/overflow_test$ ./overflow_test 
    addr of shellcode in decimal: 134518560
    index of item to fill: (-1 to quit): 10
    value of item[11]: 134518560
    index of item to fill: (-1 to quit): 11
    value of item[11]: 134518560
    index of item to fill: (-1 to quit): 12
    value of item[12]:134518560
    index of item to fill: (-1 to quit): -1
    $ ps
      PID TTY          TIME CMD
    15035 pts/4    00:00:00 bash
    29757 pts/4    00:00:00 sh
    29858 pts/4    00:00:00 ps

    程序被成功溢出转而执行 shellcode 获得了一个 shell。由于没有开启堆栈保护,溢出得以成功。

    然后开启堆栈保护,再次编译并运行程序。

    aktoon@aktoon-thinkpad:~/SCAD/overflow_test$ gcc –fno-stack-protector -o 
    overflow_test ./overflow_test.c

    通过 gdb 反汇编,不难算出,开启堆栈保护后,返回地址位于 stack[17] 的位置,而 canary 位于 stack[16] 处。在 stack[10],stack[11]…stack[17] 处填入 shellcode 的地址来模拟溢出攻击:

    aktoon@aktoon-thinkpad:~/SCAD/overflow_test$ ./overflow_test 
    addr of shellcode in decimal: 134518688
    index of item to fill: (-1 to quit): 10
    value of item[11]: 134518688
    index of item to fill: (-1 to quit): 11
    value of item[11]: 134518688
    index of item to fill: (-1 to quit): 12
    value of item[11]: 134518688
    index of item to fill: (-1 to quit): 13
    value of item[11]: 134518688
    index of item to fill: (-1 to quit): 14
    value of item[11]: 134518688
    index of item to fill: (-1 to quit): 15
    value of item[11]: 134518688
    index of item to fill: (-1 to quit): 16
    value of item[12]: 134518688
    index of item to fill: (-1 to quit): 17
    value of item[12]: 134518688
    index of item to fill: (-1 to quit): -1
    Overflow Failed
    *** stack smashing detected ***: ./overflow_test terminated
    Aborted

    这次溢出攻击失败了,提示 ”stack smashing detected”,表明溢出被检测到了。按照之前对 GCC 生成的堆栈保护代码的分析,失败应该是由于 canary 被改变引起的。通过反汇编和计算我们已经知道返回地址位于 stack[17],而 canary 位于 stack[16]。接下来尝试绕过 canary,只对返回地址进行修改。

    aktoon@aktoon-thinkpad:~/SCAD/overflow_test$ ./overflow_test 
    addr of shellcode in decimal: 134518688
    index of item to fill: (-1 to quit): 17
    value of item[17]:134518688
    index of item to fill: (-1 to quit): -1
    $ ls *.c
    bypass.c  exe.c  exp1.c  of_demo.c  overflow.c  overflow_test.c  toto.c  vul1.c
    $

    这次只把 stack[17] 用 shellcode 的地址覆盖了,由于没有修改 canary,返回地址的修改没有被检测到,shellcode 被成功执行了。同样的道理,即使我们没有修改函数的返回地址,只要 canary 被修改了(stack[16]),程序就会被保护代码中止。

    aktoon@aktoon-thinkpad:~/SCAD/overflow_test$ ./overflow_test 
    addr of shellcode in decimal: 134518688
    index of item to fill: (-1 to quit): 16
    value of item[16]:134518688
    index of item to fill: (-1 to quit): -1
    Overflow Failed
    *** stack smashing detected ***: ./overflow_test terminated
    Aborted

    在上面的测试中,我们看到编译器的插入的保护代码阻止了通常的溢出攻击。实际上,现在编译器堆栈保护技术确实使堆栈溢出攻击变得困难了。

    GCC 堆栈保护的局限

    在上面的例子中,我们发现假如攻击者能够购绕过 canary,仍然有成功实施溢出攻击的可能。除此以外,还有一些其他的方法能够突破编译器的保护,当然这些方法需要更多的技巧,应用起来也较为困难。下面对突破编译器堆栈保护的方法做一简介。

    Canary 探测方法仅对函数堆中的控制信息 (canary word, EBP) 和返回地址进行了保护,没有对局部变量进行保护。通过溢出覆盖某些局部变量也可能实施溢出攻击。此外,Stack Guard 和 SSP 都只提供了针对栈的溢出保护,不能防御堆中的溢出攻击。

    在某些情况下,攻击者还可以利用函数参数来实现溢出攻击。我们用下面的例子来说明这种攻击的原理。

    清单 6. 漏洞代码 vul.c
    int func(char *msg) {
        char buf[80];
        strcpy(buf,msg);
        strcpy(msg,buf);
    }
    int main(int argv, char** argc) {
        func(argc[1]);
    }

    运行时,func 函数的栈框如下图所示。

    图 4. func 的函数栈
    func 的函数栈

    通过 strcpy(buf,msg),我们可以将 buf 数组溢出,直至将参数 msg 覆盖。接下来的 strcpy(msg,buf) 会向 msg 所指向的内存中写入 buf 中的内容。由于第一步的溢出中,我们已经控制了 msg 的内容,所以实际上通过上面两步我们可以向任何不受保护的内存中写入任何数据。虽然在以上两步中,canaries 已经被破坏,但是这并不影响我们完成溢出攻击,因为针对 canaries 的检查只在函数返回前才进行。通过构造合适的溢出字符串,我们可以修改内存中程序 ELF 映像的 GOT(Global Offset Table)。假如我们通过溢出字符串修改了 GOT 中 _exit() 的入口,使其指向我们的 shellcode,当函数返回前检查到 canary 被修改后,会提示出错并调用 _exit() 中止程序。而此时的的 _exit() 已经指向了我们的 shellcode,所以程序不会退出,并且 shellcode 会被执行,这样就达到了溢出攻击的目的。

    上面的例子展示了利用参数避开保护进行溢出攻击的原理。此外,由于返回地址是根据 EBP 来定位的,即使我们不能修改返回地址,假如我们能够修改 EBP 的值,那么就修改了存放返回地址的位置,相当于间接的修改了返回地址。可见,GCC 的堆栈保护并不是万能的,它仍有一定的局限性,并不能完全杜绝堆栈溢出攻击。虽然面对编译器的堆栈保护,我们仍可能有一些技巧来突破这些保护,但是这些技巧通常受到很多条件的制约,实际应用起来有一定的难度。


    展开全文
  • 解决Dev-C++编译慢问题方法

    千次阅读 热门讨论 2020-02-27 21:06:13
    一般情况下大多数人的电脑在用dev这个轻便的编译器编译C/C++源文件的时候是很快的 但是、但是、但是 总有个别人的电脑编译一个文件真的是超级超级慢 慢到什么程度呢?编译一个简单的Hello World!的源程序就需要十...

    一般情况下大多数人的电脑在用dev这个轻便的编译器编译C/C++源文件的时候是很快的

    但是、但是、但是

    总有个别人的电脑编译一个文件真的是超级超级慢

    慢到什么程度呢?编译一个简单的Hello World!的源程序就需要十几秒的时间。

    我在解决这个问题的过程中发现了两个解决办法。

    第一种:

    我在写这篇文章的时候无法复现当时的场景了,只能根据记忆来做简单的描述。我当时的情况是没有装任何的杀毒软件,只有一个Windows defender。

    我在刚安装好dev后,编译第一个程序超级快,零点几秒的时间。

    然而,这个时候windows defender不知道弹出了个什么东西,我还没来及的看清楚他就消失了、消失了、消失了

    我隐约看到什么云的,后来一查才知道,windows defender有一个安全机制,在启动一个运行一个应用程序的时候,windows defender会会获取云上的一些东西,然后确保软件的安全性。

    所以我猜慢的原因是,启动编译命令的时候,会先经过windows defender的检查然后才能编译,可能这也就是慢的原因。

    解决方法,是在windows安全中心把这个检查选项给关了。但是我自从安装了火绒杀毒软件和把windows从家庭版升级到专业版以后以及系统更新后,这个选项我就找不到在哪了。所以我建议安装一个杀毒软件,升级windows到专业版,或更新windows都有可能解决这个问题,不过这解决后,编译简单文件的速度也需要2秒左右,不过快多了。

    第二种:

    这种方法才是终极大法

    首先找到dev的安装目录,接着找到MinGw64文件夹

    然后下载一个MinGw64,

    百度云连接:

    链接:https://pan.baidu.com/s/1ji445BQ4pvRGIYgLEjKhJQ 
    提取码:18sy 
    复制这段内容后打开百度网盘手机App,操作更方便哦

    这个是8.1.0版本的,支持C++17,同时也可以把文件下的bin目录的路径配置到系统变量Path下,这样就可以再命令行下使用gcc,g++等命令了。

    解压后把这个MinGw64替换掉dev目录下的MinGw64

    重启dev,可能会提示缺少一些参数, 点击Yes即可

    然后再编译文件速度快的起飞

     

    我的重启是没有任何问题的,如果重启有问题请尝试下列方法

    第一步:

    第二步:

    第三步:

    展开全文
  • 2020年10月,Embarcadero赞助并发布了Dev-C ++新fork版本6.0,并进行了改进,其中包括更新GCC 9.2.0编译器,支持Windows 10和C ++ 17 / C ++ 20,高DPI,UTF8文件和改进SVG矢量格式图标,以及深色暗黑主题选项...
  • 当你想编译一个C++源程序的时候,用的最多的是什么工具呢?GCC?BCB?VC?GCC在linux下面,一般不会用到,BCB和VC太大了,还要建立工程,编译一个控制台程序也生产N多一般来说是多余的文件。当然还有一个比较不错的...
  • devc++配置OpenGL

    千次阅读 2018-10-12 00:22:48
    非常非常重要的是,不知道是我的版本问题还是什么奇奇怪怪的原因,在64位编译器下我无论使用什么方法都无法配置成功,但是在32位编译器下很快就成功了,因此如果你完全按照网上的一些方法来配置的却始终无法成功,...
  • Dev cpp 简单配置 EGE

    2016-02-23 19:18:00
    编译器是Dev cpp。之所以说简单配置 因为只是配置一部分。 正文  1.首先下载Dev cpp。有些64位浏览器点击后没有反应,没错,我就是这样,然后想到了一个以前方法。就是直接去百度软件中心去找,至少...
  • 前文介绍了,为什么使用CFree来作为SDL开发环境,但是为什么又要安装DevCPP 或者 CodeBlacks作为编译器的原因??   这里再次质疑下国内某些开源愤青想法,我前天下CodeBlocks最新版本8,感觉并不咋,界面很...
  • 前文介绍了,为什么使用CFree来作为SDL开发环境,但是为什么又要安装DevCPP 或者 CodeBlacks作为编译器的原因??   这里再次质疑下国内某些开源愤青想法,我前天下CodeBlocks最新版本8,感觉并不咋,界面很...
  • 实验要求 (1)输人说明:以指数递降方式输人多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。 (2)输出说明:以与输入相同的格式输出导数多项式非零项的系数和...用的编译器是DeV.C++
  • 本人大一学生,最开始接触的编译器是dev,后来上课时候按照教师要求安装了vc++和codeblocks,但自从安装了这两个编译器之后,dev和codeblocks都无法运行,可以写代码,可以编译,但是运行时候就显示“不支持...
  • c语言中pow(x, y)使用

    万次阅读 多人点赞 2017-04-09 22:15:02
    pow(10,2)用整形输出结果为0 用浮点数输出...这是什么情况,我用的dev cpp,难道是编译器的问题?——————————————不是编译器的问题。pow()返回值类型是double的。对double/float类型数据输出格式用“%d
  • C语言课前准备

    2019-01-30 14:12:02
    如果你能看到我的这一篇文章,那你肯定是计算机专业,...在学校我们开始学习C语言,大多用的是vc6.0 或者是 dev 等这些比较小的编译器,但是如果想要好一点的编译器,我还是推荐大家下载 vs等系列,学习C语言的话,...
  • 昨天笔试遇到个 关于类占用空间大小问题,以前没怎么重视,回来做个试验,还真发现了问题,以后各位笔试考官门,出题时请注明是用什么编译器。 vc6/vc8 cl 和 Dev-C g++ 来做测试: 上代码, 测试代码: ...
  • 工欲善其事,必先利其器。...简单,Dev-C++无需配置编译器等,安装即 免费使用 安装Dev-C++,首先需要一台Windows系统电脑 (没有电脑也没关系,我们可以在手机端安装其他开发工具,点击这...
  • 但其实具体入栈方式其实和编译器有关,这也就是为什么用sublime跑出来和用dev跑出来结果会不一样; 所以在我们平常编写代码时,应该避免以上这种无意义代码编写方式????; 关于入栈操作和题目其他详细解释...
  • MFC详细教程

    2014-03-06 13:21:52
    有时人们说vc呢也指它内部编译器,集成开发环境必须有一个编译器内核,要不有什么用,例如DevC++其中一个编译器内核就是gcc。 MFC除了一个类库以外,还是一个框架,你应该试过,在vc++里新建一个MFC工程,开发...
  • C++小白如何入门?

    2021-01-03 19:55:43
    最好用的是什么呢? 答案就是:VScode,但是我并不建议初学者使用这款编译器,这一款编译器的功能很多,但是,对于初学者来说,是天大的灾难,毕竟,那个东西有的时候装配置文件就要把小白打趴下~~ 除了这种编译器,...
  • 『芯知识学堂』SingleYork,相信很多学过C语言或正在学C语言小伙伴们都会遇到一个这样问题:市面上有那么多C语言开发工具,如:TC2.0编译器、VC++6.0、Visual Studio、codeblock、Visual Studio Code、...
  • MFC编程简介

    2014-07-27 22:36:13
    MFC(MicrosoftFoundationClasses)微软基础类库简称,微软公司实现一个c++类库...有时人们说vc呢也指它内部编译器,集成开发环境必须有一个编译器内核,要不有什么用,例如DevC++其中一个编译器内核就是gcc。
  • C/C++中int128那点事

    2018-06-19 15:43:00
    讲道理的话,编译器的gcc不支持__int128这种数据类型的,比如在codeblocks 16.01/Dev C++无法编译的,但是提交到大部分OJ上可以编译且能用的。C/C++标准。IO不认识__int128这种数据类型的,因此要自己实现IO...
  • c++大数-__int128

    千次阅读 2019-03-10 17:20:00
    讲道理的话,编译器的gcc不支持__int128这种数据类型的,比如在codeblocks 16.01/Dev C++无法编译的,但是提交到大部分OJ上可以编译且能用的。C/C++标准。IO不认识__int128这种数据类型的,因此要自己实现IO...
  • 我目前用的编译器是DEV C++ 5.6.1 ``` #include using namespace std; int main() { size_t array_type = 10; int array[array_type]; for (size_t ix = 0; ix != array_type; ix++){ array[ix] ...

空空如也

空空如也

1 2 3 4 5
收藏数 91
精华内容 36
关键字:

dev用的是什么编译器