transposicion - Rutina de cifrado XOR simple en C/C++
cifrador afin en c (3)
Así es como podría escribir esa función de lenguaje ensamblador en C. He mantenido los nombres de las variables lo mismo que los nombres de registro para que pueda ver cómo coinciden las distintas partes.
void do_xor_crypt(char *buffer, int count) {
char *ecx = buffer;
int eax = count - 1;
if (eax > 0) {
do {
char dl = ecx[eax];
dl ^= 0xC5;
dl -= ecx[eax-1];
ecx[eax] = dl;
eax--;
} while (eax > 0);
}
}
Tenga en cuenta que he verificado para asegurarse de que eax
es mayor que cero (lo que significa que el count
es dos o más) para que el ciclo tenga algo que restar. Puede integrar este código en su ciclo de lectura como:
while (count = fread(buffer, 1, 1024, in))
{
do_xor_crypt(buffer, count);
if (fwrite(buffer, 1, count, out) != count)
{
// ...
}
}
Estoy intentando cifrar / descifrar un archivo usando XOR. Tengo la siguiente rutina de cifrado / descifrado en la que cada byte se corrige y el resultado se resta por el valor del byte que se encuentra en la ubicación anterior. La representación de ASM es la siguiente
crypt:
mov dl, [eax+ecx] ; read byte
xor dl, 0C5h ; xor it with oxC5
sub dl, [eax+ecx-1] ; sub the previous byte
mov [eax+ecx], dl ; save the new byte
dec eax ; decrement pointer
test eax, eax
jg short crypt ;
Así es como debería ser mi rutina de encriptación, estoy tratando de portar esto como C / C ++. Mi código es el siguiente
#include <stdio.h>
unsigned int xorkey = 0xC5;
int main(int argc, char *argv[])
{
if(argc < 3)
{
printf("usage: encoder input output/n");
return -1;
}
FILE *in = fopen(argv[1], "rb");
if(in == NULL)
{
printf("failed to open: %s", argv[2]);
return -1;
}
FILE *out = fopen(argv[2], "wb");
if(out == NULL)
{
fclose(in);
printf("failed to open ''%s'' for writing.",argv[2]);
return -1;
}
int count;
char buffer[1024];
while(count = fread(buffer, 1, 1024, in))
{
int i;
int end = count;
for(i = 0;i < end; ++i)
{
((unsigned int *)buffer)[i] ^= xorkey;
}
if(fwrite(buffer, 1, count, out) != count)
{
fclose(in);
fclose(out);
printf("fwrite() error/n");
return -1;
}
}
fclose(in);
fclose(out);
return 0;
}
No puedo descifrar cómo restar bytes en C ++. La rutina XOR en sí misma parece correcta, ¿no? Tenga en cuenta que también estoy tratando de encriptar el archivo comenzando desde el final del archivo hasta el comienzo. ¿Algunas ideas?
¡Gracias!
Hay un par de cosas mal con tu código C.
El código asm comienza al final del búfer y se abre y se detiene cuando eax == 0. El código asm opera en un byte a la vez, xor''ing y resta del byte anterior.
El código asm parece dejar el primer byte del buffer intacto.
Su código C mueve un índice y xors los cuatro bytes apuntados por ese índice de bytes con 0xC5. Ese código lee demasiados bytes y solo afecta al byte más bajo con el XOR.
Además, su for-loop comienza en la parte delantera y llega hasta el final, lo opuesto a su rutina de control remoto.
Suponiendo que los caracteres son de tamaño byte, para imitar la rutina asm, su paso de resta sería:
buffer[i] = buffer[i] - buffer[i-1];
que puede ser reescrito como:
buffer[i] -= buffer[i-1];
... suponiendo que arregle su for-loop para pasar del final-1 de la matriz al índice 1.
Necesita cambiar el buffer
para escribir unsigned char
y cambiar su bucle for
para:
for (i = count - 1; i > 0; i--)
{
buffer[i] ^= xorkey;
buffer[i] -= buffer[i - 1];
}
Sin embargo, tenga en cuenta que este código funciona en el archivo en fragmentos de 1024 bytes desde el principio, y luego funciona en cada fragmento al revés. Si desea trabajar en el archivo completo al revés, deberá comenzar a leer desde el final y tener un manejo especial para el primer personaje en cada fragmento.