Ollvm去平坦化脱壳

Ollvm去平坦化脱壳

RoarCTF polyre(参考CRC64)

最近复现RoarCTF的polyre时候,发现了ollvm这个保护器挺有意思的,然后参考了师傅们的blog,提出我自己的看法
首先下载D-810。https://gitlab.com/eshard/d810
把文件夹和.py复制到IDA目录的plugin下即可。(最开始我用的7.5然后移动plugins发现在ida里面没有这个d810这个插件,然后我就更换了一个ida8.3版本,发现挺好用的)

这个也可以用虚拟机跑脚本,不过需要安装一个angr的一个库,具体怎么实现的我也没太研究,就知道在虚拟机里面跑一个脚本就行

先查看main函数地址,之后执行命令

python deflat.py -f attachment --addr 0x400620 //0x400620是main函数的地址

启动ida。这是未进行脱壳的进程
这是经过d810去平坦化之后的源码

v10 = 0;
  memset(s, 0, 0x30uLL);
  memset(s1, 0, sizeof(s1));
  printf("Input:");
  v11 = s;
  __isoc99_scanf("%s", s);
  for ( i = 0; ; ++i )
  {
    v12 = i;
    v13 = i < 64;
    if ( i >= 64 )
      break;
    v14 = s[i];
    v15 = v14;
    if ( v14 == 10 )
    {
      v16 = &s[i];
      *v16 = 0;
      break;
    }
    v17 = i + 1;
  }
  for ( j = 0; ; ++j )
  {
    v18 = j;
    v19 = j < 6;
    if ( j >= 6 )
      break;
    v20 = s;
    v4 = *(_QWORD *)&s[8 * j];
    for ( k = 0; ; ++k )
    {
      v21 = k;
      v22 = k < 64;
      if ( k >= 64 )
        break;
      v23 = v4;
      v24 = v4 < 0;
      if ( v4 < 0 )
      {
        v25 = 2 * v4;
        v26 = 2 * v4;
        v4 = (2 * v4) ^ 0xB0004B7679FA26B3LL;
      }
      else
      {
        v27 = v4;
        v28 = 2 * v4;
        v4 *= 2LL;
      }
      v29 = k;
    }
    v30 = 8 * j;
    v31 = &s1[8 * j];
    *(_QWORD *)v31 = v4;
    v32 = j + 1;
  }
  v33 = memcmp(s1, &unk_402170, 0x30uLL);
  v34 = v33 != 0;
  puts("Correct!");
  return v10;

人工调整后可以复现出加密的代码,如下:

#include <bits/stdc++.h>
using namespace std;
unsigned char in[1007],flag[1007];
int len;
int main() {
	// in flag: len == 48
	memset(in,0,sizeof(in));
	memset(flag,0,sizeof(flag));
	scanf("%s",in),len=3;
	for (int i=0; i<len; i++)
		if (in[i]=='\n') in[i]=0;
	for (int i=0; i<6; i++) {
		cout<<(&in+i*8)<<endl;
		__int64 p = *((__int64 *)&in[i*8]);
		cout<<p<<endl;
		for (int j=0; j<64; j++) {
			//encode x64
			if (p>=0) p*=2; // p<<=1 
			else p=p*2^0xB0004B7679FA26B3LL; //p=p<<1^0xB000...
		}
		*(__int64 *)(&flag[i*8])=p;
	}
	if (memcmp(flag,encode,48)) puts("Wrong!");
	else puts("Correct!");
	return 0;
}

exp:

#include <bits/stdc++.h>
using namespace std;
unsigned char encode[48] = { 0x96, 0x62, 0x53, 0x43, 0x6D, 0xF2, 0x8F, 0xBC,
                    0x16, 0xEE, 0x30, 0x05, 0x78, 0x00, 0x01, 0x52,
                    0xEC, 0x08, 0x5F, 0x93, 0xEA, 0xB5, 0xC0, 0x4D,
                    0x50, 0xF4, 0x53, 0xD8, 0xAF, 0x90, 0x2B, 0x34,
                    0x81, 0x36, 0x2C, 0xAA, 0xBC, 0x0E, 0x25, 0x8B,
                    0xE4, 0x8A, 0xC6, 0xA2, 0x81, 0x9F, 0x75, 0x55
                  };
unsigned char flag[48];
int main() {
	for (int i=0;i<6;i++) {
		__int64 p  = *((__int64 *)&encode[i*8]);
		for (int j=0;j<64;j++) {
		// check the last bit 
			if (p&1) {
				p=((unsigned __int64)p^0xB0004B7679FA26B3LL)/2; // p=(p^0xB000...)>>1
				p|=0x8000000000000000; // avoid - to +
			}
			else p=(unsigned __int64)p/2; // p>>=1; 
		}
		for (int j=0;j<8;j++) printf("%c",(char)p&0xff),p>>=8;
	}
	return 0;
}

c=[0x96, 0x62, 0x53, 0x43, 0x6D, 0xF2, 0x8F, 0xBC, 0x16, 0xEE,
  0x30, 0x05, 0x78, 0x00, 0x01, 0x52, 0xEC, 0x08, 0x5F, 0x93,
  0xEA, 0xB5, 0xC0, 0x4D, 0x50, 0xF4, 0x53, 0xD8, 0xAF, 0x90,
  0x2B, 0x34, 0x81, 0x36, 0x2C, 0xAA, 0xBC, 0x0E, 0x25, 0x8B,
  0xE4, 0x8A, 0xC6, 0xA2, 0x81, 0x9F, 0x75, 0x55, 0xB3, 0x26,
  0xFA, 0x79, 0x76, 0x4B, 0x00, 0xB0]
k=8
t=[]
for i in range(0,len(c),k):
    tmp=0
    for j in range(i,i+k):
        tmp+=c[j]*2**(8*j%(k*8))
    t.append(tmp)
from Crypto.Util.number import *
key=0xB0004B7679FA26B3

def decrypt(data):
    for i in range(64):
        s=data&1
        if s==1:
            data^=key
        data//=2
        if s == 1:
            data |= 0x8000000000000000
    return data
flag=b''
for a in t:
    tmp=decrypt(a)
    flag+=long_to_bytes(tmp)[::-1]
print(flag)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值