2022HGAME中REVERSE的creakme2

99 篇文章 33 订阅

2022HGAME中REVERSE的creakme2

下载附件:
在这里插入图片描述
.
.
照例扔入 exeinfope 中查看信息:
在这里插入图片描述
.
.
照例扔入 IDA64 中查看伪代码,有 main 函数看 main 函数:
在这里插入图片描述
在这里插入图片描述
.
.
F5 未生成的异常与回调函数处理:
但是常规的 XTEA 解密算法并不对,一开始怀疑题目错了,果然还是自己太菜了,出人意料的结果都是表明中间存在未分析的操作啊!
(这里是除 0 异常和异常处理回调函数,虽然不知道那里限定了 loc_140001141 就是回调函数)
在这里插入图片描述
在这里插入图片描述

.
.
修改一下 XTEA 加密算法拿到 sum 的值先:

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

void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]){
	unsigned int i;
	uint32_t v0=v[0],v1=v[1],sum=0,delta=0x9E3779B1;
	for(i=0;i<num_rounds;i++){
		v0+=(((v1<<4)^(v1>>5))+v1)^(sum+key[sum&3]);
		sum+=delta;
		if(sum>>31==0)
		sum^=0x1234567;
		v1+=(((v0<<4)^(v0>>5))+v0)^(sum+key[(sum>>11)&3]);
	}
	v[0]=v0;v[1]=v1;
	printf("%x\n",sum);
	printf("%lu\n",sum);
	printf("%d",sum);
}



int main(){
	uint32_t v[2]={1,2};
	uint32_t const k[4]={2,2,3,4};
	unsigned int r=32;				//这里是加密轮数,自己设置 
	printf("加密前原始数据:%u %u\n",v[0],v[1]);
	encipher(r,v,k);

	return 0;
}

在这里插入图片描述
.
.
拿到 sum 值后编写解密代码:

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

void decrypt (uint32_t* v, uint32_t* k) {
    uint32_t v0=v[0], v1=v[1], sum=-946975483, i;  //这里的sum=32*delta,但是注意溢出的截取,否则就错了 
    uint32_t delta=0x9E3779B1;                   
    //uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   
    for (i=0; i<32; i++) {                        
	//v1-=(((v0<<4)^(v0>>5))+v0)^(sum+k[4*((sum>>11)&3)]);
	v1-=(((v0<<4)^(v0>>5))+v0)^(sum+k[(sum>>11)&3]);
		if (sum >> 31 == 0)
			sum ^= 0x1234567;
	sum-=delta;
	//v0-=(((v1<<4)^(v1>>5))+v1)^(sum+k[4*(sum&3)]);,IDA 的地址都是单个的,对于 DWORD 类型要 IDA 会自己乘以 4,形成我们看到的 *(DWORD)(a3+4*i),而不像我们C语言中直接的 (a3+i) 就是跨越 a3 大小类型的 i 
	v0-=(((v1<<4)^(v1>>5))+v1)^(sum+k[sum&3]);
    } 
    v[0]=v0; v[1]=v1;
}
 
int main()
{
    uint32_t v[4][2]={{1165910735,-1791522452},{528383858,-140479528},{-1902548888,1085255577},{261688884,426721414}};
	//uint32_t k[10]={1,2,3,4,5,6,7,8,9,0};
	uint32_t k[4]={1,2,3,4};//虽然题目密钥给了10个,但其实我们只要前128位的4个就可以了
    // v为要加密的数据是两个32位无符号整数
    // k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位
    printf("加密前原始数据:%u %u\n",v[0],v[1]);
    for(int i=0;i<4;i++)
    	decrypt(v[i],k);
	for (int a = 0; a < 4; a++)
	{
		for (int b = 0; b < 2; b++)
		{	
			for(int c=0; c<4; c++)
				printf("%c", (v[a][b] >> (c * 8)) & 0xFF);	//C语言32位数字符拼接 
		}
	}
    return 0;
}

在这里插入图片描述
.
.
解毕!
敬礼!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

沐一 · 林

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

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

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

打赏作者

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

抵扣说明:

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

余额充值