山西省赛
re
encryption
反调试,smc自揭密,u去除定义和p定义函数。
动调即可,再smc已经解密的那个函数下断,进去先恢复函数,然后,分析。
发现只是一个简单的变种rc4.脚本如下。
#include<stdio.h>
#include<string>
void rc4_init(unsigned char* s, unsigned char* key, unsigned long Len_k) //初始化函数
{
int i = 0, j = 0;
char k[256] = { 0 };
unsigned char tmp = 0;
for (i = 0; i < 256; i++) {
s[i] = i;
k[i] = key[i % Len_k]^0x12;
}
for (i = 0; i < 256; i++) {
j = (j + s[i] + k[i]) % 256;
tmp = s[i];
s[i] = s[j]; //交换s[i]和s[j]
s[j] = tmp;
}
}
/*
RC4加解密函数
unsigned char* Data 加解密的数据
unsigned long Len_D 加解密数据的长度
unsigned char* key 密钥
unsigned long Len_k 密钥长度
*/
void rc4_crypt(unsigned char* Data, unsigned long Len_D, unsigned char* key, unsigned long Len_k) //加解密
{
unsigned char s[256];
rc4_init(s, key, Len_k);
int i = 0, j = 0, t = 0;
unsigned long k = 0;
unsigned char tmp;
for (k = 0; k < Len_D; k++) {
i = (i + 1) % 256;
j = (j + s[i]) % 256;
tmp = s[i];
s[i] = s[j]; //交换s[x]和s[y]
s[j] = tmp;
t = (s[i] + s[j]) % 256;
Data[k] ^= s[t];
}
}
int main()
{
unsigned char DDAT[] = { 0x91, 0x74, 0x7F, 0x21, 0x5A, 0x6C, 0xB4, 0xDB, 0x11, 0xA5,
0x2D, 0x12, 0xD4, 0x0F, 0x19, 0x70 };
unsigned char key[] = { 0x60, 0x21, 0x64, 0x21, 0x60, 0x61, 0x21, 0x4D, 0x23, 0x61,
0x4D, 0x61, 0x22, 0x4D, 0x21, 0x68 };
rc4_crypt(DDAT, 16, key, 16);
//printf("%02x", DDAT);
unsigned char v8[] = { 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x30,
0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x30 ,
0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x30,
0x31,0x32};
unsigned char dw[] = "12345678901234567890123456789012";
for (int i = 0; i < 16; i +=1 )
printf("%02x", DDAT[i]);
//int v2=0; // [rsp+10h] [rbp-8h]
//int i;
//for (i = 0; i <= 7; ++i)
//{
// if ((0xFA & (1 << i)) > 0)
// v2 |= 1 << (7 - i);
//}
//printf("%d", 4746179990008951158&0x7f);
return 0;
}
#flag{7ce6798bc692ef04c6273a39d94dff9f}
vvm
没有栈的vm题,opcode给了。密文给了。且他是按字节进行加密操作。按照opcode的操作对着密文倒着解密回去就行了。
手撕的。有点乱。(也可以复现他的算法,写成解密的然后封装好,然后跑一遍opcode也行。不过手撕感觉快一点hhh