基于一道newstarctf中的逆向题学习XTEA解密_逆向 xtea算法

void decrypt(unsigned int* v, unsigned int* key) {
	unsigned int l = v[0], r = v[1], sum = 0, delta = 0x9e3779b9;
	sum = delta * 32;
	for (size_t i = 0; i < 32; i++) {
		r -= ((l << 4) + key[2]) ^ (l + sum) ^ ((l >> 5) + key[3]);
		l -= ((r << 4) + key[0]) ^ (r + sum) ^ ((r >> 5) + key[1]);
		sum -= delta;
	}
	v[0] = l;
	v[1] = r;
}  

接下来重点理解一下比赛中的魔改版XTEA算法(由于我c只看的懂但不太会写,所以我就用python实现了)

首先我们还是先了解一下XTEA算法

跟TEA算法很类似,差别就是将r的变化结果和l变化结果进行了交替赋值,同时位移次数进行了一些变化,也掺杂了一些与操作

#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=0x9E3779B9;
	for(i=0;i<num_rounds;i++){
		v0+=(((v1<<4)^(v1>>5))+v1)^(sum+key[sum&3]);
		sum+=delta;
		v1+=(((v0<<4)^(v0>>5))+v0)^(sum+key[(sum>>11)&3]);
	}
	v[0]=v0;v[1]=v1;
	}

void decipher(unsigned int num_rounds,uint32_t v[2],uint32_t const key[4]){
	unsigned int i;
	uint32_t v0=v[0],v1=v[1],delta=0x9E3779B9,sum=delta*num_rounds;
	for(i=0;i<num_rounds;i++){
	v1-=(((v0<<4)^(v0>>5))+v0)^(sum+key[(sum>>11)&3]);
	sum-=delta;
	v0-=(((v1<<4)^(v1>>5))+v1)^(sum+key[sum&3]);
	} 
	v[0]=v0;v[1]=v1;
}

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);
	printf("加密后原始数据:%u %u\n",v[0],v[1]);
	decipher(r,v,k);
	printf("解密后原始数据:%u %u\n",v[0],v[1]);
	return 0;
}  

这里我们看一道关于魔改的XTEA的题目

在这里插入图片描述

无壳64位,接着分析主函数代码

在这里插入图片描述

接下来看一下dll文件

在这里插入图片描述

这边额外补充一下TLS回调函数

在这里插入图片描述

在这里插入图片描述

分析的已经差不多了,接下来就是上脚本了

from ctypes import * 
"""c_uint32对象本身是一个包装器对象,需要使用.value来访问底层整数值"""
"""c语言中char元素是一个字节,而int元素通常是4个字节,所以一个32位无符号整数代表4个字符(一个字符通常是一个字节)"""
def encrypt(v,k):
	v0=c_uint32(v[0])
	v1=c_uint32(v[1])
	sum1=c_uint32(0)
	delta=999999999
	for i in range(33):
		v0.value+=(((v1.value<<3)^(v1.value>>4))+v1.value)^(sum1.value+k[sum1.value&3])
		sum1.value+=delta
		v1.value+=(((v0.value<<3)^(v0.value>>4))+v0.value)^(sum1.value+k[(sum1.value>>11)&3])
	return v0.value,v1.value
 
def decrypt(v,k):
	v0=c_uint32(v[0])
	v1=c_uint32(v[1])
	delta=999999999
	sum1=c_uint32((delta*33)+1)
	for i in range(33):
		v1.value-=(((v0.value<<3)^(v0.value>>4))+v0.value)^(sum1.value+k[(sum1.value>>11)&3])
		sum1.value-=delta
		v0.value-=(((v1.value<<3)^(v1.value>>4))+v1.value)^(sum1.value+k[sum1.value&3])
	return v0.value,v1.value


enc = [130,67,163,137,111,186,128,200,248,180,86,189,179,65,178,141,218,68,14,4,3,46,56,222,18,84,173,137,149,48,99,33,223,13,148,17,220,178,208,17]
k=[5,20,13,14]
t = [int.from_bytes(enc[i:i+4], byteorder='little') for i in range(0, len(enc), 4)]
"""
这是一个方法调用,它将四个字节的字节数组(刚才切片得到的)转换为一个整数。byteorder='little' 表示采用小端字节顺序,这意味着最低有效字节在前面,最高有效字节在后面
"""
#print(t)
temp = []
for i in range(0,10,2):
    v = t[i:i+2]
    res = decrypt(v,k)
    temp.extend(res)  # extend()方法通常用于将一个可迭代对象的元素添加到另一个可迭代对象中
#print(temp)
#temp=[1734437990 , 828457851,  813260652, 1983078261, 828337765 ,863461222 ,863125599 ,1916823135, 1634746719, 2099344498]
for i in range(10):


**自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**

**深知大多数网络安全工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!**

**因此收集整理了一份《2024年网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。**
![img](https://img-blog.csdnimg.cn/img_convert/ed78b86c5761bfeb421761f17059d278.png)
![img](https://img-blog.csdnimg.cn/img_convert/9effe55969cfdbdbadcc2986d22eb9e3.png)
![img](https://img-blog.csdnimg.cn/img_convert/2df01dd0dab838c8868271bc80523895.png)
![img](https://img-blog.csdnimg.cn/img_convert/8255d74cb136a09443a742e21bc07dda.png)
![img](https://img-blog.csdnimg.cn/img_convert/958a09df2f286cce63febecad8840c14.png)
![img](https://img-blog.csdnimg.cn/img_convert/3bb00590e962cd380f006dd8ddd816fa.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上网络安全知识点,真正体系化!**

**由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新**

**如果你觉得这些内容对你有帮助,可以添加VX:vip204888 (备注网络安全获取)**
![img](https://img-blog.csdnimg.cn/img_convert/bc94fc59962cab21b1bdc1b6dabb70a2.png)



### 给大家的福利


**零基础入门**


对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。


![](https://img-blog.csdnimg.cn/img_convert/95608e9062782d28f4f04f821405d99a.png)


同时每个成长路线对应的板块都有配套的视频提供:


![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/a91b9e8100834e9291cfcf1695d8cd42.png#pic_center)


因篇幅有限,仅展示部分资料

**一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
![img](https://img-blog.csdnimg.cn/img_convert/b027e2c5d75a04c8787efd59a2bab1a5.png)

ng#pic_center)


因篇幅有限,仅展示部分资料

**一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
[外链图片转存中...(img-nrBbjE5k-1712896659396)]

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是使用ST语言编写的XTEA加密算法的代码: ``` // 定义XTEA加密算法所需的常量 CONST DELTA: ARRAY[0..1] OF DINT := [0x9E3779B9, 0x7F4A7C13]; // 常量DELTA NUM_ROUNDS: DINT := 32; // 加密轮数 // 定义XTEA加密算法主函数 FUNCTION XTEA_Encrypt(Data: ARRAY[0..7] OF BYTE; Key: ARRAY[0..15] OF BYTE): ARRAY[0..7] OF BYTE; VAR V: ARRAY[0..1] OF DINT; // 存储加密结果的数组 K: ARRAY[0..3] OF DINT; // 存储加密密钥的数组 Sum: DINT := 0; // 加密轮数的累加器 I: DINT := 0; // 循环计数器 BEGIN // 将密钥转换为DINT类型的数组 K[0] := KEY_TO_DINT(Key, 0); K[1] := KEY_TO_DINT(Key, 4); K[2] := KEY_TO_DINT(Key, 8); K[3] := KEY_TO_DINT(Key, 12); // 将数据转换为DINT类型的数组 V[0] := DATA_TO_DINT(Data, 0); V[1] := DATA_TO_DINT(Data, 4); // 加密轮数循环 FOR I := 0 TO NUM_ROUNDS - 1 DO V[0] := V[0] + (((V[1] << 4) ⊕ (V[1] >> 5)) + V[1]) ⊕ (Sum + K[Sum AND 3]); Sum := Sum + DELTA[0]; V[1] := V[1] + (((V[0] << 4) ⊕ (V[0] >> 5)) + V[0]) ⊕ (Sum + K[(Sum >> 11) AND 3]); END_FOR; // 将加密结果转换为字节数组 XTEA_RESULT_TO_BYTES(V, Data); // 返回加密结果 RETURN Data; END_FUNCTION // 定义将密钥转换为DINT类型数组的函数 FUNCTION KEY_TO_DINT(Key: ARRAY[0..15] OF BYTE; Offset: DINT): DINT; VAR I: DINT := 0; // 循环计数器 Result: DINT := 0; // 转换结果 BEGIN // 循环转换密钥的每个字节 FOR I := 0 TO 3 DO Result := (Result << 8) + Key[Offset + I]; END_FOR; // 返回转换结果 RETURN Result; END_FUNCTION // 定义将数据转换为DINT类型数组的函数 FUNCTION DATA_TO_DINT(Data: ARRAY[0..7] OF BYTE; Offset: DINT): DINT; VAR I: DINT := 0; // 循环计数器 Result: DINT := 0; // 转换结果 BEGIN // 循环转换数据的每个字节 FOR I := 0 TO 3 DO Result := (Result << 8) + Data[Offset + I]; END_FOR; // 返回转换结果 RETURN Result; END_FUNCTION // 定义将加密结果转换为字节数组的函数 PROCEDURE XTEA_RESULT_TO_BYTES(Result: ARRAY[0..1] OF DINT; Data: ARRAY[0..7] OF BYTE); VAR I: DINT := 0; // 循环计数器 BEGIN // 循环转换加密结果的每个字节 FOR I := 0 TO 3 DO Data[I] := (Result[0] >> (I * 8)) AND 255; Data[I + 4] := (Result[1] >> (I * 8)) AND 255; END_FOR; END_PROCEDURE ``` 请注意,此代码仅供参考,仍需根据实际需求进行调整和优化。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值