作为安全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结构数组如何表现.这是一个例子:
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++中我可以使用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) 如果我想存储一个常量字符串,
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; 看一下这个:
#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.
我最近在我的一个课程中接受了测验.问题如下:
cmp在C中编写一个函数(调用),它接受两个整数(x和y)并返回:-1ifx<y,0ifx=y,1ifx>y.写得cmp尽可能简洁.
我能想到的最简洁的功能是:
int cmp(int x, int y) {
return ((x < y) ? (-1) : ((x == y) ? (0) : (1)));
}
Run Code Online (Sandbox Code Playgroud)
但我有一种感觉,我可以用一些操作来更简洁地做到这一点.也许是&和^?的结合?这已经困扰了我过去的几天,我想知道是否有其实IS更好的方式来做到这一点?
问题描述:计算从某个输入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的完全初学者,我遇到了我认为是一个简单的错误.我在网上查找了类似的问题,但我发现我的代码没有问题.很少,我不知道问题是什么.
这是错误:
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) 考虑以下代码段:
#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 标准有这种语言:
6.5.3.4 sizeof 和 _Alignof 运算符
语义学
- 该
sizeof运算符产生其操作数的大小(以字节为单位),该操作数可以是表达式或带括号的类型名称。大小由操作数的类型确定。结果是一个整数。如果操作数的类型是变长数组类型,则对操作数求值;否则,不计算操作数并且结果是整型常量。
我不清楚标准的含义:如果操作数的类型是可变长度数组类型,则对操作数进行求值
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