前言
队里师傅给的题目,十分有意思,是我之前很少接触的go语言逆向,借此也学到了不少go语言的知识
分析
IDA打开的main函数就是主要函数,题目并没有去除大多数符号,能很清楚看清基础逻辑。
开头两个判断是判断是否有包含参数且参数是否为45位长度
loc_491C78下就是加密部分
加密结束后call runtime_memequal与key进行比较
loc_491C78:
lea rax, main_wg
mov [rsp+0B8h+var_B8], rax
mov [rsp+0B8h+var_B0], 27h ; '''
call sync___WaitGroup__Add
mov dword ptr [rsp+0B8h+var_B8], 0
lea rax, off_4CDC68
mov [rsp+0B8h+var_B0], rax
call runtime_newproc
mov dword ptr [rsp+0B8h+var_B8], 0
lea rax, off_4CDBC0
mov [rsp+0B8h+var_B0], rax
call runtime_newproc
mov dword ptr [rsp+0B8h+var_B8], 0
lea rax, off_4CDBD0
mov [rsp+0B8h+var_B0], rax
call runtime_newproc
lea rax, main_wg
mov [rsp+0B8h+var_B8], rax
call sync___WaitGroup__Wait
mov rax, cs:qword_566608
mov rcx, cs:main_input
cmp rax, 2Dh ; '-'
jz loc_491E26
通过符号可以知道题目是使用并发的功能隐藏了加密算法,使用runtime_newproc生成加密函数的模块,然后使用sync___WaitGroup来等待并发程序完成加密。
进入runtime_newproc生成的函数里面发现还生成了新的加密函数模块
最外面有三个模块,三个模块中每个都还包含三个模块,新的三个模块里也包含三个模块
所以总共有3+9+27=39个模块
这里并没有搞清楚模块之间运行的具体顺序,依靠动态调试了解到大致是312的顺序来调用模块(没理解为什么,go是开源的语言,有机会可以研究)顺序如下
funtion3
funtion3_3
funtion3_3_3
funtion1
funtion1_3
funtion1_3_3
funtion2
funtion2_3
funtion2_3_3
funtion3_1
funtion3_1_3
funtion3_2
funtion3_2_3
funtion3_3_1
funtion3_3_2
funtion1_1
funtion1_1_3
funtion1_2
funtion1_2_3
funtion1_3_1
funtion1_3_2
funtion2_1
funtion2_1_3
funtion2_2
funtion2_2_3
funtion2_3_1
funtion2_3_2
funtion3_1_1
funtion3_1_2
funtion3_2_1
funtion3_2_2
funtion1_1_1
funtion1_1_2
funtion1_2_1
funtion1_2_2
funtion2_1_1
funtion2_1_2
funtion2_2_1
funtion2_2_2
(加入的退格是想看看顺序的规律)
依据顺序,会发现其实都是简单的加减乘除和异或,依靠z3可以比较简单的获得flag
这里贴上部分代码
solver=Solver()
solver.add((((x0^(x33-57))*(-53))+12)==k[0])
solver.add((((x1-108)^((x44*29)^((x19+58)*103)))*91)==k[1])
solver.add(((x2^(x26*(-15)))-118)==k[2])
solver.add((((x3*85)-29)^(((x0^(x33-57))*(-53))+12))==k[3])
solver.add(((x4^((x20+122)^(x8^(x11^(x24*(-81))))))*(-101))==k[4])
solver.add(((((((x5-71)+67)^x7)*(-29))-75)-111)==k[5])
solver.add((((x6-87)^x17)*27)==k[6])
solver.add((((x7*(-77))^((x19+58)*103))+39)==k[7])
solver.add((((x8^(x11^(x24*(-81))))*(-71))-105)==k[8])
solver.add((((x9*(-35))-35)^x0)==k[9])
solver.add((((x10+14)*(-47))-118)==k[10])
solver.add(((x11^(x24*(-81)))^((x41^x43)+45))==k[11])
solver.add(((x12^x35)*119)==k[12])
solver.add((((x13^(x44*29))-40)-51)==k[13])
solver.add((((x14+78)*(-47))^(x29*123))==k[14])
solver.add((x15^(x8^(x11^(x24*(-81)))))==k[15])
solver.add((((x16-69)*87)^(x6-87))==k[16])
solver.add((x17*29)==k[17])
solver.add(((x18^x19)+79)==k[18])
solver.add(((x19+58)*103)==k[19])
solver.add((((x20+122)^(x8^(x11^(x24*(-81)))))*(-9))==k[20])
solver.add((((x21*9)+103)^((x4^((x20+122)^(x8^(x11^(x24*(-81))))))*(-101)))==k[21])
solver.add((((x22*87)-48)^((((x5-71)+67)^x7)*(-29)))==k[22])#wrong
solver.add((x23^((x10+14)*(-47)))==k[23])
solver.add(((x24*(-81))+36)==k[24])
solver.add((((x25^x19)-104)*(-91))==k[25])
solver.add(((x26*(-15))+51)==k[26])
solver.add((((x27*11)^((x41^x43)+45))^(x1-108))==k[27])
solver.add((((x28^x6)^(x26*(-15)))*101)==k[28])
solver.add((x29*123)==k[29])
solver.add((((x30*85)^(x11^(x24*(-81))))+83)==k[30])
solver.add(((((x31+29)*(-29))+13)^((x18^x19)+79))==k[31])
solver.add(((x32*(-51))-3)==k[32])
solver.add((((x33-57)*33)-119)==k[33])
solver.add((((x34*99)+78)^x19)==k[34])
solver.add(((x35+12)^((x42^x4)*125))==k[35])
solver.add((((x36-66)*21)^((x1-108)^((x44*29)^((x19+58)*103))))==k[36])
solver.add(((x37*61)^(x0^(x33-57)))==k[37])
solver.add(((((x38*49)+3)*35)^((x22*87)-48))==k[38])#wrong
solver.add(((x39^x36)+26)==k[39])
solver.add((((x40*109)^((x0^(x33-57))*(-53)))+120)==k[40])
solver.add(((x41^x43)+45)==k[41])
solver.add(((((x42^x4)*125)-88)-65)==k[42])
solver.add((x43^((x35+12)^((x42^x4)*125)))==k[43])
solver.add(((x44*29)^((x19+58)*103))==k[44])