---
title: "Reversing unioncita facilb"
date: 2024-09-22T14:11:20-03:00
tags: ['reversing']
---
El ejercicio unioncita facilb se encuentra en: https://drive.google.com/file/d/1QRIk3zBGGXH54nSZorX3jnuNmURCHw6K/view?pli=1

> Todos los 'miembros' de la union comparten la misma memoria.  Los datos son los mismos pero se interpretan de manera diferente.

```c
#include <stdio.h>
union pruebita {
    int a;
    char b;
    char c[2];
};
int main(){
    union pruebita HOLA;
    HOLA.a = 65;

    HOLA.c[0] = 'C';
    printf("%d\n",HOLA.a);
    printf("%c\n",HOLA.b);

    return 0;
}
```

A diferencia de las estructuras, donde cada miembro tiene su propia área de memoria, **todos los miembros de una unión comparten la misma dirección**, lo que optimiza el uso de memoria. El tamaño total de la unión es igual al tamaño del miembro más grande. Por ejemplo, al declarar `union { int i; double d; } u;`, se puede acceder a u.i o u.d, pero modificar uno afectará al otro debido a que comparten el mismo espacio en memoria. Esto requiere que el programador tenga cuidado para asegurarse de que solo se accede al miembro correcto en uso.


Código generado por IDA:
```c

/* This file was generated by the Hex-Rays decompiler version 9.0.0.240807.
   Copyright (c) 2007-2021 Hex-Rays <info@hex-rays.com>

   Detected compiler: Visual C++
*/

#include <windows.h>
#include <defs.h>

#include <stdarg.h>


//-------------------------------------------------------------------------
// Function declarations

__int64 __fastcall funcion(S *_myun);
// unsigned __int64 *__fastcall _local_stdio_printf_options(); idb
// unsigned __int64 *__fastcall _local_stdio_scanf_options(); idb
int __fastcall vfprintf_l(_iobuf *const _Stream, const char *_Format, __crt_locale_pointers *const _Locale, va_list _ArgList);
int __fastcall vfscanf_s_l(_iobuf *const _Stream, const char *_Format, __crt_locale_pointers *const _Locale, va_list _ArgList);
int __fastcall main(int argc, const char **argv, const char **envp);
__int64 printf(const char *_Format, ...);
__int64 scanf_s(const char *_Format, ...);
__int64 __fastcall _scrt_initialize_winrt();
__int64 __fastcall get_startup_argv_mode();
char __fastcall _scrt_stub_for_acrt_uninitialize(bool __formal);

//-------------------------------------------------------------------------
// Data declarations

// extern void *(__cdecl *malloc)(size_t Size);
// extern void (__cdecl __noreturn *exit)(int Code);
// extern int (__cdecl *system)(const char *Command);
// extern int (__cdecl *__stdio_common_vfscanf)(unsigned __int64 Options, FILE *Stream, const char *Format, _locale_t Locale, va_list Arglist);
// extern FILE *(__cdecl *__acrt_iob_func)(unsigned int Ix);
// extern int (__cdecl *__stdio_common_vfprintf)(unsigned __int64 Options, FILE *Stream, const char *Format, _locale_t Locale, va_list ArgList);


//----- (0000000140001000) ----------------------------------------------------
__int64 __fastcall funcion(S *_myun)
{
  S resul; // [rsp+20h] [rbp-18h]

  resul.n = 305419896 - _myun->n;
  if ( resul.n < 0 )
    exit(1);
  resul.c *= 16;
  if ( !resul.c )
    exit(1);
  resul.s[1] = _myun->s[0] - _myun->c;
  return (unsigned int)resul.n;
}

//----- (00000001400010A0) ----------------------------------------------------
int __fastcall vfprintf_l(
        _iobuf *const _Stream,
        const char *_Format,
        __crt_locale_pointers *const _Locale,
        va_list _ArgList)
{
  unsigned __int64 *v4; // rax

  v4 = _local_stdio_printf_options();
  return __stdio_common_vfprintf(*v4, _Stream, _Format, _Locale, _ArgList);
}

//----- (00000001400010F0) ----------------------------------------------------
int __fastcall vfscanf_s_l(
        _iobuf *const _Stream,
        const char *_Format,
        __crt_locale_pointers *const _Locale,
        va_list _ArgList)
{
  unsigned __int64 *v4; // rax

  v4 = _local_stdio_scanf_options();
  return __stdio_common_vfscanf(*v4 | 1, _Stream, _Format, _Locale, _ArgList);
}

//----- (0000000140001140) ----------------------------------------------------
int __fastcall main(int argc, const char **argv, const char **envp)
{
  S *my_union; // [rsp+28h] [rbp-10h]

  my_union = (S *)malloc(4uLL);
  if ( !my_union )
    exit(1);
  printf("Ingresa un numero\n");
  scanf_s("%x", my_union);
  if ( (unsigned int)funcion(my_union) == 67130096 )
    printf("Super Genial\n");
  else
    printf("A estudiar\n");
  system("pause");
  return 0;
}

//----- (00000001400011E0) ----------------------------------------------------
__int64 printf(const char *_Format, ...)
{
  _iobuf *v1; // rax
  va_list va; // [rsp+58h] [rbp+10h] BYREF

  va_start(va, _Format);
  v1 = __acrt_iob_func(1u);
  return (unsigned int)vfprintf_l(v1, _Format, 0LL, va);
}

//----- (0000000140001260) ----------------------------------------------------
__int64 scanf_s(const char *_Format, ...)
{
  _iobuf *v1; // rax
  va_list va; // [rsp+58h] [rbp+10h] BYREF

  va_start(va, _Format);
  v1 = __acrt_iob_func(0);
  return (unsigned int)vfscanf_s_l(v1, _Format, 0LL, va);
}

//----- (0000000140001A70) ----------------------------------------------------
__int64 __fastcall _scrt_initialize_winrt()
{
  return 0LL;
}

//----- (0000000140001A74) ----------------------------------------------------
__int64 __fastcall get_startup_argv_mode()
{
  return 1LL;
}

//----- (0000000140001A94) ----------------------------------------------------
char __fastcall _scrt_stub_for_acrt_uninitialize(bool __formal)
{
  return 1;
}

// nfuncs=76 queued=9 decompiled=9 lumina nreq=0 worse=0 better=0
// ALL OK, 9 function(s) have been successfully decompiled
```

```c
#include <stdio.h>
#include <stdlib.h>

union UNIONCITA {
  int n;
  int c;
  char s[10];
};
typedef union UNIONCITA S; 

int funcion(S *_myun)
{
  S resul; // [rsp+20h] [rbp-18h]
  // result.n tiene que valer 67130096
  // Tenés que ingresar un número hexadecimal que restando ese numero 
  resul.n = 305419896 - _myun->n;
  // 305419896 - x = 67130096 
  printf("Resultado esperado: 67130096\n");
  printf("_myun->n: %d\n",_myun->n);
  printf("(unsigned int)result.n: %d\n",(unsigned int)resul.n);
  if ( resul.n < 0 )
    exit(1);
  resul.c *= 16;
  if ( !resul.c )
    exit(1);
  resul.s[1] = _myun->s[0] - _myun->c;
  return (unsigned int)resul.n;
}


int main(int argc, const char **argv, const char **envp)
{
  S *my_union; // [rsp+28h] [rbp-10h]

  my_union = (S *)malloc(4uLL);
  if ( !my_union )
    exit(1);
  printf("Ingresa un numero\n");
  scanf("%x", my_union);
  
  printf ("union: %d\n",my_union->n);
  printf ("%x\n",funcion(my_union));
  printf ("resultado: %d\n", (unsigned int)funcion(my_union));
  if ( (unsigned int)funcion(my_union) == 67130096 )
    printf("Super Genial\n");
  else
    printf("A estudiar\n");
  return 0;
}
```


```c
#include <stdio.h>
#include <stdlib.h>

typedef union 
{      
    int n;
    int s[2];
    char c;
}S;

int funcion(S *_myun)
{
  S resul; // [rsp+20h] [rbp-18h]

  resul.n = 305419896 - _myun->n;
  if ( resul.n < 0 ) exit(1);

  printf("%x %x %x %c\n",resul.n,resul.s[0],resul.s[1],resul.c);

  resul.c *= 16;

  printf("%x %x %x %c\n",resul.n,resul.s[0],resul.s[1],resul.c);

  if ( !resul.c )  exit(1);
  resul.s[1] = _myun->s[0] - _myun->c;
  return (unsigned int)resul.n;
}

int main(int argc, const char **argv, const char **envp)
{
  S *my_union; // [rsp+28h] [rbp-10h]

  my_union = (S *)malloc(4uLL);
  if ( !my_union )
    exit(1);
  printf("Enter a number\n");
  scanf("%x", my_union);
  
  
  if ( funcion(my_union) == 67130096 )
    printf("You win\n");
  else
    printf("You lost\n");
  return 0;
}
```
