我正在阅读这本黑客攻击 - 利用艺术的书,下面的代码似乎抛出以下错误

I was reading this hacking - art of exploitation book and the below code seems to throw the following error

提问人:Ecce 提问时间:3/5/2023 最后编辑:DanielEcce 更新时间:6/6/2023 访问量:73

问:

错误

pointer_types5.c: In function ‘main’:
pointer_types5.c:11:28: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
   11 |         hacky_nonpointer = (unsigned int) char_array;
      |                            ^
pointer_types5.c:15:33: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
   15 |             hacky_nonpointer, *((char *) hacky_nonpointer));
      |                                 ^
pointer_types5.c:19:28: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
   19 |         hacky_nonpointer = (unsigned int) int_array;
      |                            ^
pointer_types5.c:23:33: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
   23 |             hacky_nonpointer, *((int *) hacky_nonpointer));
      |   

法典

#include <stdio.h>

int main() {
    int i;

    char char_array[5] = {'a', 'b', 'c', 'd', 'e'};
    int int_array[5] = {1, 2, 3, 4, 5};

    unsigned int hacky_nonpointer;

    hacky_nonpointer = (unsigned int) char_array;

    for(i=0; i < 5; i++) { // iterate through the int array with the int_pointer
        printf("[hacky_nonpointer] points to %p, which contains the char '%c'\n",
            hacky_nonpointer, *((char *) hacky_nonpointer));
        hacky_nonpointer = hacky_nonpointer + sizeof(char);
    }

    hacky_nonpointer = (unsigned int) int_array;
    
    for(i=0; i < 5; i++) { // iterate through the int array with the int_pointer
        printf("[hacky_nonpointer] points to %p, which contains the integer %d\n",
            hacky_nonpointer, *((int *) hacky_nonpointer));
        hacky_nonpointer = hacky_nonpointer + sizeof(int);
    }
}
  
C 指针 转换 分段故障 警告

评论

3赞 wohlstad 3/5/2023
1. 这些是警告,而不是错误, 2.它们非常清楚 - 您将指针分配给较小的无符号 int,例如,在 64 位系统上,指针通常为 8 个字节,而无符号 int 只有 4 个字节。

答:

1赞 Vlad from Moscow 3/5/2023 #1

代码无效且具有未定义的行为。

例如,通常,该类型的对象不能存储指针类型的值,因为它们的大小不同,如第一个警告所述。unsigned int

在 header 中,有专门定义的 int 类型,旨在存储 类型的指针值。<stdint.h>uintptr_tintptr_tvoid *

此外,转换说明符旨在输出指针类型的值,而不是输出再次调用未定义行为的整数。%pvoid *

您可以通过以下方式更改程序

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>

int main( void ) 
{
    enum { N = 5 };
    char char_array[N] = {'a', 'b', 'c', 'd', 'e'};
    int int_array[N] = {1, 2, 3, 4, 5};

    uintptr_t hacky_nonpointer;

    hacky_nonpointer = ( uintptr_t )( void * )char_array;

    for ( int i = 0; i < N; i++ ) 
    { // iterate through the int array with the int_pointer
        printf("[hacky_nonpointer] points to %" PRIuPTR ", which contains the char '%c'\n",
            hacky_nonpointer, *( char * )( void * )hacky_nonpointer );
        hacky_nonpointer = hacky_nonpointer + sizeof(char);
    }

    hacky_nonpointer = ( uintptr_t )( void * )int_array;
    
    for ( int i = 0; i < N; i++ ) 
    { // iterate through the int array with the int_pointer
        printf("[hacky_nonpointer] points to %" PRIuPTR ", which contains the integer %d\n",
            hacky_nonpointer, *( int * )( void * )hacky_nonpointer );
        hacky_nonpointer = hacky_nonpointer + sizeof(int);
    }
}

如果要以十六进制输出对象的值,请使用 macro 而不是 macro 。hacky_nonpointerPRIxPTRPRIuPTR

评论

0赞 Ecce 3/5/2023
感谢您的描述性回答,真的帮助我理解了。正如您在这里所说,例如,unsigned int 类型的对象通常不能存储指针类型的值,因为它们的大小不同,正如第一个警告所说。** 将 int 转换为 long 不会起作用吗?
0赞 Trin 3/12/2023 #2

您可以尝试将 all 更改为 .unsigned intunsigned long

评论

0赞 Adrian Mole 3/16/2023
这并没有真正解决 OP 试图将数组(即指向数组的第一个元素的指针)转换为整数的问题。
0赞 Дмитрий Шатохин 6/6/2023 #3

可能您使用的是 64 位系统,如果您将 long long int 而不是 unsigned int 分配给 example,则会得到结果。