华为仓颉语言逆向加密进阶分析
字数 1191 2025-08-22 12:22:30

华为仓颉编程语言加密算法逆向分析教程

一、前言

本教程将深入分析使用华为仓颉编程语言实现的两种加密算法:基于二叉树的加密和凯撒加密。我们将从源码分析、逆向工程角度全面剖析这两种加密算法的实现原理,并提供完整的解密方法。

二、基于二叉树的加密算法分析

1. 加密流程概述

该加密算法将输入字符串分为7段,每段4个字符,分别应用不同的加密规则:

  1. 第一段:每个字符加1
  2. 第二段:每个字符与2异或
  3. 第三段:每个字符减1
  4. 第四段:每个字符加10
  5. 第五段:每个字符减10
  6. 第六段:每个字符与2异或
  7. 第七段:每个字符与5异或

2. 逆向分析关键点

IDA分析要点:

  • 主函数未经符号处理,可直接定位
  • 重点关注std.core::StringBuilder::append调用
  • 注意ZN8std_core5ArrayIh2__El函数调用,表明处理的是数字数组
  • 代码结构臃肿但规律性强,主要关注循环和运算部分

关键逆向技巧:

  1. 切片识别:输入被分为7段,每段4个字符
  2. 运算识别
    • v32 ^ 2u:异或运算
    • v34 + 10:加法运算
    • v35 - 10:减法运算
  3. 二叉树结构:加密后的数据被组织为二叉树结构,遍历顺序为C→D→B→A→F→E→G

3. 解密算法实现

def decrypt_char(char, operation):
    if operation == 1:  # 第一段:加1→减1
        return char - 1
    elif operation == 2:  # 第二段:异或2→再次异或2
        return char ^ 2
    elif operation == 3:  # 第三段:减1→加1
        return char + 1
    elif operation == 4:  # 第四段:加10→减10
        return char - 10
    elif operation == 5:  # 第五段:减10→加10
        return char + 10
    elif operation == 6:  # 第六段:异或2→再次异或2
        return char ^ 2
    elif operation == 7:  # 第七段:异或5→再次异或5
        return char ^ 5

# 示例密文
encrypted_data = [
    [119, 48, 104, 48],  # 第一段
    [115, 111, 123, 58], # 第二段
    [121, 109, 104, 102], # 第三段
    [71, 77, 66, 72],    # 第四段
    [97, 115, 105, 108], # 第五段
    [109, 110, 96, 90],  # 第六段
    [114, 52, 100, 120]  # 第七段
]

# 解密并重组(注意二叉树遍历顺序)
decrypted_parts = []
for i, data in enumerate(encrypted_data):
    decrypted = [chr(decrypt_char(c, i+1)) for c in data]
    decrypted_parts.append(''.join(decrypted))

# 按二叉树遍历顺序重组:3→4→2→1→6→5→7
final_flag = (decrypted_parts[2] + decrypted_parts[3] + decrypted_parts[1] + 
              decrypted_parts[0] + decrypted_parts[5] + decrypted_parts[4] + 
              decrypted_parts[6])
print(final_flag)

4. 仓颉源码分析

import std.console.*
import std.collection.*
import std.convert.*
import std.random.*

// 二叉树节点定义
func node(value: String, left!Unit = {=>}, right!Unit = {=>}) {
    left()
    var inputtest = Array(value)
    print("${inputtest}")
    right()
}

// 加密逻辑
var inputchar = Array(input)
var str1 = StringBuilder("")  // 加1
var str2 = StringBuilder("")  // 异或2
var str3 = StringBuilder("")  // 减1
var str4 = StringBuilder("")  // 加10
var str5 = StringBuilder("")  // 减10
var str6 = StringBuilder("")  // 异或2
var str7 = StringBuilder("")  // 异或5

// 分段处理
for (i in 0..4) { str1.append(Rune(inputchar[i]+1)) }
for (i in 4..8) { str2.append(Rune(inputchar[i]^2)) }
for (i in 8..12) { str3.append(Rune(inputchar[i]-1)) }
for (i in 12..16) { str4.append(Rune(inputchar[i]+10)) }
for (i in 16..20) { str5.append(Rune(inputchar[i]-10)) }
for (i in 20..24) { str6.append(Rune(inputchar[i]^2)) }
for (i in 24..28) { str7.append(Rune(inputchar[i]^5)) }

// 构建二叉树并遍历
let tree = node(str1, 
    left: node(str2, 
        left: node(str3, 
            right: node(str4)
        )
    ), 
    right: node(str5, 
        left: node(str6), 
        right: node(str7)
    )
)
tree()

三、凯撒加密算法分析

1. 加密原理

凯撒加密使用固定偏移量(shift=10)对字母进行位移:

  • 大写字母(65-90):(char - 65 + shift) % 26 + 65
  • 小写字母(97-122):(char - 97 + shift) % 26 + 97
  • 其他字符保持不变

2. 逆向分析要点

  • 在IDA中可识别固定偏移量shift=10
  • 注意ASCII范围检查(65-90和97-122)
  • 解密时使用反向位移或26-shift(即16)

3. 解密算法实现

def caesar_decrypt(encrypted, shift=10):
    decrypted = []
    for char in encrypted:
        c = ord(char)
        if 65 <= c <= 90:  # 大写字母
            decrypted.append(chr((c - 65 - shift) % 26 + 65))
        elif 97 <= c <= 122:  # 小写字母
            decrypted.append(chr((c - 97 - shift) % 26 + 97))
        else:  # 其他字符不变
            decrypted.append(char)
    return ''.join(decrypted)

# 示例
encrypted = "rovk{ykqck}"
print(caesar_decrypt(encrypted))  # 输出: flag{kaisa}

4. 仓颉源码分析

import std.console.*
import std.collection.*
import std.convert.*
import std.random.*

main() {
    print("plz input flag")
    var input = "flag{kaisa}"
    var inputchar = Array(input)
    var plaintext = StringBuilder("")
    var shift = 10u8
    
    for (char in inputchar) {
        if (char >= 65 && char <= 90) {  // 大写字母
            plaintext.append(Rune(((char - 65 + shift) % 26) + 65))
        } else if (char >= 97 && char <= 122) {  // 小写字母
            plaintext.append(Rune(((char - 97 + shift) % 26) + 97))
        } else {  // 其他字符
            plaintext.append(Rune(char))
        }
    }
    print(plaintext)
}

四、逆向工程技巧总结

  1. 符号分析

    • 未去符号的二进制可直接定位关键函数
    • 注意std.core::StringBuilder::append等标准库函数调用
  2. 加密模式识别

    • 查找循环结构(如while循环)
    • 识别数学运算(异或、加减等)
    • 注意数据分段处理模式
  3. 动态调试技巧

    • 使用测试输入(如"flag{123...}")观察处理过程
    • 跟踪中间值变化验证加密逻辑
  4. 仓颉语言特点

    • 类似Python的高层次语法
    • 大量使用标准库(std.core等)
    • 二叉树等数据结构实现方式独特

五、总结

本教程详细分析了华为仓颉语言实现的两种加密算法,提供了完整的逆向分析和解密方法。关键点包括:

  1. 二叉树加密的7段不同加密规则
  2. 凯撒加密的固定位移模式
  3. 逆向工程中的模式识别技巧
  4. 仓颉语言的特定语法和结构特点

掌握这些加密算法的逆向分析方法,不仅有助于理解仓颉语言的实现细节,也能提升对类似加密方案的逆向能力。

华为仓颉编程语言加密算法逆向分析教程 一、前言 本教程将深入分析使用华为仓颉编程语言实现的两种加密算法:基于二叉树的加密和凯撒加密。我们将从源码分析、逆向工程角度全面剖析这两种加密算法的实现原理,并提供完整的解密方法。 二、基于二叉树的加密算法分析 1. 加密流程概述 该加密算法将输入字符串分为7段,每段4个字符,分别应用不同的加密规则: 第一段:每个字符加1 第二段:每个字符与2异或 第三段:每个字符减1 第四段:每个字符加10 第五段:每个字符减10 第六段:每个字符与2异或 第七段:每个字符与5异或 2. 逆向分析关键点 IDA分析要点: 主函数未经符号处理,可直接定位 重点关注 std.core::StringBuilder::append 调用 注意 ZN8std_core5ArrayIh2__El 函数调用,表明处理的是数字数组 代码结构臃肿但规律性强,主要关注循环和运算部分 关键逆向技巧: 切片识别 :输入被分为7段,每段4个字符 运算识别 : v32 ^ 2u :异或运算 v34 + 10 :加法运算 v35 - 10 :减法运算 二叉树结构 :加密后的数据被组织为二叉树结构,遍历顺序为C→D→B→A→F→E→G 3. 解密算法实现 4. 仓颉源码分析 三、凯撒加密算法分析 1. 加密原理 凯撒加密使用固定偏移量(shift=10)对字母进行位移: 大写字母(65-90): (char - 65 + shift) % 26 + 65 小写字母(97-122): (char - 97 + shift) % 26 + 97 其他字符保持不变 2. 逆向分析要点 在IDA中可识别固定偏移量shift=10 注意ASCII范围检查(65-90和97-122) 解密时使用反向位移或26-shift(即16) 3. 解密算法实现 4. 仓颉源码分析 四、逆向工程技巧总结 符号分析 : 未去符号的二进制可直接定位关键函数 注意 std.core::StringBuilder::append 等标准库函数调用 加密模式识别 : 查找循环结构(如while循环) 识别数学运算(异或、加减等) 注意数据分段处理模式 动态调试技巧 : 使用测试输入(如"flag{123...}")观察处理过程 跟踪中间值变化验证加密逻辑 仓颉语言特点 : 类似Python的高层次语法 大量使用标准库(std.core等) 二叉树等数据结构实现方式独特 五、总结 本教程详细分析了华为仓颉语言实现的两种加密算法,提供了完整的逆向分析和解密方法。关键点包括: 二叉树加密的7段不同加密规则 凯撒加密的固定位移模式 逆向工程中的模式识别技巧 仓颉语言的特定语法和结构特点 掌握这些加密算法的逆向分析方法,不仅有助于理解仓颉语言的实现细节,也能提升对类似加密方案的逆向能力。