菜鸟对一道ctf逆向的分析。大神路过多指导 运行,Input your flag: IDA打开,-》shirt+f12打开字符串窗口,搜索input your flag,找到使用这串字符串的函数,发现是程序主要的算法函数。 分析算法,由于我这个小菜鸟代码能力有限,结合OD分析的,下面时算法分析过程。 1:发现定义的变量var134-var_129连续占一个字节,猜测是一个char型数组,找到 Var_134的地址,*键改为数组,改为in。后面的var——35->var25也是一样改为inin。 2:OD载入,运行。程序跑起来,随便输入一组数据,发现程序跑到这里,会把输入每位与与0XCC异或处理,并发现比较了处理了20次(0x13=19,前面xor ecx,ecx,使得ecx为0,即0-19,20次。 发现异或后的值送进了var-1FC这个变量里面,ida继续看后面 发现异或后的值每位与var-100这个变量里的值比较,如果不等,就跳转到ERROr。 Od 里数据窗口跟随,比较的时候得值为b1 a4 b5 87 ad ad 93 b9 bf bf 93 fd fc b8 ff b7 f9 b8 ed a4 当时做到这里以为算法就是这样, for(i=0;i<=19;i++) B=input ^ 0XCC for(i=0;i<=19;i++) If(b!=var_100) Cout<<eroor 然后写了程序,跑出来发现不对,回到IDA,发现开始输入后还有一段对输入进行了操作 发现最后是in(输入)+8猜测对输入的前九位进行了操作。光看汇编代码我这个菜鸟看不出来是怎么操作的,于是在OD里面单步跟踪,数据窗口跟随, a[20]=28f86c b[20]=28f770 b[0]=a[19] b[1]=a[3]+2 b[2]=a[17] b[3]=a[5]+2 b[4]=a[15] b[5]=a[7]+2 b[6]=a[13] b[7]=a[9]+2 b[8]=a[11] 发现是把输入复制了一份,定义了两个数组都是输入,大致操作就是 for(i=0;i<=8;i++) if(i%2==0) b=a[19-i] else b=a[i+2]+2 其余没有用到的位置不变,用到了的位置,比如b[11],由于a[11]已经给了b[8],所以相当于进行了交换,b[11]=a[8]; 知道了大致的算法,写出逆算法。由于奇数时,直接从第三位开始了,所以第一位靠猜。 代码: #include<iostream> using namespace std; int main(){ char flag[20]; char key[] = { 0xb1, 0xa4, 0xb5, 0x87, 0xad, 0xad, 0x93, 0xb9, 0xbf, 0xbf, 0x93, 0xfd, 0xfc, 0xb8, 0xff, 0xb7, 0xf9, 0xb8, 0xed, 0xa4 }; char b[20]; int i; for ( i = 0; i < 20; i++) b = key ^ 0XCC; for (i = 0; i <= 8; i++){ if (i % 2 == 0) flag[19 - i] = b; else flag[i + 2] = b - 2; } flag[1] = 'c'; for (i = 0; i < 5; i++){ flag[i * 2] = b[19 - i*2];
} flag[9] = b[9]; flag[10] = b[10]; flag[8] = b[11]; flag[12] = b[12]; flag[14] = b[14]; flag[16] = b[16]; flag[18] = b[18]; for (i = 0; i < 20; i++) cout << flag;
system("PAUSE"); return 0; }
|