逆向ctf-亦步亦趋

一、题目来源介绍

题目来源于看雪论坛CTF题库->题目要求为:

        本题Flag值为123456用户的序列号。

二、解题过程

万事不要慌,先把软件运行起来康康:

哟呵!这是需要破解的节奏呀!!!由于是exe文件,首先使用exeinfope检查是否存在壳的现象:

查壳工具表明,软件不存在加壳操作。从题目查找序列号可以了解到,解题方法相当于破解该软件,那就上道具,开启OD整起来,一路F8干就完事了。遇到弹窗不要慌(因为题目要求123456用户序列号,所以Username就是123456),下断点并重新运行再F9直到:

CompareStringA()这个函数,传入值为我们自己的序列号以及通过用户名(123456)生成的序列号,做对比相同就注册成功,反之失败。进入函数后就会发现我们想要的答案了:

结果一目了然,明显的是用户123456的序列号为894904543,当然这也是本题的Flag。

三、算法原理解释

算法是这样的:
    先把用户名的第一位去掉,再在用户名最后加一个ASCII码为0的字符组成新的字符串s1然后再进入下面的四步运算.
    第一步,ASCII码AA,89,C4,FE,46加到新字符串s1头部组成字符串s2,S1与S2各位异或得s3
    第二步,S3尾部加E7,03,D0,F0,78组成S4,S4与S3各位异或得S5
    第三步,F7,FD,F4,E7,B9加到S5头部得S6,S6与S5各位异或得S7
    第四步,S7尾部加B5,1B,C9,50,73组成S8,S8与S7各位异或得S9
做完这四步后,最后得到S9,再把S9的第一,五,九...位相加放到第一位,第二,六,十...位相加放到第二位,第三,七,十一...位相加放到第三位,第四,八,十二...位相加放到第四位,这样最后得到长度为四的字符串S10,再把S10的ASCII码看成是一个32位的无符号整数,转化为10进制数就得到注册码了.

四、注册机代码

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

int main()
{
    unsigned char a[40] = {0xAA,
                     0x89, 0xC4, 0xFE, 0x46, 0x78, 0xF0, 0xD0, 0x03, 0xE7, 0xF7, 0xFD, 0xF4, 0xE7, 0xB9, 0xB5, 0x1B,
                     0xC9, 0x50, 0x73, 0x00, 0x48, 0x90, 0x25, 0x00, 0xDC, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };

    char temp[10] = "qwer";
    unsigned char user[10];
    int userLen = strlen(temp);
    int index = 0;
    unsigned int res;
    unsigned char ch;

    for(int i=0; i<userLen; i++)
        user[i] = (unsigned char) temp[i];
    user[userLen] = '\0';

    index = 0;
    for(int i=1; i<=userLen; i++)
    {
        ch = user[i];
        user[i] ^= a[index];
        a[index] = ch;
        index++;
        if(index>=5)
            index -= 5;
    }

    index = 5;
    for(int i=userLen; i>0; i--)
    {
        ch = user[i];
        user[i] ^= a[index];
        a[index] = ch;
        index++;
        if(index>=10)
            index -= 5;
    }

    index = 10;
    for(int i=1; i<=userLen; i++)
    {
        ch = user[i];
        user[i] ^= a[index];
        a[index] = ch;
        index++;
        if(index>=15)
            index -= 5;
    }

    index = 15;
    for(int i=userLen; i>0; i--)
    {
        ch = user[i];
        user[i] ^= a[index];
        a[index] = ch;
        index++;
        if(index>=20)
            index -= 5;
    }

    for(int i=1; i<=4; i++)
    {
        for(int j=i+4; j<=userLen; j+=4)
            user[i] += user[j];
    }

    res = (user[4]<<24) + (user[3]<<16) + (user[2]<<8) + user[1];
    printf("%u\n", res);

    return 0;
}

OVER!!!!!!!

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值