-
-
[原创]国赛babytree wp
-
2022-6-5 16:55 6725
-
<!--
* @Author: wenling
* @Date: 2022-06-03 19:18:11
* @LastEditors: wenling
* @LastEditTime: 2022-06-05 16:39:50
* @Description: 请填写简介
-->
2022国赛babytree wp
题目给了一个txt文件,里面是swift的抽象语法树
文本很长而且是我不熟悉的swift语言,所以先了解一下swift的抽象语法树吧
swift开发环境搭建:https://www.fatbobman.com/posts/swift-in-linux/
例子:
var str = "hello"
使用如下命令将switf文件转换为ast文件
1 | swiftc -dump-ast hello.swift |
![图 2]
如图就是一个初始化语句的ast结构:
- pattern_binding_decl:初始化语句
- pattern_named type='String' 'str':变量名称
- value="hello":变量值
在题目给出的ast中,有类似的结构
1 2 3 4 5 6 7 8 | (pattern_binding_decl range = [re.swift: 18 : 5 - line: 18 : 15 ] (pattern_named type = 'String' 'key' ) Original init: (string_literal_expr type = 'String' location = re.swift: 18 : 15 range = [re.swift: 18 : 15 - line: 18 : 15 ] encoding = utf8 value = "345y" builtin_initializer = Swift.( file ).String extension.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:) initializer = * * NULL * * ) Processed init: (string_literal_expr type = 'String' location = re.swift: 18 : 15 range = [re.swift: 18 : 15 - line: 18 : 15 ] encoding = utf8 value = "345y" builtin_initializer = Swift.( file ).String extension.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:) initializer = * * NULL * * )) (var_decl range = [re.swift: 18 : 9 - line: 18 : 9 ] "key" type = 'String' interface type = 'String' access = fileprivate let readImpl = stored immutable) |
所以这一块结构的意思就是:
var key = "345y"
再看一个例子:
var num = 10 if num == 10 { num = 100 }
![图 3]
if语句
- if_stmt:if语句
- declref_expr:比较的对象
- integer_literal_expr:比较的值
赋值语句
- assign_expr:赋值语句
- declref_expr:赋值的对象
- integer_literal_expr:赋值的值
其他的对应关系就不列出了,可以自己写代码对照
1 2 3 4 5 6 7 8 9 10 11 12 13 | (call_expr type = '()' location = re.swift: 20 : 5 range = [re.swift: 20 : 5 - line: 20 : 17 ] nothrow (declref_expr type = '(Any..., String, String) -> ()' location = re.swift: 20 : 5 range = [re.swift: 20 : 5 - line: 20 : 5 ] decl = Swift.( file ). print (_:separator:terminator:) function_ref = single) (argument_list labels = _:separator:terminator: (argument (vararg_expansion_expr implicit type = 'Any...' location = re.swift: 20 : 11 range = [re.swift: 20 : 11 - line: 20 : 11 ] (array_expr implicit type = 'Any...' location = re.swift: 20 : 11 range = [re.swift: 20 : 11 - line: 20 : 11 ] initializer = * * NULL * * (erasure_expr implicit type = 'Any' location = re.swift: 20 : 11 range = [re.swift: 20 : 11 - line: 20 : 11 ] (declref_expr type = 'Bool' location = re.swift: 20 : 11 range = [re.swift: 20 : 11 - line: 20 : 11 ] decl = re.( file ).top - level code.result@re.swift: 19 : 9 function_ref = unapplied))))) (argument label = separator (default_argument_expr implicit type = 'String' location = re.swift: 20 : 10 range = [re.swift: 20 : 10 - line: 20 : 10 ] default_args_owner = Swift.( file ). print (_:separator:terminator:) param = 1 )) (argument label = terminator (default_argument_expr implicit type = 'String' location = re.swift: 20 : 10 range = [re.swift: 20 : 10 - line: 20 : 10 ] default_args_owner = Swift.( file ). print (_:separator:terminator:) param = 2 )) ))))))) |
- call_expr:函数调用
- declref_expr:调用的函数,decl=Swift.(file).print(_:separator:terminator:),这里调用的是print函数
- argument:参数
print(result)
这段代码中,调用了print函数,打印的是result的值,result是Bool类型的数据,所以程序会输出true或者false
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | (pattern_binding_decl range = [re.swift: 19 : 5 - line: 19 : 33 ] (pattern_named type = 'Bool' 'result' ) Original init: (call_expr type = 'Bool' location = re.swift: 19 : 18 range = [re.swift: 19 : 18 - line: 19 : 33 ] nothrow (declref_expr type = '(String, String) -> Bool' location = re.swift: 19 : 18 range = [re.swift: 19 : 18 - line: 19 : 18 ] decl = re.( file ).check@re.swift: 1 : 6 function_ref = single) (argument_list (argument (declref_expr type = 'String' location = re.swift: 19 : 24 range = [re.swift: 19 : 24 - line: 19 : 24 ] decl = re.( file ).top - level code.data@re.swift: 17 : 9 function_ref = unapplied)) (argument (declref_expr type = 'String' location = re.swift: 19 : 30 range = [re.swift: 19 : 30 - line: 19 : 30 ] decl = re.( file ).top - level code.key@re.swift: 18 : 9 function_ref = unapplied)) )) Processed init: (call_expr type = 'Bool' location = re.swift: 19 : 18 range = [re.swift: 19 : 18 - line: 19 : 33 ] nothrow (declref_expr type = '(String, String) -> Bool' location = re.swift: 19 : 18 range = [re.swift: 19 : 18 - line: 19 : 18 ] decl = re.( file ).check@re.swift: 1 : 6 function_ref = single) (argument_list (argument (declref_expr type = 'String' location = re.swift: 19 : 24 range = [re.swift: 19 : 24 - line: 19 : 24 ] decl = re.( file ).top - level code.data@re.swift: 17 : 9 function_ref = unapplied)) (argument (declref_expr type = 'String' location = re.swift: 19 : 30 range = [re.swift: 19 : 30 - line: 19 : 30 ] decl = re.( file ).top - level code.key@re.swift: 18 : 9 function_ref = unapplied)) ))) (var_decl range = [re.swift: 19 : 9 - line: 19 : 9 ] "result" type = 'Bool' interface type = 'Bool' access = fileprivate let readImpl = stored immutable) |
result变量就在call语句块的上方,可以分析出result是初始化的变量,用来初始化result变量的是一个call语句,调用的函数是check,参数分别是data和key
var result = check(data, key)
1 2 3 4 5 6 7 8 | (pattern_binding_decl range = [re.swift: 18 : 5 - line: 18 : 15 ] (pattern_named type = 'String' 'key' ) Original init: (string_literal_expr type = 'String' location = re.swift: 18 : 15 range = [re.swift: 18 : 15 - line: 18 : 15 ] encoding = utf8 value = "345y" builtin_initializer = Swift.( file ).String extension.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:) initializer = * * NULL * * ) Processed init: (string_literal_expr type = 'String' location = re.swift: 18 : 15 range = [re.swift: 18 : 15 - line: 18 : 15 ] encoding = utf8 value = "345y" builtin_initializer = Swift.( file ).String extension.init(_builtinStringLiteral:utf8CodeUnitCount:isASCII:) initializer = * * NULL * * )) (var_decl range = [re.swift: 18 : 9 - line: 18 : 9 ] "key" type = 'String' interface type = 'String' access = fileprivate let readImpl = stored immutable) |
再往上可以找到key的定义
var key = "345y"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | (pattern_binding_decl range = [re.swift: 17 : 5 - line: 17 : 39 ] (pattern_named type = 'String' 'data' ) Original init: (subscript_expr type = '<null>' (member_ref_expr type = '@lvalue [String]' location = re.swift: 17 : 28 range = [re.swift: 17 : 16 - line: 17 : 28 ] decl = Swift.( file ).CommandLine.arguments (type_expr type = 'CommandLine.Type' location = re.swift: 17 : 16 range = [re.swift: 17 : 16 - line: 17 : 16 ] typerepr = 'CommandLine' )) (argument_list (argument (integer_literal_expr type = 'Int' location = re.swift: 17 : 38 range = [re.swift: 17 : 38 - line: 17 : 38 ] value = 1 builtin_initializer = Swift.( file ). Int .init(_builtinIntegerLiteral:) initializer = * * NULL * * )) )) Processed init: (load_expr implicit type = 'String' location = re.swift: 17 : 37 range = [re.swift: 17 : 16 - line: 17 : 39 ] (subscript_expr type = '@lvalue String' location = re.swift: 17 : 37 range = [re.swift: 17 : 16 - line: 17 : 39 ] decl = Swift.( file ).Array extension.subscript(_:) [with (substitution_map generic_signature = <Element> (substitution Element - > String))] (inout_expr implicit type = 'inout Array<String>' location = re.swift: 17 : 16 range = [re.swift: 17 : 16 - line: 17 : 28 ] (member_ref_expr type = '@lvalue [String]' location = re.swift: 17 : 28 range = [re.swift: 17 : 16 - line: 17 : 28 ] decl = Swift.( file ).CommandLine.arguments (type_expr type = 'CommandLine.Type' location = re.swift: 17 : 16 range = [re.swift: 17 : 16 - line: 17 : 16 ] typerepr = 'CommandLine' ))) (argument_list (argument (integer_literal_expr type = 'Int' location = re.swift: 17 : 38 range = [re.swift: 17 : 38 - line: 17 : 38 ] value = 1 builtin_initializer = Swift.( file ). Int .init(_builtinIntegerLiteral:) initializer = * * NULL * * )) )))) (var_decl range = [re.swift: 17 : 9 - line: 17 : 9 ] "data" type = 'String' interface type = 'String' access = fileprivate let readImpl = stored immutable) |
这里是data的定义,data是有一个subscript_expr语句块定义的,subscript_expr其实是在去数组的下标,这里取的是arguments[1],也就是第二个命令行参数
var data = CommandLine.arguments[1]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | (if_stmt range = [re.swift: 16 : 1 - line: 21 : 1 ] (binary_expr type = 'Bool' location = re.swift: 16 : 32 range = [re.swift: 16 : 4 - line: 16 : 35 ] nothrow (dot_syntax_call_expr implicit type = '(Int, Int) -> Bool' location = re.swift: 16 : 32 range = [re.swift: 16 : 32 - line: 16 : 32 ] nothrow (declref_expr type = '(Int.Type) -> (Int, Int) -> Bool' location = re.swift: 16 : 32 range = [re.swift: 16 : 32 - line: 16 : 32 ] decl = Swift.( file ). Int extension.> = function_ref = single) (argument_list implicit (argument (type_expr implicit type = 'Int.Type' location = re.swift: 16 : 32 range = [re.swift: 16 : 32 - line: 16 : 32 ] typerepr = 'Int' )) )) (argument_list implicit (argument (member_ref_expr type = 'Int' location = re.swift: 16 : 26 range = [re.swift: 16 : 4 - line: 16 : 26 ] decl = Swift.( file ).Array extension.count [with (substitution_map generic_signature = <Element> (substitution Element - > String))] (load_expr implicit type = '[String]' location = re.swift: 16 : 16 range = [re.swift: 16 : 4 - line: 16 : 16 ] (member_ref_expr type = '@lvalue [String]' location = re.swift: 16 : 16 range = [re.swift: 16 : 4 - line: 16 : 16 ] decl = Swift.( file ).CommandLine.arguments (type_expr type = 'CommandLine.Type' location = re.swift: 16 : 4 range = [re.swift: 16 : 4 - line: 16 : 4 ] typerepr = 'CommandLine' ))))) (argument (integer_literal_expr type = 'Int' location = re.swift: 16 : 35 range = [re.swift: 16 : 35 - line: 16 : 35 ] value = 2 builtin_initializer = Swift.( file ). Int .init(_builtinIntegerLiteral:) initializer = * * NULL * * )) )) |
在往上是一个if语句,操作符是 >=(extension.>=),操作数一个是argument.count(),一个是2,所以这一块的意思就是比较命令行参数是否大于等于2
if CommandLine.arguments.count >= 2 { }
![图 4]
在往上就是top_level_code_decl,顶层表达式了,如图所示,这个程序真是由一个func_decl和一个top_level_code_decl组成,我们已经分析完了下面的top_level_code_decl:
func check(encoded: String, keyValue:String) -> Bool { } if CommandLine.arguments.count >= 2 { let data = CommandLine.arguments[1] let key = "345y" let result = check(encoded: data, keyValue: key) print(result) }
1 2 3 4 5 6 7 8 | (func_decl range = [re.swift: 1 : 1 - line: 14 : 1 ] "check(_:_:)" interface type = '(String, String) -> Bool' access = internal (parameter_list range = [re.swift: 1 : 11 - line: 1 : 49 ] (parameter "encoded" type = 'String' interface type = 'String' ) (parameter "keyValue" type = 'String' interface type = 'String' )) (result (type_ident (component id = 'Bool' bind = Swift.( file ). Bool ))) (brace_stmt range = [re.swift: 1 : 59 - line: 14 : 1 ] |
上方函数的大体结构为:参数,返回值和一个表达式
1 2 3 | (parameter_list range = [re.swift: 1 : 11 - line: 1 : 49 ] (parameter "encoded" type = 'String' interface type = 'String' ) (parameter "keyValue" type = 'String' interface type = 'String' )) |
参数分别为encoded和keyValue,都是String类型
1 2 3 | (result (type_ident (component id = 'Bool' bind = Swift.( file ). Bool ))) |
返回值为Bool类型
1 2 3 4 5 6 7 8 9 10 11 12 | (brace_stmt range = [re.swift: 1 : 59 - line: 14 : 1 ] (pattern_binding_decl range = [re.swift: 2 : 5 - line: 2 : 33 ] (var_decl range = [re.swift: 2 : 9 - line: 2 : 9 ] "b" type = '[UInt8]' interface type = '[UInt8]' access = private readImpl = stored writeImpl = stored readWriteImpl = stored) (pattern_binding_decl range = [re.swift: 3 : 5 - line: 3 : 34 ] (var_decl range = [re.swift: 3 : 9 - line: 3 : 9 ] "k" type = '[UInt8]' interface type = '[UInt8]' access = private readImpl = stored writeImpl = stored readWriteImpl = stored) (pattern_binding_decl range = [re.swift: 4 : 5 - line: 4 : 25 ] (var_decl range = [re.swift: 4 : 9 - line: 4 : 9 ] "r0" type = 'UInt8' interface type = 'UInt8' access = private readImpl = stored writeImpl = stored readWriteImpl = stored) (var_decl range = [re.swift: 4 : 13 - line: 4 : 13 ] "r1" type = 'UInt8' interface type = 'UInt8' access = private readImpl = stored writeImpl = stored readWriteImpl = stored) (var_decl range = [re.swift: 4 : 17 - line: 4 : 17 ] "r2" type = 'UInt8' interface type = 'UInt8' access = private readImpl = stored writeImpl = stored readWriteImpl = stored) (var_decl range = [re.swift: 4 : 21 - line: 4 : 21 ] "r3" type = 'UInt8' interface type = 'UInt8' access = private readImpl = stored writeImpl = stored readWriteImpl = stored) (for_each_stmt range = [re.swift: 5 : 5 - line: 12 : 5 ] (return_stmt range = [re.swift: 13 : 5 - line: 13 : 198 ] |
下方的语句块中又包含了3个定义变量的语句,1个for循环,1个返回语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | (pattern_binding_decl range = [re.swift: 2 : 5 - line: 2 : 33 ] (pattern_named type = '[UInt8]' 'b' ) Original init: (call_expr type = '[UInt8]' location = re.swift: 2 : 19 range = [re.swift: 2 : 13 - line: 2 : 33 ] nothrow (constructor_ref_call_expr type = '(String.UTF8View) -> [UInt8]' location = re.swift: 2 : 19 range = [re.swift: 2 : 13 - line: 2 : 19 ] nothrow (declref_expr implicit type = '(Array<UInt8>.Type) -> (String.UTF8View) -> Array<UInt8>' location = re.swift: 2 : 19 range = [re.swift: 2 : 19 - line: 2 : 19 ] decl = Swift.( file ).Array extension.init(_:) [with (substitution_map generic_signature = <Element, S where Element = = S.Element, S : Sequence> (substitution Element - > UInt8) (substitution S - > String.UTF8View))] function_ref = single) (argument_list implicit (argument (type_expr type = '[UInt8].Type' location = re.swift: 2 : 13 range = [re.swift: 2 : 13 - line: 2 : 19 ] typerepr = '[UInt8]' )) )) (argument_list (argument (member_ref_expr type = 'String.UTF8View' location = re.swift: 2 : 29 range = [re.swift: 2 : 21 - line: 2 : 29 ] decl = Swift.( file ).String extension.utf8 (declref_expr type = 'String' location = re.swift: 2 : 21 range = [re.swift: 2 : 21 - line: 2 : 21 ] decl = re.( file ).check(_:_:).encoded@re.swift: 1 : 14 function_ref = unapplied))) )) Processed init: (call_expr type = '[UInt8]' location = re.swift: 2 : 19 range = [re.swift: 2 : 13 - line: 2 : 33 ] nothrow |
第一个定义变量的语句,变量名为b,类型是一个[UInt8]数组,这个数组是由ebcoded(decl=re.(file).check(::).encoded@re.swift)转换过来的
var b = [UInt8](encoded.utf8)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | (pattern_binding_decl range = [re.swift: 3 : 5 - line: 3 : 34 ] (pattern_named type = '[UInt8]' 'k' ) Original init: (call_expr type = '[UInt8]' location = re.swift: 3 : 19 range = [re.swift: 3 : 13 - line: 3 : 34 ] nothrow (constructor_ref_call_expr type = '(String.UTF8View) -> [UInt8]' location = re.swift: 3 : 19 range = [re.swift: 3 : 13 - line: 3 : 19 ] nothrow (declref_expr implicit type = '(Array<UInt8>.Type) -> (String.UTF8View) -> Array<UInt8>' location = re.swift: 3 : 19 range = [re.swift: 3 : 19 - line: 3 : 19 ] decl = Swift.( file ).Array extension.init(_:) [with (substitution_map generic_signature = <Element, S where Element = = S.Element, S : Sequence> (substitution Element - > UInt8) (substitution S - > String.UTF8View))] function_ref = single) (argument_list implicit (argument (type_expr type = '[UInt8].Type' location = re.swift: 3 : 13 range = [re.swift: 3 : 13 - line: 3 : 19 ] typerepr = '[UInt8]' )) )) (argument_list (argument (member_ref_expr type = 'String.UTF8View' location = re.swift: 3 : 30 range = [re.swift: 3 : 21 - line: 3 : 30 ] decl = Swift.( file ).String extension.utf8 (declref_expr type = 'String' location = re.swift: 3 : 21 range = [re.swift: 3 : 21 - line: 3 : 21 ] decl = re.( file ).check(_:_:).keyValue@re.swift: 1 : 33 function_ref = unapplied))) )) Processed init: (call_expr type = '[UInt8]' location = re.swift: 3 : 19 range = [re.swift: 3 : 13 - line: 3 : 34 ] nothrow |
同上,接着定义一个变量k
var k = [UInt8](keyValue.utf8)
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 | (pattern_binding_decl range = [re.swift: 4 : 5 - line: 4 : 25 ] (pattern_typed type = 'UInt8' (pattern_named type = 'UInt8' 'r0' ) (type_ident (component id = 'UInt8' bind = Swift.( file ).UInt8))) (pattern_typed type = 'UInt8' (pattern_named type = 'UInt8' 'r1' ) (type_ident (component id = 'UInt8' bind = Swift.( file ).UInt8))) (pattern_typed type = 'UInt8' (pattern_named type = 'UInt8' 'r2' ) (type_ident (component id = 'UInt8' bind = Swift.( file ).UInt8))) (pattern_typed type = 'UInt8' (pattern_named type = 'UInt8' 'r3' ) (type_ident (component id = 'UInt8' bind = Swift.( file ).UInt8)))) (var_decl range = [re.swift: 4 : 9 - line: 4 : 9 ] "r0" type = 'UInt8' interface type = 'UInt8' access = private readImpl = stored writeImpl = stored readWriteImpl = stored) (var_decl range = [re.swift: 4 : 13 - line: 4 : 13 ] "r1" type = 'UInt8' interface type = 'UInt8' access = private readImpl = stored writeImpl = stored readWriteImpl = stored) (var_decl range = [re.swift: 4 : 17 - line: 4 : 17 ] "r2" type = 'UInt8' interface type = 'UInt8' access = private readImpl = stored writeImpl = stored readWriteImpl = stored) (var_decl range = [re.swift: 4 : 21 - line: 4 : 21 ] "r3" type = 'UInt8' interface type = 'UInt8' access = private readImpl = stored writeImpl = stored readWriteImpl = stored) |
接下来的语句块中定义了四个未初始化的变量r0, r1, r2, r3,类型是UInt8
var r0, r1, r2, r3:UInt8
1 2 3 4 5 6 7 | (dot_syntax_call_expr implicit type = '(Int, Int) -> ClosedRange<Int>' location = re.swift: 5 : 15 range = [re.swift: 5 : 15 - line: 5 : 15 ] nothrow (declref_expr type = '(Int.Type) -> (Int, Int) -> ClosedRange<Int>' location = re.swift: 5 : 15 range = [re.swift: 5 : 15 - line: 5 : 15 ] decl = Swift.( file ).Comparable extension.... [with (substitution_map generic_signature = <Self where Self : Comparable> (substitution Self - > Int ))] function_ref = double) (argument_list implicit (argument (type_expr implicit type = 'Int.Type' location = re.swift: 5 : 15 range = [re.swift: 5 : 15 - line: 5 : 15 ] typerepr = 'Int' )) )) (argument_list implicit |
可以看到(decl=Swift.(file).Comparable extension....),说明这是一个for-in循环
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | (argument (integer_literal_expr type = 'Int' location = re.swift: 5 : 14 range = [re.swift: 5 : 14 - line: 5 : 14 ] value = 0 builtin_initializer = Swift.( file ). Int .init(_builtinIntegerLiteral:) initializer = * * NULL * * )) (argument (binary_expr type = 'Int' location = re.swift: 5 : 25 range = [re.swift: 5 : 18 - line: 5 : 26 ] nothrow (dot_syntax_call_expr implicit type = '(Int, Int) -> Int' location = re.swift: 5 : 25 range = [re.swift: 5 : 25 - line: 5 : 25 ] nothrow (declref_expr type = '(Int.Type) -> (Int, Int) -> Int' location = re.swift: 5 : 25 range = [re.swift: 5 : 25 - line: 5 : 25 ] decl = Swift.( file ). Int extension. - function_ref = double) (argument_list implicit (argument (type_expr implicit type = 'Int.Type' location = re.swift: 5 : 25 range = [re.swift: 5 : 25 - line: 5 : 25 ] typerepr = 'Int' )) )) (argument_list implicit (argument (member_ref_expr type = 'Int' location = re.swift: 5 : 20 range = [re.swift: 5 : 18 - line: 5 : 20 ] decl = Swift.( file ).Array extension.count [with (substitution_map generic_signature = <Element> (substitution Element - > UInt8))] (load_expr implicit type = '[UInt8]' location = re.swift: 5 : 18 range = [re.swift: 5 : 18 - line: 5 : 18 ] (declref_expr type = '@lvalue [UInt8]' location = re.swift: 5 : 18 range = [re.swift: 5 : 18 - line: 5 : 18 ] decl = re.( file ).check(_:_:).b@re.swift: 2 : 9 function_ref = unapplied)))) (argument (integer_literal_expr type = 'Int' location = re.swift: 5 : 26 range = [re.swift: 5 : 26 - line: 5 : 26 ] value = 4 builtin_initializer = Swift.( file ). Int .init(_builtinIntegerLiteral:) initializer = * * NULL * * )) ))) |
循环的范围是从0到b.count-4
for i in 0...b.count-4 { }
![图 5]
紧跟着的是六条赋值语句
![图 6]
展开发现首尾的赋值语句格式相似,中间四条赋值语句格式相似,所以我们应该只需要仔细分析两种不同格式中的各一种
![图 7]
1 2 3 4 5 6 7 8 | (load_expr implicit type = 'UInt8' location = re.swift: 6 : 30 range = [re.swift: 6 : 29 - line: 6 : 32 ] (subscript_expr type = '@lvalue UInt8' location = re.swift: 6 : 30 range = [re.swift: 6 : 29 - line: 6 : 32 ] decl = Swift.( file ).Array extension.subscript(_:) [with (substitution_map generic_signature = <Element> (substitution Element - > UInt8))] (inout_expr implicit type = 'inout Array<UInt8>' location = re.swift: 6 : 29 range = [re.swift: 6 : 29 - line: 6 : 29 ] (declref_expr type = '@lvalue [UInt8]' location = re.swift: 6 : 29 range = [re.swift: 6 : 29 - line: 6 : 29 ] decl = re.( file ).check(_:_:).b@re.swift: 2 : 9 function_ref = unapplied)) (argument_list (argument (declref_expr type = 'Int' location = re.swift: 6 : 31 range = [re.swift: 6 : 31 - line: 6 : 31 ] decl = re.( file ).check(_:_:).i@re.swift: 5 : 9 function_ref = unapplied)) ))) |
这是第一个赋值语句的结构,做的事情是用b数组的值填充r0到r3
r0, r1, r2, r3 = b[i], b[i+1], b[i+2], b[i+3]
![图 8]
第二个赋值语句,首先是一个取下标,取的是b[i+0]
![图 9]
![图 10]
接着是一个运算语句块
![图 11]
初步看出是用r2异或一个表达式
该表达式是另一个表达式 & 0xff得到
![图 13]
接着又是加运算
一个是k[0]
![图 15]
一个是r0 >> 4
综上,第二个赋值语句:
b[i+0] = r2 ^ ((k[0] + (r0 >> 4)) & 0xff)
同理可以分析出接下来的几条赋值语句
b[i+1] = r3 ^ ((k[1] + (r1 >> 2)) & 0xff) b[i+2] = r0 ^ k[2] b[i+3] = r1 ^ k[3] k[0], k[1], k[2], k[3] = k[1], k[2], k[3], k[0]
for循环之后就是返回语句
![图 16]
返回语句由一条判断语句组成,操作符是==
![图 17]
第一个参数是b数组
![图 18]
第二个参数是一个给定的数组
[88, 35, 88, 225, 7, 201, 57, 94, 77, 56, 75, 168, 72, 218, 64, 91, 16, 101, 32, 207, 73, 130, 74, 128, 76, 201, 16, 248, 41, 205, 103, 84, 91, 99, 79, 202, 22, 131, 63, 255, 20, 16]
return (b == [88, 35, 88, 225, 7, 201, 57, 94, 77, 56, 75, 168, 72, 218, 64, 91, 16, 101, 32, 207, 73, 130, 74, 128, 76, 201, 16, 248, 41, 205, 103, 84, 91, 99, 79, 202, 22, 131, 63, 255, 20, 16])
re.swift
func check(encoded: String, keyValue:String) -> Bool { var b = [UInt8](encoded.utf8) var k = [UInt8](keyValue.utf8) var r0, r1, r2, r3:UInt8 for i in 0...b.count-4 { r0 = b[i] r1 = b[i+1] r2 = b[i+2] r3 = b[i+3] b[i+0] = r2 ^ ((k[0] + (r0 >> 4)) & 0xff) b[i+1] = r3 ^ ((k[1] + (r1 >> 2)) & 0xff) b[i+2] = r0 ^ k[2] b[i+3] = r1 ^ k[3] let temp = k[0] k[0] = k[1] k[1] = k[2] k[2] = k[3] k[3] = temp } return (b == [88, 35, 88, 225, 7, 201, 57, 94, 77, 56, 75, 168, 72, 218, 64, 91, 16, 101, 32, 207, 73, 130, 74, 128, 76, 201, 16, 248, 41, 205, 103, 84, 91, 99, 79, 202, 22, 131, 63, 255, 20, 16]) } if CommandLine.arguments.count >= 2 { let data = CommandLine.arguments[1] let key = "345y" let result = check(encoded: data, keyValue: key) print(result) }
解题脚本
1 2 3 4 5 6 7 8 9 10 11 | b = [ 88 , 35 , 88 , 225 , 7 , 201 , 57 , 94 , 77 , 56 , 75 , 168 , 72 , 218 , 64 , 91 , 16 , 101 , 32 , 207 , 73 , 130 , 74 , 128 , 76 , 201 , 16 , 248 , 41 , 205 , 103 , 84 , 91 , 99 , 79 , 202 , 22 , 131 , 63 , 255 , 20 , 16 ] k = [ 121 , 51 , 52 , 53 ] / / 换位后的key for i in range ( len (b) - 4 , - 1 , - 1 ): k[ 1 ], k[ 2 ], k[ 3 ], k[ 0 ] = k[ 0 ], k[ 1 ], k[ 2 ], k[ 3 ] r1 = k[ 3 ] ^ b[i + 3 ] r0 = k[ 2 ] ^ b[i + 2 ] r3 = ((k[ 1 ] + (r1 >> 2 )) & 0xff ) ^ b[i + 1 ] r2 = ((k[ 0 ] + (r0 >> 4 )) & 0xff ) ^ b[i] b[i], b[i + 1 ], b[i + 2 ], b[i + 3 ] = r0, r1, r2, r3 for i in b: print ( chr (i), end = '') |
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界