-
-
[原创]KCTF2022秋季赛 第二题 盗贼作乱 题解
-
2022-11-30 12:26 8013
-
CM2022
根据调试,确定函数的功能
首先通过第一个if条件进入while 1循环后,进入第一个函数调试,会发现程序会有一个大数结构
1 2 3 4 | struct bignum{ int len ; uint8_t data[ 32 ]; } |
那么前面的函数的功能也可以据此bignum
推测出来了。
此时main函数的比较部分整理出来如下:
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 | if ( v3 > 0 && (v6 = v4 - v3, v4 - v3 > 0 ) && frombase62(first, &a2, v3, table) > 0 && frombase62(&second, &v10[v3], v6 - 1 , table) > 0 && (frombase62(&example, "IRtzloZ6iuB" , strlen( "IRtzloZ6iuB" ), table), init(firstop, 0 ), init(secondop, 0 ), compare((char * )first, (char * )&second) < 0 ) && compare((char * )first, (char * )&example) < 0 && compare((char * )&second, (char * )&example) < 0 ) { v7 = 0 ; while ( 1 ) { i = v7 + 1 ; plus(firstop, firstop, first); plus(secondop, secondop, &second); mod((unsigned int * )firstop, (char * )firstop, (char * )&example); mod((unsigned int * )secondop, (char * )secondop, (char * )&example); init(&firststageNumber, 1 ); sub(&firststageNumber, firstop, &firststageNumber); if ( !compare((char * )&firststageNumber, (char * )first) ) { + + succ; sbf1(&firststageNumber, &firststageNumber, first); / / sbf1唯一的作用就是当i = = 32 时,succ + = 4 } init(&secondStageNumber, 1 ); plus(&secondStageNumber, secondop, &secondStageNumber); if ( !compare((char * )&secondStageNumber, (char * )&second) ) { + + succ; sbf2(&secondStageNumber, (char * )&example, (char * )&second); / / sbf2唯一的作用就是当i = = 32 时,succ + = 4 } if ( succ = = 10 ) break ; v7 = i; if ( i > = 2097152 ) goto LABEL_20; } sub_40284A(( int )aSuccess); return 0 ; } |
难搞的是sbf1
,sbf2
函数,因为此函数多次引用了main函数里面的全局变量,而且包含多个if条件,在乘法计算完后有这些操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | arrAnd(&firststageNumber, firstop, secondop); if ( compare((char * )&firststageNumber, (char * )&secondStageNumber) > 0 && succ > 0 ) { maybe_div2(&firststageNumber, &firststageNumber, i); plus(&secondStageNumber, first, second); sub(&firststageNumber, &firststageNumber, &secondStageNumber); } init(&firststageNumber, 4 ); shlarg3(&secondStageNumber, &firststageNumber, 3 ); if ( succ > 0 && * ( int * )((char * )&examplerawNumber + (unsigned __int8)SecondStageNumber) = = (unsigned __int8)SecondStageNumber ) / / i = = 32 { plus(&firststageNumber, &firststageNumber, &secondStageNumber); v13 = GetModImm(&firststageNumber, i); * ((_BYTE * )&examplerawNumber + * ((unsigned __int8 * )&firststageNumber + 4 )) + = 4 ; shlarg3(&firststageNumber, &firststageNumber, v13); sub(&secondStageNumber, &firststageNumber, &secondStageNumber); } |
而这些函数里面又有类似sbf1
的操作
理性分析一下会发现一个问题:sbf1
,sbf2
函数改了哪些变量呢?
改了图里的firststagenumber
和secondstageNumber
这两个变量在执行compare 比较之前会被重新赋值,没有问题
还有在特殊条件下有一个条件会改example->data
的值
这个example->data
是前面用来取模的数
这个特殊条件又是写死的。
当example->data
+ 32 == 32时,即在内存布局中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | .data: 0040A9D0 example dd 0 ; DATA XREF: sub + AD↑o .data: 0040A9D0 ; ArrOr + FF↑o ... .data: 0040A9D4 examplerawNumber dd 8 dup( 0 ) ; DATA XREF: sbf1 + 1B9 ↑r .data: 0040A9D4 ; sbf1 + 1FD ↑o ... .data: 0040A9F4 i dd 0 ; DATA XREF: compare:loc_4016D0↑r .data: 0040A9F4 ; compare + 65 ↑r ... .data: 0040A9F8 succ dd 0 ; DATA XREF: compare + 7B ↑r .data: 0040A9F8 ; plus + D0↑r ... .data: 0040A9FC ; signed int firstop[ 9 ] .data: 0040A9FC firstop dd 0 , 8 dup(?) ; DATA XREF: ArrOr + 83 ↑o .data: 0040A9FC ; sbf1 + 118 ↑o ... .data: 0040AA20 ; signed int secondop[ 9 ] .data: 0040AA20 secondop db ? ; DATA XREF: arrAnd + 89 ↑o .data: 0040AA20 ; arrAnd + 11A ↑o ... |
i == 32
时,example->data + 36 (succ) += 4;
说人话即是
计算方程
1 2 | 32 * X - 1 % 10000000000000000000 = X 32 * X + 1 % 10000000000000000000 = X |
的两个解
这里直接z3解
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | from z3 import * magic = 0x8AC7230489E80000 Input1 = Int ( "Input1" ) Input2 = Int ( "Input2" ) s = Solver() s.add(Input1 < Input2) s.add(Input2 < magic) s.add( 32 * Input1 % magic - 1 = = Input1) s.add( 32 * Input2 % magic + 1 = = Input2) print (magic) print (s.check()) print (s.model()) # [Input2 = 6129032258064516129, Input1 = 3870967741935483871] # 用cyberchef 转换一下 print ( "4bx4XreZxSZ" [:: - 1 ]) print ( "7Il21x7Pvyj" [:: - 1 ]) # ZSxZerX4xb4-jyvP7x12lI7 |
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法
赞赏
他的文章
看原图