一道ollvm的题,主要是去平坦化
先查壳,64位elf,无壳
直接拖入ida,定位到main函数
发现是ollvm平坦化,我们用在linux中使用deflat进行平坦化
去除之后用ida打开
找到关键的算法
while ( 1 ) { do v12 = v6; while ( dword_603058 >= 10 && ((((_BYTE)dword_603054 - 1) * (_BYTE)dword_603054) & 1) != 0 ); v13 = v12 < 64; while ( dword_603058 >= 10 && ((((_BYTE)dword_603054 - 1) * (_BYTE)dword_603054) & 1) != 0 ) ; if ( !v13 ) break; v14 = input[v6]; do v15 = v14; while ( dword_603058 >= 10 && ((((_BYTE)dword_603054 - 1) * (_BYTE)dword_603054) & 1) != 0 ); if ( v15 == 10 ) { v16 = &input[v6]; *v16 = 0; break; } v17 = v6 + 1; do v6 = v17; while ( dword_603058 >= 10 && ((((_BYTE)dword_603054 - 1) * (_BYTE)dword_603054) & 1) != 0 ); } for ( i = 0; ; ++i ) { do v18 = i; while ( dword_603058 >= 10 && ((((_BYTE)dword_603054 - 1) * (_BYTE)dword_603054) & 1) != 0 ); do v19 = v18 < 6; while ( dword_603058 >= 10 && ((((_BYTE)dword_603054 - 1) * (_BYTE)dword_603054) & 1) != 0 ); if ( !v19 ) break; do v20 = input; while ( dword_603058 >= 10 && ((((_BYTE)dword_603054 - 1) * (_BYTE)dword_603054) & 1) != 0 ); v4 = *(_QWORD *)&v20[8 * i]; v7 = 0; while ( 1 ) { v21 = v7; do v22 = v21 < 64; while ( dword_603058 >= 10 && ((((_BYTE)dword_603054 - 1) * (_BYTE)dword_603054) & 1) != 0 ); if ( !v22 ) break; v23 = v4; v24 = v4 < 0; if ( v4 >= 0 ) { v27 = v4; do v28 = 2 * v27; while ( dword_603058 >= 10 && ((((_BYTE)dword_603054 - 1) * (_BYTE)dword_603054) & 1) != 0 ); v4 = v28; } else { v25 = 2 * v4; do v26 = v25; while ( dword_603058 >= 10 && ((((_BYTE)dword_603054 - 1) * (_BYTE)dword_603054) & 1) != 0 ); v4 = v26 ^ 0xB0004B7679FA26B3LL; } v29 = v7; do v7 = v29 + 1; while ( dword_603058 >= 10 && ((((_BYTE)dword_603054 - 1) * (_BYTE)dword_603054) & 1) != 0 ); } v30 = 8 * i; v31 = &s1[8 * i]; if ( dword_603058 >= 10 && ((((_BYTE)dword_603054 - 1) * (_BYTE)dword_603054) & 1) != 0 ) LABEL_55: *(_QWORD *)v31 = v4; *(_QWORD *)v31 = v4; if ( dword_603058 >= 10 && ((((_BYTE)dword_603054 - 1) * (_BYTE)dword_603054) & 1) != 0 ) goto LABEL_55; v32 = i + 1; }
此时还存在一些无用代码,将无用代码删除
while ( 1 ) { v12 = v6; v13 = v12 < 64; if ( !v13 ) break; v14 = s[v6]; v15 = v14; if ( v15 == 10 ) { v16 = &s[v6]; *v16 = 0; break; } v17 = v6 + 1; v6 = v17; } for ( i = 0; ; ++i ) { v18 = i; v19 = v18 < 6; if ( !v19 ) break; v20 = s; v4 = *(_QWORD *)&v20[8 * i]; v7 = 0; while ( 1 ) { v21 = v7; v22 = v21 < 64; if ( !v22 ) break; v23 = v4; v24 = v4 < 0; if ( v4 >= 0 ) { v27 = v4; v28 = 2 * v27; v4 = v28; } else { v25 = 2 * v4; v26 = v25; v4 = v26 ^ 0xB0004B7679FA26B3LL; } v29 = v7; v7 = v29 + 1; } v30 = 8 * i; v31 = &s1[8 * i]; *(_QWORD *)v31 = v4; v32 = i + 1; } v33 = memcmp(s1, &unk_402170, 0x30uLL); v34 = v33 != 0;
发现只是进行移位操作,直接把过程逆过来就可以
C++ exp
#include<iostream> #include<stdio.h> #include<windows.h> using namespace std; unsigned char l[] = {0x96,0x62,0x53,0x43,0x6d,0xf2,0x8f,0xbc,0x16,0xee,0x30,0x5,0x78,0x0,0x1,0x52,0xec,0x8,0x5f,0x93,0xea,0xb5,0xc0,0x4d,0x50,0xf4,0x53,0xd8,0xaf,0x90,0x2b,0x34,0x81,0x36,0x2c,0xaa,0xbc,0xe,0x25,0x8b,0xe4,0x8a,0xc6,0xa2,0x81,0x9f,0x75,0x55,0xb3,0x26,0xfa,0x79,0x76,0x4b,0x0,0xb0}; int main() { __int64 v4; __int64 v23; for(int i = 0;i < 6;i++) { v4 = *(__int64 *)&l[8 * i]; for(int j = 0;j < 64;j++){ if (v4 &1) { v4 = (unsigned __int64)v4 ^ 0xB0004B7679FA26B3LL; v4 >>= 1; v4 |= 0x8000000000000000; } else { v4 = (unsigned __int64)v4 >> 1; } } for(int i = 0;i < 8;i++) { printf("%c",(char)(v4&0xff)); v4 >>= 8; } } }
标签:10,polyre,603054,while,v4,dword,BYTE,xctf From: https://www.cnblogs.com/polang19/p/16926080.html