study

指针数组int***arr[5]={0};char*keyword[]={"if","for","while",”switch","NULL"};结构体指针structArg{inta;intb;intc;};++运算Arg*pArg;pArg=(Arg*)100;//function1s(1);pArg++;//因为struct数组宽度为12100+12运算时候需要砍*printf("%d\n",pArg);//112Arg***pArg;pArg=(Arg***)100;//function1s(1);pArg++;//100运算时候需要砍*Arg*为4个字节所以为104printf("%d\n",pArg);//112加一个整数Arg*pArg;pArg=pArg+5;pArg++;//因为struct数组宽度为5*12100+60运算时候需要砍*printf("%d\n",pArg);//112加一个整数Arg***pArg;pArg=pArg+5;pArg++;//因为struct数组宽度为5*4100+20运算时候需要砍*printf("%d\n",pArg);//112减法Arg*pArg;pArg=(Arg*)100;//function1s(1);pArg=pArg-5;//100-60=40砍去一个*pArg宽度为12printf("%d\n",pArg);return0;Arg**pArg;pArg=(Arg**)100;//function1s(1);pArg=pArg-5;//100-20=80砍去一个*pArg宽度为4printf("%d\n",pArg);return0;减法:Arg*pArg;pArg=(Arg*)100;pArg2=(Arg*)20;intx=pArg-pArg2;//100-20在除以Arg*砍一个*12=80/12=6printf("%d\n",x);Arg**pArg2;Arg**pArg;pArg=(Arg**)100;pArg2=(Arg**)20;intx=pArg-pArg2;//100-20在除以Arg**砍一个*4=80/4=20printf("%d\n",x);通过结构体指针读取、修改:Students;s.a=10;s.b=20;s.c=30;Student*ps;ps=&s;//通过指针读取数据printf("%d\n",ps->a);//通过指针修改数据ps->a=100;printf("%d\n",ps->a);结构体指针指向的内存可以是一个非结构体,例如;StructArg{inta;intb;intc;}指向int:intx=10;Arg*ps=(Arg*)&x;printf("%d\n",ps->a);//10printf("%d\n",ps->b);//未知,也可能可以访问假设指向一个int类型的数组intdata[]={10,30,40}Arg*ps=(Arg*)&data[0];printf("a->%d\n,b->%d\n,c->%d\n",ps->a,ps->b,ps->c);练习题:01创建一个int*arr[5]数组,并为数组赋值(使用&).inta1=100;inta2=200;inta3=300;inta4=400;inta5=500;int*p1=&a1;int*p2=&a2;int*p3=&a3;int*p4=&a4;int*p5=&a5;int*arr[5]={p1,p2,p3,p4,p5};intmain(intargc,char*argv[]){int**x=arr;//指针&arr的返回类型为本身加*int*加*=int**printf("%d\n",*(*x));//*x为p1的指针的值*x=p1**x=*(p1)=100return0;}循环获取指针数组:inta1=100;inta2=200;inta3=300;inta4=400;inta5=500;int*p1=&a1;int*p2=&a2;int*p3=&a3;int*p4=&a4;int*p5=&a5;int*arr[5]={p1,p2,p3,p4,p5};int**x=arr;for(inti=0;i<5;i++){printf("%d\n",**x);**x++;}2、创建一个字符指针数组,存储所有的C的关键词(查资料找),并全部打印出来.char*p1="if";char*p2="for";char*p3="while";char*p4="switch";char*keyword[]={p1,p2,p3,p4};char**px=keyword;printf("%x\n",px);//0012FF60printf("%x\n",*px);//*0012FF60=0042213cfor(inti=0;i<4;i++){printf("%s\n",*px);px++;}反汇编代码:468:char*p1="if";0040DB98movdwordptr[ebp-4],offsetstring"if"(0042213c)//将常量if存储到0042213c中469:char*p2="for";0040DB9Fmovdwordptr[ebp-8],offsetstring"for"(0042202c)//将常量for存储到0042213c中470:char*p3="while";0040DBA6movdwordptr[ebp-0Ch],offsetstring"while"(00422fc4)//将常量while存储到00422fc4中471:char*p4="switch";0040DBADmovdwordptr[ebp-10h],offsetstring"switch"(00422fbc)//将常量switch存储到00422fbc中472:473:/*474:char**px1=&p1;475:printf("%x\n",px1);px1476:printf("%x\n",*px1);477:*/478:479:char*keyword[]={p1,p2,p3,p4};0040DBB4moveax,dwordptr[ebp-4]//将0042213c放到eax0040DBB7movdwordptr[ebp-20h],eax//将0042213c放到地址ebp-20h(0012FF60)中0040DBBAmovecx,dwordptr[ebp-8]//以此类推0040DBBDmovdwordptr[ebp-1Ch],ecx0040DBC0movedx,dwordptr[ebp-0Ch]0040DBC3movdwordptr[ebp-18h],edx0040DBC6moveax,dwordptr[ebp-10h]0040DBC9movdwordptr[ebp-14h],eax480:481:char**px=keyword;0040DBCCleaecx,[ebp-20h]//取0012FF60ecx=0012FF600040DBCFmovdwordptr[ebp-24h],ecx将ecx放到px=0012FF60482:483:printf("%x\n",px);//输出0012FF600040DBD2movedx,dwordptr[ebp-24h]//ebp-24h=0012FF60放到edx0040DBD5pushedx//0012FF60的值0040DBD6pushoffsetstring"%x\n"(00422fb4)//%x为print的第二个参数0040DBDBcallprintf(004014f0)//调用print函数地址0040DBE0addesp,8//堆栈平衡484:printf("%x\n",*px);0040DBE3moveax,dwordptr[ebp-24h]//ebp-24h=0012FF60放到eax0040DBE6movecx,dwordptr[eax]//将0012FF60的值放到ecx0040DBE8pushecx0040DBE9pushoffsetstring"%x\n"(00422fb4)0040DBEEcallprintf(004014f0)0040DBF3addesp,8485:486:for(inti=0;i<4;i++){0040DBF6movdwordptr[ebp-28h],00040DBFDjmpmain+88h(0040dc08)0040DBFFmovedx,dwordptr[ebp-28h]0040DC02addedx,10040DC05movdwordptr[ebp-28h],edx0040DC08cmpdwordptr[ebp-28h],40040DC0Cjgemain+0ACh(0040dc2c)487:488:printf("%s\n",*px);0040DC0Emoveax,dwordptr[ebp-24h]0040DC11movecx,dwordptr[eax]0040DC13pushecx0040DC14pushoffsetstring"%c"(00422028)0040DC19callprintf(004014f0)0040DC1Eaddesp,8489:px++;0040DC21movedx,dwordptr[ebp-24h]0040DC24addedx,40040DC27movdwordptr[ebp-24h],edx作业3:3、查找这些数据中,有几个id=1level=8的结构体信息。0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x07,0x09,0x00,0x20,0x10,0x03,0x03,0x0C,0x00,0x00,0x44,0x00,0x00,0x33,0x01,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x64,0x00,0x00,0x00,0xAA,0x00,0x00,0x00,0x64,0x01,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x02,0x00,0x74,0x0F,0x41,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0A,0x00,0x00,0x02,0x57,0x4F,0x57,0x00,0x06,0x08,0x00,0x00,0x00,0x00,0x00,0x64,0x00,0x0F,0x00,0x00,0x0D,0x00,0x00,0x00,0x23,0x00,0x00,0x64,0x00,0x00,0x64,0x00typedefstructTagPlayer{intid;intlevel;}Player;voidfunction1(){char*p=data;intnsum=0;Player*splayer;//实例化一个结构体指针for(inti=0;i<96;i++){splayer=(Player*)(int*)(p+i);if(splayer->id==1&&splayer->level==8){nsum++;}}printf("%d\n",nsum);}

study

语法:int*x;int*x;推荐使用char*x;short*y;int*z;float*f;double*d;Student*st;总结:1、带有*的变量类型的标准写法:变量类型*变量名2、任何类型都可以带*加上*以后是新的类型3、*可以是任意多个赋值:1、带*类型的变量赋值时只能使用“完整写法”.2、带*类型的变量宽度永远是4字节、无论类型是什么,无论有几个*.voidFunction(){char*x;short*y;int*z;x=(char*)1;y=(short*)2;z=(int*)3;}++--char****a;short****b;int****c;a=(char****)100;b=(short****)100;c=(int****)100;a++;//104b++;//104c++;//104printf("%d%d%d",a,b,c);1、不带*类型的变量,++或者--都是假1或者减12、带*类型的变量,可是进行++或者--的操作3、带*类型的变量,++或者--新增(减少)的数量是去掉一个*后变量的宽度加减法char*a;short*b;int*c;a=(char*)100;b=(short*)100;c=(int*)100;a=a+5;//100+5*1b=b+5;//100+5*2c=c+5;//100+5*4printf("%d%d%d",a,b,c);1、带*类型的变量可以加、减一个整数,但不能乘或者除.2、带*类型变量与其他整数相加或者相减时:带*类型变量+N=带*类型变量+N*(去掉一个*后类型的宽度)带*类型变量-N=带*类型变量-N*(去掉一个*后类型的宽度)求差值列子1:Student*s1;//8Student*s2;//8intx;s1=(Student*)300;//200-s2=(Student*)100;x=s1-s2;//x的值是多少?//计算方法为300-100=200%8=25printf("%d",x);列子2:Student*s1;//8Student*s2;//8intx;s1=(Student*)200;s2=(Student*)100;x=s1-s2;//x的值是多少?//计算方法为200-100=100%8=12.5取12printf("%d",x);1、两个类型相同的带*类型的变量可以进行减法操作.2、想减的结果要除以去掉一个*的数据的宽度.比较:带*的变量,如果类型相同,可以做大小的比较。

2021-7-17 11 0
study

数组取值一维数组:voidHelloWord(){intx=1;ebp-4inty=2;ebp-8intarr1[5]={1,2,3,4,5};printf("%d",arr1[x+y]);}反汇编代码:00401498movdwordptr[ebp-4],10040149Fmovdwordptr[ebp-8],2004014A6movdwordptr[ebp-1Ch],1004014ADmovdwordptr[ebp-18h],2004014B4movdwordptr[ebp-14h],3004014BBmovdwordptr[ebp-10h],4004014C2movdwordptr[ebp-0Ch],5004014C9moveax,dwordptr[ebp-4]004014CCaddeax,dwordptr[ebp-8]004014CFmovecx,dwordptr[ebp+eax*4-1Ch]一维数组取值方式:[ebp+(1+2)*4(int为4个字节)-1Ch]多维数组voidHelloWord(){intarr[3][4]={{1,2,3,5},{2,3,4,5},{9,2,3,1}};printf("%d",arr[0][2]);}反汇编代码:00401498movdwordptr[ebp-30h],10040149Fmovdwordptr[ebp-2Ch],2004014A6movdwordptr[ebp-28h],3004014ADmovdwordptr[ebp-24h],5004014B4movdwordptr[ebp-20h],2004014BBmovdwordptr[ebp-1Ch],3004014C2movdwordptr[ebp-18h],4004014C9movdwordptr[ebp-14h],5004014D0movdwordptr[ebp-10h],9004014D7movdwordptr[ebp-0Ch],2004014DEmovdwordptr[ebp-8],3004014E5movdwordptr[ebp-4],1004014ECmoveax,dwordptr[ebp-28h]一维数组取值方式:arr[0][2]arr[0*12+2]例子2:intarr[5][12]={{1,2,1,4,5,6,7,8,9,1,2,3},{11,12,11,14,15,16,17,18,19,11,12,13},{21,22,21,24,25,26,27,28,29,21,22,23},{31,32,31,34,35,36,37,38,39,31,32,33},{41,42,41,44,45,46,47,48,49,41,42,43}}编译器分配内存空间intarr[5*12]={.................................}假设取值:arr[3][7]编译器是如何找到这个数据的//5*12*4=240////(3*12+7)=43* 4=172//240-172=68=44ebp-44arr[3*12+7]例子3:intarr[5][4][3]={{{1,2,3},{4,5,6},{7,8,9},{11,12,13}},{{11,12,13},{14,15,16},{17,18,19},{111,112,113}},//1arr[1][2][1]=18{{21,22,23},{24,25,26},{27,28,29},{211,212,213}},//2arr[1*4*3+2*3+1]{{31,32,33},{34,35,36},{37,38,39},{311,312,313}},//3442{{41,42,43},{44,45,46},{47,48,49},{411,412,413}}//4arr[3][3][1]};arr[3*4*3+3*3+1]例子4:编译器如何分配空间:intarr[5*4*3]={.....................};如果获取第2个班级、第3组、第2个人的年龄.arr[1][2][1]编译器如何计算:arr[1*4*3+2*3+1]intarr[n][m][k][w][r];arr[2][3][4][2][2]arr[2*m*k*w*r+3*k*w*r+4*w*r+2*r+2]

2021-7-9 20 0
2021-7-8 20 0
2021-7-8 17 0
2021-7-7 20 0
2021-7-5 31 0
逆向

JCC指令也只影响EIP首先要明确一点,所有的判断跳转指令都是根据标志位来进行判断的1、JE,JZ结果为零则跳转(相等时跳转)ZF=12、JNE,JNZ结果不为零则跳转(不相等时跳转)ZF=03、JS结果为负则跳转SF=14、JNS结果为非负则跳转SF=05、JP,JPE结果中1的个数为偶数则跳转PF=16、JNP,JPO结果中1的个数为偶数则跳转PF=07、JO结果溢出了则跳OF=18、JNO结果没有溢出则跳转OF=09、JB,JNAE小于则跳转(无符号数)CF=110、JNB,JAE大于等于则跳转(无符号数)CF=011、JBE,JNA小于等于则跳转(无符号数)CF=1orZF=112、JNBE,JA大于则跳转(无符号数)CF=0andZF=013、JL,JNGE小于则跳转(有符号数)SF≠OF14、JNL,JGE大于等于则跳转(有符号数)SF=OF15、JLE,JNG小于等于则跳转(有符号数)ZF=1orSF≠OF16、JNLE,JG大于则跳转(有符号数)ZF=0andSF=OF有符号无符号的区别:CMPAL,CLJG0x12345678JA0x12345678英文全称含义判断标志位JE,JZjumpequal,jumpzero结果为零则跳转(相等时跳转)ZF=1JNE,JNZjumpnotequal,jumpnotzero结果不为零则跳转(不相等时跳转)ZF=0JSjumpsign结果为负则跳转SF=1JNSjumpnotsign结果为非负则跳转SF=0JP,JPEjumpparity,jumpparityeven结果中1的个数为偶数则跳转PF=1JNP,JPOjumpnotparity,jumpparityodd结果中1的个数为偶数则跳转PF=0JOjumpoverflow结果溢出了则跳转OF=1JNOjumpnotoverflow结果没有溢出则跳转OF=0JB,JNAEjumpbelow,jumpnotaboveequal小于则跳转(无符号数)CF=1JNB,JAEjumpnotbelow,jumpaboveequal大于等于则跳转(无符号数)CF=0JBE,JNAjumpbelowequal,jumpnotabove小于等于则跳转(无符号数)CF=1orZF=1JNBE,JAjumpnotbelowequal,jumpabove大于则跳转(无符号数)CF=0andZF=0JL,JNGEjumpless,jumpnotgreaterequal小于则跳转(有符号数)SF≠OFJNL,JGEjumpnotless,jumpgreaterequal大于等于则跳转(有符号数)SF=OFJLE,JNGjumplessequal,jumpnotgreater小于等于则跳转(有符号数)ZF=1orSF≠OFJNLE,JGjumpnotlessequal,jumpgreater大于则跳转(有符号数)ZF=0andSF=OF

2021-6-20 25 0