re学习笔记(74)BUUCTF - re - [安洵杯 2019]game

[安洵杯 2019]game

ollvm混淆
直接贴上分析后的代码了

unsigned int sudoku[81] = {
    1, 4, 5, 3, 2, 7, 6, 9, 
    8, 8, 3, 9, 6, 5, 4, 1, 
    2, 7, 6, 7, 2, 8, 1, 9, 
    5, 4, 3, 4, 9, 6, 1, 8, 
    5, 3, 7, 2, 2, 1, 8, 4, 
    7, 3, 9, 5, 6, 7, 5, 3, 
    2, 9, 6, 4, 8, 1, 3, 6, 
    7, 5, 4, 2, 8, 1, 9, 9, 
    8, 4, 7, 6, 1, 2, 3, 5, 
    5, 2, 1, 9, 3, 8, 7, 6, 
    4
};
unsigned int D0g3[81] = {
    1, 0, 5, 3, 2, 7, 0, 0, 8,
    8, 0, 9, 0, 5, 0, 0, 2, 0, 
    0, 7, 0, 0, 1, 0, 5, 0, 3, 
    4, 9, 0, 1, 0, 0, 3, 0, 0, 
    0, 1, 0, 0, 7, 0, 9, 0, 6, 
    7, 0, 3, 2, 9, 0, 4, 8, 0, 
    0, 6, 0, 5, 4, 0, 8, 0, 9, 
    0, 0, 4, 0, 0, 1, 0, 3, 0,
    0, 2, 1, 0, 3, 0, 7, 0, 4
};
int main(){
    printf("input your flag:");
    gets(v8, argv);
    v10 = general_inspection((int (*)[9])sudoku); // 不知道什么东西
    if(!v10){
        v7 = blank_num((int (*)[9])sudoku);
        v4 = mem_alloc(v7); // 申请相应的空间
        trace((__int64)sudoku, (int *)v4, v7);  // 对sudoku数组进行修改
        // check((int (*)[9])sudoku);   //无用操作
        check1(v8);
        check3(v8);
    }
    else
    {
        printf("error");
        check((int (*)[9])sudoku);
    }
    return 0;

}
int check(int (*a1)[9])
{
    for(v6=0;v6<9;v6++){
        for(v5=0;v5<9;v5++){
            // 无用操作
        }
    }
}
/**
 * 对输入
 * 前半段和后半段进行交换
 * 每两个字符 交换
 * 对每个字符进行变换
 **/
int check1(char* s)
{
    len = strlen(s);
    int i,j;
    for(i=0,j = len/2;i<len/2;i++,j++){
        temp = s[j];
        s[j] = s[i];
        s[i] = temp;
    }
    for(j=0;j<len;j+=2){
        temp = s[j];
        s[j] = s[j+1];
        s[j+1]= temp;
    }
    for(j=0;j<len;j++){
        s[j] = (s[j] & 0xF3 | ~s[j] & 0xC) - 20;
    }
}
int check3(char* a1)
{
    if(! check2(a1))
    {
        printf("error!\n");
    }else
    {
        printf("you get it!\n");
    }
}

/**
 * 将输入填入空并比较
 */
int check2(char* a1)
{
    s = a1;
    i = 0;
    j = 0;
    k = 0;
    for(i=0;i<strlen(s);i++){
        // 将字符数字转换为数字
        v16[i] = s[i]-48;
    }
    printf("\n");
    for(i=0;i<9;i++){
        for(j=0;j<9;j++){
            // 如果数据中为空,就把输入字符填进去
            if(!D0g3[9*15+j]){
                D0g3[9 * i + j] = v16[k++];
            }
        }
    }
    for(i = 0;i<9;i++){
        for(j = 0;j<9;++j){
            // 进行比较
            if(D0g3[9 * i + j] != sudoku[9 * i + j]){
                return 0;
            }
        }
    }
    return 1;
}
/**
 * 数出sudoku数独数组的空位置(==0)有多少
 * 并返回
 **/
int blank_num(int (*a1)[9])
{
    num = 0;
    i = 0;
    for(i=0;i<9;++i){
        for(j=0;j<9;++j){
            if( !(*a1)[9 * i + j] ) ++num;
        }
    }
    return num;
}

解题脚本

#include <stdio.h>
#include <string.h>
unsigned int sudoku[81] = {
    1, 4, 5, 3, 2, 7, 6, 9,
    8, 8, 3, 9, 6, 5, 4, 1,
    2, 7, 6, 7, 2, 8, 1, 9,
    5, 4, 3, 4, 9, 6, 1, 8,
    5, 3, 7, 2, 2, 1, 8, 4,
    7, 3, 9, 5, 6, 7, 5, 3,
    2, 9, 6, 4, 8, 1, 3, 6,
    7, 5, 4, 2, 8, 1, 9, 9,
    8, 4, 7, 6, 1, 2, 3, 5,
    5, 2, 1, 9, 3, 8, 7, 6,
    4
};
unsigned int D0g3[81] = {
    1, 0, 5, 3, 2, 7, 0, 0, 8,
    8, 0, 9, 0, 5, 0, 0, 2, 0,
    0, 7, 0, 0, 1, 0, 5, 0, 3,
    4, 9, 0, 1, 0, 0, 3, 0, 0,
    0, 1, 0, 0, 7, 0, 9, 0, 6,
    7, 0, 3, 2, 9, 0, 4, 8, 0,
    0, 6, 0, 5, 4, 0, 8, 0, 9,
    0, 0, 4, 0, 0, 1, 0, 3, 0,
    0, 2, 1, 0, 3, 0, 7, 0, 4
};
int dec(char* s) {
    int len = strlen(s);
    int i, j,temp;
    for (j = 0; j < len; j++) {
        s[j] += 20;
        s[j] = (s[j] & 0xF3 | ~s[j] & 0xC); //可逆操作
    }
    for (j = 0; j < len; j += 2) {
        temp = s[j];
        s[j] = s[j + 1];
        s[j + 1] = temp;
    }
    for (i = 0, j = len / 2; i < len / 2; i++, j++) {
        temp = s[j];
        s[j] = s[i];
        s[i] = temp;
    }
    return 0;
}
int main() {
    int i, j;
    char flag[41] = { 0 };
    char ch;
    for (i = 0, j = 0; i < 81; ++i)
    {
        if (D0g3[i] == 0)
            flag[j++] = sudoku[i]+'0';
    }
    dec(flag);
    puts(flag);
    // KDEEIFGKIJ@AFGEJAEF@FDKADFGIJFA@FDE@JG@J
}

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Forgo7ten

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值