初音ミクの消失

qwb_JustRe

字数统计: 653阅读时长: 2 min
2019/05/26 Share

JustRe

JustRe.7z

思路

程序读入了26位 十六进制数

其中前8为送入eax寄存器

把eax扩展为了16个字节 01234567012345670123456701234567 记作 input

后两位(假设为ab) 填充为了ababababababababab…..ababab,记作 ab

从内存中取16个字节,记作 key1

还从内存取了16个字节,形如00000003000000020000000100000000 记作 key2

key = (ab + key1)^ (input + key2) 并且将结果存在原来key1的位置

依次循环

注意key2第二次 key2’ += key2 ,而不是直接从内存取

接下来的循环 循环了八次,是对从0x405058的32个字节进行处理,每次四个字节

同样

input 01 23 45 67

key 从内存中取四个字节

ab 用89位填充的四个字节

esi 从0x10 开始 一直到0x18

key = (ab + key) ^ (input + esi) 并且将结果存在key的位置

然后 0x405018 和 0x404148的 0x60个字节进行比较,要相等

事实证明,后面这些运算,对于解出input的帮助并不大,我们只需要解出一组input,并且判断它们是否是四个分块都相等即可

dec1 = 0x4364162A031410D2EF95C26D80B899BD
enc1 = 0x405004A100000278EC81F0E483EC8B55
key1 = 0x00000003000000020000000100000000


def FILL(a): #用八九位这一个字节去填充为16字节
return a * 0x01010101010101010101010101010101

def DIVIDE(a):
for i in range(4):
res.append((a << (32 * i) & 0xffffffffffffffffffffffffffffffff) >> (32 * 3))
return res

def ADD(a, b):
a = DIVIDE(a)
b = DIVIDE(b)
res = 0
for i in range(4):
res += ((a[i]+b[i]) & 0xffffffff) << (32 * (3-i))
return res

def CALC(dec,enc,key,t):
return (ADD(FILL(t),dec) ^ enc) - key


for t in range(100):#枚举第八第九位的所有情况
res = CALC(dec1,enc1,key1,t)
if(inpu & 0xffffffff == res >> (3 * 32)):
print(hex(CALC(dec1,enc1,key1,t) >> (3*32)),hex(t))

前十位 1324229810

用来过验证的passwd:13242298100123456789abcdef

后面这个加密函数是好像藏在data区里面的,看起来应该是一个加密算法,谷歌了几个比较关键的常数,发现是个3des加密

https://www.cnblogs.com/one--way/archive/2016/07/05/5643771.html

密钥应该是这个 AFSAFCEDYCXCXACNDFKDCQXC

再配上解密后的密文(实际上只用到了16个字节,剩下的8个字节可要可不要)

注意:大端序,不能直接复制,要先把顺序颠倒一下

轮子不太完整,修改了一下,以下是main函数中修改过的内容

	char k[32] = "AFSAFCEDYCXCXACNDFKDCQXC";

char data[128] = {
0x50,0x7C,0xA9,0xE6,
0x87,0x09,0xCE,0xFA,
0x20,0xD5,0x0D,0xCF,
0x90,0xBB,0x97,0x6C,0
}; /* 原始明文 */
nlen = strlen(data);


.....

for (i = 0; i < len; i += 8) {
DES_ecb3_encrypt((const_DES_cblock *)(src + i), (DES_cblock *)(out + i), &ks1, &ks2, &ks3, DES_DECRYPT);
}

printf("encrypted Hex:");
for (i = 0; i < len; i++) {
printf("%02X" , *(out + i));
}
printf("\n");

printf("encrypted Bin:");
for (i = 0; i < len; i++) {
printf("%c", *(out + i));
}
printf("\n");

原文作者:mrh929

原文链接:https://mrh1s.top/posts/2946351e/

发表日期:May 26th 2019, 10:43:14 am

更新日期:June 14th 2019, 12:12:46 am

版权声明:本文采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可

CATALOG
  1. 1. JustRe
    1. 1.1. 思路