指针宽度永远是4,指针可以做+ -,指针可以比较大小,两个指针可以相减,结果除以砍*长度,指针可以指向任何地方。
指针只是一个类型。
char code[]={
0x00,.....//一百个字节数
}
char (*px)[5];
px = (char (*px)[5])code;
printf("%x\n",*(*(px+4)+3));//code地址后弟23个字节的地址的值
int (*px)[5];
px = (int(*[5]))code;
printf("%x\n",*(*(px+2)+2));//int 取4个字节,window数据小段存储,高位在后低位在前
2.二维数组指针
char (*py)[2][3];
py =(char (*)[2][3])code;
printf("%x\n",*(*(*(py))));//第一个值00
printf("%x\n",*(*(*(py+2)+3)+5));//第29个后面的值1*2*3*2+1*3*3+1*5=??
int(*py)[2][3];
printf("%x\n",*(*(*(px+2)+2)+2));//4*2*3*2+4*3*2+4*2=80 数组第80位以后,4个char 小段存储
3三维数组
char (*px)[2][3][2];
px =(char(*)[2][3][2])code;
printf("%x\n",*(*(*(*(px+2)+2)+2+2)));
第一层宽度24
第二层宽度12
第三层宽度4
第四层宽度2
指向地址24+12+4+2=42
一维数组指针访问一维数组
一维数组指针访问二维数组
一维数组指针访问三维数组
二维数组指针访问一维数组
二维数组指针访问二维数组
二维数组指针访问三维数组
int arr[2][3]={
{1,2,3},
{4,5,6}
}
//1 2 3 4 5 6
int arr[2][3]={
{1,2},
{4,5}
//1 2 0 4 5 0
//一维数组指针访三维数组
int arr[3][3][2]={
{{1,2},{3,4},{5}},
{{6,7}, {8},{9,10}},
{{11},{12,13},{14,15}}
}
int (*p)[5]=(int(*)[5])arr;
print("%d\n",*(*(p)+4));
print("%d\n",*(*(p+1)+4));
print("%d\n",*(*(p+2)+2));
int (*p)[5] = (int(*)[5])arr;
00881880 lea eax,[arr]
00881883 mov dword ptr [p],eax
printf("%d\n", *(*(p)+4));
00881886 mov eax,dword ptr [p]
00881889 mov ecx,dword ptr [eax+10h]
0088188C push ecx
0088188D push offset string "%d\n" (0887B30h)
00881892 call _printf (0881334h)
00881897 add esp,8
printf("%d\n", *(*(p + 1) + 4));
0088189A mov eax,dword ptr [p]
0088189D mov ecx,dword ptr [eax+24h]
008818A0 push ecx
008818A1 push offset string "%d\n" (0887B30h)
008818A6 call _printf (0881334h)
008818AB add esp,8
printf("%d\n", *(*(p + 2) + 2));
008818AE mov eax,dword ptr [p]
008818B1 mov ecx,dword ptr [eax+30h]
008818B4 push ecx
008818B5 push offset string "%d\n" (0887B30h)
008818BA call _printf (0881334h)
008818BF add esp,8
//二维数组指针访问二维数组 囧
int arr[2][15]={
{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15},
{21,22,23,24,25,26,27,28,29,30,31,32,33,34,35}
}
下列说法是否正确?为什么?
指针的指针,就是指针指针的指针。
结构指针,就是指向结构的指针。
数组指针,就是指向数组的指针。
函数指针,就是指向函数的指针。
以上说法,错的。指针就是指针,想指向什么指向什么。可以相互转换的。
代码和数据有什么区别?
代码也是数据,数据也可以是代码。代码和数据没有区别。
int x =10;//存储数据区
//代码区
int Function(int x ,int y ){
retrun x+y;
}
int Function2(int x ,int y ){
int g=10;
retrun x+y;
}int main(int argc,char* argv[]){
int y =x;
return 0;
}
vc6,x是变量,函数也是变量
x 0A
函数 55 8b ec 83
ec 40 53 c0
57 8d 7d c0
89 10 00 00
看懂这个需要硬编码,暂时忽略,可以被cpu执行
// 探测宽度,探测++ --- +-整数,相减 比较
int (*pFun)(int,int);
printf("%d\n",sizeof(pFun)); //4
pFun=(int(_cdecl *)(int,int))10;
printf("%d\n",pFun);
pFun++;
printf("%d\n",pFun);
//函数宽度不确定,编译不过去
相减运算也要除以本身宽度所以不可以做
可以做比较,就是比较数字
pFun=Function;//默认cd call
int x = pFun(1,2);//x==3 //用于加载dll, 隐藏代码到数据区
反汇编引擎
00881808 C7 45 B0 01 00 00 00 mov dword ptr [arr],1
0088180F C7 45 B4 02 00 00 00 mov dword ptr [ebp-4Ch],2
00881816 C7 45 B8 03 00 00 00 mov dword ptr [ebp-48h],3
0088181D C7 45 BC 04 00 00 00 mov dword ptr [ebp-44h],4
00881824 C7 45 C0 05 00 00 00 mov dword ptr [ebp-40h],5
0088182B 33 C0 xor eax,eax
0088182D 89 45 C4 mov dword ptr [ebp-3Ch],eax
00881830 C7 45 C8 06 00 00 00 mov dword ptr [ebp-38h],6
00881837 C7 45 CC 07 00 00 00 mov dword ptr [ebp-34h],7
0088183E C7 45 D0 08 00 00 00 mov dword ptr [ebp-30h],8
00881845 33 C0 xor eax,eax
00881847 89 45 D4 mov dword ptr [ebp-2Ch],eax
0088184A C7 45 D8 09 00 00 00 mov dword ptr [ebp-28h],9
00881851 C7 45 DC 0A 00 00 00 mov dword ptr [ebp-24h],0Ah
00881858 C7 45 E0 0B 00 00 00 mov dword ptr [ebp-20h],0Bh
0088185F 33 C0 xor eax,eax
00881861 89 45 E4 mov dword ptr [ebp-1Ch],eax
00881864 C7 45 E8 0C 00 00 00 mov dword ptr [ebp-18h],0Ch
0088186B C7 45 EC 0D 00 00 00 mov dword ptr [ebp-14h],0Dh
00881872 C7 45 F0 0E 00 00 00 mov dword ptr [ebp-10h],0Eh
00881879 C7 45 F4 0F 00 00 00 mov dword ptr [ebp-0Ch],0Fh
00881880 8D 45 B0 lea eax,[arr]
00881883 89 45 A4 mov dword ptr [p],eax
00881886 8B 45 A4 mov eax,dword ptr [p]
00881889 8B 48 10 mov ecx,dword ptr [eax+10h]
0088188C 51 push ecx
0088188D 68 30 7B 88 00 push offset string "%d\n" (0887B30h)
00881892 E8 9D FA FF FF call _printf (0881334h)
00881897 83 C4 08 add esp,8
0088189A 8B 45 A4 mov eax,dword ptr [p]
0088189D 8B 48 24 mov ecx,dword ptr [eax+24h]
008818A0 51 push ecx
008818A1 68 30 7B 88 00 push offset string "%d\n" (0887B30h)
008818A6 E8 89 FA FF FF call _printf (0881334h)
008818AB 83 C4 08 add esp,8
008818AE 8B 45 A4 mov eax,dword ptr [p]
008818B1 8B 48 30 mov ecx,dword ptr [eax+30h]
008818B4 51 push ecx
008818B5 68 30 7B 88 00 push offset string "%d\n" (0887B30h)
008818BA E8 75 FA FF FF call _printf (0881334h)
008818BF 83 C4 08 add esp,8
008818C2 33 C0 xor eax,eax
008818C4 52 push edx
008818C5 8B CD mov ecx,ebp
008818C7 50 push eax
008818C8 8D 15 F4 18 88 00 lea edx,ds:[8818F4h]
008818CE E8 94 F9 FF FF call @_RTC_CheckStackVars@8 (0881267h)
008818D3 58 pop eax
008818D4 5A pop edx
008818D5 5F pop edi
008818D6 5E pop esi
008818D7 5B pop ebx
008818D8 8B 4D FC mov ecx,dword ptr [ebp-4]
008818DB 33 CD xor ecx,ebp
008818DD E8 99 F9 FF FF call @__security_check_cookie@4 (088127Bh)
008818E2 81 C4 20 01 00 00 add esp,120h
008818E8 3B EC cmp ebp,esp
008818EA E8 33 F8 FF FF call __RTC_CheckEsp (0881122h)
008818EF 8B E5 mov esp,ebp
008818F1 5D pop ebp
008818F2 C3 ret
硬编码转换成汇编
int (*pFun)(int,int );
pFun=(int (*)(int,int))arr;//欺骗编译器//代码区,弄到数据区。
int x = pFun(2,3);
printf("%d\n",x);//x ==5,