bitwise - Cifrado C++ XOR
bitwise operators python (2)
Después de leer varios libros blancos sobre cifrado y crypters PE de tiempo de ejecución, decidí escribir el mío. Es muy simple y solo para propósitos educativos.
Aquí está el repo de GitHub: https://github.com/Jyang772/XOR_Crypter
Tengo dos preguntas.
- En primer lugar , ¿por qué tengo que seguir cambiando los permisos de mi archivo para iniciar cada .exe extraído (el archivo creado por Builder.exe no es el compilador)? Crea un archivo que es
Shared
. Tengo que hacer clic derecho y seleccionar compartir conNobody
. ¿Tiene esto algo que ver con el acceso a archivos y los derechos de seguridad? Estoy usandoCreateFile()
yReadfile
para leer y escribir los archivos de entrada y salida.
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363858(v=vs.85).aspx
- En segundo lugar , parece que no puedo lograr que el cifrado XOR funcione. Parece bastante sencillo para lo que he hecho. Los tamaños de bytes son iguales. Mientras estaba investigando, hice que el Creador y el Stub cada salida un archivo con los datos del archivo sin cifrar. Ellos son lo mismo. Luego probé con los datos encriptados. No hay duda de que los datos están encriptados con el cifrado, sin embargo, aparece en blanco cuando es descifrado por el código auxiliar más adelante. Estoy confundido.
Aquí está mi implementación XOR:
fs = tamaño del byte Rsize = tamaño del byte Debería ser el mismo.
Constructor:
char cipher[] ="penguin";
for (int i = 0; i < fs; i++)
{
FB[i] ^= cipher[i % strlen(cipher)]; // Simple Xor chiper
}
Talón:
char cipher[] = "penguin";
for (int i = 0; i < Rsize; i++)
{
RData[i] ^= cipher[i % strlen(cipher)];
}
Si tuviera que comentar la función de encriptación en el Generador y Stub, el archivo encriptado funciona bien. Uhh, excepto con el error de permisos.
También estoy tratando de incluir un menú de opciones donde el usuario puede seleccionar el método de encriptación utilizado. Tal vez podría haber hecho algo mal allí? El Builder.exe agrega un byte que contiene la elección del usuario al final del búfer de FB
. Stub.exe lee eso y determina qué método de encriptación se usa para descifrar los datos.
Dependiendo de los datos de su contenido, escriba la opción char en la memoria asignada apuntada por FB o después ( overrun del búfer ) en "C ++ Builder / main.cpp" al llamar a strcat (FB, choice).
Solución: asigne suficiente espacio en FB para datos + opción char. Como está tratando con datos binarios, no debe usar funciones de cadena (por ejemplo, strcat ).
FB = new char[fs + 1];
memcpy(FB +fs, option, 1); // copy the option at end
En primer lugar, con el "cifrado" de XOR, sus funciones de "cifrado" y "descifrado" deberían ser las mismas:
void xor_crypt(const char *key, int key_len, char *data, int data_len)
{
for (int i = 0; i < data_len; i++)
data[i] ^= key[ i % key_len ];
}
Debería poder usar esta misma función tanto en el programa "XOR Crypter" como en su programa "Stub".
No es un estilo muy C ++; ordinariamente usaría std::string
o std::vector
. Por ejemplo:
void xor_crypt(const std::string &key, std::vector<char> data)
{
for (size_t i = 0; i != data.size(); i++)
data[i] ^= key[ i % key.size() ];
}
Luego, en el programa que llama a esto, declararías:
std::string key = "penguin";
y usted leería su archivo así:
std::vector<char> file_data; // With your current program, make this a global.
fs = GetFileSize(efile, NULL);
file_data.resize(fs); // set vector length equal to file size
// Note: Replace &( file_data[0] ) with file_data.data() if you have C++11 support
ReadFile(efile, (LPVOID)( &( file_data[0] )), fs, &bt, NULL);
if (fs != bt)
// error reading file: report it here.
Entonces simplemente xor_crypt( key, file_data );
con xor_crypt( key, file_data );
. Para escribir datos XOR-crypted en su recurso, creo que llamaría a su función existente con:
// replace &( file_data[0] ) with file_data.data() if C++11
WriteToResources(output, 1, (BYTE *)&( file_data[0] ), file_data.size() );
Sospecho que el problema real es con las API de Windows que está utilizando. ¿ LoadResource
proporciona datos mutables o se le requiere que los copie? No conozco la API de Windows, pero no me sorprendería que LoadResource
le proporcione una copia de solo lectura.
Si necesita hacer su propia copia para modificar el recurso, en su programa "Stub" recuperar el recurso XOR-crypted debería verse más o menos así:
std::vector<char> RData;
void Resource(int id)
{
size_t Rsize;
HRSRC hResource = FindResource(NULL, MAKEINTRESOURCE(1), RT_RCDATA);
HGLOBAL temp = LoadResource(NULL, hResource);
Rsize = SizeofResource(NULL, hResource);
RData.resize(RSize);
memcpy( (void*)&(RData[0]), temp, RSize ); // replace &RData[0] with RData.data() if C++11
}
y la desencriptación en su "Stub" debería ser simplemente xor_crypt( key, RData );
.
Tengo un último pensamiento. El error más grande que veo en tu programa "Stub" es esta línea:
switch (RData[strlen(RData)-1])
Una vez que haya cifrado XOR sus datos, algunos de los bytes se convertirán en cero. La función strlen()
no devolverá el índice del último byte en su RData
como resultado. Y, hay un error diferente, más sutil: esto devuelve el último byte de la cadena, no el último byte del recurso. Realmente no puedo ver cómo esta línea fue alguna vez correcta; más bien, sospecho que su programa estaba funcionando cuando el cifrado se deshabilitó a pesar de sí mismo, cayendo en el default
de la caja del conmutador.
Si realmente tiene la intención de distinguir entre diferentes tipos de datos basados en el último byte de la carga útil del recurso, entonces realmente debería usar el tamaño devuelto por la API de Windows para encontrar ese byte.
Si cambias al vector<char>
como sugiero arriba, entonces puedes encontrarlo con RData.back()
. De lo contrario, si continúa utilizando char *
, entonces ese byte sería RData[RSize - 1]
.