Páginas

anun1

sábado, 15 de agosto de 2026

Editor Hexadecimal En JavaScript y HTML

Hola amigos hoy no vengo con un crackme sino con un simple programa que se me vino ala mente, ya que los que hacemos ingeniería inversa usamos mucho los editores hexadecimales, así que se me ocurrió hacer uno simple en JavaScript y HTML solo que hay un inconveniente solo acepta ejecutables o archivos que pesen menos de 1 megabyte, ya que si le pongo un valor mayor este programa o mejor dicho el navegador se nos trabaría y si así con 700 kb se quiere trabar en fin aquí una foto del programa ya terminado, otra cosa use chatgpt para hacerlo es una herramienta muy cómoda de programar y sin quebrarte tanto la cabeza y no por eso nos va a sustituir, ya que tenemos que revisar bien el código, bueno aquí la foto


Y si se preguntan que podemos hacer, pues les cuento al cargar el ejecutable nos muestra sus valores en hexadecimal y podemos seleccionar los bytes para modificarlos y si quieren descargar la nueva versión solo dan en clic en el botón guardar, también pueden comparar los archivos si son iguales o diferentes en algunos bytes y si es diferente estos se marcaran a color, también puedes ir a alguna dirección dada y también te muestra el peso del archivo en bytes...bueno sin tanto rollo aquí les dejo el código por si lo quieren probar solo copean y pegan en el bloc de notas como editor.html

<html lang="es">
<head>
<meta charset="UTF-8">
<title>Editor Hexadecimal</title>
<style>
        *
        {
            box-sizing: border-box;
        }
        body
        {
            margin: 0;

            background: #1e1e1e;

            color: #ddd;

            font-family:
                Consolas,
                "Courier New",
                monospace;
        }
        #barra
        {
            background: #252526;

            padding: 10px;

            border-bottom:
                1px solid #444;

            display: flex;

            gap: 6px;

            align-items: center;

            flex-wrap: wrap;
        }
        button
        {
            background: #333;

            color: white;

            border:
                1px solid #555;

            padding:
                7px 10px;

            cursor: pointer;
        }
        button:hover
        {
            background: #444;
        }
        input[type="text"]
        {
            background: #1e1e1e;

            color: white;

            border:
                1px solid #555;

            padding: 7px;
        }
        input[type="file"]
        {
            display: none;
        }
        #info
        {
            margin-left: auto;

            color: #aaa;
        }
        #resultado
        {
            padding:
                8px 12px;

            background: #202020;

            border-bottom:
                1px solid #444;

            color: #aaa;
        }
        #contador
        {
            color: #ffcc00;
        }
        #cabecera
        {
            display: grid;

            grid-template-columns:
                90px
                1fr
                1fr
                170px;

            padding:
                8px 12px;

            background: #333;

            border-bottom:
                1px solid #555;
        }
        #editor
        {
            height:
                calc(100vh - 180px);

            overflow: auto;
        }
        .fila
        {
            display: grid;

            grid-template-columns:
                90px
                1fr
                1fr
                170px;

            min-height: 27px;

            padding:
                2px 12px;
        }
        .fila:hover
        {
            background: #292929;
        }
        .offset
        {
            color: #569cd6;

            padding-top: 4px;
        }
        .hex
        {
            display: flex;

            gap: 4px;
        }
        .byte
        {
            width: 24px;

            height: 23px;

            background: transparent;

            color: #dcdcaa;

            border:
                1px solid transparent;

            text-align: center;

            font-family:
                Consolas,
                monospace;
        }
        .byte:focus
        {
            outline: none;

            border:
                1px solid #569cd6;

            background: #264f78;
        }
        .byte2
        {
            width: 24px;

            height: 23px;

            color: #9cdcfe;

            text-align: center;

            padding-top: 3px;
        }
        .ascii
        {
            white-space: pre;

            color: #ce9178;
        }
        /*
            Byte diferente
        */
        .diferente
        {
            background:
                #672727 !important;

            color:
                #ff9999 !important;

            border-color:
                #ff5555 !important;
        }
        /*
            Diferencia seleccionada
        */
        .actual
        {
            background:
                #b06000 !important;

            color:
                white !important;

            border-color:
                #ffcc00 !important;
        }
        /*
            Coincidencias de búsqueda
        */
        .busqueda
        {
            background:
                #665c00 !important;

            color:
                #ffff99 !important;

            border-color:
                #ffff00 !important;
        }
        /*
            Coincidencia actual
        */

        .busquedaActual
        {
            background:
                #b06000 !important;

            color:
                white !important;

            border-color:
                #ffcc00 !important;
        }
</style>
</head>
<body>
    <!-- ===================================
         BARRA DE HERRAMIENTAS
         =================================== -->
    <div id="barra">
        <button onclick="abrir1()">
            Abrir archivo 1
        </button>
        <button onclick="abrir2()">
            Abrir archivo 2
        </button>
        <button onclick="comparar()">
            Comparar
        </button>
        <button onclick="primeraDiferencia()">
            |&lt;
        </button>
        <button onclick="anteriorDiferencia()">
            &lt;
        </button>
        <button onclick="siguienteDiferencia()">
            &gt;
        </button>
        <button onclick="ultimaDiferencia()">
            &gt;|
        </button>
        <span id="contador">
            Diferencias: 0
        </span>
        <input type="text" id="buscar" placeholder="Buscar HEX/texto">
        <button onclick="buscar()">
            Buscar
        </button>
        <button onclick="anteriorBusqueda()">
            Buscar anterior
        </button>
        <button onclick="siguienteBusqueda()">
            Buscar siguiente
        </button>
        <input type="text" id="offset" placeholder="Offset HEX" style="width: 100px;">
        <button onclick="irAOffset()">
            Ir
        </button>
        <button onclick="guardar()">
            Guardar
        </button>
        <span id="info">
            Sin archivos
        </span>
    </div>
    <!-- ===================================
         RESULTADO
         =================================== -->
    <div id="resultado">
        Abre dos archivos y pulsa Comparar.
    </div>
    <!-- ===================================
         INPUTS DE ARCHIVOS
         =================================== -->
    <input type="file" id="archivo1">
    <input type="file" id="archivo2">
    <!-- ===================================
         CABECERA
    =================================== -->
    <div id="cabecera">
        <div>
            OFFSET
        </div>
        <div>
            ARCHIVO 1
        </div>
        <div>
            ARCHIVO 2
        </div>
        <div>
            ASCII
        </div>
    </div>
    <!-- ===================================
         EDITOR
     =================================== -->


    <div id="editor"></div>
<script>
/*
    ====================================
    VARIABLES
    ====================================
*/
let datos1 = new Uint8Array(0);
let datos2 = new Uint8Array(0);
let nombre1 = "archivo1.bin";
let nombre2 = "archivo2.bin";
const MAX_TAMANO = 1024 * 1024;
/*
    Lista de diferencias
*/
let diferencias = [];
/*
    Índice de diferencia actual
*/
let indiceDiferencia = -1;
/*
    Lista de resultados de búsqueda
*/
let resultadosBusqueda = [];
/*
    Índice de búsqueda actual
*/
let indiceBusqueda = -1;
/*
    Elementos HTML
*/
const archivo1 = document.getElementById("archivo1");
const archivo2 = document.getElementById("archivo2");
const editor = document.getElementById("editor");
/*
    ====================================
    ABRIR ARCHIVO 1
    ====================================
*/
function abrir1()
{
   archivo1.click();
}
archivo1.addEventListener("change", async function()
{
    const archivo = this.files[0];

    if(!archivo)
    {
        return;
    }

    if(archivo.size > MAX_TAMANO)
    {
        alert("El archivo no puede superar 1 MB.");

        this.value = "";

        return;
    }

    nombre1 = archivo.name;

    const buffer = await archivo.arrayBuffer();

    datos1 = new Uint8Array(buffer);

    /*
        Limpiar comparación
    */

    diferencias = [];

    indiceDiferencia = -1;

    mostrar();

    actualizarInfo();
});
/*
    ====================================
    ABRIR ARCHIVO 2
    ====================================
*/
function abrir2()
{
   archivo2.click();
}
archivo2.addEventListener("change", async function()
{
    const archivo = this.files[0];

    if(!archivo)
    {
        return;
    }

    if(archivo.size > MAX_TAMANO)
    {
        alert("El archivo no puede superar 1 MB.");

        this.value = "";

        return;
    }

    nombre2 = archivo.name;

    const buffer = await archivo.arrayBuffer();

    datos2 = new Uint8Array(buffer);

    diferencias = [];

    indiceDiferencia = -1;

    mostrar();

    actualizarInfo();
});
/*
    ====================================
    ACTUALIZAR INFORMACIÓN
    ====================================
*/
function actualizarInfo()
{
   document.getElementById("info").textContent = "Archivo 1: " + datos1.length + " bytes | Archivo 2: " + datos2.length + " bytes";
}
/*
    ====================================
    MOSTRAR ARCHIVOS
    ====================================
*/
function mostrar()
{
   editor.innerHTML = "";
   const max = Math.max(datos1.length, datos2.length);
   const fragment = document.createDocumentFragment();
   /*
       Recorrer archivo
       en grupos de 16 bytes
   */
   for(let i = 0; i < max; i += 16)
   {
      const fila = document.createElement("div");
      fila.className = "fila";
      /*
          ----------------------------
          OFFSET
          ----------------------------
      */
      const offset = document.createElement("div");
      offset.className = "offset";
      offset.textContent = i.toString(16).padStart(8, "0").toUpperCase();
      fila.appendChild(offset);
      /*
          ----------------------------
          HEX ARCHIVO 1
          ----------------------------
      */
      const hex1 = document.createElement("div");
      hex1.className = "hex";
      /*
          ----------------------------
          HEX ARCHIVO 2
          ----------------------------
      */
      const hex2 = document.createElement("div");
      hex2.className = "hex";
      /*
          ----------------------------
          ASCII
          ----------------------------
      */
      const ascii = document.createElement("div");
      ascii.className = "ascii";
      let texto = "";
      /*
          Mostrar 16 bytes
      */
      for(let j = 0; j < 16; j++)
      {
         const pos = i + j;
         /*
             ------------------------
             ARCHIVO 1
             ------------------------
         */
         if(pos < datos1.length)
         {
            const input = document.createElement("input");
            input.className = "byte";
            input.maxLength = 2;
            input.value = datos1[pos].toString(16).padStart(2, "0").toUpperCase();
            input.dataset.pos = pos;
            input.addEventListener("input", editarByte);
            input.addEventListener("keydown", navegar);
            hex1.appendChild(input);
         }
         else
         {
            const espacio = document.createElement("span");
            espacio.style.width = "24px";
            hex1.appendChild(espacio);
         }
         /*
             ------------------------
             ARCHIVO 2
             ------------------------
         */
         if(pos < datos2.length)
         {
            const span = document.createElement("span");
            span.className = "byte2";
            span.textContent = datos2[pos].toString(16).padStart(2, "0").toUpperCase();
            span.dataset.pos = pos;
            hex2.appendChild(span);
         }
         else
         {
            const espacio = document.createElement("span");
            espacio.style.width = "24px";
            hex2.appendChild(espacio);
         }
         /*
             ------------------------
             ASCII
             ------------------------
         */
         let b = null;
         if(pos < datos1.length)
         {
            b = datos1[pos];
         }
         else if(pos < datos2.length)
         {
            b = datos2[pos];
         }
         if(b !== null)
         {
            if(b >= 32 && b <= 126)
            {
               texto += String.fromCharCode(b);
            }
            else
            {
               texto += ".";
            }
         }
         else
         {
            texto += " ";
         }
      }
      ascii.textContent = texto;
      fila.appendChild(hex1);
      fila.appendChild(hex2);
      fila.appendChild(ascii);
      fragment.appendChild(fila);
   }
   editor.appendChild(fragment);
   /*
       Marcar diferencias
   */
   if(diferencias.length > 0)
   {
      marcarDiferencias();
   }
   /*
       Marcar búsquedas
   */
   if(resultadosBusqueda.length > 0)
   {
      marcarBusquedas();
   }
}
/*
    ====================================
    COMPARAR
    ====================================
*/
function comparar()
{
   diferencias = [];
   indiceDiferencia = -1;
   const max = Math.max(datos1.length, datos2.length);
   /*
       Comparar cada byte
   */
   for(let i = 0; i < max; i++)
   {
      const a = i < datos1.length ? datos1[i] : null;
      const b = i < datos2.length ? datos2[i] : null;
      if(a !== b)
      {
         diferencias.push(i);
      }
   }
   document.getElementById("contador").textContent = "Diferencias: " + diferencias.length;
   /*
       No existen diferencias
   */
   if(diferencias.length === 0)
   {
      document.getElementById("resultado").textContent = "Los archivos son idénticos.";
      mostrar();
      return;
   }
   /*
       Existen diferencias
   */
   document.getElementById("resultado").textContent = "Se encontraron " + diferencias.length + " diferencias.";
   mostrar();
   /*
       Ir a la primera
   */
   indiceDiferencia = 0;
   irADiferencia();
}
/*
    ====================================
    MARCAR DIFERENCIAS
    ====================================
*/
function marcarDiferencias()
{
   for(let i = 0; i < diferencias.length; i++)
   {
      const pos = diferencias[i];
      const e1 = document.querySelector('.byte[data-pos="' + pos + '"]');
      const e2 = document.querySelector('.byte2[data-pos="' + pos + '"]');
      if(e1)
      {
         e1.classList.add("diferente");
      }
      if(e2)
      {
         e2.classList.add("diferente");
      }
   }
}
/*
    ====================================
    IR A DIFERENCIA
    ====================================
*/
function irADiferencia()
{
   if(diferencias.length === 0)
   {
      return;
   }
   /*
       Quitar selección anterior
   */
   document.querySelectorAll(".actual").forEach(function(elemento)
   {
      elemento.classList.remove("actual");
   });
   const pos = diferencias[indiceDiferencia];
   const e1 = document.querySelector('.byte[data-pos="' + pos + '"]');
   const e2 = document.querySelector('.byte2[data-pos="' + pos + '"]');
   if(e1)
   {
      e1.classList.add("actual");
      e1.scrollIntoView(
      {
         behavior: "smooth",
         block: "center"
      });
   }
   if(e2)
   {
      e2.classList.add("actual");
   }
   const a = pos < datos1.length ? datos1[pos] : null;
   const b = pos < datos2.length ? datos2[pos] : null;
   const offset = "0x" + pos.toString(16).toUpperCase().padStart(8, "0");
   const valorA = a === null ? "--" : a.toString(16).padStart(2, "0").toUpperCase();
   const valorB = b === null ? "--" : b.toString(16).padStart(2, "0").toUpperCase();
   document.getElementById("resultado").textContent = "Diferencia " + (indiceDiferencia + 1) + " de " + diferencias.length + " | Offset " + offset + " | " + valorA + " → " + valorB;
}
/*
    ====================================
    PRIMERA DIFERENCIA
    ====================================
*/
function primeraDiferencia()
{
   if(diferencias.length === 0)
   {
      return;
   }
   indiceDiferencia = 0;
   irADiferencia();
}
/*
    ====================================
    DIFERENCIA ANTERIOR
    ====================================
*/
function anteriorDiferencia()
{
   if(diferencias.length === 0)
   {
      return;
   }
   indiceDiferencia--;
   if(indiceDiferencia < 0)
   {
      indiceDiferencia = diferencias.length - 1;
   }
   irADiferencia();
}
/*
    ====================================
    SIGUIENTE DIFERENCIA
    ====================================
*/
function siguienteDiferencia()
{
   if(diferencias.length === 0)
   {
      return;
   }
   indiceDiferencia++;
   if(indiceDiferencia >= diferencias.length)
   {
      indiceDiferencia = 0;
   }
   irADiferencia();
}
/*
    ====================================
    ÚLTIMA DIFERENCIA
    ====================================
*/
function ultimaDiferencia()
{
   if(diferencias.length === 0)
   {
      return;
   }
   indiceDiferencia = diferencias.length - 1;
   irADiferencia();
}
/*
    ====================================
    EDITAR BYTE
    ====================================
*/
function editarByte(e)
{
   let valor = e.target.value.replace(/[^0-9a-fA-F]/g, "");
   e.target.value = valor.toUpperCase();
   if(valor.length === 2)
   {
      const pos = parseInt(e.target.dataset.pos);
      const numero = parseInt(valor, 16);
      if(!isNaN(numero))
      {
         datos1[pos] = numero;
      }
   }
}
/*
    ====================================
    NAVEGAR ENTRE BYTES
    ====================================
*/
function navegar(e)
{
   const pos = parseInt(e.target.dataset.pos);
   let nueva = null;
   if(e.key === "ArrowRight")
   {
      nueva = document.querySelector('.byte[data-pos="' + (pos + 1) + '"]');
   }
   if(e.key === "ArrowLeft")
   {
      nueva = document.querySelector('.byte[data-pos="' + (pos - 1) + '"]');
   }
   if(e.key === "ArrowDown")
   {
      nueva = document.querySelector('.byte[data-pos="' + (pos + 16) + '"]');
   }
   if(e.key === "ArrowUp")
   {
      nueva = document.querySelector('.byte[data-pos="' + (pos - 16) + '"]');
   }
   if(nueva)
   {
      e.preventDefault();
      nueva.focus();
      nueva.select();
   }
}
/*
    ====================================
    BUSCAR
    ====================================
*/
function buscar()
{
   const texto = document.getElementById("buscar").value.trim();
   if(!texto)
   {
      return;
   }
   const limpio = texto.replace(/\s+/g, "");
   let patron = [];
   /*
       -------------------------------
       BUSCAR HEX
       -------------------------------
   */
   if(/^[0-9a-fA-F]+$/.test(limpio) && limpio.length % 2 === 0)
   {
      for(let i = 0; i < limpio.length; i += 2)
      {
         patron.push(parseInt(limpio.substr(i, 2), 16));
      }
   }
   /*
       -------------------------------
       BUSCAR TEXTO
       -------------------------------
   */
   else
   {
      for(let i = 0; i < texto.length; i++)
      {
         patron.push(texto.charCodeAt(i));
      }
   }
   /*
       Limpiar resultados
   */
   resultadosBusqueda = [];
   indiceBusqueda = -1;
   /*
       Buscar TODAS las coincidencias
   */
   for(let i = 0; i <= datos1.length - patron.length; i++)
   {
      let encontrado = true;
      for(let j = 0; j < patron.length; j++)
      {
         if(datos1[i + j] !== patron[j])
         {
            encontrado = false;
            break;
         }
      }
      if(encontrado)
      {
         resultadosBusqueda.push(i);
      }
   }
   /*
       No encontrado
   */
   if(resultadosBusqueda.length === 0)
   {
      document.getElementById("resultado").textContent = "No encontrado.";
      mostrar();
      return;
   }
   /*
       Primera coincidencia
   */
   indiceBusqueda = 0;
   mostrar();
   irABusqueda();
}
/*
    ====================================
    MARCAR RESULTADOS DE BÚSQUEDA
    ====================================
*/
function marcarBusquedas()
{
   /*
       Primero marcar todas
   */
   for(let i = 0; i < resultadosBusqueda.length; i++)
   {
      const pos = resultadosBusqueda[i];
      const elemento = document.querySelector('.byte[data-pos="' + pos + '"]');
      if(elemento)
      {
         elemento.classList.add("busqueda");
      }
   }
   /*
       Marcar la actual
   */
   if(indiceBusqueda >= 0)
   {
      const pos = resultadosBusqueda[indiceBusqueda];
      const elemento = document.querySelector('.byte[data-pos="' + pos + '"]');
      if(elemento)
      {
         elemento.classList.remove("busqueda");
         elemento.classList.add("busquedaActual");
      }
   }
}
/*
    ====================================
    IR A BÚSQUEDA
    ====================================
*/
function irABusqueda()
{
   if(resultadosBusqueda.length === 0)
   {
      return;
   }
   /*
       Quitar selección actual
   */
   document.querySelectorAll(".busquedaActual").forEach(function(elemento)
   {
      elemento.classList.remove("busquedaActual");
      elemento.classList.add("busqueda");
   });
   const pos = resultadosBusqueda[indiceBusqueda];
   const elemento = document.querySelector('.byte[data-pos="' + pos + '"]');
   if(elemento)
   {
      elemento.classList.remove("busqueda");
      elemento.classList.add("busquedaActual");
      elemento.scrollIntoView(
      {
         behavior: "smooth",
         block: "center"
      });
      elemento.focus();
      elemento.select();
   }
   const offset = "0x" + pos.toString(16).toUpperCase().padStart(8, "0");
   document.getElementById("resultado").textContent = "Coincidencia " + (indiceBusqueda + 1) + " de " + resultadosBusqueda.length + " | Offset " + offset;
}
/*
    ====================================
    SIGUIENTE BÚSQUEDA
    ====================================
*/
function siguienteBusqueda()
{
   if(resultadosBusqueda.length === 0)
   {
      return;
   }
   indiceBusqueda++;
   if(indiceBusqueda >= resultadosBusqueda.length)
   {
      indiceBusqueda = 0;
   }
   irABusqueda();
}
/*
    ====================================
    BÚSQUEDA ANTERIOR
    ====================================
*/
function anteriorBusqueda()
{
   if(resultadosBusqueda.length === 0)
   {
      return;
   }
   indiceBusqueda--;
   if(indiceBusqueda < 0)
   {
      indiceBusqueda = resultadosBusqueda.length - 1;
   }
   irABusqueda();
}
/*
    ====================================
    IR A OFFSET
    ====================================
*/
function irAOffset()
{
   const valor = document.getElementById("offset").value.trim();
   const pos = parseInt(valor, 16);
   if(isNaN(pos) || pos < 0 || pos >= datos1.length)
   {
      alert("Offset inválido.");
      return;
   }
   irAPosicion(pos);
}
/*
    ====================================
    IR A POSICIÓN
    ====================================
*/
function irAPosicion(pos)
{
   const elemento = document.querySelector('.byte[data-pos="' + pos + '"]');
   if(!elemento)
   {
      return;
   }
   elemento.scrollIntoView(
   {
      behavior: "smooth",
      block: "center"
   });
   elemento.focus();
   elemento.select();
}
/*
    ====================================
    GUARDAR ARCHIVO 1
    ====================================
*/
function guardar()
{
   if(datos1.length === 0)
   {
      alert("No hay archivo abierto.");
      return;
   }
   const blob = new Blob(
      [datos1],
      {
         type: "application/octet-stream"
      });
   const enlace = document.createElement("a");
   enlace.href = URL.createObjectURL(blob);
   enlace.download = nombre1;
   enlace.click();
   URL.revokeObjectURL(enlace.href);
}
/*
    ====================================
    ATAJOS DE TECLADO
    ====================================
*/
document.addEventListener("keydown", function(e)
{
   /*
       Ctrl + S
   */
   if(e.ctrlKey && e.key.toLowerCase() === "s")
   {
      e.preventDefault();
      guardar();
   }
   /*
       Ctrl + F
   */
   if(e.ctrlKey && e.key.toLowerCase() === "f")
   {
      e.preventDefault();
      document.getElementById("buscar").focus();
   }
   /*
       F3
       Siguiente búsqueda
   */
   if(e.key === "F3" && !e.shiftKey)
   {
      e.preventDefault();
      if(resultadosBusqueda.length > 0)
      {
         siguienteBusqueda();
      }
      else
      {
         siguienteDiferencia();
      }
   }
   /*
       Shift + F3
       Anterior búsqueda
   */
   if(e.key === "F3" && e.shiftKey)
   {
      e.preventDefault();
      if(resultadosBusqueda.length > 0)
      {
         anteriorBusqueda();
      }
      else
      {
         anteriorDiferencia();
      }
   }
});
</script>
</body>
</html>


Bueno creo que eso es todo aquí les dejo una foto donde compare un ejecutable el original y el modificado



Espero les guste saludos Flamer y si le falta algo me dicen ya que es algo muy simple


martes, 11 de agosto de 2026

Solucion al Crackme de Mek En Delphi

Hola amigos hoy veremos la solución del crackme de Mek y si se preguntan quien es Mek era un forero del foro el hacker.net también llamado Señor Patata así lo mienta rojodos en un hilo del foro, su crackme lo encontré en dicho foro y esta fácil de resolver y entretenido bueno para pasar el rato, bueno empecemos aquí una foto del reto.

Para empezar el campo nombre debe contener 10 dígitos o más, si contiene menos nos saca del programa.

Ahora aquí es donde está el chico bueno o mejor dicho el corazón del crackme donde hace la magia

00408408 | 8B55 FC                  | mov edx,dword ptr ss:[ebp-4]               | [ebp-04]:"polokolomes"
0040840B | 0FB6541A FF              | movzx edx,byte ptr ds:[edx+ebx-1]          |
00408410 | 33C2                     | xor eax,edx                                |
00408412 | 03C3                     | add eax,ebx                                |
00408414 | 50                       | push eax                                   |
00408415 | 8D45 FC                  | lea eax,dword ptr ss:[ebp-4]               | [ebp-04]:"polokolomes"

Lo que hace es tomar dígito por dígito del campo nombre (que tiene que ser mayor a 10 dígitos) lo xorea con la longitud del campo nombre y después le suma la posición del dígito si es el 1 o 2 o 3 según en la vuelta que vaya y con longitud del nombre me refiero a el número de dígitos del campo en este caso "polokolomes" tiene 11 dígitos de longitud.

Bueno aquí les dejo una foto del generador de claves


aqui el codigo por si lo quieren probar

<html>
<head>
<title>Keygen</title>
</head>
<body bgcolor="black">
<marquee style="color:white;font-size:30;">Generador De Claves Del Crackme De MEK En Delphi  ...:::By Flamer:::...</marquee><br>
<br><br>
<center>
<input type="text" id="nombre" placeholder="Entrada" size="50px" style="background-color:DarkSlateGray;color:white;text-align:center;">
<input type="button" value="Copiar" onclick="copiar1()">
<br><br>
<input type="text" id="pass" placeholder="Salida" size="50px" style="background-color:DarkSlateGray;color:white;text-align:center;">
<input type="button" value="Copiar" onclick="copiar2()">
<br><br>
<input type="button" id="g" value="Generar" onclick="generar()">
<input type="button" id="a" value="Automatico" onclick="autoni()">
<input type="button" id="c" value="Limpiar" onclick="cleare()">
</center> 
<script>
let tiempo;
function copiar1() 
{
   let c=document.getElementById('nombre'); 
   c.select();
   document.execCommand('copy');
}
function copiar2() 
{
   let c=document.getElementById('pass'); 
   c.select();
   document.execCommand('copy');
}
function generar()
{
   let nom = document.getElementById("nombre").value;
   if(nom.length>=10)
   {
      document.getElementById("pass").value=coder(nom);
   }
   else
   {
      alert("Error El Nombre Debe Contener 10 o Mas Digitos Menos No");
   }
}
function cleare()
{
   document.getElementById("nombre").value="";
   document.getElementById("pass").value="";
}
function autoni()
{
   if(document.getElementById("a").value=="Automatico")
   {
      document.getElementById("a").value="Detener";
      document.getElementById("g").disabled=true;	
      document.getElementById("c").disabled=true;	  
      tiempo=setTimeout("auto()",10);	  
   }
   else
   {
      document.getElementById("a").value="Automatico"; 
      document.getElementById("g").disabled=false;	
      document.getElementById("c").disabled=false;	
      clearTimeout(tiempo);
   }
}
function auto()
{
   let cadena = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
   let largo  = cadena.length - 1;
   let x,posi,nom="";
   let lar = Math.floor(Math.random() * (30 - 10 + 1)) + 10;
   
   for(x=0;x<lar;x++)
   {
      posi=Math.floor(Math.random() * (largo - 0 + 1)) + 0;
      nom+=cadena[posi];
   }
   
   document.getElementById("nombre").value=nom;
   document.getElementById("pass").value=coder(nom); 
   
   tiempo=setTimeout("auto()",10);   
}
function coder(nom)
{
   // Tu secuencia hexadecimal original
   let x,codigo="",digi;
   
   for(x=0;x<nom.length;x++)
   {
      digi=nom[x].charCodeAt(0);
      digi=(digi ^ nom.length) + (x+1);
      codigo+=digi.toString(16);
   }
   
// Ejecutar e imprimir el resultado
   let resultado = Texto(codigo);
   return resultado;
}
function Texto(cadenaHex) 
{
    // 1. Tabla completa de caracteres de la página de códigos CP437 (0x00 a 0xFF)
    const Symbols = 
        "\0☺☻♥♦♣♠•◘○◙♂♀♪♫☼►◄↕‼¶§▬↨↑↓→←∟↔▲▼" +
        " !\"#$%&'()*+,-./0123456789:;<=>?" +
        "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" +
        "`abcdefghijklmnopqrstuvwxyz{|}~⌂" +
        "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒ" +
        "áíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐" +
        "└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀" +
        "αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ ";

    // 2. Limpiar los espacios en blanco
    const cadenaLimpia = cadenaHex.replace(/\s+/g, '');
    
    // 3. Extraer las parejas hexadecimales
    const parejas = cadenaLimpia.match(/.{1,2}/g);
    if (!parejas) return "";

    // 4. Mapear cada byte con su símbolo correspondiente en la tabla antigua
    let resultado = "";
    for (let i = 0; i < parejas.length; i++)
    {
        const valorDecimal = parseInt(parejas[i], 16);
        // Asegurarnos de que el índice esté dentro del rango de la tabla (0-255)
        if (valorDecimal >= 0 && valorDecimal < 256)
	{
            resultado += Symbols[valorDecimal];
        }
    }
    return resultado;
}
</script>
</body>
</html>

Si me preguntan por qué algo tan sencillo ocupa un programa tan grande es porque para empezar tiene 3 botones el limpiar, el automático y el generar.... El limpiar no ocupa mucho código, pero lo demás si y más ya que el crackme el serial da dígitos raros y si se preguntan eso que tiene que ver pues les explico, no es lo mismo presionar  Alt+1 que imprimir dicho carácter desde un programa... ya que si lo haces desde un programa te da un cuadrito ejemplo:

Si presionó Alt+1 me da esto , pero si lo hago desde un programa pasa esto imagen:


Bueno aqui la imagen del mensaje de correcto



Bueno creo que eso es todo saludos Flamer y hasta la próxima y saludos a todos los CrackSLatinoS [CLS] en especial a Ricardo,Neutrino que acabó de leer su tutorial del crackme 6 de RogerFm.Net, también a apuromafo que me ayudo en algunos crackmes de la página hbh.sh el cual el primero era muy sencillo y no veía la solución por siego jajaja y tambien a tincopasan y a todos los demas de la lista saludos


martes, 4 de agosto de 2026

Solucion al Crackme 8 de RogerFm.Net

Hola amigos este es el último reto de la sección de crackmes de la página rogerfm.net, es el último crackme que nos quedaba pendientes y con esto terminamos, este reto tenía tiempo que lo avía solucionado así que empecemos.

ingresamos un serial al azar y nos arroja lo siguiente



Primera mente el reto acepta solo de 1 a 8 dígitos y tenemos que poner como fecha en el ordenador 20/05/1992 para que quede registrado.

Bueno para generar el serial tomamos digitos al azar de esta cadena

0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ

Nota:tome esta cadena porque no tiene dígitos raros, primera mente para generar el serial tomamos el dígito 1 y 7 al azar de la cadena, después para calcular el dígito 3 tenemos que tomar una posición al azar de 0 a 8, en el keygen es de 1 a 9 porque en JavaScript los string empiezan de 0.

Bueno tenemos la longitud de 0 a 8 y después lo sumamos con el valor ASCII del dígito 1 y verificamos si se encuentra un dígito en la cadena antes mencionada y si se encuentra lo tomamos si no se encuentra el ciclo se repite, eso mismo pasa con el dígito 8 del serial pero esta vez no se suma, se resta y se busca en la cadena si se encuentra algún dígito que restado del valor ASCII del dígito 7 menos la longitud de 0 a 8 y si se encuentra se toma y si no el ciclo se repite.

Esto mismo pasa con los dígitos 5 y 6... los dígitos 2 y 4 se toman al azar desde la cadena y al dígito 5 se le suma x longitud de 0 a 8 y para calcular el dígito 6 se hace lo mismo, pero a este sele resta, es igual como se hizo anterior mente.

Bueno el serial del archivo "abc.xyz" que se descarga se toman los dígitos 6,4,8,1 del serial que se pone en el crackme, esos dígitos van adentro del archivo antes mencionado.

aquí el código del generador de claves

<html>
<head><title>Keygen Crackme 8 Rogerfm.Net</title>
</head>
<body bgcolor="black">
<center>
<table border="1" width="1200" style="font-size:30px;color:white;">
<tr><td>
<marquee>Keygen Crackme 8 Rogerfm.Net    .....:::::By Hacked Flamer:::::.....</marquee>
</td></tr>
</table>
<br><br><br><br>
<table border="1" width="600" height="180" style="font-size:20px;text-align:center;color:white;">
<tr><td>
<input type="text" id="s1" placeholder="Serial" style="background-color:#4D524A;color:white;font-size:15;text-align:center;"> <input type="button" value="Copy" onclick="copiar1()"><br><br>
<input type="button" value="Descargar Archivo" onclick="downloads()" style="background-color:Gray;color: white;font-size: 10px;font-size:30px;">
</td></tr>
</table>
<br><br>
<input type="button" id="genera" value="Generar" onclick="generar()">    <input type="button" value="Detener" onclick="stop()">
<br><br><br><br><br><br><br><br><br><br><br><br>
<div style="color:white;font-size:23px">Debes Cambiar La Fecha De Tu Sistema Operativo a 20/05/1992 Para Que El Crackme Pueda Ser Registrado Y El Archivo abc.xyz Debe Estar En La Misma Carpeta Del Crackme</div>
</center>
<script>
let tiempo;
let bytes;
function copiar1() 
{
   document.getElementById("s1").disabled=false;
   let c=document.getElementById('s1'); 
   c.select();
   document.execCommand('copy');
   document.getElementById("s1").disabled=true;
}
//===============================================================
function stop()
{
   clearTimeout(tiempo);
   document.getElementById("genera").disabled=false;
}
//===============================================================
function generar()
{ 
  tiempo=setTimeout(function(){gen()},10);
  document.getElementById("genera").disabled=true;
}
//================================================================
function gen()
{
  let digi   = new Array(8),posicion,sr,a,b,x,y;
  let cadena = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
  let largo  = cadena.length - 1;
   
  posicion = Math.floor(Math.random() * ((largo+1) - 0) + 0);
  digi[1]  = cadena[posicion];
  
  posicion = Math.floor(Math.random() * ((largo+1) - 0) + 0);
  digi[7]  = cadena[posicion];
  
  sr = Math.floor(Math.random()*((9+1)-1)+1);
  a  = digi[1].charCodeAt(0);
  b  = digi[7].charCodeAt(0);
  do
  {
     x = String.fromCharCode(a + sr);
     y = String.fromCharCode(b - sr);
     sr--;
  }
  while((cadena.indexOf(x) == -1) || (cadena.indexOf(y) == -1))
  
  digi[3] = x; 
  digi[8] = y;  
 
  posicion = Math.floor(Math.random() * ((largo+1) - 0) + 0);
  digi[2]  = cadena[posicion];
  
  posicion = Math.floor(Math.random() * ((largo+1) - 0) + 0);
  digi[4]  = cadena[posicion];
  
  sr = Math.floor(Math.random()*((9+1)-1)+1);
  a  = digi[2].charCodeAt(0);
  b  = digi[4].charCodeAt(0);
  do
  {
     x = String.fromCharCode(a + sr);
     y = String.fromCharCode(b - sr);
     sr--;
  }
  while((cadena.indexOf(x) == -1) || (cadena.indexOf(y) == -1))
  
  digi[5] = x; 
  digi[6] = y;  
 
 tiempo=setTimeout(function(){gen()},10);
 
 document.getElementById("s1").value=digi[1] + digi[2] + digi[3] + digi[4] + digi[5] + digi[6] + digi[7] + digi[8];
 bytes=digi[6] + digi[4] + digi[8] + digi[1];
}
function downloads()
{
   const blob = new Blob([bytes], { type: 'application/octet-stream' });
   const enlace = document.createElement('a');
   enlace.href = URL.createObjectURL(blob);
   enlace.download = 'abc.xyz'; 
   enlace.click();
   URL.revokeObjectURL(enlace.href);  
}
</script>
</body>
</html>

Si lo quieren probar solo copean el codigo en el bloc de notas y pegan para despues aguardar como "genera.html" aqui una foto


Damos clic en generar y luego detener y descargamos el archivo para después aguardar en el mismo lugar del crackme y copeamos el serial dado para después pegarlo en el crackme y nos arroja lo siguiente.


Bueno creo que eso es todo por hoy otra cosa no me adentro tanto en el debugger x32dbg, ya que como digo son soluciones y explico como funcionan los retos, no explico como traceo el crackme, ni pongo imágenes del desensamblado por miedo a que me quiten el blog, son soluciones y explicó como funciona.

En fin espero les haya gustado saludo flamer


sábado, 25 de julio de 2026

Solucion al Crackme De Tr4ceflow

Hola amigos hoy veremos la solución del crackme de tr4ceflow, este reto o crackme mejor dicho lo resolví hace tiempo en uno de los retos que ponía el maestro Ricardo Narvaja en el grupo de crackslatinos y es de nivel 3, ya que lo encontré en la página de crackmes.one y hay dice su nivel... Bueno sin tanta palabra pasamos a verlo

si ejecutamos el crackme nos arroja un mensaje que tenemos que eliminar


Bueno eso lo hacemos nopeando la api MessageBoxA que arroja ese mensaje así que para eso lo haré desde un editor hexadecimal y nos quedaría así


Pueden usar el x32dbg para eso y encontrar el mensaje y nopearlo por si lo quieren hacer de ese modo

Ahora pasamos a explicar como funciona o como genera el serial válido, para empezar el nombre debe contener mínimo 2 dígitos y máximo 5 si no nos arroja el mensaje incorrecto, otra cosa el nombre ingresado su dígitos son convertidos a mayúsculas.

después de esto el crackme busca el dígito menor del nombre cuando digo menor me refiero a su código ASCII como por ejemplo el menor vendría siendo el dígito A otra cosa el crackme no acepta números en el campo nombre si pones te manda el cartelito incorrecto.

Ya que tiene el dígito menor este dígito se le es restado 2 y después entra en un bucle y a cada dígito sele resta dicho valor y en cada vuelta de le resta 1 ejemplo si ingresamos como nombre la palabra "papa"... Nota lo convierte a mayúsculas y quedaría así "PAPA" y A=65-2 es igual a 63

Digito   |   Valor ASCII   |  Digito Menor  |  Resultado  |

P ------------- 80 --------------- 63 -------------- 17

A -------------65 --------------- 62 -------------- 3

P ------------- 80 --------------- 61 -------------- 19

A ------------ 65 --------------- 60 -------------- 5

después el campo serial tiene que ser de 8 a 10 dígitos si no nos manda el cartelito de error, ya que tenemos el serial este es dividido por los siguientes valores

37  41  43  47  53

Como ven es para 5 digitos, ya que cuando divida por 37 el residuo de la división tiene que dar 17 como en el primer digito de la tabla anterior y después divide por 41 y el residuo de la división tiene que dar 3 y así después divide por 43 y el residuo tiene que dar 19 y así... Como no tengo el serial para "papa" no les puedo poner la tabla como ejemplo

Y si se preguntan como hice el keygen, pues les digo que mi keygen da nombres al azar y no saca el serial de un nombre en especifico y como me dijo mi amigo tincopasan eso no es un keygen ya que no te genera un serial para un nombre específico, pero en fin se me hizo más fácil ami y funciona para el crackme ya que te manda el cartelito correcto aquí una foto del keygen de aquella ves que lo hice para crackslatinos


Como perdí el código fuente de aquella vez no puedo mostrárselos así que ahora lo hice en JavaScript y HTML aquí el código... Si quieren probarlo ya saben copean y pegan en el bloc de notas como keygen.html

<html>
<head>
<title>Generador De Claves</title>
<style>
.textbox
{
   background-color:black;
   color:lime;
   border-radius:8px;
   border:2px solid;
   height:30px;
   width:300px;
   text-align:center;
   font-size:15px;
}
.textbox:hover
{
   border-color: white;
}
.mark
{
   color:lime;
   font-size:35px;
}
.boton
{
   background-color:black;
   color:lime;
   border-radius:8px;
   border:2px solid;
   height:30px;
   width:100px;
}
.boton:hover
{
   border-color: white;
}
</style>
</head>
<body bgcolor="black">
<marquee class="mark">Keygen Crackme tr4ceflow   ...:::By Flamer:::...</marquee><br>
<br><br>
<center>
<input type="text" id="nick" placeholder="Nombre" class="textbox" disabled>
<input type="button" value="Copiar" onclick="copiar1()" class="boton">
<br><br>
<input type="text" id="pass" placeholder="Serial" class="textbox" disabled>
<input type="button" value="Copiar" onclick="copiar2()" class="boton">
<br><br>
<input type="button" id="g" value="Generar" onclick="auto()" class="boton">&emsp;
<input type="button" id="d" value="Detener" onclick="detente()" class="boton" disabled>
</center> 
<script>
let t=0;
function copiar1() 
{
   let c=document.getElementById('nick'); 
   document.getElementById('nick').disabled=false;
   c.select();
   document.execCommand('copy');
   document.getElementById('nick').disabled=true;
}
function copiar2() 
{
   let c=document.getElementById('pass'); 
   document.getElementById('pass').disabled=false;
   c.select();
   document.execCommand('copy');
   document.getElementById('pass').disabled=true;
}
function inverso(a, m)
{
    let m0 = m;
    let x0 = 0;
    let x1 = 1;

    while (a > 1)
    {
        let q = Math.floor(a / m);

        let t = m;
        m = a % m;
        a = t;

        t = x0;
        x0 = x1 - q * x0;
        x1 = t;
    }

    if (x1 < 0)
        x1 += m0;

    return x1;
}

function CRT(modulos, residuos)
{
    let M = 1;

    for (let i = 0; i < modulos.length; i++)
        M *= modulos[i];

    let r = 0;

    for (let i = 0; i < modulos.length; i++)
    {
        let Mi = M / modulos[i];
        let inv = inverso(Mi % modulos[i], modulos[i]);
        r += residuos[i] * Mi * inv;
    }

    r %= M;

    if (r < 0)
        r += M;

    return r;
}

function calcularP1(nombre)
{
    let p1 = [];
    let d = nombre.charCodeAt(0);

    // Buscar el menor ASCII
    for (let i = 1; i < nombre.length; i++)
    {
        let c = nombre.charCodeAt(i);

        if (c < d)
            d = c;
    }

    d -= 2;

    for (let i = 0; i < nombre.length; i++)
    {
        let c = nombre.charCodeAt(i);
        p1[i] = c - d;
        d--;
    }

    return p1;
}

function nombreAleatorio()
{
    const letras = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    let largo = Math.floor(Math.random() * 4) + 2; // 2 a 5 letras
    let nombre = "";

    for (let i = 0; i < largo; i++)
        nombre += letras[Math.floor(Math.random() * letras.length)];

    return nombre;
}

function generar()
{
   const modulos = [37,41,43,47,53];
   let nombre,numero;
   for(let i=0;i<10;i++)
   {
       nombre = nombreAleatorio();

       let p1 = calcularP1(nombre);

    // completar residuos si el nombre tiene menos de 5 letras
       while(p1.length<5)
           p1.push(0);

       numero = CRT(modulos,p1);
   }
   document.getElementById("nick").value=nombre;
   document.getElementById("pass").value=numero;
   t=setTimeout("generar()",10);
}   
function auto()
{
   generar();
   document.getElementById('g').disabled=true;
   document.getElementById('d').disabled=false;
}
function detente()
{
   clearTimeout(t);
   document.getElementById('g').disabled=false;
   document.getElementById('d').disabled=true;
}
</script>
</body>
</html>

Y aqui una foto


Una cosa tengo que aclarar la primera vez que lo hice no use chatgpt, no existían las IA en aquel entonces me toco quebrarme la cabeza por días así que esta vez si, porque no quise batallar para eso solo hice lo que hace el crackme y le pedí a la IA que lo revirtiera y guala tenemos el keygen

bueno en fin espero les haya gustado saludo flamer y una foto del reto ya solucionado


Quiero mandar saludos a todos los crackslatinos en especial a ricardo por el reto, tincopasan por decirme que eso no es un keygen...pero funciona no jajaja, apuromafo, softdat, @papitapro1234,  EdePC y a MCKSys Argentina y demás


jueves, 16 de julio de 2026

Solucion De Un Crackme Random 0

Hola amigos hoy veremos un crackme sencillo solo que esta vez no sé quien es el autor por esa razón le puse random y cero porque es el primero que no se su nombre y si después me encuentro con otro crackme igual donde no sepa su nombre le pondré random 1 y así sucesivamente.... Bueno empecemos

aquí una foto del reto


Como dice el formato la contraseña o serial tiene que ser de 3 partes divididos por guiones lo que nos da un total de 14 dígitos de longitud si tiene más dígitos el serial el crackme se cierra o marca error.

Bueno y si se preguntan que hace el crackme pues deja les digo toma el nombre de el usuario de Windows actual y suma sus dígitos después toma el nombre de la PC y hace los mismos los suma y por último toma el pid de su proceso este tiene que ser menor o igual a 4 dígitos porque si su pid es 12345 el crackme no nos mandara el cartelito correcto... Por otro lado su pid es 123 el keygen que le hice le agrega un cero al principio y quedaría así 0123.

Bueno si quieren saber el nombre de usuario solo abran el cmd y tecleen lo siguiente:

echo %USERNAME%

Y les mostrara el nombre de usuario de Windows actual, ahora si quieren el nombre de la PC solo teclean: 

echo %COMPUTERNAME%

Ahora aquí les dejó el creador de claves para este reto o keygen, no necesitan hacer lo de arriba el keygen lo hace por ustedes solo dije lo de arriba como dato extra

<html>
<head>
<title>Generador De Claves</title>
<style>
.textbox
{
   background-color:black;
   color:lime;
   border-radius:8px;
   border:2px solid;
   height:30px;
   width:300px;
   text-align:center;
   font-size:15px;
}
.textbox:hover
{
   border-color: white;
}
.mark
{
   color:lime;
   font-size:35px;
}
.boton
{
   background-color:black;
   color:lime;
   border-radius:8px;
   border:2px solid;
   height:30px;
   width:100px;
}
.boton:hover
{
   border-color: white;
}
</style>
</head>
<body bgcolor="black">
<marquee class="mark">Keygen Crackme Random   ...:::By Flamer:::...</marquee><br>
<br><br>
<center>
<input type="file" id="exe" style="width:400px;" class="textbox">
<br><br>
<input type="text" id="pass" placeholder="Serial" class="textbox">
<input type="button" value="Copiar" onclick="copiar()" class="boton">
<br><br>
<input type="button" value="Generar" onclick="generar()" class="boton">
</center> 
<script>
function copiar()
{
    var c = document.getElementById("pass");
    window.clipboardData.setData("Text", c.value);
}
function generar()
{
    var net, fso,locator, wmi,procesos,e,proceso,archivo,usuario,suma1,suma2,computa;
    var pid=0,p="";

    try
    {
        net = new ActiveXObject("WScript.Network");
        fso = new ActiveXObject("Scripting.FileSystemObject");

        usuario = net.UserName;
        computa = net.ComputerName;

        archivo = fso.GetFile(document.getElementById("exe").value);

        locator = new ActiveXObject("WbemScripting.SWbemLocator");
        wmi = locator.ConnectServer(".", "root\\cimv2");

        procesos = wmi.ExecQuery("SELECT ProcessId, CommandLine FROM Win32_Process WHERE Name='" + archivo.Name + "'");

        e = new Enumerator(procesos);

        while (!e.atEnd())
        {
            proceso = e.item();

            if (proceso.CommandLine != null)
            {
                if (proceso.CommandLine.toLowerCase().indexOf(archivo.Path.toLowerCase()) != -1)
                {
                    pid = proceso.ProcessId;
                    break;
                }
            }

            e.moveNext();
        }
		
	p=pid.toString();
		
	if(p.length<=4)
	{
	   suma1=sumando(usuario);
           suma2=sumando(computa);
        
	   p=ceros(p);
	   suma1=ceros(suma1);
	   suma2=ceros(suma2);
		
           document.getElementById("pass").value = suma2 + "-" + suma1 + "-" + p;
	}
        else
	{
	   alert("El pid del crackme es mayor a 4 digitos, esto haria que el reto no quedara verificado,cierralo y ejecutalo de nuevo");
	}
    }
    catch (err)
    {
        alert("Error: " + err.description + "\n\nNúmero: " + err.number);
    }
}
function sumando(s)
{
   var x,suma=0,su="";
   for (x=0;x<s.length;x++)
   {
      suma+=s.charCodeAt(x);
   }
   
   su=suma.toString();
     
   return su;
}
function ceros(ss)
{
   var cer="";
   while(ss.length<4)
   {
      cer=cer + "0";
      ss=cer + ss;
   }
   return ss.toString();
}
</script>
</body>
</html>

Bueno si se preguntan por qué hago los keygenes en JavaScript y HTML es porque creo que los keygenes deberían estar en estos lenguajes de texto plano y no compilados, aun que puedo enseñar el código si los hiciera en C++.... pero si por alguna razón no lo tienen instalado el C++, se me hace más básico que mejor copeen y pegan en el bloc de notas y listo pueden probarlos sin necesidad de instalar nada bueno aquí una foto del keygen otra cosa este lo copean y lo pegan y aguardan como "genera.hta" este está con la extensión hta porque no puedo obtener los datos necesarios para generar la clave si estuviera usando el navegador con la extensión HTML


Ahora les digo como funciona, al ejecutarlo damos clic en examinar para buscar la ubicación o carpeta donde tenemos el crackme y lo seleccionamos y también tenemos que ejecutar el reto para que el generador de claves obtenga si pid, el pid es un número que se les da a cada programa que ejecutamos en la computadora para identificarlos en fin, ya que tenemos el crackme corriendo presionamos generar y nos dará la clave ami me dio esta "0439-0531-3296" ahora la pego en el crackme y me arroja lo siguiente


Si les aparece este mensaje solo cierran el crackme y abren de nuevo es porque el pid es mayor a 4 dígitos


En fin creo que eso es todo... Otra cosa no pongo link de descargar de los crackmes y es porque tengo miedo que me quiten el blog, ya que algunos son marcados como infectados o son falsos positivos y tienen que verse desde una máquina virtual... En fin creo que eso es todo saludos flamer

domingo, 12 de julio de 2026

Solucion Al Crackme 1 De DobleCero

Hola amigos hoy veremos el crackme 1 de doblecero, este usuario es del año 2004 lo encontré en el foro y el crackme creo que también... Pero en fin el crackme es algo interesante y divertido algo bueno para quitarse el aburrimiento se puede parchar, pero lo bueno de esto es encontrar un serial válido y de paso hacer el keygen como decía mi amigo PeterPunk.

Bueno pasamos a los hechos este reto solo acepta nombres con la cantidad de 1 a 6 dígitos si se pasa de 6 ya nos manda al cartelito incorrecto y la contraseña solo acepta de números menores a 8 dígitos.

aquí una foto del reto


Ahora ingresamos un nombre y un serial yo pondré como nombre "polon" y como contraseña "123456" y damos clic en registrar y nos lanza lo siguiente


Yo le hice un generador de claves y siempre me arroja la misma clave y con diferente nombre ya lo verán les dejaré el código aquí abajo, yo solo revertí las operaciones, el reto toma el primer dígito y el antepenúltimo del nombre ingresado y toma su valor ASCII y los concatena después hace una serie de operaciones las cuales verán en el código... como siempre se los dejaré en JavaScript y HTML

<html>
<head>
<title>Keygen Crackme 1 De DobleCero</title>
<style>
.textbox
{
   background-color:black;
   color:lime;
   border-radius:8px;
   border:2px solid;
   height:30px;
   width:300px;
   text-align:center;
   font-size:15px;
}
.textbox:hover
{
   border-color: white;
}
.mark
{
   color:lime;
   font-size:35px;
}
.boton
{
   background-color:black;
   color:lime;
   border-radius:8px;
   border:2px solid;
   height:30px;
   width:100px;
}
.boton:hover
{
   border-color: white;
}
</style>
</head>
<body bgcolor="black">
<marquee class="mark">Keygen Crackme 1 De DobleCero   ...:::By Flamer:::...</marquee><br>
<br><br>
<center>
<input type="button" value="Copiar" onclick="copiar1()" class="boton">
<input type="text" id="nom" placeholder="Nombre" class="textbox">
<br><br>
<input type="button" value="Copiar" onclick="copiar2()" class="boton">
<input type="text" id="pass" placeholder="Serial" class="textbox">
<br><br>
<input type="button" value="Generar" onclick="generar()" class="boton">
</center> 
<script>
function copiar1() 
{
   let c=document.getElementById('nom'); 
   c.select();
   document.execCommand('copy');
}
function copiar2() 
{
   let c=document.getElementById('pass'); 
   c.select();
   document.execCommand('copy');
}
function generar()
{
   let nick=document.getElementById("nom").value.toUpperCase(); //toma el nombre ingresado y lo convierte en mayusculas
   let d1,d2,s1,s2,n,eax,ebx,ecx,edx;
   if(nick!="" && nick.length<7)
   {
      d1=nick[0];  //toma el primer digito
      d2=nick.substr(-3,1); //toma el antepenultimo digito
      s1=d1.charCodeAt(0); //convierte el digito a su valor ASCII
      s2=d2.charCodeAt(0); //convierte el digito a su valor ASCII
      n=parseInt(s1.toString() + s2.toString()); //los concatena y se almasena en n
	   
      eax=-200; //inicializa eax en -200
      ecx=0; //inicializa ecx en 0
      edx=0; //incializa edx en 0
      edi=0; //inicializa edi en 0
      ecx=ecx-eax; //ecx se le resta eax
      ecx=ecx+500; //a ecx sele suma 500
      eax=eax+400; //a eax sele suma 400
      ecx=ecx+1000; // se le suma 1000 a ecx
      eax=eax-500;  //a eax sele resta 500
      edx=edx-n;  //a edx se le resta n
      edi=edi-n;  // a edi se le resta n
      edi=edi-edx;  // a edi se le resta edx
      edi=edi+578;  //a edi se le suma 578
      edi=edi+ecx; // a edi se le suma ecx
      ecx=ecx-eax; //a ecx se le resta el valor de eax 
      ecx=ecx+60; //a ecx se le suma 60
      eax=eax+1900; //a eax se le suma 1900
      edx=edx-25698; // edx se le resta 25698
      edi=edi ^ 7; // edi es xoreado con 7
      edi=eax; // edi valdra lo mismo que eax
      ebx=ebx ^ 3; // xorea ebx con 3
      ebx=eax; // ebx valdra lo mismo que eax
      ecx=ecx-170; // ecx sele resta 170
      eax=eax-214; // eax sele resta 214
	    
      document.getElementById("pass").value=ecx.toString() + eax.toString();
   }
   else
   {
      alert("Error Hay Campos Vacios o El Nombre Tiene Mas De 6 Digitos...");
   }
}
</script>
</body>
</html>

Si lo quieren probar solo copean y pegan en el bloc de notas como "generador.html" y lo ejecutan aquí una foto del keygen


Bueno ya tenemos la clave para el nombre "polon" ahora buscamos el reto e ingresamos el nombre "polon" y la clave "18901386" y nos arroja lo siguiente


Si buscan el crackme lo encontraran en el foro el hacker.net...Bueno creo que eso es todo saludos Flamer 


viernes, 3 de julio de 2026

Solucion al Crackme 3 De Cruehead By Flamer

Hola amigos hoy veremos como resolver el crackme 3 de cruehead este es el último de la serie y está más complejo que los anteriores, pero no es la gran cosa se puede reversear, se puede solucionar.

Bueno empecemos este crackme o reto lee un archivo llamado "CRACKME3.KEY" y no es un TXT, sino un archivo con la extensión KEY, en fin este archivo tiene que tener la clave la cual se conforma de 18 dígitos y esta clave es leída cuando se está cargando el crackme y si el crackme corrió y no mostro nada quiere decir que la clave no era la correcta o no tenía los 18 dígitos en fin esta es una foto del reto.


Lo que hace el código de este reto es buscar el archivo antes mencionado en la misma ubicación o misma carpeta donde este el crackme para leerlo y mostrar el cartelito correcto si la clave es la correcta y si no lo es no muestra nada.

Bueno aquí el código en JavaScript y HTML de generación de la clave correcta o mejor dicho el generador del archivo de verificación

<head>
<title>Generador de Claves</title>
</head>
<body bgcolor="black">
<marquee style="color:white;font-size:30;">Keygen Crackme3 Cruehead By ...:::Flamer:::...</marquee><br><br>
<center>
<br><br>
<input type="button" value="Generar Archivo Key" onclick="generator()" style="background-color:Gray;color: white;font-size: 16px;font-size: 50px;border-radius: 10px;border: 2px solid Lime;">
</center>
<script>
function generator()
{
   let fso,x,digi,xo=65,suma=0,pass="";
   let cadena="OPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
   let largo=cadena.length;
   let bytesPuros = new Uint8Array(18);
    
   for(x=0;x<14;x++)
   {
     digi=parseInt(Math.random() * (largo-0)+0);
     pass+=cadena[digi];
     bytesPuros[x]=cadena[digi].charCodeAt(0);
   }
   
   for(x=0;x<14;x++)
   {
      digi=pass[x].charCodeAt(0);
      digi=digi ^ xo;
      suma+=digi;
      xo++;
   }
   
   suma=suma ^ 305419896;
   cadena=suma.toString(16);
   largo=14;
   
   for(x=6;x>=0;x-=2)
   {
      digi=cadena.substr(x,2);
      bytesPuros[largo] = parseInt(digi,16);
      largo++;   
   }
 
   const blob = new Blob([bytesPuros], { type: 'application/octet-stream' });
   const enlace = document.createElement('a');
   enlace.href = URL.createObjectURL(blob);
   enlace.download = 'CRACKME3.KEY'; 
   enlace.click();
   URL.revokeObjectURL(enlace.href);   
}
</script>
</body>
</html>

Aqui una foto del generador de claves


Si lo quieren probar el codigo ya saben copean el código y pegan en el bloc de notas y aguardan como genera.html y listo después al ejecutarlo solo cliquean en el botón Generar archivo key esto les dará el archivo a aguardar

Ahora lo explicaré brevemente primero creamos una variable llamada cadena la cual contiene los dígitos que contendrá la contraseña del archivo de verificación, sise fijan empieza desde O mayúscula porque la variable con la que xorearemos será la variable xo y esta empieza desde A y si la clave del archivo empieza desde A y la variable xo también desde A al xorear esta nos dará 0 y eso nos saca del código de generación del serial es por eso que la variable cadena empieza desde O para que el serial no contenga esos caracteres.

Bueno seguimos el primer ciclo crea los primeros 14 dígitos al azar y los almacena en la variable pass y también en la variable bytesPuros pero su valor ASCII

el segundo for toma los 14 dígitos del serial creado al azar en el for anterior y que fueron guardados en la variable pass y son convertidos en su valor ASCII y luego los xorea con la variable xo para después el resultado es sumado y guardado en la variable suma...Nota: esta variable xo aumenta en 1 en cada vuelta si era 65 a la siguiente será 66 y así

después que sale del ciclo el resultado de suma es xoreado con el numero 305419896, para después ser convertido en hexadecimal y aguardado en la variable cadena y el siguiente for toma el resultado que fue guardado en la variable cadena y empieza a tomar los bytes desde el reverso hasta el primer byte... Estos bytes se concatenan con los 14 primeros y como son 4 más 14 son 18 y son los que se aguardan en el archivo KEY

aquí una foto del crackme resuelto

Y aquí una foto del contenido del archivo KEY... Nota: no modifiquen el contenido del archivo, ya que son bytes y si los modifican puede que no funcione



Bueno creo que eso es todo y terminamos con la serie de crackmes de cruehead saludos Flamer