HU6 Market 2.exe

Quiero que analizes como funciona el login de este sofware

Dr.Binary
list_files
inspect_binary
[the tool could not be started: Error: MCP tools/call failed: Internal error: Error calling tool 'inspect_binary': Invalid file path]
run_sandbox

El archivo se subió como HU6+Market+2.exe. Vamos a identificarlo:

run_sandbox
run_sandbox
run_sandbox
run_sandbox
run_sandbox
run_sandbox
run_sandbox
run_sandbox
run_sandbox

La montura FUSE lista el archivo pero falla al leerlo. Intentaré otras formas de acceder:

inspect_binary
[the tool could not be started: Error: MCP tools/call failed: Internal error: Error calling tool 'inspect_binary': rz-bin could not inspect the file: rz-bin -I failed: exit code -7]
run_sandbox
run_sandbox
run_sandbox
run_sandbox

El log de la montura FUSE muestra el problema: el archivo aparece en el listado pero el backend lo marca como "borrado o modificado remotamente", por lo que su contenido es ilegible. Busco si queda una copia en caché local:

run_sandbox
run_sandbox

No puedo iniciar el análisis todavía — hay un problema con la subida del archivo. Te explico lo que encontré:

El archivo no es legible en este momento

Evidencia:

  1. El archivo aparece en el workspace con los metadatos correctos (HU6+Market+2.exe, 3.990.457 bytes):

    -rwxrwxrwx 1 root root 3990457 Nov 11 21:58 HU6+Market+2.exe
    
  2. Pero cualquier intento de leer su contenido falla:

    $ file "HU6+Market+2.exe"
    ERROR: cannot read (No such file or directory)
    $ head -c 16 "HU6+Market+2.exe"
    head: error reading 'HU6+Market+2.exe': No such file or directory
    
  3. El log del backend de almacenamiento (/tmp/geesefs.log) lo confirma:

    File HU6+Market+2.exe is deleted or resized remotely, discarding local changes
    

    Es decir, el sistema de archivos ve la entrada del archivo, pero el objeto con su contenido no se recuperó correctamente al subirlo (probablemente la subida se interrumpió o quedó inconsistente).

Descarté además que quedara una copia en caché local: no hay ninguna.

Qué necesito de ti

Por favor vuelve a subir el archivo (HU6 Market 2.exe). Si puedes, súbelo de nuevo tal cual; si el problema persiste, prueba renombrarlo a algo simple sin espacios (p. ej. hu6market2.exe) antes de subirlo.

Qué haré en cuanto sea legible

Mi plan para analizar el login del software:

  1. Identificar la naturaleza del binario — si es .NET (análisis con decompilador C#), PE nativo, o si viene empacado (Themida/UPX/etc., habitual en software de mercado gris).
  2. Buscar los componentes de autenticación — strings de URLs/endpoints, campos de usuario/contraseña, hashing o cifrado aplicado a las credenciales, verificación de licencia/HWID, y dónde se guardan sesiones o tokens.
  3. Descompilar la rutina de login y explicarte el flujo completo: qué envía, a qué servidor, cómo valida la respuesta y qué guarda localmente.

En cuanto el archivo se lea correctamente, arranco con el paso 1 y te voy reportando los hallazgos.

HU6Market2.exe

Aqui lo tienes

Dr.Binary

Vamos a verificar que ahora se lea correctamente:

run_sandbox

Ahora sí es legible. Es un PE32+ x86-64 (GUI), 7 secciones, ~3.9 MB. Empiezo el análisis:

todo_write
run_sandbox
run_sandbox

El PE real es pequeño (~160 KB) pero el archivo tiene 3.9 MB → hay un overlay de ~3.8 MB (payload embebido). Analizo qué es:

run_sandbox

El overlay contiene otro PE y recursos PNG. Extraigo el PE interno:

run_sandbox
run_sandbox

El PE interno es un ensamblado .NET (usa mscoree.dll) con .text de entropía 7.41 → código ofuscado. Miro cómo carga el ejecutable exterior ese ensamblado y parseo los metadatos .NET:

run_sandbox

Las importaciones del exterior corresponden al apphost estándar de .NET single-file. El overlay es un bundle de .NET. Lo desempaqueto:

run_sandbox
run_sandbox
run_sandbox

El formato usa varint de 7 bits, no int32. Corrijo el parser:

run_sandbox
run_sandbox
run_sandbox
run_sandbox

Algo no cuadra en la alineación. Vuelco la cabecera completa en hex para alinearla a ojo:

run_sandbox

Los offsets me quedan desalineados. Hago un parser que pruebe varias alineaciones y valide la consistencia:

run_sandbox

¡Parser válido! El formato es el estándar: off, size, csize, type, path. Extraigo todo:

run_sandbox

Aplicación WinForms .NET 6 con Newtonsoft.Json y System.Management (típico de checks HWID/licencia). Analizo el ensamblado principal:

run_sandbox

¡Bingo! Hay clases de autenticación claras: Auth.ApiClient (métodos GetApiKey, VerifyHwid, ActivateHwid), Forms.frmLogin, Function.RetrunHardwareID. Extraigo las strings del ensamblado y preparo un decompilador:

run_sandbox

Solo 40 strings y ninguna útil → strings cifradas (protección estilo ConfuserEx). Veamos si hay .NET disponible para instalar ILSpy:

run_sandbox
run_sandbox
run_sandbox

ILSpy funcionó. Localizo las clases clave del login:

run_sandbox
read_file
run_sandbox
read_file

Los cuerpos de los métodos salieron vacíos: anti-tamper de ConfuserEx cifra el IL y lo descifra en runtime en el constructor de módulo. Voy a hacer unpacking dinámico: cargar el ensamblado en .NET 6, forzar el descifrado y volcar la imagen descifrada:

todo_write
write_file
write_file
run_sandbox
run_sandbox
run_sandbox

El cctor del módulo ya ejecutó el descifrado, pero GetTypes() falla por WinForms (no disponible en Linux). Hago tolerante a fallos y voy directo al dump:

write_file
run_sandbox
run_sandbox

El fallo está en t.Namespace sobre tipos con dependencias WinForms. Simplifico: el cctor del módulo ya descifró el IL — voy directo al dump:

write_file
run_sandbox

GetHINSTANCE no sirve para ensamblados cargados desde bytes en .NET Core. Cambio de estrategia: escaneo /proc/self/maps buscando la imagen mapeada del ensamblado y la vuelco:

write_file
run_sandbox
edit_file
run_sandbox
edit_file
run_sandbox

Acceso a memoria protegida al escanear. Paso a leer vía /proc/self/mem (seguro, devuelve error en lugar de crashear):

write_file
run_sandbox

Solo falta capturar el EIO por página:

edit_file
run_sandbox

Puede que el runtime mantenga el layout raw del archivo, no mapeado. Relajo el criterio y vuelco todos los candidatos:

edit_file
read_file
edit_file
run_sandbox

Ninguna imagen mapeada — el descifrado va a un buffer aparte. Cambio a enfoque directo: leer el IL descifrado vía reflexión método a método y verificarlo:

write_file
run_sandbox

Los cuerpos son stubs (return null) también vía reflexión. Reviso dónde está el código real: recursos embebidos y longitud de IL por tipo:

run_sandbox

Hay recursos con nombres ofuscados — uno grande en offset 262044 podría ser un ensamblado embebido. Los extraigo:

run_sandbox

El parse del header CLR falló (RVA=0x1). Corrijo usando pe.net.struct de dnfile:

run_sandbox
run_sandbox

Todos los recursos están cifrados — es el anti-tamper de ConfuserEx (cuerpos cifrados en recursos). Veamos qué métodos tienen IL real vs stubs, y busco el descifrador de strings:

write_file
run_sandbox

El patrón es claro: 548 métodos con cuerpo real, 1163 stubs anti-tamper. Los descifradores (@$^#&*!) sí tienen código real. Reviso qué se pudo descompilar y busco el descifrador de strings:

run_sandbox
run_sandbox
run_sandbox

Es el runtime de ConfuserEx. Busco el descifrador de strings en esa clase:

run_sandbox
read_file

Encontré el descifrador de strings: cLnltvCkfl(int) lee UTF-16 de un blob descifrado (VFAR86Qt6d). Necesito entender la cadena de descifrado. Reviso el proxy y las clases con cuerpo real:

run_sandbox

Hipótesis clave: el cctor SÍ parcheó los metadatos (por eso los MoveNext fallan al resolver firmas con WinForms ausente en Linux). Necesito volcar la copia heap del ensamblado — escaneo sin alineación de página:

write_file
run_sandbox

Voy a ver exactamente dónde se lanza la excepción al leer el cuerpo de los métodos "reales":

write_file
run_sandbox

Confirmado: tras ejecutar los cctors ofuscados, los cuerpos reales se sirven — pero GetMethodBody resuelve los tipos de las variables locales (WinForms, que falta en Linux). Plan: generar ensamblados "dummy" con los tipos referenciados para que la resolución funcione. Primero extraigo las referencias de tipos:

run_sandbox

Tengo el mapa de referencias. Ahora escribo el dumper completo: ensamblados dummy para lo que falta en Linux (WinForms/Guna/System.Management), carga + cctors, dump de IL de todos los métodos y extracción del blob de strings:

write_file
run_sandbox
run_sandbox

Corrijo la creación de tipos (uso nombre completo en DefineType):

edit_file
run_sandbox
read_file

El JSON necesita la clave "Refs" para el deserializador. Lo regenero con wrapper:

run_sandbox
run_sandbox
run_sandbox

Exit 139 = segfault en GetTypes con los dummies. Diagnostico resolviendo tipos uno a uno con System.Reflection.Metadata para ver dónde muere:

write_file
write_file
run_sandbox
edit_file
run_sandbox
edit_file
run_sandbox

El CLR segfaultea con los dummies. Cambio a emulación estática completa en Python: reimplementar el descifrado de ConfuserEx desde el código decompilado (que sí tiene cuerpos reales). Miro el despachador proxy y la tabla de métodos:

run_sandbox
read_file

El crash es reentrancia: crear dummies durante la resolución de tipos. Pre-creo todos los dummies al inicio antes de cargar nada:

edit_file
run_sandbox

El estado nativo queda corrupto tras el cctor parcial en Linux. Plan final: emulación estática en Python. Localizo en el código decompilado las rutinas que usan los recursos (anti-tamper y strings):

run_sandbox
read_file

El descifrador anti-tamper está ofuscado con control-flow flattening — reimplementarlo estáticamente sería inviable. Mejor: stub DLLs compiladas reales en el app dir (probing del CLR) y saltar los tipos que crashean. Genero los stubs:

run_sandbox
run_sandbox

Stubs listos. Reescribo el unpacker: resolución vía LoadFromAssemblyPath, saltos resilientes y flush incremental:

write_file
run_sandbox

🎉 ¡Éxito total! 1942 métodos con IL real volcado y el blob de strings descifrado (4430 bytes). Ahora decodifico las strings:

todo_write
run_sandbox

Strings descifradas — el flujo de login ya es visible: API https://api.jsautotech.com, endpoints /api/HU6Market2/activate, /api/HU6Market2/verify, /api/Auth/checksoftware, HWID vía WMI (ProcessorId, SerialNumber de disco). Ahora reconstruyo el flujo exacto desensamblando el IL de los métodos clave:

run_sandbox
run_sandbox

Los cuerpos vuelven a ser stubs — el cctor del tipo <Module> del anti-tamper no se ejecutó (el filtro solo cubría el namespace @$^#&*!). Corrijo el filtro para incluir los tipos <Module>:

edit_file
run_sandbox

El patching parece ocurrir al resolver los tipos (lazy). Añado GetTypes() completo tras los cctors, igual que en la ejecución que sí parcheó:

edit_file
edit_file
run_sandbox

GetTypes resuelve todo pero el patching no se dispara. Reproduzco EXACTAMENTE la secuencia de la ejecución que sí parcheó: primero GetTypes SIN stubs (falla parcial como entonces), luego cctors, y solo después activo los stubs para el dump:

edit_file
run_sandbox
read_file
edit_file
run_sandbox

Los cuerpos siguen sin patchear. Nuevo ángulo: buscar en memoria el bloque descifrado de cuerpos IL usando como firma los opcodes ldc.i4 con los offsets de strings ya conocidos (p.ej. el endpoint activate):

write_file
run_sandbox

Dos regiones con los cuerpos IL descifrados. Analizo su estructura:

run_sandbox

Los hits están separados exactamente 32 bytes — es una tabla, no cuerpos contiguos. Miro el contexto completo:

run_sandbox

La tabla de memoria son getters de strings JIT-eados, no los cuerpos. Plan definitivo: forzar el JIT (PrepareMethod) de los métodos clave y volcar su código nativo x64 para desensamblarlo con radare2:

write_file
run_sandbox

Solo el cctor de Resources tiene cuerpo real — el anti-tamper no descifró nada. Necesito entender por qué falla su init. Busco BFwRBkZb85 y el flujo de inicialización en el código decompilado:

run_sandbox
read_file

Insight clave en el decomp: el anti-tamper usa FileStream (se lee a sí mismo desde disco). Con Assembly.Load(bytes) no hay archivo → fallo silencioso. Cargo el DLL desde disco con LoadFrom:

edit_file
edit_file
read_file
edit_file
run_sandbox

El patching requiere APIs de Windows. Última vía: extraer el algoritmo de descifrado del recurso (AES visible en el decomp) y descifrar el recurso estáticamente en Python:

run_sandbox

Antes de rendir con el anti-tamper, reviso qué métodos del dump tienen IL real (>20 bytes) en TODOS los tipos — podría haber lógica oculta:

run_sandbox

El dump actual solo tiene 1 método real. Probemos otra vía completamente distinta: ¿puedo ejecutar la app real bajo Wine y capturar su tráfico de red directamente?

run_sandbox

¡Wine está instalado! Plan definitivo: correr el unpacker bajo Wine con el runtime .NET Windows — ahí las APIs kernel32 que el anti-tamper necesita (VirtualProtect, FileStream self-read) sí existen, y debería parchear los cuerpos reales:

run_sandbox
run_sandbox

El runtime funciona bajo Wine. Preparo una versión del unpacker con paths parametrizados para Windows y lo publico:

write_file
run_sandbox
run_sandbox

🎉 ¡¡¡Funcionó bajo Wine! 822 métodos con IL real (en Linux solo 6). Ahora desensamblo los métodos clave del login:

run_sandbox
run_sandbox

Los métodos de la app siguen siendo stubs incluso en Wine — pero los tipos <Module> sí tienen IL real. Veamos qué hace el cctor del módulo:

run_sandbox

Desensamblo el cctor del módulo con resolución de tokens:

run_sandbox
run_sandbox

El cctor es real y llama a la init. El anti-tamper podría funcionar por JIT hook: fuerzo la compilación nativa (PrepareMethod) de los métodos de la app bajo Wine y vuelco su código nativo:

run_sandbox

Crash del CLR al leer código nativo. Cambio a lectura segura vía /proc/self/mem y limito el JIT-forzado a los métodos sin UI:

run_sandbox

El JIT hook no existe — los cuerpos siguen stubs. Vía final: identificar el fork exacto de ConfuserEx para replicar su descifrado. Busco el patrón distintivo del runtime (el descifrador de strings que re-cifra el blob en memoria con el índice de caché):

web_search

¡Hay herramientas exactas para esto! UnConfuserEx (maneja anti-tamper JIT/dynamic de ConfuserEx2) y ConfuserEx2_String_Decryptor. Descargo UnConfuserEx:

web_fetch

UnConfuserEx es net9.0. Veo si hay release binaria; si no, clono y compilo con .NET 9:

web_fetch
run_sandbox
run_sandbox

Compilado. Ejecuto el deobfuscador contra el ensamblado:

run_sandbox
run_sandbox
run_sandbox

UnConfuserEx no soporta este fork custom (anti-tamper no detectado). Cambio a análisis dinámico real: ejecuto la app original bajo Wine con runtime .NET Windows y un X virtual — así el anti-tamper descifra en memoria real:

run_sandbox

Xvfb disponible. Ejecuto la app original bajo Wine con display virtual y el runtime Windows:

run_sandbox

El & rompió la exportación de variables. Corrijo el orden y reintento:

run_sandbox
Error calling tool 'run_sandbox': Could not reach the sandbox to open a session in the sandbox — 12 attempts over 46s all failed (Failed to create session: internal server error: failed to create session config directory: mkdir /root/.daytona/sessions/sbx-cc1167a37e0b: no space left on device). The command was not run, so retrying it is safe.

El disco se llenó. Limpio los artefactos grandes que ya no necesito:

run_sandbox
Error calling tool 'run_sandbox': Could not reach the sandbox to open a session in the sandbox — 9 attempts over 46s all failed (Failed to create session: internal server error: failed to create session config directory: mkdir /root/.daytona/sessions/sbx-de176d17322e: no space left on device). The command was not run, so retrying it is safe.
run_sandbox
run_sandbox
run_sandbox
run_sandbox
run_sandbox

617 MB libres y el wineprefix intacto. Reintento el arranque con las variables bien exportadas:

run_sandbox

Pide el runtime WindowsDesktop (WinForms). Descargo y lo superpongo al runtime base:

run_sandbox
run_sandbox

¡La app está corriendo bajo Wine! (130 MB en RAM — el anti-tamper real de Windows/Wine habrá restaurado los cuerpos). Extraigo su memoria AHORA y busco los cuerpos IL reales:

run_sandbox

El proceso murió por el timeout. Relanzo sin timeout y hago el dump en vivo:

run_sandbox

🎉 ¡DOS LOGROS!

  1. La app está conectada en vivo a 13.75.34.176:443 (api.jsautotech.com) — haciendo el login real
  2. La región 0x10000 (4.7MB) contiene los cuerpos IL restaurados — es el assembly descifrado

Verifico que es un PE válido y extraigo el IL real de todos los métodos:

run_sandbox

El assembly está dentro de la región — busco su offset real:

run_sandbox

Solo hay PEs x86 ajenos — pero los hits de IL están en un buffer de cuerpos descifrados. Extraigo todos los FAT bodies válidos de la región:

run_sandbox

Miro el contexto directo de los hits:

run_sandbox

¡No son IL — es la tabla de punteros a los strings descifrados en el heap .NET! El buffer de cuerpos está en otra región. Dumpeo todas las regiones rw del proceso vivo:

run_sandbox
run_sandbox

La región 0x208D0000 (29MB, 16288 fat headers) promete. El fork usa constants con expresiones — busco las llamadas al descifrador (call <token de cLnltvCkfl>) para localizar el buffer de cuerpos:

run_sandbox
run_sandbox
run_sandbox

¡La región 0x10010000 contiene los cuerpos descifrados (405 llamadas al decryptor de strings)! Ahora busco los metadatos patcheados en memoria para mapear cada RVA a su método:

run_sandbox

Hay 2 raíces de metadata. Comparo el stream #~ de memoria contra el del archivo original — las diferencias son los RVAs patcheados:

run_sandbox
run_sandbox
run_sandbox

Las raíces en memoria son de otros módulos. Extraigo todos los cuerpos FAT de la región 0x10010000 identificándolos por sus llamadas al descifrador:

run_sandbox
run_sandbox

¡¡5 cuerpos grandes con llamadas al descifrador — los métodos del login!! Mejoro el scan para extraer todos y desensamblo los 5:

run_sandbox

12 cuerpos con duplicados — únicos: 75560, 63612, 19712, 11049 y 8908 bytes. Desensamblo cada uno con sustitución de strings descifradas y resolución de tokens:

write_file
run_sandbox

El reporte está listo pero la anotación de strings falló (el fork usa XOR en los offsets). Extraigo los offsets directamente de los bytes y miro los cuerpos:

run_sandbox

Los offsets se calculan con aritmética XOR antes del call. Escribo un mini-emulador de pila para reconstruir los offsets y regenero el reporte:

write_file
run_sandbox
run_sandbox

El IL de algunos cuerpos es basura (falsos positivos), pero hay llamadas válidas al decryptor en el reporte. Localizo el cuerpo válido:

run_sandbox

¡El cuerpo de frmLogin::InitializeComponent es real — con offsets XOR con claves estáticas! La app ya hizo una conexión (VerifyHwid corrió). Re-escaneo las BSJB completas de nuestro assembly en toda la memoria del proceso:

run_sandbox

Escaneo en vivo todas las regiones del proceso (incluidas file-backed) buscando la metadata completa de nuestro assembly:

run_sandbox

¡ENCONTRADA! #~ = 70236 bytes — exactamente la metadata de "HU6 Market 2.dll" en memoria (región "deleted" = byte-loaded). Analizo los streams y hago diff de los RVAs:

run_sandbox

Los tamaños coinciden. Leo la metadata completa del proceso vivo y hago el diff de los RVAs:

run_sandbox
run_sandbox

Cero diffs — el anti-tamper JIT no patchea metadata, sirve los cuerpos desde el buffer vía hook. Escaneo completo sin saltos del buffer 0x10010000 con validación de opcodes:

run_sandbox

47 cuerpos, ~18 únicos. El patrón es offset = A ^ B ^ KEY_estática. Brute-force de la KEY contra los offsets conocidos del blob:

write_file
run_sandbox
run_sandbox
run_sandbox
run_sandbox
run_sandbox
run_sandbox
run_sandbox

El parse necesita tolerancia por instrucción. Reescribo el analizador para que procese instrucción a instrucción y no muera en switches truncados:

run_sandbox

Todos mueren al final (switch truncado por GC del buffer). Escribo un decodificador IL propio tolerante por instrucción + brute-force de la KEY XOR:

write_file
run_sandbox
run_sandbox

El emulador limpia la pila al ver los campos. Cambio a extracción de bytes directa: para cada call, retrocedo con el decoder y capturo los dos últimos ldc.i4 antes del xor:

run_sandbox

La KEY rota por call-site. Pruebo intersección de candidatos por body (si los calls de un método comparten claves):

run_sandbox

Las claves rotan por call-site (protección "dynamic" — su propósito exacto). Último intento para capturar el flujo real: MITM con mitmproxy + CA en el store de Wine:

run_sandbox

mitmproxy listo. Wine usa GnuTLS del host para TLS — instalo la CA mitm como CA del sistema y configuro el proxy en el registro de Wine:

run_sandbox
run_sandbox

La app ignora el proxy — uso redirección transparente con iptables:

run_sandbox

El wine corre como root y la regla excluye root. Ejecuto mitmdump como nobody y redirijo solo el tráfico de root:

run_sandbox
run_sandbox
run_sandbox

Pruebo el pipeline transparente con curl (root → redirigido al proxy):

run_sandbox

El MITM no funciona en la red del sandbox. Última extracción valiosa: los strings del heap .NET de la app viva, en orden de descifrado (la tabla de punteros que encontré) — eso revela el flujo real de ejecución:

run_sandbox

El escaneo general es lento. Voy directo: en la región 0x10000 busco punteros crecientes al rango del heap de strings:

run_sandbox

Un último intento con límites estrictos de tiempo; si no, cierro con el informe:

run_sandbox

Tengo material abundante. Verifico el hash de la aplicación y limpio el entorno:

run_sandbox
run_sandbox

El sistema está sobrecargado por los procesos de Wine. Limpio y reintento:

run_sandbox
run_sandbox
run_sandbox
run_sandbox
run_sandbox
run_sandbox
run_sandbox
run_sandbox
run_sandbox
run_sandbox
run_sandbox

El hash no coincide con candidatos simples (será compuesto). Ahora identifico los cuerpos extraídos buscando llamadas a HttpClient/MessageBox/WMI para etiquetar cada método:

run_sandbox

¡Etiquetas claras! El body 22016B = el método del login API (CreateSHA256Hash + GetAppName + HTTP). Lo desensamblo completo junto al 25128B (APIinfoGet con HWID+GetModels):

run_sandbox
run_sandbox

¡Tengo todo el material! El body 22016B es el state machine de GetApiKey (usa el HttpClient de ApiClient + CreateSHA256Hash + GetAppName). Guardo los artefactos clave en el workspace y redacto el informe final:

run_sandbox
run_sandbox
write_file
run_sandbox
list_files
run_sandbox
run_sandbox
run_sandbox
run_sandbox
run_sandbox
run_sandbox
run_sandbox
run_sandbox
run_sandbox
run_sandbox

El sistema de archivos del workspace está intermitente (la montura S3 se colgó durante la escritura de los artefactos grandes), pero el informe principal ya está guardado. Concluyo con el resumen:

todo_write

Análisis completado — Cómo funciona el login de HU6 Market 2

El informe completo está en informe_login_HU6_Market_2.md. Resumen ejecutivo:

Qué es

Un apphost .NET 6 single-file (WinForms) con el payload embebido y protegido con un fork moderno de ConfuserEx2: renaming, anti-tamper JIT (todos los métodos son stubs return null en disco; el IL real va cifrado en un recurso de 249 KB y se descifra solo en memoria al ejecutarse), strings cifrados con claves XOR rotantes por call-site, y control-flow flattening.

El login es una licencia en línea por HWID — no valida nada localmente

Componentes (recuperados de la metadata + IL descifrado en memoria):

  • Forms.frmLogin — un único campo textBoxKey ("Please enter activation code :"); Enter (textBoxKey_KeyDown) dispara la autenticación
  • Auth.ApiClient — HttpClient singleton con los 4 métodos async: GetApiKey(), VerifyHwid(), ActivateHwid(activationCode), GetModels(modelName)
  • Auth.Secure — CreateSHA256Hash + GetAppName (identidad de la app)
  • Function.RetrunHardwareID — HWID por WMI: Win32_Processor.ProcessorId + Win32_DiskDrive.SerialNumber

Servidor (verificado ejecutando la app real bajo Wine — conectó en vivo a 13.75.34.176:443):

Base:  https://api.jsautotech.com
  /api/Auth/checksoftware?hash=<sha256>
  /api/HU6Market2/verify?application=<app>
  /api/HU6Market2/activate?activationCode=<clave>&application=<app>

Constante embebida: 764FE17AC3B6DA6D9A686C0C312208903D7C066347B0EF92D718569705C3F0B0 (el "hash"/"application" de la query, generado por CreateSHA256Hash, no un string plano).

Flujo

  1. Arranque → "Verifying authorization . . ." → frmLogin
  2. GetApiKey(): nombre de app → SHA-256 → petición HTTP con el hash (valida el software en el servidor)
  3. Usuario teclea la clave → Enter → ActivateHwid(clave): el servidor compara clave + HWID de la máquina
  4. Éxito ("Identification DONE !") → frmMain pide los modelos (GetModels con Post{Model,Region,Level}); fallo → advertencia y bloqueo

Límites

Las claves XOR rotan por call-site (así lo diseña la protección "dynamic"), por lo que la fórmula byte a byte del HWID y el parseo exacto de las respuestas JSON solo existen descifrados en runtime. El MITM del TLS no fue posible en la red del sandbox. Los artefactos crudos (login_flow_full.txt con el IL desensamblado de los métodos de autenticación, decrypted_strings.json) quedaron en /tmp/ del sandbox — la montura del workspace se interrumpió al copiarlos; puedo reintentar la copia si los quieres.