霍雅
追求源于热爱,极致源于梦想!
这题有点意思,不过被py烂了
结束前有184解
main函数还原如下
有一堆反调试,直接用dbg调试
rc4代码如下
其中sub_401c90是生成密钥流和逐字节加密
但是dbg并没有调用这个函数,而是调用另一个
00401A60
在这里dump下来,ida打开才是真的加密逻辑
给大家看看真的和假的区别
应该是类似于smc的东西,如果有调试就不smc真代码,貌似有看到这种逻辑
没有动态dump原始sub_401A60的代码,一坨乱码
这个rc4是一个魔改的rc4,我们已知s盒、加密代码,先提取出s盒
初始化了一个v5,也就是ebp-208
然后把ebp-208给到edx再入栈
调用s盒函数
步过s盒函数去看ebp-208就是s盒
把s盒提取出来
0x35, 0xE9, 0x55, 0xD7, 0x6E, 0x5F, 0x47, 0x3D, 0xCC, 0x9D, 0xD2, 0x6B, 0xEB, 0x52, 0x97, 0x19,
0xD5, 0xC5, 0x80, 0x0B, 0x64, 0x2B, 0xCD, 0xF6, 0x95, 0xB1, 0x31, 0x34, 0x31, 0x08, 0x43, 0xBE,
0x8C, 0x86, 0x16, 0x70, 0xFE, 0x36, 0x11, 0xFD, 0xA7, 0xB9, 0x55, 0xA0, 0x4E, 0x40, 0xDA, 0x08,
0x1F, 0x4B, 0xA2, 0x4C, 0x50, 0x47, 0x15, 0xCE, 0xC3, 0x8D, 0xB5, 0x00, 0xFB, 0x43, 0x07, 0x32,
0x1D, 0x5E, 0xDC, 0x4D, 0xF5, 0x19, 0x98, 0x0F, 0x8D, 0xB0, 0xEC, 0x48, 0xAB, 0x92, 0x15, 0xD6,
0xDA, 0x6F, 0x1B, 0x85, 0x45, 0x04, 0x84, 0x8A, 0x5B, 0x0E, 0x66, 0xB6, 0xA0, 0x1E, 0x2A, 0x6D,
0x3C, 0x8F, 0x26, 0xC7, 0x90, 0x89, 0xDC, 0x8B, 0x87, 0xE0, 0x82, 0x57, 0xCE, 0x66, 0x13, 0x4B,
0x49, 0x6A, 0x1F, 0x1A, 0x09, 0x32, 0x8E, 0x36, 0xAD, 0x65, 0x58, 0xBC, 0xD4, 0x5E, 0xD0, 0x2C,
0x68, 0xBF, 0xBD, 0xA1, 0x45, 0x17, 0x16, 0x05, 0x9A, 0x4C, 0xFC, 0x0B, 0xB9, 0x49, 0xDB, 0x6F,
0x37, 0x27, 0x30, 0x51, 0x69, 0x61, 0xD5, 0x75, 0xD3, 0x74, 0xEB, 0x4F, 0x23, 0x54, 0x0C, 0x1C,
0x70, 0xDE, 0xE9, 0x7F, 0x62, 0x25, 0xF4, 0x84, 0x3E, 0x2F, 0x76, 0x03, 0x7A, 0x79, 0x5F, 0xCA,
0x01, 0x07, 0x41, 0x57, 0xC4, 0x97, 0x04, 0x33, 0x6C, 0x42, 0x4E, 0x38, 0x0E, 0xE7, 0x93, 0xE2,
0x64, 0x3F, 0xB7, 0x5C, 0x5D, 0xE5, 0x59, 0x8C, 0x6D, 0xED, 0x34, 0x85, 0xDF, 0x62, 0x91, 0x09,
0x94, 0xB3, 0x05, 0x2E, 0x18, 0xD8, 0xBF, 0x7E, 0xAC, 0xAE, 0x9E, 0xD6, 0xC1, 0x3B, 0x54, 0x72,
0x22, 0x5C, 0xE7, 0xD0, 0x6B, 0x25, 0xFE, 0xFF, 0xFB, 0x3B, 0x2D, 0x7C, 0x65, 0x5A, 0xCD, 0xF0,
0xBD, 0x67, 0x74, 0x17, 0x02, 0x42, 0x2C, 0x2E, 0x5A, 0xA7, 0xD1, 0x73, 0x94, 0xAF, 0x89, 0x06
{
0x50, 0x59, 0xA2, 0x94, 0x2E, 0x8E, 0x5C, 0x95, 0x79, 0x16, 0xE5, 0x36, 0x60, 0xC7, 0xE8, 0x06,
0x33, 0x78, 0xF0, 0xD0, 0x36, 0xC8, 0x73, 0x1B, 0x65, 0x40, 0xB5, 0xD4, 0xE8, 0x9C, 0x65, 0xF4,
0xBA, 0x62, 0xD0
};
把dump下来的正确的加密代码copy下来
sub_401226是申明,没意义
unsigned int __cdecl sub_401A60(int a1, int a2, unsigned int a3)
{
unsigned int result; // eax
int v4; // ecx
char v5; // al
char v6; // [esp+D3h] [ebp-35h]
unsigned int i; // [esp+DCh] [ebp-2Ch]
int v8; // [esp+F4h] [ebp-14h]
int v9; // [esp+100h] [ebp-8h]
sub_401226(&unk_41200F);
v9 = 0;
v8 = 0;
for ( i = 0; ; ++i )
{
result = i;
if ( i >= a3 )
break;
v9 = (v9 + 1) % 256;
v8 = (v8 + v9 * *(v9 + a1)) % 256;
v6 = *(v9 + a1);
*(v9 + a1) = *(v8 + a1);
*(v8 + a1) = v6;
v4 = (*(v8 + a1) + *(v9 + a1)) % 256;
if ( i % 2 )
v5 = *(v4 + a1) + *(i + a2);
else
v5 = *(i + a2) - *(v4 + a1);
*(i + a2) = v5;
}
return result;
}
这个代码的加密是
if ( i % 2 )
v5 = *(v4 + a1) + *(i + a2);
else
v5 = *(i + a2) - *(v4 + a1)
所以逆向还原就是取反
if (!(i % 2))
v5 = *(v4 + a1) + *(i + a2);
else
v5 = *(i + a2) - *(v4 + a1);
完整代码
#include <iostream>
#include <windows.h>
unsigned int sub_401A60(unsigned char* a1, unsigned char* a2, unsigned int a3)
{
unsigned int result; // eax
int v4; // ecx
char v5; // al
char v6; // [esp+D3h] [ebp-35h]
unsigned int i; // [esp+DCh] [ebp-2Ch]
int v8; // [esp+F4h] [ebp-14h]
int v9; // [esp+100h] [ebp-8h]
v9 = 0;
v8 = 0;
for (i = 0; ; ++i)
{
result = i;
if (i >= a3)
break;
v9 = (v9 + 1) % 256;
v8 = (v8 + v9 * *(v9 + a1)) % 256;
v6 = *(v9 + a1);
*(v9 + a1) = *(v8 + a1);
*(v8 + a1) = v6;
v4 = (*(v8 + a1) + *(v9 + a1)) % 256;
if (!(i % 2))
v5 = *(v4 + a1) + *(i + a2);
else
v5 = *(i + a2) - *(v4 + a1);
*(i + a2) = v5;
}
return result;
}
int main()
{
unsigned char data[256] = {
0x35, 0xE9, 0x55, 0xD7, 0x6E, 0x5F, 0x47, 0x3D, 0xCC, 0x9D, 0xD2, 0x6B,
0xEB, 0x52, 0x97, 0x19,
0xD5, 0xC5, 0x80, 0x0B, 0x64, 0x2B, 0xCD, 0xF6, 0x95, 0xB1, 0x31, 0x34,
0x31, 0x08, 0x43, 0xBE,
0x8C, 0x86, 0x16, 0x70, 0xFE, 0x36, 0x11, 0xFD, 0xA7, 0xB9, 0x55, 0xA0,
0x4E, 0x40, 0xDA, 0x08,
0x1F, 0x4B, 0xA2, 0x4C, 0x50, 0x47, 0x15, 0xCE, 0xC3, 0x8D, 0xB5, 0x00,
0xFB, 0x43, 0x07, 0x32,
0x1D, 0x5E, 0xDC, 0x4D, 0xF5, 0x19, 0x98, 0x0F, 0x8D, 0xB0, 0xEC, 0x48,
0xAB, 0x92, 0x15, 0xD6,
0xDA, 0x6F, 0x1B, 0x85, 0x45, 0x04, 0x84, 0x8A, 0x5B, 0x0E, 0x66, 0xB6,
0xA0, 0x1E, 0x2A, 0x6D,
0x3C, 0x8F, 0x26, 0xC7, 0x90, 0x89, 0xDC, 0x8B, 0x87, 0xE0, 0x82, 0x57,
0xCE, 0x66, 0x13, 0x4B,
0x49, 0x6A, 0x1F, 0x1A, 0x09, 0x32, 0x8E, 0x36, 0xAD, 0x65, 0x58, 0xBC,
0xD4, 0x5E, 0xD0, 0x2C,
0x68, 0xBF, 0xBD, 0xA1, 0x45, 0x17, 0x16, 0x05, 0x9A, 0x4C, 0xFC, 0x0B,
0xB9, 0x49, 0xDB, 0x6F,
0x37, 0x27, 0x30, 0x51, 0x69, 0x61, 0xD5, 0x75, 0xD3, 0x74, 0xEB, 0x4F,
0x23, 0x54, 0x0C, 0x1C,
0x70, 0xDE, 0xE9, 0x7F, 0x62, 0x25, 0xF4, 0x84, 0x3E, 0x2F, 0x76, 0x03,
0x7A, 0x79, 0x5F, 0xCA,
0x01, 0x07, 0x41, 0x57, 0xC4, 0x97, 0x04, 0x33, 0x6C, 0x42, 0x4E, 0x38,
0x0E, 0xE7, 0x93, 0xE2,
0x64, 0x3F, 0xB7, 0x5C, 0x5D, 0xE5, 0x59, 0x8C, 0x6D, 0xED, 0x34, 0x85,
0xDF, 0x62, 0x91, 0x09,
0x94, 0xB3, 0x05, 0x2E, 0x18, 0xD8, 0xBF, 0x7E, 0xAC, 0xAE, 0x9E, 0xD6,
0xC1, 0x3B, 0x54, 0x72,
0x22, 0x5C, 0xE7, 0xD0, 0x6B, 0x25, 0xFE, 0xFF, 0xFB, 0x3B, 0x2D, 0x7C,
0x65, 0x5A, 0xCD, 0xF0,
0xBD, 0x67, 0x74, 0x17, 0x02, 0x42, 0x2C, 0x2E, 0x5A, 0xA7, 0xD1, 0x73,
0x94, 0xAF, 0x89, 0x06 };
uint8_t v7[35]{ 0x50, 0x59, 0xA2, 0x94, 0x2E, 0x8E, 0x5C, 0x95, 0x79, 0x16, 0xE5, 0x36, 0x60, 0xC7, 0xE8, 0x06,
0x33, 0x78, 0xF0, 0xD0, 0x36, 0xC8, 0x73, 0x1B, 0x65, 0x40, 0xB5, 0xD4, 0xE8, 0x9C, 0x65, 0xF4,
0xBA, 0x62, 0xD0 };
sub_401A60(data, v7, 35);
for (int i = 0; i < 35; i++)
printf("%c", v7[i]);
return 0;
}