gpt4 book ai didi

c - 相同值的不同 Int 值?

转载 作者:行者123 更新时间:2023-11-30 16:18:12 25 4
gpt4 key购买 nike

我遇到了整数溢出问题,我设法解决了这个问题,但只能通过反复试验。

由于这是一个整数溢出问题,我编写了一些代码来打印缓冲区。缓冲区的开头是存储 array[0] 的地址。然后,我开始将 MAX_INT 和 MIN_INT 值传递给程序。我注意到,当我将 MIN_INT 值传递给 argv[1] 时,它覆盖了缓冲区的开头。所以我传递了 MIN_INT+1 值,并注意到它覆盖了缓冲区的第二个地址。从那里就很容易解决。

问题是,我不明白为什么会这样。在 place_int_array 函数中,当我将 MIN_INT+6 值传递给 argv[1] 时,if 语句“if (slot > 3)”返回 false,因此它转到“else”语句,因为 MIN_INT+6 是负值,因此它小于或等于 3,因此插槽的值被解释为“MIN_INT+6”值。但在“else”语句中,array[slot] 在缓冲区中上升到“array[0]+6”的地址,这意味着,slot 的值作为“array”的索引被解释为“6”。

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

int secretCode = 10;

void dump_stack(void **stack, size_t n, void **arg0) {
printf("Stack dump (stack at %p, len %d): \n", stack, n);
//if the buffer if not aligned on a dword boundary - force alignment of print

void** alignedStack = (void**)(((unsigned int)stack >> 2) << 2);
while (n-- > 0) {
printf("0x%08x: 0x%08x", (unsigned int)&alignedStack[n], (unsigned int)alignedStack[n]);
if (n == 0) {
printf(" (beginning of buffer)");
}
if (&alignedStack[n] == arg0 + 6+1) {
printf(" (main first argument (argc))");
}
if (&alignedStack[n] == arg0 + 6) {
printf(" (main return address (saved eip))");
}
if (&alignedStack[n] == arg0) {
printf(" (second argument)");
}
if (&alignedStack[n] == arg0 - 1) {
printf(" (first argument)");
}
if (&alignedStack[n] == arg0 - 2) {
printf(" (place_int_array return address (saved eip))");
}
if (&alignedStack[n] == arg0 - 3) {
printf(" (saved ebp)");
}

printf("\n");
}
}

void print_secret_code() {
//TODO - call this from somewhere...
printf("You get better at this stuff, ah?! Go get your treasure, the code is %d\n", secretCode);
}

void fill_array(int array[], size_t len) {
unsigned int i;
for (i = 0; i < len; i++) {
array[i] = i * 10;
}
}

void place_int_array(int slot, int value) {
int array[3];

printf("place_int_array ret address: %p\n‬", __builtin_return_address(0));
printf("&array: %p\n", &array);
printf("slot: %d\n", slot);
printf("&array[slot]: %p\n", &array[slot]);


fill_array(array, sizeof(array) / sizeof(array[0]));

printf("slot: %d\n", slot);
if (slot > 3) //we stop bad guys here
printf("safe number is greater than 3, out of bounds.\n");
else {
array[slot] = value;
dump_stack((void **) array, 30, (void **) &value);
printf("filled safe %d with %d.\n", slot, value);
}
return;
}

int main(int argc, char **argv) {
printf("print_secret_code function = %p\n", print_secret_code);

if (argc != 3) {
printf("Welcome to Alladin's magic cave!\n");
printf("Enter the secret number into the right safe and get the treasure cave entrance code!\n");
printf("syntax: %s [SAFE NUMBER] [SECRET NUMBER]\n", argv[0]);

//TEMP TEMP - for debugging only
printf("print_secret_code function = %p\n", print_secret_code);
}
else
{

place_int_array(atoi(argv[1]), atoi(argv[2]));
}

exit(0);
}

这是输出:

[lab8_IntegerOverflow]$ ./aladdinSafe -2147483648 1
print_secret_code function = 0x804864b
place_int_array ret address: 0x804880d
&array: 0xffbd8464
slot: -2147483648
&array[slot]: 0xffbd8464
slot: -2147483648
Stack dump (stack at 0xffbd8464, len 30):
0xffbd84d8: 0xbca9b1bd
0xffbd84d4: 0x72f595ac
0xffbd84d0: 0x00000000
0xffbd84cc: 0x00000000
0xffbd84c8: 0x00000000
0xffbd84c4: 0xf773c000
0xffbd84c0: 0x0804825c
0xffbd84bc: 0x0804a01c
0xffbd84b8: 0xffbd84d4
0xffbd84b4: 0xffbd8534
0xffbd84b0: 0x00000003
0xffbd84ac: 0xf7765cca
0xffbd84a8: 0xffbd8544
0xffbd84a4: 0xffbd8534
0xffbd84a0: 0x00000003 (main first argument (argc))
0xffbd849c: 0xf75aaaf3 (main return address (saved eip))
0xffbd8498: 0x00000000
0xffbd8494: 0xf773c000
0xffbd8490: 0x08048820
0xffbd848c: 0xf773c000
0xffbd8488: 0x0804882b
0xffbd8484: 0x00000001 (second argument)
0xffbd8480: 0x80000000 (first argument)
0xffbd847c: 0x0804880d (place_int_array return address (saved eip))
0xffbd8478: 0xffbd8498 (saved ebp)
0xffbd8474: 0xf7778938
0xffbd8470: 0xffbda5cb
0xffbd846c: 0x00000014 //address of array[2], filled at "fill_array" function with 2*10 = 20 = 0x14
0xffbd8468: 0x0000000a //address of array[1], filled at "fill_array" function with 1*10 = 10 = 0xa
0xffbd8464: 0x00000001 (beginning of buffer) //address of array[0], overwritten with argv[2] = 1.
filled safe -2147483648 with 1.

我希望如果“slot > 3”的槽被解释为 MIN_INT+6,那么“array[slot]”的槽也会被解释为相同。

为什么插槽的值会根据其使用情况而变化?

最佳答案

@IanAbbott 明白了。整数“slot”在“array[slot]”处下溢,因为编译器将“slot”乘以 4。因此,当 INT_MIN 乘以 4 时,它会流向 0。当 slot = INT_MIN + 6 时,当尝试计算 array[slot] 的地址时,它首先将 slot 乘以 4,等于 (INT_MIN + 6)*4,下溢为 0 + 6*4,这正好是“array[0]”地址上方的 6 个地址。但在这个语句“if (slot > 3)”中,slot 只是一个负数,即 INT_MIN + 6,因此“slot > 3”返回 false。

关于c - 相同值的不同 Int 值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56021920/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com