reverse学习

一.[Zer0pts2020]easy strcmp

[Zer0pts2020]easy strcmp 分析与加法-CSDN博客

BUUCTF之[Zer0pts2020]easy strcmp(详细教程)-CSDN博客

无壳,进入ida看到了,大致看了看

CENSORED”通常表示某些内容被审查、屏蔽或删除了。在不同的语境中,其具体含义可能有所不同,但总体上是指对信息、媒体或通信等进行限制或控制,以隐藏某些被认为不合适、敏感或违反规定的内容。

我们一直找,看到了关键处,这里只分析代码的写法

在密码学和数据处理中,当我们讨论块相加(如64位块)和逐字节相加时,是否需要进位取决于具体的操作和上下文。以下是两种情况的详细解释:

1. 块相加(如64位块)

在处理64位块时,通常不需要显式考虑进位,因为64位加法是按照模 264 进行的。这意味着当加法结果超过64位能表示的最大值时,结果会自动回绕(wrap around)。这种操作称为模 264 加法,常见于加密算法中,如AES。

例如,如果你有两个64位的数 A 和 B,它们的和 S=A+B 如果超过了 264−1(64位能表示的最大值),则结果 S 会回绕到 Smod264。

2. 逐字节相加

当逐字节进行加法时,通常需要考虑进位。这是因为每个字节是8位的,最大能表示的值是255(28−1)。如果两个字节相加的结果超过了255,就需要将超出的部分进位到下一个更高的字节。

例如,考虑两个字节 a 和 b,它们的和 s=a+b。如果 s>255,则需要将 s 减去256,并将1进位到下一个更高的字节。

所以在得到了两个数组的时候,我们可以块相加写代码,分析逻辑

#include <stdio.h>
#include<stdint.h>
#include<string.h>
int main() {
	char fake[] = { "zer0pts{********CENSORED********}" };
	unsigned char flag[50];
	uint64_t key[] = { 0LL, 4686632258374338882LL, 796841318371695088LL, 5695428477452625963LL, 0LL };
	for (int i = 0; i < strlen(fake) / 8; i++)
	{
		*(uint64_t*)&(fake[i * 8]) += key[i];
	}
	printf("%s", fake);
	return 0;
}

块相加操作逻辑

  1. 循环处理

    • for (int i = 0; i < strlen(fake) / 8; i++):循环遍历 fake 数组,每次处理8个字节(64位)。循环次数由 fake 的长度决定,除以8是因为每次处理64位(8字节)。

  2. 类型转换和加法操作

    • *(uint64_t*)&(fake[i * 8]) += key[i];:这行代码执行以下操作:

      • &(fake[i * 8]):获取 fake 数组中第 i * 8 个字节的地址。

      • (uint64_t*):将该地址转换为 uint64_t 类型的指针。

      • *(uint64_t*)&(fake[i * 8]):解引用该指针,获取指向的64位整数。

      • += key[i]:将 key 数组中对应索引的值加到这个64位整数上。

也可以单个相加,但是要加上进位

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

int main()
{	
    char flag[] = "********CENSORED********"; // È·±£Õâ¸ö×Ö·û´®ÖÁÉÙÓÐ24¸ö×Ö·û
    int enc[] = { 0x42, 0x09, 0x4A, 0x49, 0x35, 0x43, 0x0A, 0x41, 0xF0, 0x19, 0xE6, 0x0B, 0xF5, 0xF2, 0x0E, 0x0B, 0x2B, 0x28, 0x35, 0x4A, 0x06, 0x3A, 0x0A, 0x4F };
    int t = 0;

    for (int j = 0; j < 24; ++j)
    {
        int sum = (flag[j] + enc[j] + t) % 256; // È·±£½á¹ûÔÚ0-255·¶Î§ÄÚ
        flag[j] = sum;
        t = (flag[j] + enc[j]+t) / 256; // ¼ÆËã½øλ
        printf("%c", flag[j]);
    }	
    return 0;
}

单个相加循环逻辑

  1. 循环条件for (int j = 0; j < 24; ++j)。循环24次,每次处理 flagenc 数组中的一个字符。

  2. 字符相加

    • int sum = (flag[j] + enc[j] + t) % 256;:将 flag 数组中的第 j 个字符、enc 数组中的第 j 个值和进位值 t 相加,然后取模256。这确保了结果在0到255的范围内,即有效的ASCII字符范围内。

    • flag[j] = sum;:将计算结果存储回 flag 数组的第 j 个位置。

  3. 进位计算

    • t = (flag[j] + enc[j]+t) / 256;:计算进位值。如果 flag[j] + enc[j]+t 的和大于255,则进位值为 ((flag[j] + enc[j]+t) / 256) 的整数部分。

二.[BJDCTF2020]BJD hamburger competition

是unity逆向,需要用到ILSpy

关键处

\TPH\TPH_Data\Managed\Assembly-CSharp.dll

我们用ILSpy打开

之后根据游戏查找关键函数处

合理猜测是正确的配方才可以得到flag

这个函数名"生成水果按钮"和右面的Md5和Sha1是和hash函数有关的,我们分析一下

是有一个密文,通过Sha-1和已知哈希值相等,让后把密文进行Md5操作转成字符串当做result即flag

我们找网站解决

但是我这个sha-1的哈希值也用md5的解密出来了,挺巧的,不管了,我们再得到Md5哈希值

得到了字符串,我们尝试提交flag但是不对,我们仔细查看代码分析

其中的Md5代码中

  • ToString("X2") 方法将字节转换为两位十六进制字符串,并且因为是大写的"X"所以结果是大写的
  • Substring(0, 20) 方法截取前20个字符作为结果。MD5 哈希值通常表示为32个字符的十六进制字符串,但这里只截取了前20个字符

因为我们知道他正常是32字符所以不会出现0XA转成0X0A这样的,所以我们直接取前20位即可

flag{B8C37E33DEFDE51CF91E}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值