DLLReflector: Una joya oscura del código que carga DLLs como un ninja
¿Alguna vez viste código que parece salido de una película de espías? Bueno, DLLReflector es justo eso. Es como ese agente secreto que se infiltra sin que nadie lo vea, hace su trabajo y desaparece sin dejar huella. Si trabajás con Windows, seguridad informática o simplemente sos un fan del low-level hacking, este pedazo de código te va a volar la cabeza. Y no, no estoy exagerando.
🧠 ¿Qué hace exactamente?
A ver, imaginate que tenés una DLL (una biblioteca de código compilado) y querés cargarla en memoria, pero sin usar LoadLibrary
como todo el mundo. Porque, bueno, a veces no querés que te vean. Querés algo más sigiloso. Ahí entra DLLReflector, que agarra una DLL cruda desde un archivo o un stream de memoria y la mete en memoria como si nada, lista para ejecutar. Sin tocar el disco (si no querés), sin dejar rastro. Pura magia negra.
Y lo mejor: funciona tanto en sistemas de 32 como de 64 bits. ¿Hermoso, no?
🕵️♂️ ¿Y cómo lo hace?
Este código es básicamente un mini loader de PE (Portable Executable), el formato que usan los EXE y DLL en Windows. Vamos parte por parte para que veas la artesanía que hay detrás.
1. Identificación de la cabecera PE
La función IdentifyPEHeader
es donde empieza la aventura. Lo que hace es analizar la estructura interna del archivo PE (o sea, la DLL). Esto es como leer el ADN de la biblioteca: se fija dónde están las cabeceras, cuántas secciones tiene, cómo están organizadas, etc.
Y no lo hace “a medias”: va byte por byte, interpretando campos como e_magic
, lfanew
, FileHeader
, OptionalHeader
, y todos los headers de secciones. Una pasada total.
👉 Dato curioso: si alguna vez abriste una DLL en un editor hexadecimal, todo eso que parece jeroglífico está siendo leído acá como si nada.
2. Carga del código en memoria
Una vez entendido el formato, viene la parte heavy: reservar memoria con VirtualAlloc
, copiar cabeceras, secciones, y preparar todo como si Windows lo hubiera cargado oficialmente.
Ahí entra en juego ReflectLibraryFromMemory
, que se encarga de construir una versión viva de esa DLL dentro del proceso actual. Como armar una maqueta exacta del edificio, pero dentro de tu casa.
🧩 Esto incluye:
-
Copiar las secciones crudas
-
Rellenar con ceros donde haga falta
-
Respetar los tamaños virtuales esperados
Y todo esto en modo ninja total.
3. Resolución de imports
Las DLL no son islas: suelen depender de otras DLL. Así que este código tiene una función clave llamada ResolveImportTable
, que es básicamente el Google Maps de las funciones externas.
Escanea la tabla de imports, busca cada función o módulo necesario, los carga y apunta los punteros correctamente.
¿Sabés lo que significa eso? Que la DLL puede usar MessageBox
, CreateFile
, o cualquier función del sistema sin chocar contra una pared. Todo porque este loader se encargó de armar el camino por ella.
4. Relocalización de direcciones
Este es uno de esos detalles técnicos que si no lo hacés bien, todo explota. Si la DLL esperaba estar en una dirección de memoria y vos la cargaste en otra, las direcciones absolutas internas quedan mal.
Ahí aparece PerformBaseRelocation
, que ajusta cada dirección usando la tabla de relocations del PE. Hace un cálculo con el delta entre la dirección original y la actual, y va corrigiendo todo.
💣 Si no sabías que esto existía, ahora lo sabés. Y sí, es tan necesario como parece.
5. Obtener funciones exportadas
Una vez cargada, toca usarla. Y para eso está GetReflectedProcAddress
, que básicamente emula lo que hace GetProcAddress
pero desde tu DLL “reflejada”.
¿Querés llamar a DoSomethingCool
? Este código te devuelve el puntero exacto para que lo hagas. ¿Preferís ir por el ordinal 3? También se puede. Todo es válido.
🔥 ¿Y esto para qué sirve?
Te voy a ser sincero: esto no es para usar en una app normal de escritorio. Esto es para situaciones donde necesitás:
-
Evadir antivirus o detección estática
-
Cargar código en memoria sin tocar disco
-
Ejecutar módulos de forma sigilosa
-
Hacer pentesting nivel pro
O simplemente si querés aprender cómo funciona Windows por dentro. Porque este código es prácticamente un curso avanzado de PE Loading comprimido en unas pocas líneas.
⚠️ ¿Y los riesgos?
Bueno, como todo poder grande, esto también puede usarse para el mal. De hecho, los malwares más sofisticados usan técnicas parecidas para esconderse del sistema operativo.
Así que si lo vas a usar, que sea con ética. En entornos controlados, para aprender, o para hacer herramientas de seguridad.
🤯 Detalles que me volaron la cabeza
-
Usa
{$IFDEF WIN64}
para adaptar estructuras automáticamente según la arquitectura. ¡Elegancia pura! -
Tiene soporte tanto para carga desde archivo (
ReflectLibraryFromFile
) como desde memoria (ReflectFromMemoryStream
). Ideal para payloads sin disco. -
El manejo de estructuras PE está tan bien hecho que podés adaptarlo para EXEs con unos pocos cambios.
📦 Ejemplo de uso
El código ya te deja todo mascado:
`pReflectedModuleBase := ReflectLibraryFromFile(‘test.dll’);
@pReflectedMethod := GetReflectedProcAddress(pReflectedModuleBase, ‘ModuleAction’);
if Assigned(pReflectedMethod) then
pReflectedMethod();`
¿Lo viste? En 3 líneas estás llamando una función que nunca se cargó oficialmente. Si eso no es poder, no sé qué lo es.
🧩 ¿Lo puedo modificar?
¡Claro que sí! Algunas ideas que se me ocurren:
-
Agregar soporte para TLS callbacks
-
Hacerlo multihilo para cargar varias DLLs en paralelo
-
Adaptarlo para ejecutar EXEs reflejados como si fueran DLLs
-
Empaquetarlo en una librería propia tipo “ReflectorLib”
La base es sólida, ahora podés llevarlo hasta donde quieras.
✍️ Palabras finales (pero sin muletillas, tranqui)
Si llegaste hasta acá, ya te diste cuenta de que este código es una joyita. No es algo que veas todos los días, y definitivamente no es lo típico que se enseña en un curso de programación. Es más bien de esos tesoros que encontrás en foros underground, de gente que realmente sabe.
A mí me dejó pensando. No solo por lo que hace, sino por cómo está hecho: limpio, eficiente, y elegante. ¿Lo vas a usar? ¿Lo vas a estudiar? ¿Lo vas a mejorar?
Sea como sea, ya tenés una herramienta más en tu arsenal. Y de las buenas.
Mas abajo te dejo el código completo:
https://unprotect.it/snippet/reflective-dll-injection/207/raw/