标头“CF10”似乎是一个私人添加的签名,表示文件的其余部分已“编码”。这是一个非常简单的 XOR 编码:xor 8Dh 是我尝试的第一个值,而且我第一次就做对了。 尝试作为第一个值的原因是,8D 值在前 100 个字节左右出现非常频繁,它们通常可能是很多零。
“解密”因此非常简单:如果文件以CF10 四个字节开头,则删除它们并在文件的其余部分应用xor 8Dh。解码文件显示第一个“JPG”实际上是一个很小的 PNG 图像(并且不是一个非常有趣的启动图像),第二个确实是一个 PNG 文件:
文件扩展名可能是也可能不是原始文件扩展名;一个名为“.jpg”的样本实际上也是一个 PNG 文件,从它的标题签名可以看出。
以下快速而简单的 C 源代码将解码图像。同样的程序也可以调整为encode它们,因为xor的操作是完全一样的。唯一需要的是添加一点逻辑流程:
- 读取输入文件的前 4 个字节(最大)并测试这是否形成字符串
CF10
- 如果不是,则文件未编码:
一个。将CF10 写入输出文件
湾。通过在每个字节上应用xor 8Dh 对图像进行编码
- 如果是这样,
湾。通过在每个字节上应用xor 8Dh 来解码图像。
如您所见,没有“3a”,两个“b”步骤相同。
#include <stdio.h>
#include <string.h>
#ifndef MAX_PATH
#define MAX_PATH 256
#endif
#define INPUTPATH "c:\\documents"
#define OUTPUTPATH ""
int main (int argc, char **argv)
{
FILE *inp, *outp;
int i, encode_flag = 0;
char filename_buffer[MAX_PATH];
char sig[] = "CF10", *ptr;
if (argc != 3)
{
printf ("usage: decode [input] [output]\n");
return -1;
}
filename_buffer[0] = 0;
if (!strchr(argv[1], '/') && !strchr(argv[1], 92) && !strchr(argv[1], ':'))
strcpy (filename_buffer, INPUTPATH);
strcat (filename_buffer, argv[1]);
inp = fopen (filename_buffer, "rb");
if (inp == NULL)
{
printf ("bad input file '%s'\n", filename_buffer);
return -2;
}
ptr = sig;
while (*ptr)
{
i = fgetc (inp);
if (*ptr != i)
{
encode_flag = 1;
break;
}
ptr++;
}
if (encode_flag)
{
/* rewind file because we already read some bytes */
fseek (inp, 0, SEEK_SET);
printf ("encoding input file: '%s'\n", filename_buffer);
} else
printf ("decoding input file: '%s'\n", filename_buffer);
filename_buffer[0] = 0;
if (!strchr(argv[2], '/') && !strchr(argv[2], 92) && !strchr(argv[2], ':'))
strcpy (filename_buffer, OUTPUTPATH);
strcat (filename_buffer, argv[2]);
outp = fopen (filename_buffer, "wb");
if (outp == NULL)
{
printf ("bad output file '%s'\n", filename_buffer);
return -2;
}
printf ("output file: '%s'\n", filename_buffer);
if (encode_flag)
fwrite (sig, 1, 4, outp);
do
{
i = fgetc(inp);
if (i != EOF)
fputc (i ^ 0x8d, outp);
} while (i != EOF);
fclose (inp);
fclose (outp);
printf ("all done. bye bye\n");
return 0;
}