-
-
[原创]2023SCTF-Syclang-关于中间指令的分析
-
2小时前
197
-
[原创]2023SCTF-Syclang-关于中间指令的分析
2023SYCTF的Syclang这道题还怪有意思的,作者写了一个简单的反编译器,将源代码输出中间指令、asm等格式
然后,我们今天要来头铁分析一下IR中间代码(个人感觉像Go语言hhh)
主要调出几个典型的指令进行一个分析,然后就可以逆出这段程序的大致意思了
感觉分析完这个中间指令,对程序的理解又更进了一步
程序的逻辑很简单,就是多个循环,加减加密,然后与密文比较。
在文章的结束,将会把附件上传,大家也可以下载下来分析
(作者水平有限,如有错误,请大佬指出)
调了几个很典型的指令,CTF题给了800多行代码,都是由这些指令组成的。
1 2 3 4 5 6 | / / 声明一个结构体
STRUCT exp :
ARRAY .key( int )[ 24 ]< + 0 > / / int 类型,这里占 8 个字节, 8 * 24 = 192
ARRAY .L( int )[ 8 ]< + 192 >
ARRAY .R( int )[ 8 ]< + 256 >
ARRAY .X( int )[ 8 ]< + 320 >
|
定义函数
1 2 3 4 5 6 7 8 9 10 11 12 | FUNCTION read - 8 :
PARAM var2< + 8 >
LABEL Flabelread :
FUNCTION writes - 0 :
LABEL Flabelwrites :
FUNCTION writef - 0 :
LABEL Flabelwritef :
FUNCTION exit - 0 :
LABEL Flabelexit :
|
入口main函数
char类型在这里占一个字节,int类型占了8字节
<+n>这个表示偏移,理解一下就可以
1 2 3 4 5 6 7 8 9 10 | FUNCTION main - 1640 :
ARRAY var11(char)[ 24 ]< + 0 > / / char类型占一个字节
STRUCT var22(exp)< + 488 >
STRUCT var23(exp)< + 872 >
STRUCT var24(exp)< + 1256 >
STRUCT var25(exp)< + 1640 >
ARG var11< + 24 >
temp1 : = CALL read / / 调用函数,获取我们的flag
temp2 : =
var15< + 56 > : = temp2
|
分析第一个循环结构,其他的循环结构都是类似的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | / / 第一个循环,运算 1
LABEL label4 :
temp4 : =
IF var15< + 56 > < temp4 GOTO label3 / / 一个循环结构
GOTO label2
LABEL label3 :
temp5 : =
var12< + 32 > : = temp5
var16< + 64 > : = var15< + 56 >
var12< + 32 > :: = var11< + 1 >< + tempa> / / var12 = input [i]
temp6 : =
temp7 : = temp6 - var15< + 56 >
var18< + 80 > : = temp7
var22(@exp.key[ 0 ])< + 8 >< + 488 >< + tempa> : = var12< + 32 >
/ / var22(@exp.key[ 0 ])< + 8 >< + 488 >获得exp结构体数组的起始地址,exp.key[ 23 - i] = var12 = input [i]
temp3 : =
var15< + 56 > : = var15< + 56 > + temp3
GOTO label4
/ / 第二个循环,运算 2
LABEL label2 :
temp8 : =
var15< + 56 > : = temp8
LABEL label11 :
temp10 : =
IF var15< + 56 > > temp10 GOTO label10
GOTO label9
....... / / 其他代码
|
一个循环可以提取出来C代码:
1 2 3 | for ( int i = 0 ; i < 24 ; i + + ) {
var22.key[ 23 - i] = inputflag[i];
}
|
分析第二个循环结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | / / 第二个循环,运算 2
LABEL label2 :
temp8 : =
var15< + 56 > : = temp8
LABEL label11 :
temp10 : =
IF var15< + 56 > > temp10 GOTO label10 / / 终止条件
GOTO label9
LABEL label10 :
var18< + 80 > : = var15< + 56 >
var19< + 88 > : = var22(@exp.key[ 0 ])< + 8 >< + 488 >< + tempa>
temp11 : =
temp12 : = var15< + 56 > - temp11 / / i - 1
var16< + 64 > : = temp12
var17< + 72 > : = var22(@exp.key[ 0 ])< + 8 >< + 488 >< + tempa>
temp13 : = var19< + 88 > - var17< + 72 >
var21< + 104 > : = temp13
var22(@exp.key[ 0 ])< + 8 >< + 488 >< + tempa> : = var21< + 104 > / / exp.key[i] = exp.key[i] - exp.key[i - 1 ]
temp9 : =
var15< + 56 > : = var15< + 56 > - temp9
GOTO label11
/ / 初始化数组区
LABEL label9 :
|
第二个循环转换为c代码如下:
1 2 3 | for ( int i = 23 ; i > 0 ; i - - ) {
var22.key[i] = var22.key[i] - var22.key[i - 1 ];
}
|
初始化数组区,就是很常见的赋值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | LABEL label9 :
temp15 : =
var22(@exp.L[ 0 ])< + 200 >< + 488 > : = temp15
temp17 : =
var22(@exp.R[ 0 ])< + 264 >< + 488 > : = temp17
temp19 : =
var22(@exp.X[ 0 ])< + 328 >< + 488 > : = temp19
temp21 : =
var22(@exp.L[ 1 ])< + 208 >< + 488 > : = temp21
temp23 : =
var22(@exp.R[ 1 ])< + 272 >< + 488 > : = temp23
temp25 : =
temp26 : =
temp27 : = temp25 - temp26
var22(@exp.X[ 1 ])< + 336 >< + 488 > : = temp27
temp29 : =
var22(@exp.L[ 2 ])< + 216 >< + 488 > : = temp29
temp31 : =
var22(@exp.R[ 2 ])< + 280 >< + 488 > : = temp31
temp33 : =
var22(@exp.X[ 2 ])< + 344 >< + 488 > : = temp33
temp35 : =
var22(@exp.L[ 3 ])< + 224 >< + 488 > : = temp35
temp37 : =
var22(@exp.R[ 3 ])< + 288 >< + 488 > : = temp37
temp39 : =
temp40 : =
temp41 : = temp39 - temp40
var22(@exp.X[ 3 ])< + 352 >< + 488 > : = temp41
......
|
其它的循环和赋值都是类似了,这里不在详细分析了
这里贴一下,翻译后的大致伪代码
感谢s0rry师傅的帮助~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | typedef struct {
long long int key[ 24 ];
long long int L[ 8 ];
long long int R[ 8 ];
long long int X[ 8 ];
} exp;
int main() {
exp var22;
exp var23;
exp var24;
exp var25;
var22.L[ 0 ] = 0 ;
var22.R[ 0 ] = 8 ;
var22.X[ 0 ] = 11 ;
var22.L[ 1 ] = 15 ;
var22.R[ 1 ] = 23 ;
var22.X[ 1 ] = - 13 ;
var22.L[ 2 ] = 2 ;
var22.R[ 2 ] = 11 ;
var22.X[ 2 ] = 17 ;
var22.L[ 3 ] = 10 ;
var22.R[ 3 ] = 20 ;
var22.X[ 3 ] = - 19 ;
var22.L[ 4 ] = 6 ;
var22.R[ 4 ] = 13 ;
var22.X[ 4 ] = 23 ;
var22.L[ 5 ] = 9 ;
var22.R[ 5 ] = 21 ;
var22.X[ 5 ] = - 29 ;
var22.L[ 6 ] = 1 ;
var22.R[ 6 ] = 19 ;
var22.X[ 6 ] = 31 ;
var22.L[ 7 ] = 4 ;
var22.R[ 7 ] = 17 ;
var22.X[ 7 ] = - 37 ;
var23.key[ 0 ] = 252 ;
var23.key[ 1 ] = 352 ;
var23.key[ 2 ] = 484 ;
var23.key[ 3 ] = 470 ;
var23.key[ 4 ] = 496 ;
var23.key[ 5 ] = 487 ;
var23.key[ 6 ] = 539 ;
var23.key[ 7 ] = 585 ;
var23.key[ 8 ] = 447 ;
var23.key[ 9 ] = 474 ;
var23.key[ 10 ] = 577 ;
var23.key[ 11 ] = 454 ;
var23.key[ 12 ] = 466 ;
var23.key[ 13 ] = 345 ;
var23.key[ 14 ] = 344 ;
var23.key[ 15 ] = 486 ;
var23.key[ 16 ] = 501 ;
var23.key[ 17 ] = 423 ;
var23.key[ 18 ] = 490 ;
var23.key[ 19 ] = 375 ;
var23.key[ 20 ] = 257 ;
var23.key[ 21 ] = 203 ;
var23.key[ 22 ] = 265 ;
var23.key[ 23 ] = 125 ;
/ / 初始化
for ( int i = 0 ; i < 24 ; i + + ) {
var22.key[ 23 - i] = input [i];
}
for ( int i = 23 ; i > 0 ; i - - ) {
var22.key[i] = var22.key[i] - var22.key[i - 1 ];
}
/ / 对flag加密
for ( int i = 0 ; i < 8 ; i + + ) {
var22.key[var22.L[i]] + = var22.X[i];
var22.key[var22.R[i]] - = var22.X[i];
}
for ( int i = 1 ; i < 24 ; i + + ) {
var22.key[i] + = var22.key[i - 1 ];
}
/ / 对var23密文进行运算
for ( int i = 23 ; i > 0 ; i - - ) {
var23.key[i] - = var23.key[i - 1 ];
}
for ( int i = 0 ; i < 8 ; i + + ) {
var23.key[var22.L[i]] - = var22.key[i * 3 ];
var23.key[var22.R[i]] + = var22.key[i * 3 ];
}
for ( int i = 1 ; i < 24 ; i + + ) {
var23.key[i] + = var23.key[i - 1 ];
}
/ / 比较密文和输入flag的密文
for ( int i = 0 ; i < 24 ; i + + ) {
if (var22.key[i] ! = var23.key[i]) {
exit; / / 不相等则退出
}
}
return 0 ;
}
|
Unicorn高级逆向与反混淆
文章来源: https://bbs.pediy.com/thread-277942.htm
如有侵权请联系:admin#unsafe.sh