小编chq*_*lie的帖子

基于堆栈的缓冲区溢出-使用scanf和有限输入的C语言中的挑战

作为安全CS课程的一部分,我班的任务是利用漏洞利用堆栈/缓冲区溢出来击败密码检查。带有漏洞的代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/md5.h>

int main(int argc, char **argv) {
    char correct_hash[16] = {
        0xd0, 0xf9, 0x19, 0x94, 0x4a, 0xf3, 0x10, 0x92,
        0x32, 0x98, 0x11, 0x8c, 0x33, 0x27, 0x91, 0xeb
    };
    char password[16];

    printf("Insert your password: ");
    scanf("%29s", password);

    MD5(password, strlen(password), password);

    if (memcmp(password, correct_hash, 16) == 0) {
        printf("Correct Password!\n");
    } else {
        printf("Wrong Password, sorry!\n");
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我了解经典的“堆栈粉碎”原理(我认为),并且这里存在一个明显的溢出漏洞,该漏洞correct_hash可以通过在提示时输入长度超过15个字符的密码来覆盖数组的前14个字节。但是,我不知道如何利用此功能使memcmp检查通过,从而完成挑战。我发现/尝试过的一些东西:

  • 设置password为等价是correct_hash行不通的,因为password使用MD5()进行了哈希处理(无论如何都不可能将两者相等),因为 …

c stack-overflow md5 buffer-overflow stack-smash

5
推荐指数
1
解决办法
1828
查看次数

具有灵活数组成员的结构数组如何表现?

正如标题所述,我想知道具有灵活数组成员的C结构数组如何表现.这是一个例子:

struct vector {
    size_t length;
    double array[];
};
Run Code Online (Sandbox Code Playgroud)

维基百科的文章说:

sizeof这种结构上的操作符需要给出柔性阵列成员的偏移量.

在我的机器上,这对应于8个字节(sizeof(size_t)).但是,当我执行以下操作时会发生什么:

显然,数组不能保存向量数据v0,因为它只有3*8字节= 24字节宽.我该如何处理这样的情况?

#define LENGTH 10

int main() {
    struct vector arr[3];

    struct vector *v0 = calloc(1, sizeof(*v0) + LENGTH * sizeof(v0->array[0]));
    v0->length = LENGTH;

    size_t i;
    for (i = 0; i < v0->length; i++) {
        v0->array[i] = (double) i;
    }

    struct vector v1;
    struct vector v2;

    arr[0] = *v0;
    arr[1] =  v1;
    arr[2] =  v2;

    for (i = 0; …
Run Code Online (Sandbox Code Playgroud)

c arrays struct flexible-array-member

5
推荐指数
1
解决办法
1158
查看次数

按C中的流行度排序字符

我写了一个代码来列出字符串中字符的出现.它有效,但我想知道,是否有可能把它整理好?例如下降.听起来很简单,但我在这里使用了两个数组,我不知道怎么可能将它们链接起来,这样它们就不会在排序后搞砸了.我读到在C++中我可以使用std :: pair但是从我发现的内容来看,在C++中没有替代品.

是不是只有一个简单的方法来排序它,以便我可以有一个大多数/最不受欢迎的字符列表?我开始进入冒泡排序,但无论我选择什么,两个阵列之间仍然没有链接.

这是代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

main(int argc, char **argv) {
    int hits[26] = { 0 };
    char letters[26] = {
        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
        'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
        'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
    char *line;
    int i;

    printf("Write the line:\n");
    scanf("%25[^\n]", line);
    for (i = 0; i < strlen(line); i++) {
        if (!isalpha(line[i]))
            continue;
        hits[(int)(tolower(line[i]) - 'a')]++;
    }

    for (i …
Run Code Online (Sandbox Code Playgroud)

c sorting

5
推荐指数
1
解决办法
110
查看次数

声明带有指针的字符串文字比声明常量数组更有效吗?

如果我想存储一个常量字符串,

const char array[] = "Some string literal.";
Run Code Online (Sandbox Code Playgroud)

C引子加书说

然后,引用的字符串存储在作为可执行文件一部分的数据段中.只有在程序开始运行后才会分配数组的内存.那时,引用的字符串被复制到数组中.

这是否意味着内存为字符串文字分配了两次?

另一方面,当使用指针声明时,它仅为指针变量留出存储空间并将字符串文字的地址存储到其中.

const char *pt = "Some string literal.";
Run Code Online (Sandbox Code Playgroud)

这意味着只有一个字符串文字的副本,并且使用字符串文字声明指针比数组的内存效率更高?

c pointers

5
推荐指数
2
解决办法
128
查看次数

在C中两个连续的printf()调用的奇怪行为

我在玩C; 看一下这个:

#include <stdio.h>
#include <stdlib.h>

void main() {
    printf("%d\n", 1.5);
    printf("%f", 0);
}
Run Code Online (Sandbox Code Playgroud)

我期待输出:

0
0.000000
Run Code Online (Sandbox Code Playgroud)

但它打印:

0
1.500000
Run Code Online (Sandbox Code Playgroud)

第一次printf()通过1.5第二次printf()吗?

PS:我知道(%d对于整数,%f浮标).正如我所提到的,我只是在搞乱代码.

PS2:我正在使用DevC++和Code :: Blocks.

c printf

5
推荐指数
2
解决办法
236
查看次数

C中的按位运算比较两个整数

我最近在我的一个课程中接受了测验.问题如下:

cmp在C中编写一个函数(调用),它接受两个整数(xy)并返回:-1if x< y,0if x= y,1if x> y.写得cmp尽可能简洁.

我能想到的最简洁的功能是:

int cmp(int x, int y) {
    return ((x < y) ? (-1) : ((x == y) ? (0) : (1)));
}
Run Code Online (Sandbox Code Playgroud)

但我有一种感觉,我可以用一些操作来更简洁地做到这一点.也许是&^?的结合?这已经困扰了我过去的几天,我想知道是否有其实IS更好的方式来做到这一点?

c bit-manipulation bitwise-operators

5
推荐指数
2
解决办法
3041
查看次数

计算交替的上/下序列

问题描述:计算从某个输入n向上的所有序列的数量.所以用户输入n; 然后我创建一个数字1..n数组,然后用该属性编号序列

例: n = 4

1 3 2 4
1 4 2 3
2 3 1 4
2 4 1 3
3 4 1 2
Run Code Online (Sandbox Code Playgroud)

回答: 5

我的程序有效,但出于某种原因,我有时会得到0而不是答案.

#include <stdio.h>
#include <stdlib.h>

void *safeMalloc(int n) {
    void *p = malloc(n);
    if (p == NULL) {
        printf("Error: malloc(%d) failed. Out of memory?\n", n);
        exit(EXIT_FAILURE);
    }
    return p;
}

void swap(int *fir, int *sec) {
    int temp = *fir;
    *fir = *sec;
    *sec = temp;
}

void permute(int *array, int i, …
Run Code Online (Sandbox Code Playgroud)

c algorithm recursion

5
推荐指数
1
解决办法
212
查看次数

C:数组初始化需要括号括起初始化列表 - 简单代码

我是C的完全初学者,我遇到了我认为是一个简单的错误.我在网上查找了类似的问题,但我发现我的代码没有问题.很少,我不知道问题是什么.

这是错误:

C: Array initialization requires a brace-enclosed initializer list

这是我的完整代码

#include <stdio.h>

int main() {
    char walk[10][10] = { 0 };

    for (int row = 0; row < 10; row++) {
        for (int col = 0; col < 10; col++) {
            walk[row][col] = '.';
            printf("%c", walk[row][col]);
        }
    }

    getchar();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c arrays

5
推荐指数
1
解决办法
270
查看次数

GNU readline:巨大的内存泄漏

考虑以下代码段:

#include <stdio.h>
#include <stdlib.h>
#include <readline/readline.h>

int main() {
    for (;;) {
        char *buf = readline(">>> ");
        if (!buf)
            break;

        free(buf);
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的系统上,使用valgrinds进行编译-lreadline,在其下执行程序valgrind并输入一些行会导致巨大的内存泄漏,如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <readline/readline.h>

int main() {
    for (;;) {
        char *buf = readline(">>> ");
        if (!buf)
            break;

        free(buf);
    }
}
Run Code Online (Sandbox Code Playgroud)

运行--show-leak-kinds=all类似这样的结果(整个过程长数百行,我只显示开始):

==7651== LEAK SUMMARY:
==7651==    definitely lost: 0 bytes in 0 blocks
==7651==    indirectly lost: 0 bytes in 0 blocks
==7651==      possibly lost: 0 bytes in …
Run Code Online (Sandbox Code Playgroud)

c gnu readline

5
推荐指数
1
解决办法
310
查看次数

何时以及如何在 sizeof 表达式中计算 VLA?

C 标准有这种语言:

6.5.3.4 sizeof 和 _Alignof 运算符

语义学

  1. sizeof运算符产生其操作数的大小(以字节为单位),该操作数可以是表达式或带括号的类型名称。大小由操作数的类型确定。结果是一个整数。如果操作数的类型是变长数组类型,则对操作数求值;否则,不计算操作数并且结果是整型常量。

我不清楚标准的含义:如果操作数的类型是可变长度数组类型,则对操作数进行求值

  • 如果操作数的类型是可变长度数组类型,则评估参数似乎没有任何目的,因为可以根据类型的定义确定大小,如 6.7.6.2 数组声明符中规定那样可变长度数组类型的每个实例的大小在其生命周期内不会改变。
  • 另一方面,如果操作数是带括号的可变长度数组类型的名称,例如在sizeof(char[foo()])大小表达式中必须在运行时求值来计算大小,但标准的语言似乎没有涵盖这种情况(什么是类型名称的类型吗?)

C 标准的语言是否应该修改以澄清?

下面是一个测试程序,用于说明 VLA 的某些特定情况下的行为:

#include <stdio.h>

static int N = 0;
int foo(void) { return ++N; }

int main() {
    typedef char S[foo()];      // foo() is called
    printf("typedef char S[foo()];\t");                             printf("N=%d\n", N);
    printf("sizeof(S)=%d\t\t", (int)sizeof(S));                     printf("N=%d\n", N);

    typedef char U[foo()];      // foo() is called
    printf("typedef char U[foo()];\t");                             printf("N=%d\n", N);
    printf("sizeof(U)=%d\t\t", (int)sizeof(U));                     printf("N=%d\n", N);

    S s1;
    printf("S s1;\t\t\t"); …
Run Code Online (Sandbox Code Playgroud)

c c99 expression-evaluation language-lawyer variable-length-array

5
推荐指数
1
解决办法
132
查看次数