逆向常见的算法

本文介绍了逆向工程中常见的三种加密算法:Base64、TEA和MD5。Base64算法通过将3个8位字节转换为4个6位字节并使用索引表进行替换;TEA是一种简单的块密码,其特征是固定使用的Image Number;MD5则是创建128位散列值的密码学算法,涉及四个变量h0到h3。文章提供了部分加密代码和伪代码,帮助理解这些算法的实现。

Base64

对于Base64来说 是我们通常比较常见的加密算法 通常是应用 动态页面开发 或者是流媒体路径加密上 对于我这样的
菜鸡来说 通常常见于Web题中 但是在逆向题中也偶有见到

Base64算法通俗的来讲就是 将3个8位字节转换为4个6位字节

在重新分配完6个字节后 会在6位字节前部补0 将字节补成八位 也就是说 此时字节最大值为 00111111=63
此时 Base64算法会将此时的字节所代表的的十进制数作为下标来索引表中进行替换 索引表如下

编号字符编号字符编号字符编号字符
0A16Q32g48w
1B17R33h49x
2C18S34i50y
3D19T35j51z
4E20U36k520
5F21V37l531
6G22W38m542
7H23X39n553
8I24Y40o564
9J25Z41p575
10K26a42q586
11L27b43r597
12M28c44s608
13N29d45t619
14O30e46u62+
15P31f47v63/

在这里插入图片描述
Base64算法在逆向中的体现 主要就在于程序内存中存在一个索引表
同理 如果是Base64解密 内存中当然存在一个解密表

并且在程序算法中存在明显的 右移2位和右移4位等明显位运算操作
同理 如果是Base64解密 应该存在左移2位和左移4位等明显的位运算操作

但是注意 Base64是可以设计变种的 即更改索引表来实现变种加密 后续还是需要自己实现下Base64加密的算法 以达到就算是更改了索引表依旧能成功解密的水平

具体算法设计可以查看
https://www.jianshu.com/p/61833e529cfc

Base64加密代码简单实现

在研究了一下午之后 写出了不完全的Base64加密算法 仅支持三位及以下的加密 代码以后会继续完善 仅供查看Base64加密的代码特征

#include <iostream>
using namespace std;

char sy[64]=
{
	'A','B','C','D','E','F',
	'G','H','I','J','K','L',
	'M','N','O','P','Q','R',
	'S','T','U','V','W','X',
	'Y','Z','a','b','c','d',
	'e','f','g','h','i','j',
	'k','l','m','n','o','p',
	'q','r','s','t','u','v',
	'w','x','y','z','0','1',
	'2','3','4','5','6','7',
	'8','9','+','-' 
};
char ans[100];
void EnBase64()
{
	int i=0;
	while(1)
	{
		int tmp1=0,tmp2=0,tmp3=0,tmp4=0;
		char a[3]={' ',' ',' '};
		cin>>a;
		if(a[0]=='#')
		{
			break;
		}
		
		tmp1=a[0]>>2;
		ans[i]=sy[tmp1];
		i++;
		
		if(a[1]=='#')
		{
			tmp2=(a[0]&3)<<4>>2;
			ans[i]=sy[tmp2];
			i++;
			ans[i]='=';
			break;	
		}
		
		tmp2=((a[1]>>2)|((a[0]&3)<<6))>>2;
		ans[i]=sy[tmp2];
		i++;
		
		if(a[2]=='#')
		{
			tmp3=(a[1]&15)<<4>>2;
			ans[i]=sy[tmp3];
			i++;
			ans[i]='=';
			break;
		}
				
		tmp3=(((a[1]&15)<<4)|((a[2]&192)>>4))>>2;
		ans[i]=sy[tmp3];
		i++;
		
		tmp4=(a[2]&63);
		ans[i]=sy[tmp4];
		i++;
		//cout<<"000";
	}	
}


int main(void)
{
	int i=0;
	EnBase64();
	cout<<ans;

} 

Tea

在密码学中,微型加密算法(Tiny Encryption Algorithm,TEA)是一种易于描述和执行的块密码,通常只需要很少的代码就可实现。其设计者是剑桥大学计算机实验室的大卫 · 惠勒与罗杰 · 尼达姆

Tea的实现代码比较固定 这里给出常见Tea加密的实现代码

#include <stdint.h>

void encrypt (uint32_t* v, uint32_t* k) {
    uint32_t v0=v[0], v1=v[1], sum=0, i;           /* set up */
    uint32_t delta=0x9e3779b9;                     /* a key schedule constant */
    uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */
    for (i=0; i < 32; i++) {                       /* basic cycle start */
        sum += delta;
        v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
        v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);  
    }                                              /* end cycle */
    v[0]=v0; v[1]=v1;
}

void decrypt (uint32_t* v, uint32_t* k) {
    uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i;  /* set up */
    uint32_t delta=0x9e3779b9;                     /* a key schedule constant */
    uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */
    for (i=0; i<32; i++) {                         /* basic cycle start */
        v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
        v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
        sum -= delta;                                   
    }                                              /* end cycle */
    v[0]=v0; v[1]=v1;
}

Tea加密的明显特征是 存在一个Image Number:0x9e3779b9

MD5

MD5 消息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个 128 位(16 字节)的散列值(hash value),用于确保信息传输完整一致。MD5 由美国密码学家罗纳德 · 李维斯特(Ronald Linn Rivest)设计,于 1992 年公开,用以取代 MD4 算法。这套算法的程序在 RFC 1321 中被加以规范

这里给出MD5实现的伪代码

/Note: All variables are unsigned 32 bits and wrap modulo 2^32 when calculating
var int[64] r, k

//r specifies the per-round shift amounts
r[ 0..15]:= {7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22} 
r[16..31]:= {5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20}
r[32..47]:= {4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23}
r[48..63]:= {6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21}

//Use binary integer part of the sines of integers as constants:
for i from 0 to 63
    k[i] := floor(abs(sin(i + 1)) × 2^32)

//Initialize variables:
var int h0 := 0x67452301
var int h1 := 0xEFCDAB89
var int h2 := 0x98BADCFE
var int h3 := 0x10325476

//Pre-processing:
append "1" bit to message
append "0" bits until message length in bits ≡ 448 (mod 512)
append bit length of message as 64-bit little-endian integer to message

//Process the message in successive 512-bit chunks:
for each 512-bit chunk of message
    break chunk into sixteen 32-bit little-endian words w[i], 0 ≤ i ≤ 15

//Initialize hash value for this chunk:
var int a := h0
var int b := h1
var int c := h2
var int d := h3

//Main loop:
for i from 0 to 63
    if 0 ≤ i ≤ 15 then
        f := (b and c) or ((not b) and d)
        g := i
    else if 16 ≤ i ≤ 31
        f := (d and b) or ((not d) and c)
        g := (5×i + 1) mod 16
    else if 32 ≤ i ≤ 47
        f := b xor c xor d
        g := (3×i + 5) mod 16
    else if 48 ≤ i ≤ 63
        f := c xor (b or (not d))
        g := (7×i) mod 16

    temp := d
    d := c
    c := b
    b := leftrotate((a + f + k[i] + w[g]),r[i]) + b
    a := temp
Next i
//Add this chunk's hash to result so far:
h0 := h0 + a
h1 := h1 + b 
h2 := h2 + c
h3 := h3 + d
End ForEach var int digest := h0 append h1 append h2 append h3 //(expressed as little-endian)

MD5算法的显著特征就是 存在4个变量 h0=0x67452301 h1=0xefcdab89 h2=0x98badcfe h3=0x10325476

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值