<<<<<<< HEAD
Autor Carlos Garrido
origin/main
Preguntas
Relacionado: objetos COM. 12 Introduccion a la Criptografiaseguridad. 2025 02 20 Seguridad iOS memoria permisos y sandboxing. Sistema de Gestion de la Seguridad de la Informacion.
1- Dado el binario analízalo brevemente y describe por encima que simula este binario.
2- Al igual que en la práctica anterior describe las funciones definidas por el programador.
3- ¿En qué lenguaje crees que está escrito el binario?, en caso de ser un lenguaje
orientado a objetos identifica al menos un constructor de clase.
4 - En primer lugar consigue parchear la petición de licencia para evitarla. Describe el
proceso
5 - En segundo lugar parchea el nombre del jugador para que aparezca el tuyo. Describe
el proceso
6 - En tercer lugar intenta conseguir imprimir el mensaje “Has ganado” (parcheando el
binario). Describe el proceso
7 - Por último, obtén uno varios códigos de licencia correctos. En este caso, al describir el
proceso deberás hacerlo usando el código ensamblador, sin usar el pseudocódigo
proporcionado por el decompilador.
Contenido
<<<<<<< HEAD
1- Dado el binario analízalo brevemente y describe por encima que simula este binario.
2- Al igual que en la práctica anterior describe las funciones definidas por el programador.
3- ¿En qué lenguaje crees que está escrito el binario?, en caso de ser un lenguaje
orientado a objetos identifica al menos un constructor de clase.
4 - En primer lugar consigue parchear la petición de licencia para evitarla. Describe el
proceso
5 - En segundo lugar parchea el nombre del jugador para que aparezca el tuyo. Describe
el proceso
6 - En tercer lugar intenta conseguir imprimir el mensaje “Has ganado” (parcheando el
binario). Describe el proceso
7 - Por último, obtén uno varios códigos de licencia correctos. En este caso, al describir el
proceso deberás hacerlo usando el código ensamblador, sin usar el pseudocódigo
proporcionado por el decompilador.
=======
1- Dado el binario analízalo brevemente y describe por encima que simula este binario.
Simula el funcionamiento de un casino en el que jugador inteta adividnar una casilla correcta para ir acumulando puntos hasta llegar a 10 000 puntos para poder ganar. El algoritmo es el siguiente. Primero inicializa el programa y pide una licencia para verificar si es valida , en el caso de que no lo sea termina el programa y si es valida crea un objeto que representa al casino y da la bienvenida al jugador. A continuación entra en el bucle y empezaría el juego, cuando llegue a los 10.000 puntos se termina el juego indicando que ha ganado.
2- Al igual que en la práctica anterior describe las funciones definidas por el programador.
La función sub_132D es la que verifica si la licencia del jugador es correcta. para que sea valida el primer caracter(el menos signfiicativo) tiene que ser par en ascci, el cuarto 1,el quinto - , el sexto y el noveno tiene que ser 2.
La función sub_1ACC representa el constructor del casino, que inicializa la puntuación a cero y establece la casilla ganadora en 42.
sub_1ACC En está sección también esta la función saludar la cual se utilizar para dar la bienvenida al jugador cuando entra al juego.
La función sub_1B32 Se encarga de imprimir las instrucciones al jugador. Muestra el siguiente mensaje: Para ganar tienes que sumar 10.000 puntos.
La función sub_1B76 es la que simula el juego, en esta casilla se comprueba si el número que ha introducido el jugador corresponde con el número 42, si es así muestra que “has ganado” e incrementa el contador y devuelve 1 para indicar que siga jugando en el caso de que no es así devuelve 0 y termina el juego.
La función sub_1C38 es la que comprueba si has ganado para ello compara tu puntación con 9999 si es mayor imprime el mensaje de vitoria.
sub_1C86 esta función es un get que devuelve el valor acumulado de la puntación.
3- ¿En qué lenguaje crees que está escrito el binario?, en caso de ser un lenguaje orientado a objetos identifica al menos un constructor de clase.
Se ha hecho en c++ ya que es un lenguaje orientado a objetos como prueba de ello esta en el constructor que está definido en la función sub_1ACC .
4 - En primer lugar consigue parchear la petición de licencia para evitarla. Describe el proceso
Para parchear pues tenemos que cambiar la comprobación en la función sub_132D
hacemos un reverse jump en los jne que hay dentro de la función.
Quedando de resultado así.
Cerramos la aplicación y la ejecutamos para comprobar si ha funcionado.

5 - En segundo lugar parchea el nombre del jugador para que aparezca el tuyo. Describe el proceso
Para el nombre primero tenemos que encontrar donde está USUARIO UAH Y nos fijamos en la posición de memoria.
Es la posición 203b, en un editor hexadecimal cambiamos el nombre por el nuestro.
He utilizado ghex y he cambiado usuario uah por carlos
El cambio se ha hecho en la sección de data.

6 - En tercer lugar intenta conseguir imprimir el mensaje “Has ganado” (parcheando el binario). Describe el proceso
Cambiamos el comparado de funcion que compara la puntación que es la sub_1C38
He rellando el equals con nops para que no salte y muestre el mensaje de que has ganado

7 - Por último, obtén uno varios códigos de licencia correctos. En este caso, al describir el proceso deberás hacerlo usando el código ensamblador, sin usar el pseudocódigo proporcionado por el decompilador.
La función que se encarga de la validación de la licencia es la siguiente:
sub_132D.
Lo primero que hace para ver si es par el lsbl es fijarse si acaba en 0, para ello utiliza la operación and y luego hace un test. para el resto de operaciones se va desplazadando el registros eax y comprueba haciendo cmp con lo valores anteriromete descritos en apartados anteriores.
Para ello utilizo el siguiente código para generar licencias hecho en python.
import random
import string
def generar_licencia_valida():
while True:
licencia = list('X' * 9)
# a1[0] debe tener bit menos significativo en 0 => ASCII par
licencia[0] = random.choice([c for c in string.ascii_letters + string.digits if ord(c) % 2 == 0])
# Fijamos las posiciones clave
licencia[3] = '1'
licencia[4] = '-'
licencia[5] = '2'
licencia[8] = '2'
# Rellenamos los demás caracteres con letras o números aleatorios
for i in range(9):
if licencia[i] == 'X':
licencia[i] = random.choice(string.ascii_uppercase + string.digits)
return ''.join(licencia)
# Generar varias licencias válidas
for _ in range(10):
print(generar_licencia_valida())Probarnos una de las licencias que nos ha generado el programa:
Y nos da la bienvenida.
Otras licencias son:
t5C1-2I42
40Y1-2JU2
V8X1-2202
h9N1-2X32
r2W1-2QJ2
T1T1-2UU2
V3N1-2OB2
8Q71-29I2
h5S1-2CH2
origin/main
codigo
Main sub_1391
// bad sp value at call has been detected, the output may be wrong!
int __cdecl main(int argc, const char **argv, const char **envp)
{
int v3; // eax
Casino *v4; // edi
int v5; // eax
Casino *v6; // edi
int Puntuacion; // eax
int v8; // eax
Casino *v9; // ebx
int v11; // eax
int v12; // [esp+10h] [ebp-50h] BYREF
int v13; // [esp+14h] [ebp-4Ch]
Casino *v14; // [esp+18h] [ebp-48h]
char *s; // [esp+1Ch] [ebp-44h]
int *v16; // [esp+20h] [ebp-40h]
int v17[6]; // [esp+24h] [ebp-3Ch] BYREF
char v18[4]; // [esp+3Ch] [ebp-24h] BYREF
Casino *v19; // [esp+40h] [ebp-20h]
int *p_argc; // [esp+50h] [ebp-10h]
p_argc = &argc;
v3 = std::operator<<<std::char_traits<char>>(&std::cout, &unk_2008);
std::ostream::operator<<(v3, &std::endl<char,std::char_traits<char>>);
std::operator>><char,std::char_traits<char>>(&std::cin, v18);
if ( checkLicencia(v18) )
{
v4 = (Casino *)operator new(0x20u);
Casino::Casino(v4);
v14 = v4;
s = "USUARIO UAH";
v16 = &v12;
std::string::basic_string<std::allocator<char>>((int)v17, "USUARIO UAH", (int)&v12);
Casino::saludar((int)v4, (int)v17);
std::string::~string(v17);
std::__new_allocator<char>::~__new_allocator(&v12);
v19 = v14;
Casino::imprimirInstrucciones();
v13 = 1;
while ( v13 == 1 )
{
v12 = 0;
v5 = std::operator<<<std::char_traits<char>>(&std::cout, "A que casilla quieres apostar: \n");
std::ostream::operator<<(v5, &std::endl<char,std::char_traits<char>>);
std::istream::operator>>(&std::cin, &v12);
v13 = Casino::jugar(v14, v12);
v6 = v14;
Puntuacion = Casino::getPuntuacion(v14);
Casino::hasGanado(v6, Puntuacion);
}
v8 = std::operator<<<std::char_traits<char>>(&std::cout, &unk_206C);
std::ostream::operator<<(v8, &std::endl<char,std::char_traits<char>>);
v9 = v14;
if ( v14 )
{
Casino::~Casino(v14);
operator delete(v9, 0x20u);
}
return 0;
}
else
{
v11 = std::operator<<<std::char_traits<char>>(
&std::cout,
"La licencia introducida para este programa no es correcta");
std::ostream::operator<<(v11, &std::endl<char,std::char_traits<char>>);
return 0;
}
}checkLicense sub_132D
_BOOL4 __cdecl checkLicencia(const char *a1)
{
int v2; // [esp+Ch] [ebp-4h]
v2 = 0;
if ( (*a1 & 1) == 0 && a1[4] == 45 && a1[3] == 49 && a1[5] == 50 )
return a1[8] == 50;
return v2;
}Casino sub_1ACC
void __cdecl Casino::Casino(Casino *this)
{
_BYTE v1[5]; // [esp+17h] [ebp-11h] BYREF
unsigned int v2; // [esp+1Ch] [ebp-Ch]
v2 = __readgsdword(0x14u);
*(_DWORD *)&v1[1] = v1;
std::string::basic_string<std::allocator<char>>((int)this, "DEFAULT NAME", (int)v1);
std::__new_allocator<char>::~__new_allocator(v1);
*((_DWORD *)this + 6) = 0;
*((_DWORD *)this + 7) = 42;
}Saludar → sub_1ACC
int __cdecl Casino::saludar(int a1, int a2)
{
int v2; // eax
int v3; // eax
std::string::operator=(a1, a2);
v2 = std::operator<<<std::char_traits<char>>(&std::cout, "Bienvenido: ");
v3 = std::operator<<<char>(v2, a1);
return std::ostream::operator<<(v3, &std::endl<char,std::char_traits<char>>);
}imprimirInstrucciones→sub_1B32
int Casino::imprimirInstrucciones()
{
int v0; // eax
v0 = std::operator<<<std::char_traits<char>>(&std::cout, "Para ganar tienes que sumar 10.000 puntos\n");
return std::ostream::operator<<(v0, &std::endl<char,std::char_traits<char>>);
}jugar sub_1B76
int __cdecl Casino::jugar(Casino *this, int a2)
{
int v2; // eax
int v3; // eax
int v4; // eax
if ( a2 != *((_DWORD *)this + 7) )
return 0;
++*((_DWORD *)this + 6);
v2 = std::operator<<<std::char_traits<char>>(&std::cout, &unk_2157);
v3 = std::ostream::operator<<(v2, *((_DWORD *)this + 6));
std::ostream::operator<<(v3, &std::endl<char,std::char_traits<char>>);
v4 = std::operator<<<std::char_traits<char>>(&std::cout, &unk_216B);
std::ostream::operator<<(v4, &std::endl<char,std::char_traits<char>>);
Casino::hasGanado(this, *((_DWORD *)this + 6));
return 1;
}has ganado sub_1C38
void __cdecl Casino::hasGanado(Casino *this, int a2)
{
int v2; // eax
if ( a2 > 9999 )
{
v2 = std::operator<<<std::char_traits<char>>(&std::cout, &unk_216D);
std::ostream::operator<<(v2, &std::endl<char,std::char_traits<char>>);
}
}getPuntuación sub_1C86
int __cdecl Casino::getPuntuacion(Casino *this)
{
return *((_DWORD *)this + 6);
}