1
MeteorCat 2018-04-04 18:51:57 +08:00 via Android
其实数组是可以为负的,Redis 有数组-1 位移运算的用法,当然这种高端黑科技用法不推荐
|
2
MeteorCat 2018-04-04 18:58:33 +08:00 via Android
redis 源码的 sds.h 函数 sds_len 有这个方面实践,这算是比较偏门的黑魔法吧
|
3
z0z OP @MeteorCat 嗯。
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<stdint.h> 4 #include<string.h> 5 6 7 int main(void) 8 { 9 uint8_t arrary[8]={0,1,2,3,4,5,6,7}; 10 uint8_t *p=&arrary[4]; 11 12 printf("p[-1]=%d\n",p[-1]); 13 14 return 0; 15 } xxxxxxx@server5:~/temp/testarray$ ./test p[-1]=3 刚试了一下,c 也支持。 原来编译器还有这种功能。 。。。。 |
4
MeteorCat 2018-04-04 19:09:56 +08:00 via Android
@z0z 很好玩的特性,但是很容易就玩脱了,我感觉在 C++11 慢慢上来的时候,能够用 vector 这种容器就用得了
|
5
Librazy 2018-04-04 19:13:22 +08:00 via Android 1
C++默认的下标表达式 E1[E2] 等同于表达式 *(E1 + E2) ,所以只要解引用 E1 + E2 是合法的就可以了
|
6
Librazy 2018-04-04 19:15:39 +08:00 via Android
如何理解完全等同:试试 -1[p] 就知道了
|
7
sfqtsh 2018-04-04 19:21:26 +08:00 via Android
这都可以的:
int i = 2; char c = "abcdefg"[i]; |
8
bumz 2018-04-04 19:33:48 +08:00
int * a = new int[4] + 2;
然后愉快地 a[-2], a[-1], a[0], a[1] 2333 |
9
aheadlead 2018-04-04 19:58:10 +08:00
火星了…
C 你写成这样也可以: char *str="233333"; putchar(1[str]); |
10
h4lbhg1G 2018-04-04 20:00:49 +08:00
似乎可以这么写
int a[5]={0,1,2,3,4}; 2[a]=1[a]+0[a]; |
11
Akiyu 2018-04-04 20:02:13 +08:00 1
我也是才知道,之前没有做过这种骚操作
之所以说是"骚操作",是因为你不知道那个地址里面是什么东西,类似于按照数组的类型去解释未知内存一样 理解了原理就知道了 它是拿着那个整数做偏移,然后按照数组的类型来拿取和解释那块内存(占多大,是如何存储的) 引申: 如果对汇编感兴趣的话就知道各种数组取值的不同写法,就像楼上的 1[p]一样 idata+[寄存器], 寄存器+idata, 寄存器+寄存器+idata...(具体可能有误, 我不记得细节了 不过都是那种概念,就是表示偏移地址寻址, 本质都是一样的,具体可以参照<<汇编语言>>) PS: 如果楼主对这方面感兴趣的话,可以看看<<汇编语言>> (汇编有 x86 和 ARM, 看完之后你会一边内心叫着 MMP, 一边想着底层真有趣) |
12
h4lbhg1G 2018-04-04 20:06:44 +08:00
似乎可以这么写
嗯 看到上面的字符串 我想起一个黑魔法了 char* str1="12345678"; char* str2="abcdefghi"; char* p=str2; for(int i=0;i<strlen(str1);i++)putchar((-i)[p]); |
13
gnaggnoyil 2018-04-05 06:37:22 +08:00
@h4lbhg1G 你这么写就不对了……指针运算其结果必须要么处于合法的数组或者 malloc 出来的空间的内部,要么是这个空间紧跟着的下一个地址,否则是未定义行为.
|
14
h4lbhg1G 2018-04-20 19:29:55 +08:00
@gnaggnoyil #13 刚刚才看到 这就是假设两个字符串常量被紧凑放在内存里,如果编译器不这么按顺序连续分配内存(不太清楚 C 标准具体有没有规定)当然就不行了。
有点函数内部用内联汇编的感觉吧。虽然我是感觉这种代码顶多只会在逆向破解的 poc 程序中出现 |
15
gnaggnoyil 2018-04-20 19:42:59 +08:00
@h4lbhg1G
>如果编译器不这么按顺序连续分配内存(不太清楚 C 标准具体有没有规定) 当然没有.这玩意在标准中如果不是 implementation defined 那就是 unspecified.不过这不是关键点.关键点在于,只要你这段代码出现了越界的未定义行为,不管这两段 storage 的排列是如何,编译器的最终行为也是没有定义,不可预料的. |