← SEARCHABLE ARCHIVE
Assembly · 2026-08-15

Depuración y desensamblado práctico de x86-64

Recuperar contratos de función, pila, ABI y memoria desde una dirección de fallo

INTERACTIVE READING MODE →

Depuración y desensamblado práctico de x86-64

Este artículo se ha creado con fines didácticos. El desensamblado observa comportamiento binario; no demuestra intención del fuente ni autorización. Analice solo programas y fallos para los que tenga permiso.

En builds optimizados desaparecen variables, se inlinean funciones y el instruction pointer cae en un mov. Lo importante es un procedimiento que conecte registros, pila, memoria y ABI por orden de evidencia.

Preservar pruebas

Guarde executable/modules exactos con build ID o hash, PDB/DWARF coincidente, excepción/señal, dirección y offset de módulo, registros/flags, stack trace y bytes, tipo read/write/execute, entrada, hilo, SO y CPU. Símbolos de un build parecido pueden mapear el offset a otra función.

Normalice ASLR:

module_offset = faulting_address - loaded_module_base

Empezar en la instrucción de fallo

mov eax, dword ptr [rcx + rdx*4]
effective_address = RCX + RDX * 4
access_width = 4 bytes

Compruebe si rcx es null, liberado u otro objeto; si rdx es índice u offset; si el cálculo coincide con el fallo; si los cuatro bytes son válidos; y dónde se originaron ambos registros. El lugar del fallo no siempre es el origen.

Provenance y restricciones de camino

mov rcx, [rbx + 20h]
test rcx, rcx
je error
mov edx, [rsi + 8]
mov eax, [rcx + rdx*4]

Investigue objetos padre, camino real y cambios de lifetime por otros hilos. Un race puede no probarse con un snapshot de un hilo.

cmp rdx, r8
jae fail
mov eax, [rcx + rdx*4]

La arista normal prueba unsigned rdx < r8. Anote estas restricciones y no confunda jl con jb.

Auditar stack trace y ABI

El stack trace depende de símbolos y unwind. Buffer overflow, metadatos ASM erróneos, símbolos incorrectos, tail calls, inlining o context switches pueden dañarlo. Cada retorno debe pertenecer a módulo ejecutable y call site plausible.

Windows inicia argumentos en rcx,rdx,r8,r9; System V en rdi,rsi,rdx,rcx,r8,r9, pero se reutilizan. Retroceda hasta el caller antes de poner nombres de parámetros.

push rbx
sub rsp, 40h
mov rbx, rcx

Con entrada rsp=S, derive posiciones de registros guardados y retorno y verifique todos los exits. En Windows compare .pdata/.xdata con el prólogo real.

Calls indirectos y memoria

call qword ptr [rax + 18h]

Puede ser tabla de funciones, vtable, import thunk o callback. Siga rax, acceso a tabla, destino ejecutable, convención, argumentos, lifetime y CFG/CET. Una dirección ejecutable no prueba la firma correcta.

Inspeccione memoria como bytes con anchura y little endian. Use-after-free puede seguir legible; guard pages y AddressSanitizer detectan antes la causa.

El disassembler decodifica, debugger observa una ejecución, decompiler infiere nivel alto, profiler muestrea y sanitizer instrumenta contratos. Nombres y if del decompiler son hipótesis que deben cruzarse con instrucciones y ABI reales.

Resumen

El análisis x86-64 se amplía desde la instrucción de fallo a dirección efectiva, provenance, restricciones, ABI, pila y lifetime. Binary y símbolos exactos son requisito; stack trace y decompiler también se verifican. Cierre con corrección de fuente y tests de regresión.

Fuentes oficiales