ASLR打开时返回的指针地址被修改

时间:2022-04-15 21:44:03

I have this piece of C code running on development box with ASLR enabled. It is returning a char pointer (char *) to a function, but somehow few bytes in the returned pointer address are getting changed, printf output below:

我在启用了ASLR的开发盒上运行了这段C代码。它将一个char指针(char *)返回给一个函数,但不知何故返回的指针地址中的几个字节正在改变,printf输出如下:

kerb_selftkt_cache is 0x00007f0b8e7fc120
cache_str from get_self_ticket_cache 0xffffffff8e7fc120

The char pointer 0x00007f0b8e7fc120 is being returned to another function, which is getting modified as 0xffffffff8e7fc120 that differs from the original pointer address by one word (4-bytes) 0xffffffff instead of 0x00007f0b, the last four bytes (8e7fc120) being same. Any idea what might be going on? and how do I possibly fix this. The code is running on linux 64-bit architecture on Intel Xeon. This code is from an existing proprietary library, so I can't share the exact code, but the code logic looks something like this:

字符指针0x00007f0b8e7fc120返回到另一个函数,该函数被修改为0xffffffff8e7fc120,它与原始指针地址相差一个字(4字节)0xffffffff而不是0x00007f0b,后四个字节(8e7fc120)相同。知道可能会发生什么吗?我怎么可能解决这个问题该代码在Intel Xeon上的Linux 64位架构上运行。此代码来自现有的专有库,因此我无法共享确切的代码,但代码逻辑看起来像这样:

typedef struct mystr {
 int num;
 char addr[10];
}mystr;

static mystr m1;

char *get_addr() {
 return m1.addr;
}

void myprint() {
 printf("mystr m1 address %p\n",&m1);
 printf("mystr m1 addr %p\n",m1.addr);
}

int main (int argc, char *argv[]) {

char *retadd;
myprint();

retadd = get_addr();
printf("ret address %p\n",retadd);

return 0;
}

retadd and m1.addr are different when ASLR is turned on.

当ASLR打开时,retadd和m1.addr不同。

1 个解决方案

#1


My guess is the func takes an int or something else only 4 bytes wide, then the argument gets casted to a pointer type which sign-extends it. Except the compiler (gcc?) should warn you even without flags like -Wall, but hey, maybe you have weird-ass macros or something which obfuscate it.

我的猜测是func接受一个只有4个字节宽的int或其他东西,然后该参数被转换为一个对其进行符号扩展的指针类型。除了编译器(gcc?)之外应该警告你,即使没有像-Wall这样的标志,但是,嘿,也许你有奇怪的屁股宏或者混淆它的东西。

Alternatively what you mean by passing is the fact that you return it (as opposed to passing as an argument). That could be easily explained by C defaulting to int as a return value if function declaration is missing. So in that case make sure you got stuff declared.

或者你通过传递的意思是你返回它(而不是作为参数传递)。如果函数声明丢失,C可以很容易地解释为int作为返回值。所以在这种情况下确保你已经宣布了东西。

#1


My guess is the func takes an int or something else only 4 bytes wide, then the argument gets casted to a pointer type which sign-extends it. Except the compiler (gcc?) should warn you even without flags like -Wall, but hey, maybe you have weird-ass macros or something which obfuscate it.

我的猜测是func接受一个只有4个字节宽的int或其他东西,然后该参数被转换为一个对其进行符号扩展的指针类型。除了编译器(gcc?)之外应该警告你,即使没有像-Wall这样的标志,但是,嘿,也许你有奇怪的屁股宏或者混淆它的东西。

Alternatively what you mean by passing is the fact that you return it (as opposed to passing as an argument). That could be easily explained by C defaulting to int as a return value if function declaration is missing. So in that case make sure you got stuff declared.

或者你通过传递的意思是你返回它(而不是作为参数传递)。如果函数声明丢失,C可以很容易地解释为int作为返回值。所以在这种情况下确保你已经宣布了东西。