第一种花指令
第二种花指令
根据两种花指令特征,写出去花指令脚本
saddr=0x401000
eaddr=0x435000
for i in range(saddr,eaddr):
if get_wide_dword(i)==0x01740275:
print(hex(i)+','+hex(get_wide_dword(i)))
patch_byte(i-5,0x90)
patch_dword(i-4,0x90909090)
patch_dword(i,0x90909090)
patch_word(i+4,0x9090)
if get_qword(i)==0x8336E800000001E8:
print(hex(i)+','+hex(i+4)+','+hex(get_wide_dword(i)))
patch_qword(i,0x9090909090909090)
patch_dword(i+8,0x90909090)
patch_byte(i+12,0x90)
使用脚本将花指令去除后,u,c,p一下基本没啥问题。
可以得到下面正常main函数
分析可得为rc4+xor加密
saddr=0x401000
eaddr=0x435000
for i in range(saddr,eaddr):
if get_wide_dword(i)==0x01740275:
print(hex(i)+','+hex(get_wide_byte(i)))
patch_dword(i,0x90909090)
patch_dword(i-4,0x90909090)
patch_word(i+4,0x9090)
patch_byte(i-5,0x90)
if get_wide_dword(i)==0x000001E8:
if get_wide_dword(i+4)==0x8336E800:
print(hex(i)+','+hex(get_wide_byte(i)))
patch_dword(i,0x90909090)
patch_dword(i+4,0x90909090)
patch_dword(i+8,0x90909090)
patch_byte(i+12,0x90)
用下面idapython脚本得到密文和key
enc=list(map(lambda x:get_wide_dword(x),range(0x004440E0,0x004440E0+27*4,4)))
print(enc)
key=''.join(map(lambda x:chr(get_wide_byte(x)),range(0x00446900,0x0044690f)))
print(key)
exp
#include<iostream>
#include<cstdint>
using namespace std;
void main()
{
uint8_t aHelloCtfers[] = "Hello_Ctfers!!!";
uint32_t key_len = sizeof(aHelloCtfers);
uint32_t data[] = { 77, 4294967270, 73, 4294967189, 3, 45, 43, 4294967226, 4294967274, 109, 4294967295, 89, 112, 0, 27, 4294967209, 44, 4294967216, 50, 4294967192, 111, 4294967180, 86, 4294967202, 76, 121, 127 };
uint32_t data_len = 27;
for (int i = data_len - 1; i >= 0; i--)
{
data[i] = data[i] ^ data[(i + 1) % data_len];
}
uint32_t result; // eax
uint8_t v4[320]; // [esp+Ch] [ebp-25Ch]
uint32_t v5; // [esp+14Ch] [ebp-11Ch]
uint32_t k; // [esp+150h] [ebp-118h]
uint32_t j; // [esp+154h] [ebp-114h]
uint32_t i; // [esp+158h] [ebp-110h]
uint32_t v9; // [esp+15Ch] [ebp-10Ch]
uint32_t m; // [esp+160h] [ebp-108h]
uint8_t v11[256]; // [esp+164h] [ebp-104h] BYREF
for (i = 0; i < 256; ++i)
{
v11[i] = i;
v4[i] = aHelloCtfers[i % key_len];
}
v9 = 0;
for (j = 0; j < 256; ++j)
{
v9 = (v4[j] + v9 + v11[j]) % 256;
swap(v11[j], v11[v9]);
}
m = 0;
v9 = 0;
for (k = 0; k < data_len; ++k)
{
m = (m + 3) % 256;
v9 = (v9 + v11[m] + 1) % 256;
swap(v11[m], v11[v9]);
v5 = (v11[v9] + v11[m]) % 256;
v4[k + 256] = v11[v5];
}
for (m = 0; ; ++m)
{
result = m;
if (m >= data_len)
break;
data[m] ^= v4[m + 256];
}
for (int i = 0; i < 27; i++)
cout << (char)data[i];
}