LINUX.ORG.RU

Как зареверсировать такую пакость?

 ,


0

2

Доброго времени суток. Помогите решить одну проблему у меня есть программа следующего вида:

#include <stdlib.h>
#include <conio.h>
#include <time.h>
#include <stdio.h>
#define k "jf1ay9238x0ax0"
char f1(char a);
int a1(int a);

int main()
{
    srand(time(0));

    printf("Enter path:");
    fflush(stdout);
    char p[64];
    scanf("%s", p);
    char c;
    do {
        c = getchar();
    } while (c != '\n' && c != EOF);

    FILE* f = fopen(p, "rb");
    if (f == NULL) {
        printf("Error opening file");
        getch();
        exit(-3);
    }
    char m[64];
    fread(&m, sizeof(char), 64, f);
    fclose(f);

    printf("%s\n", p);
    printf("Cipher?(Y/n):");
    fflush(stdout);
    char r;
    scanf("%c", &r);
    do {
        c = getchar();
    } while (c != '\n' && c != EOF);
    char ot = r;

    if (ot == 'Y') {
        char s = 0;
        for (int i = 0; i < 64; ++i) {
            s ^= m[i];
        }

        for (int i = 0; i < 63; ++i) {
            m[i] ^= (m[i + 1] ^ s^r^i ^ ((0xf) << 4) ^ ((i % 2) << 7));
            m[i] = f1(m[i]);
        }
        m[63] ^= s;

        FILE* f = fopen("out.txt", "wb");
        fputc(s, f);
        fwrite(m, sizeof(char), 64, f);
        fclose(f);    
    }

    return 0;
}
char f1(char a)
{
    char ss = 0xd;
    static int t = 0;
    int b = a1(rand()) % 0xffff;

    b <<= 4;
    b ^= (k[(t++) % ss] >> 4);
    b <<= 4;
    b ^= (k[(t++) % ss]);

    a ^= (char)b;
    return a;
}

int a1(int a) {
    if (a < 0)
        return (-a);
    else
        return a;
}

Её суть в том, что она читает побайтно файл с текстом, а затем хорит его по определенному алгоритму и записывает в другой файл. В общем суть моего вопроса: помогите написать реверсирующую процедуру, т.е. чтобы подавая на вход зашифрованное сообщение получался исходный читаемый текст. Всю голову себе уже исколупал, 10 раз прошел по алгоритму, но все равно где-то я что-то упускаю (может сдвиг может еще что) И да, я знаю, что 2х xor дает исходный результат.

Спасибо большое заранее тем, кто откликнется

Псевдокод:

char key[13] = {0x06, 0x51, 0x49, 0x03, 0x48, 0x51, 0x1a, 0x51, 0x19, 0x02, 0x08, 0x40, 0x18}
char buf[65] <- read_crypted_file();
buf[64] ^= buf[0]

char s = buf[0]
for i in 63..1 {
  buf[i] ^= i ^ (0xf0 ^ ((i % 2) << 7)) ^ s ^ 0x59 ^ key[i % 13] ^ buf[i + 1]
}
Вроде ничего не попутал (:

uCore ()

Мельком глянул, и кажется что это шифрующая программа не сможет себя расшифровать.

Так как в функции шифрования f1 используются случайные числа. А seed (в данном случае time(0)) мы никуда не сохраняем...

fsb4000 ★★ ()

Изи же! Хочешь прикол? А никак, потому что UB с типами и их сдвигами, оно энкодится, но с косяками. Тебе нужно просто сделать всё наоборот и там видно что в первый байт записывается XOR от всей строки, это кабы соль, в последний 64 делается XOR на уже закодированный символ, поэтому при декоде ты берёшь нулевой символ, который не данные, а соль, ксоришь им предпоследний (последний) символ, так как строка обтратно разворачиватся в обратном направлении тоесть при кодировании певый символ кодируется вторым, второй третьим и так далее, при декоде ты обратно должен это всё делать, причём операций кодирования две, их также задом наперёд, в функции кодирования локальная static переменная, поэтому при декодировании её значение надо сбрасывать. Вот тебе портянка отреверснутая

dron@gnu:~$ gcc cryxor.c `pkg-config --libs --cflags ncurses` 
dron@gnu:~$ cat cryxor.c 
#include <stdlib.h>
#include <curses.h>
#include <time.h>
#include <stdio.h>
#include <stdbool.h>
#define ENCODE_SIZE 64
int reset_encode_decode = false;
int clamp(int a) 
{
    return (a < 0)?(-a):a;
};
uint8_t encode_decode(uint8_t a,char * key)
{
    uint8_t ss = 0xd;
    static int t = 0;
    if(reset_encode_decode)
    {
        t=0;
    };
    int b = clamp(rand()) % 0xffff;
    b <<= 4;
    b ^= (key[(t++) % ss] >> 4);
    b <<= 4;
    b ^= (key[(t++) % ss]);
    a ^= (uint8_t)b;
    return a;
}
void xorencode(char * file_in,char * file_out, char * key)
{
    srand(time(0));
    uint8_t buff[ENCODE_SIZE];
    FILE * intxt  = fopen(file_in,"rb");
    fread(&buff, sizeof(uint8_t), ENCODE_SIZE, intxt);
    fclose(intxt);
    uint8_t send =  0;
    for (int i = 0; i < ENCODE_SIZE-1; ++i)
    {
            send ^= buff[i];
    };
    for (uint8_t i = 0; i < ENCODE_SIZE-1; ++i)
    {
         buff[i] ^= (buff[i + 1] ^ send^'Y'^i ^ ((0xf) << 4) ^ ((i % 2) << 7));
    };
    reset_encode_decode = true;
    for (uint8_t i = 0; i < ENCODE_SIZE-1; ++i)
    {
         buff[i] = encode_decode(buff[i],key);
    };

    buff[ENCODE_SIZE-1]^=send;
    FILE * outtxt = fopen(file_out,"wb");
    fputc(send,outtxt);
    fwrite(buff, sizeof(uint8_t), ENCODE_SIZE, outtxt);
    fclose(outtxt);  
}

void xordecode(char * file_in,char * file_out,char * key)
{
    srand(time(0));
    uint8_t buff[ENCODE_SIZE+1];
    FILE * intxt  = fopen(file_in,"rb");
    fread(&buff, sizeof(uint8_t), ENCODE_SIZE+1, intxt);
    fclose(intxt);
    uint8_t send = buff[0];
    for (int i = 0; i < ENCODE_SIZE+1; i++)
    {
        buff[i]=buff[i+1];
    }
    buff[ENCODE_SIZE-1]^=send;
    reset_encode_decode=true;
    for (uint8_t i = 0; i < ENCODE_SIZE-1; ++i)
    {
         buff[i] = encode_decode(buff[i],key);
    };
    for (uint8_t i = ENCODE_SIZE-1; i !=0 ; i--) 
    {
        buff[i-1] ^= (buff[i ] ^ send^'Y'^i-1 ^ ((0xf) << 4) ^ ((i-1 % 2) << 7));
    };

    FILE * outtxt = fopen(file_out,"wb");
    fwrite(buff, sizeof(char), ENCODE_SIZE, outtxt);
    fclose(outtxt);
}

int main(int argc, char *argv[])
{
    char key[]  = "jf1ay9238x0ax0";
    xorencode("in.txt","encode.txt",key);
    xordecode("encode.txt","decode.txt",key);
    return 0;
}
dron@gnu:~$ 

С тем говном что ты выше указал она несовместима, она кодит и декодит следуя алгоритму, что бы работала с выхлопом твоего чуда-юда uint8_t меняй на char и наблюдай приколы.Когда длаешь XOR «одного и того же» в разных функциях, получаешь разный результат. Хотя...вероятно код из i386. Или я что-то не доглядел, в любом случае без размерных типов, я испытал боль ибо оно работало, но уж очень странно, байты в голове считать лень было. Если избавишься от uint8_t и у тебя будет всё ок работать и декодить выхлоп оригинала, дай знать мне интересно. Если же тебе насрать на то какой код, а важен сам алгоритм то слава те хоспади, но у меня подозрения что тебе надо энкодить именно выхлоп того что накодил твой оригинальный кусок. Удачи чё)

Deleted ()