Problema al pasar cadenas a los campos de un struct en FASM

Iniciado por Swicher, 31 Enero 2013, 09:36 AM

0 Miembros y 1 Visitante están viendo este tema.

Swicher

Hola a todos, estoy convirtiendo este código en Python en una librería en Assembler y esto es lo que tengo hasta ahora:

Código (asm) [Seleccionar]
format PE GUI 4.0 DLL
entry DllEntryPoint

include 'win32a.inc'

section '.code' code readable executable

struct SHELLEXECUTEINFO
    cbSize dd ?
    fMask dd ?
    hwnd dd ?
    lpVerb dd ?
    lpFile dd ?
    lpParameters dd ?
    lpDirectory dd ?
    nShow dd ?
    hInstApp  dd ?
    lpIDList  dd ?
    lpClass dd ?
    hKeyClass  dd ?
    dwHotKey dd ?
    hIconOrMonitor  dd ?
    hProcess  dd ?
ends

proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
        mov     eax,TRUE
        ret
endp

proc ShowProp filepath
    mov [sei.cbSize], sizeof.SHELLEXECUTEINFO
    mov [sei.fMask], SEE_MASK_NOCLOSEPROCESS or SEE_MASK_INVOKEIDLIST
    mov [sei.lpVerb], prop
    mov ecx, [filepath]
    mov [sei.lpFile], ecx
    mov [sei.nShow], 1
    invoke ShellExecuteEx, sei
    ret
endp

section '.data' data readable writeable

SEE_MASK_NOCLOSEPROCESS = 0x00000040
SEE_MASK_INVOKEIDLIST = 0x0000000C
prop db "properties",0
sei SHELLEXECUTEINFO

section '.idata' import data readable writeable

library shell32,'SHELL32.DLL'
import shell32,ShellExecuteEx,'ShellExecuteEx'

section '.edata' export data readable

  export 'ShowProperties.dll', ShowProp, 'ShowProp'

section '.reloc' fixups data discardable


pero el mismo no compila. Al hacer unas pruebas (esto es, comentar lineas hasta que no me aparecieran mas errores) descubri que el problema esta en las lineas 41 y 42 al intentar asignar cadenas a los campos lpVerb y lpFile del struct SHELLEXECUTEINFO y sin importar como lo haga, el compilador siempre muestra algun error. ¿Que estoy haciendo mal? Por cierto, estos son los errores que me aparecen:






LineaModificaciónError que aparece
41mov[sei.lpVerb],propinvalid use of symbol.
41mov [sei.lpVerb], "properties"value out of range.
42mov [sei.lpFile], filepathinvalid value.
37 y 42proc ShowProp filepath* y mov [sei.lpFile], filepath (con y sin * al final)extra characters on line. (en endp)


Edit varios días después: Ya arregle ese problema que aparecía al ejecutar la función (eso de "access violation writing ..."). Abajo explico como lo logre.

Eternal Idol

La estructura esta mal definida, los punteros a cadena no son db, no es un byte, sino que son dd que es el tamaño de un puntero en x86 (4 bytes).

Creo que con esto solventas el error que queda pero probalo:
Código (asm) [Seleccionar]
mov ecx, [filepath]
mov [sei.lpFile], ecx
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

Swicher

Gracias Eternal Idol, logre compilar el código con las correcciones que mencionaste (ya sospechaba yo que el problema era alguna simpleza como esa ya que para hacer la estructura me base en lo que decía el manual de FASM y creía que las cadenas en las estructuras se asignaban de forma diferente a los números).
Por cierto, cuando importo la librería con Python y llamo a la función ShowProp (todo mediante ctypes) me aparece el error "WindowsError: exception: access violation writing 0x010E200F" y la única forma de arreglarlo que encontré fue agregándole el flag "writeable" a la sección ".code" y en este caso la función se ejecuta correctamente aunque también aparece "WindowsError: exception: access violation writing 0x00000001" (ciertamente es algo raro, pero bueno, quizás después le agregue mas código para ver que error produce con GetLastError o pruebe a importar la DDL en otro programa).

Eternal Idol

Primero depuralo con WinDbg usando un programa propio y cuando funcione probalo con Python  ;)
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

fary

Recuerda que no puedes mover información de una variable a otra con mov, ejemplo erroneo:

Código (asm) [Seleccionar]
mov [var1],[var2]


Ejemplo correcto:

Código (asm) [Seleccionar]
mov eax,[var2]
mov [var1],eax


ó:

Código (asm) [Seleccionar]
push [var2]
pop [var1]


saludos!
Un byte a la izquierda.

Swicher

Después de varias pruebas y errores descubrí que para que la función se ejecutara sin problemas solamente tenia que crear una instancia (no se si en ASM se le dice de otro modo) de SHELLEXECUTEINFO en la sección .data en lugar de hacerlo mientras se ejecuta ShowProp.
Cita de: Eternal Idol 7D en 31 Enero 2013, 13:29 PM
Primero depuralo con WinDbg usando un programa propio y cuando funcione probalo con Python  ;)
Curiosamente estuve depurando la librería con OllyDbg mediante este truco pero hasta que no hice lo de cambiar de lugar la instancia de SHELLEXECUTEINFO, el programa solo reconocía la función "DllEntryPoint" (o sea, es como que si Showprop no existiera).
Para terminar, actualizo el código del primer post por si a alguien mas le llega a resultar útil (cualquier mejora u optimización es bienvenida).