Quantcast
Channel: 记事本
Viewing all articles
Browse latest Browse all 122

ISG初赛BT

$
0
0

这道题目是去年ISG初赛的一道ARM逆向题,当时的知识储备还不足以解决。但其实稍微了解了下ARM汇编之后就可以做了,虽然说还不熟练,花了较久时间。

我是开始想用IDA的反编译的,但不知怎么回事,对thumb代码的处理总有问题;继而无奈用hopper,然而hopper得到的伪代码还是比较简陋的,而且发现居然会把本应是*ptr+=1这样的反编译为*ptr=1,这个错误太大了……于是最后基本还是通过读汇编代码,理解分析后得到伪代码如下

structsNode{charvalue;structsNode*left;structsNode*right;};typedefstructsNodeNode;structsInfo{Node*node;intheight;intvalue2;}typedefstructsInfoInfo;intrecord[128];//record=0x11258intindex;//&index=0x116f8intinfoCount;//&infoCount=0x116fcInfo*infoStack[];//infoStack=0x11058functionsetup{//sub_8610memset(0x11058,0x0,0x200);}functionbuildTree(char*str,Node**nodeAddr){//sub_86d4charch;//&ch=r7+0xfch=str[index];if(ch==0)return;index++;if(ch==' ')return;Node*newNode=malloc(sizeof(Node));*nodeAddr=newNode;newNode->value=ch;buildTree(str,&(newNode->left));buildTree(str,&(newNode->right));return;}functionpush(Info*info){//sub_8634if(infoCount<=0x7e){infoStack[infoCount++]=info;}return;}functionpop{//sub_867cif(infoCount>0){returninfoStack[--infoCount];}elsereturnNULL;}functiontraverse(Node*node){//sub_8790push(NULL);Node*current=node;//*current=r7+8intheight=0;//&height=r7+0xcintsomeVal=0;//&someVal=r7+0x10Info*info;//*info = r7+0x14while(current!=NULL){if(record[current->value]!=0){record[current->value]=someVal;}if(current->right!=NULL){info=malloc(sizeof(Info));info->node=current->right;info->height=height+1;info->value2=49*(height+1)+someVal;push(info);}if(current->left!=NULL){height++;someVal+=48*height;current=current->left;}else{info=pop();if(info!=NULL){current=info->node;height=info->height;someVal=info->value2;free(info);}elsecurrent=NULL;}}return;}functioncheck(char*str,size_tlen){intbuf[0xa0/4];//buf=r7+0x10inti=0;//&i=r7+0xcmemset(buf,0x0,0xa0);while(i<len){buf[i]=record[str[i]];i++;}doCheck(buf,len);}functiondoCheck(int*buf,size_tlen){if(len==0x22&&buf=={0xc6b,0xa59,0x2d9,0x30,0x1e7,0xc75,0x881,0xa5a,0x169d,0x111c,0x870,0x546,0x169d,0x6c8,0x90,0x870,0x1129,0x3f6,0x13be,0xeab,0x31,0x169d,0x2d4,0x13cb,0x1990,0x870,0xc75,0x2d4,0x870,0x1110,0x6cf,0x2d0,0x3f0,!0x125})puts("correct");elseputs("wrong");}functiondestroyTree(Node*node){if(node!=NULL){destroyTree(node->left);destroyTree(node->right);free(node);}return;}functionmain{//sub_88d4Node*node;//&node=r7;charbuf[40];//buf=r7+0xcsetup();printf("Password:");fgets(buf,0x28,stdin);size_tlen=strlen(buf);//&len = r7+8len--;buf[len]=0;//'\n' => '\0'inti=0;//&i = r7+4while(i<len){record[buf[i]]=1;i++;}char*string="g{3q9OLNZ_bVWCyJk  l  sh  c  ax  r  d6  A  MY  t  Iv  P  4u  i  TS  Q  eB  n  Xz  o  R7  H  U2  p  F5  G  Km  8  Dw  }  Ej  f ";//string = 0x8c10buildTree(string,&node);traverse(node);check(buf,len);destroyTree(node);return0;}

可以看到,首先通过一个给定的字符串构造了一个二叉树,字符串中的连续两个空格就使左右子树均为空;然后进行深度优先搜索,对每个节点的字符计算了一个数;最后由前面生成的对应,检查输入字符串的每个字符。

为了找到正确的输入,我是依照树的构造方式和DFS,先找到每个字符对应的值,然后反过来查输入的各个字符应该为什么。

下面是我的python代码,二叉树构造那里写的很别扭……

#!/usr/bin/env python2classNode(object):value,left,right=0,None,Nonedef__init__(self,v):self.value=vclassTree(object):def__init__(self,string):self.string=stringself.root=Noneself.index=0self.height=0self.someVal=0self.stack=[]self.record={}defaddNode(self):ch=self.string[self.index]self.index+=1ifch==" ":returnNoneelse:returnNode(ch)defbuild(self,root):ifroot==Noneorself.index>=len(self.string):returnNonenode=self.addNode()root.left=self.build(node)node=self.addNode()root.right=self.build(node)returnrootdeftraverse(self,node):current=nodewhilenotcurrent==None:#print "%s:%s" % (current.value, hex(self.someVal))self.record[self.someVal]=current.valueifnotcurrent.right==None:self.stack.append((current.right,self.height+1,49*(self.height+1)+self.someVal))ifnotcurrent.left==None:self.height+=1self.someVal+=48*self.heightcurrent=current.leftelse:try:info=self.stack.pop(-1)current=info[0]self.height=info[1]self.someVal=info[2]exceptIndexError:current=Noneif__name__=="__main__":string="g{3q9OLNZ_bVWCyJk  l  sh  c  ax  r  d6  A  MY  t  Iv  P  4u  i  TS  Q  eB  n  Xz  o  R7  H  U2  p  F5  G  Km  8  Dw  }  Ej  f     "tree=Tree(string)root=tree.build(tree.addNode())tree.traverse(root)res=[]code=(0xc6b,0xa59,0x2d9,0x30,0x1e7,0xc75,0x881,0xa5a,0x169d,0x111c,0x870,0x546,0x169d,0x6c8,0x90,0x870,0x1129,0x3f6,0x13be,0xeab,0x31,0x169d,0x2d4,0x13cb,0x1990,0x870,0xc75,0x2d4,0x870,0x1110,0x6cf,0x2d0,0x3f0)forxincode:res.append(tree.record[x])print''.join(res)

运行得到除最后一个字符外,输入应该为ISG{8in4rY_7re3_tRavEr5Al_i5_CoOL。虽然检查时只要求最后一个字符对应的数不是0x125,但我们显然知道应该是右花括号}


Viewing all articles
Browse latest Browse all 122

Trending Articles