一些Reverse新生赛题目

一些简单的软件逆向,都是新生赛的题目

周二 10月 22 2024
975 字 · 8 分钟

0xgame题目

[Week 3] BabyASM

汇编语言,上网参考了好多资料。

汇编语言入门教程 - 阮一峰的网络日志

先声明了一个data数组。然后L3这里有一个循环,当计数器小于等于21时,就跳转L4

PLAINTEXT
L3:
    cmp    DWORD PTR [esp+28], 21
    jle    L4

L4执行操作的大意是把data中对应位置元素加上28

PLAINTEXT
add    eax, 28

之后进入L5,将22-42的元素进行异或(22对应0,类推)

最后附上解密脚本:

PYTHON
# 定义初始数据
data = [
    20, 92, 43, 69, 81, 73, 95, 23, 72, 22, 24, 69,
    25, 27, 22, 17, 23, 29, 24, 73, 17, 24, 85, 27,
    112, 76, 15, 92, 24, 1, 73, 84, 13, 81, 12, 0,
    84, 73, 82, 8, 82, 81, 76, 125]

# 第一个循环:将前22个字节加28
for i in range(0,22):
    data[i] += 28

# 第二个循环:对接下来的22个字节进行异或操作
for i in range(22, 43):  # 从22到42
    data[i] ^= data[i - 22]  # 异或当前字节与22个前的字节

# 将字节转换为字符并打印
output = ''.join(chr(byte) for byte in data)
print("最终结果:")
print(output)

[Week 3] LittlePuzzle

使用cfr-0.152.jar反编译

JAVA
/*
 * Decompiled with CFR 0.152.
 */
import java.util.Scanner;

public class Puzzle {
    static int[][] board = new int[][]{{5, 7, 0, 9, 4, 0, 8, 0, 0}, {0, 0, 8, 0, 3, 0, 0, 0, 5}, {0, 1, 0, 2, 0, 0, 0, 3, 7}, {0, 0, 9, 7, 2, 0, 0, 0, 0}, {7, 3, 4, 0, 0, 8, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 7, 5, 1}, {3, 0, 0, 0, 1, 4, 2, 0, 0}, {0, 6, 0, 0, 0, 2, 0, 4, 0}, {0, 2, 7, 0, 0, 9, 5, 0, 0}};

    public static void exit() {
        System.out.println("\u89e3\u8c1c\u5931\u8d25");
        System.exit(1);
    }

    public static boolean check(int n, int n2) {
        int n3;
        int n4 = board[n][n2];
        int n5 = n - n % 3;
        int n6 = n2 - n2 % 3;
        for (n3 = 0; n3 < 9; ++n3) {
            if (n3 == n || n3 == n2 || n4 != board[n][n3] && n4 != board[n3][n2]) continue;
            return false;
        }
        for (n3 = 0; n3 < 3; ++n3) {
            for (int i = 0; i < 3; ++i) {
                if (n5 + n3 == n || n6 + i == n2 || n4 != board[n5 + n3][n6 + i]) continue;
                return false;
            }
        }
        return true;
    }

    static String flag(String string) {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < string.length(); i += 6) {
            int n = Integer.parseInt(string.substring(i, i + 6));
            stringBuilder.append(Integer.toHexString(n));
        }
        return stringBuilder.toString();
    }

    public static void main(String[] stringArray) {
        int n;
        int n2;
        System.out.println("\u8bf7\u8f93\u5165\u4f60\u7684\u89e3\u8c1c\u7ed3\u679c:");
        Scanner scanner = new Scanner(System.in);
        String string = scanner.nextLine();
        scanner.close();
        if (string.length() != 48) {
            Puzzle.exit();
        }
        int n3 = 0;
        for (n2 = 0; n2 < 9; ++n2) {
            for (n = 0; n < 9; ++n) {
                if (board[n2][n] != 0) continue;
                int n4 = string.charAt(n3) - 48;
                if (n4 > 0 && n4 <= 9) {
                    Puzzle.board[n2][n] = n4;
                    ++n3;
                    continue;
                }
                Puzzle.exit();
            }
        }
        for (n2 = 0; n2 < 9; ++n2) {
            for (n = 0; n < 9; ++n) {
                if (Puzzle.check(n2, n)) continue;
                Puzzle.exit();
            }
        }
        System.out.println(String.format("0xGame{%s}", Puzzle.flag(string)));
    }
}

chatgpt问了一遍后发现这是数独游戏,在线找个解密器即可

BuildCTF

pyc

PyLingual即可反编译,得到源文件之后对应加密写一个decode函数即可。

PYTHON
def decode(message):
    s = base64.b64decode(message)
    decoded_message = ''
    for byte in s:
        # Reverse the encoding steps
        x = byte - 16
        if x < 0:
            x += 256
        x = x ^ 32
        decoded_message += chr(x)
    return decoded_message

晴窗细乳戏分茶

程序采用了TEA加密算法,逆向操作进行解密就行,但是好像遇到一个问题是用python写的解密脚本运行是错误的,好像因为原程序使用的是uint32_t,使用python脚本会导致数据非常大,但是C语言写会因为溢出等原因出来正确数据

用c语言写的程序可以跑起来

第一部分:

PYTHON
#include <stdio.h>
#include <stdint.h>
#include <string.h>

void decrypt(uint32_t *v, uint32_t *k) {
    uint32_t sum = -1640531527 * 32;
    uint32_t v0 = v[0];
    uint32_t v1 = v[1];

    for (int i = 0; i < 32; ++i) {
        v1 -= (v0 + sum) ^ (16 * v0 + k[2]) ^ ((v0 >> 5) + k[3]);
        v0 -= (v1 + sum) ^ (16 * v1 + k[0]) ^ ((v1 >> 5) + k[1]);
        sum += 1640531527;
    }
    v[0] = v0;
    v[1] = v1;
}

void to_string(uint32_t v0, uint32_t v1, char *output) {
    uint32_t values[2] = {v0, v1};
    memcpy(output, values, sizeof(values));
    output[8] = '\0'; 
}

int main() {
    uint32_t enc[6] ;
    enc[0] = -1559465970;
    enc[1] = -158607645;
    enc[2] = -1059812880;
    enc[3] = 314506021;
    enc[4] = -2131835469;
    enc[5] = 731233488;
    uint32_t key[4] = {1646625, 164438, 164439, 2631985};
    uint32_t ena[2];
    for(int a=0;a<6;a+=2){
        ena[0] = enc[a];
        ena[1] = enc[a+1];
        decrypt(ena, key);
        char result[9]; 
        to_string(ena[0], ena[1], result);
        printf("%s", result);
    }

}

第二部分同理


Thanks for reading!

一些Reverse新生赛题目

周二 10月 22 2024
975 字 · 8 分钟