Foro de elhacker.net

Programación => ASM => Mensaje iniciado por: Yuki en 1 Mayo 2016, 18:37 pm



Título: Cadenas en FASM
Publicado por: Yuki en 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.

Código:
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:
; 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?


Título: Re: Cadenas en FASM
Publicado por: fary en 1 Mayo 2016, 19:28 pm
Tienes que crear un buffer con malloc, LocalAlloc o similar y ahí concatenar las cadenas.

Saludos.


Título: Re: Cadenas en FASM
Publicado por: Yuki en 1 Mayo 2016, 20:16 pm
¿Me podrias dar un pequeño ejemplo? no puedo visualizar el código sin usar registros.

Código:
.datos
cadenita dd ?
TmpStr1 db "Soy una cadenita de longitud 50 o que se yo."
TmpLng = $ - TmpStr1
.código
inicio:
       ccall [malloc],TmpLng
       add esp,4 ; Liberamos el stack.
       mov [cadenita],eax
       push TmpStr1
       push [cadenita]
       ccall [strcat]
       add esp,8 ; Liberamos el stack.
       ; [cadenita] = Puntero A "Soy una cadenita de longitud 50 o que se yo."????????

entry inicio




Disculpen por el doble comentario, solucione mi problema con un procedimiento propio que hice, lo pongo acá por si alguien tiene el mismo problema que yo y requiere una solución, ademas no me gusta dejar mis posts sin el "resuelto".

Utilizo el siguiente procedimiento en mi compilador para concatenar cadenas.
Acepta 2 parametros (punteros a cadenas) y retorna un puntero a la cadena concatenada en EAX.

Código:
proc concatenar uses ecx,Fuente2,Fuente1 ; Retorna en EAX
mov EDI, [Fuente2]
push EDI
call [strlen]
Add ESP, 4
mov ESI, EAX
mov EDI, [Fuente1]
push EDI
call [strlen]
add ESP, 4
add ESI,EAX ; ecx = len(Fuente2) + len(Fuente1)
push ESI
call [malloc]
add ESP, 4
push EDI
push EAX
call [strcpy]
add ESP, 8
mov EDI, [Fuente2]
push EDI
push EAX
call [strcat]
add ESP, 8
ret
endp

Me hubiera gustado que fuera mas chica, pero como esta escrita en ensamblador supongo que de todas maneras debe ser muy rapida.


Título: Re: Cadenas en FASM
Publicado por: fary en 6 Mayo 2016, 10:28 am
Hola Yuki,

Es combeniente que  el buffer sea de tamaño len(Fuente2) + len(Fuente1) + 1 para el byte nulo de final de cadena.

Usa mejor invoke para llamar a las API, queda un código mas corto y mas limpio y viene a ser lo mismo... para las funciones de las librerias de C usa cinvoke, que te arregla la pila.

Código
  1. proc concatenar uses ecx,Fuente2,Fuente1 ; Retorna en EAX
  2.    cinvoke strlen, [Fuente2]
  3.    mov ESI, EAX
  4.    cinvoke strlen, [Fuente1
  5.  
  6.    add ESI,EAX ; ecx = len(Fuente2) + len(Fuente1)
  7.    cinvoke malloc, esi
  8.    cinvoke strcpy, eax, edi
  9.    cinvoke strcat, eax, [Fuente2]
  10.  
  11.    ret
  12. endp

Ademas el buffer que crees con malloc limpialo con ZeroMemory o similares para que no contenga caracteres extraños, llegado el momento puedes tener lios con eso.

saludos y suerte con tu proyecto.