[SOLUCIONADO] [Gnu AS] BruteForce

Iniciado por GGZ, Octubre 01, 2016, 01:36:17 AM

Tema anterior - Siguiente tema

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

Octubre 01, 2016, 01:36:17 AM Ultima modificación: Octubre 05, 2016, 10:30:50 PM por Nobody
Voy al grano,

Hecho en C:
Código: c
#include <stdio.h>

int fuerzabruta(char *S, char *s, int lS, int ls)
{
        int i, j;

        for(i=0; i<lS-ls+1; i++)
                if(S[i]==s[0]) {
                      for (j=0; j<ls; j++){
                              if (S[i+j] != s[j]) break;
                      }
   
                        if(j==ls) return i;
        }
        return -1;
}   


Lo pasé a ASM y anduvo, pero lo quise hacer de nuevo y no funcionó:

1era versión:
Código: asm
#int fuerzabruta(char *S, char *s, int lS, int ls){
# int i, j;
# for(i=0; i<lS-ls+1; i++)
# if(S[i]==s[0]) {
# for(j=0; j<ls && S[i+j]==s[j]; j++);
# if(j==ls) return i;
# }
# return -1;
#}

# Retorna la posición del primer elemento de la cadena a buscar.
# "sHolasos" "sos" retorna 5.



# lS = %rdx
# ls = %rcx

.data
i: .quad 0

.text
.global bf
bf:
# iremos incrementando (df = 0)
cld

# Guardo variable ls en otro registro.
# rdx = ls
movq %rcx,%r8


# cuantas veces repetimos al primer for?

subq %rcx,%rdx # rdx = rdx - rcx
# es decir: lS = lS - ls

addq $1,%rdx # sumo 1



# Lo cargamos al rcx para el bucle.
movq %rdx, %rcx
aca:
lodsb # copiamos el primer caracter de la 2da cadena en el rax
# decq %rsi

sigue1:
#lodsb
# primero busco el primer caracter de la cadena 2 en la cadena 1.
# mas tecnico: comparamos rax con rdi
scasb
# si encontramos el primer caracter en algun lugar de la cadena, saltamos al 2do for.

je found
loop sigue1
# termina.
# -1 si no lo encontramos el primer caracter de la 2da cadena en la primera.
movq $-1, %rax
ret


found:
# encontramos el primer caracter de la 2da cadena en la primera.
# estamos dentro del primer if.
# usaremos el registro r8, hasta el momento r8 = ls.

# Quiero saber el valor de i
# i = %rdx - %rcx
# i = lS-ls+1 - veces repetido (hacia atras,es decir del tope al 0).

# Guardamos informacion del bucle anterior.
movq %rcx,%r13
movq %rdx,%r15
movq %rsi,%r9
subq $1,%r9

subq %rcx,%rdx # rdx = rdx - rcx ( i = rdx )


# Cargamos r8=ls a rcx para el 2do for. Hay que restar uno.
movq %r8,%rcx
decq %rcx
movq %rdi,%r14
sigue2:
# comprobamos si los siguientes caracteres estan en la cadena 1.
# tengo que cambiar adonde apunta rdi, es decir la primer cadena. ( S[i+j] )
# i = rdx
cmpsb
jne fail
loop sigue2
movq %rdx,%rax
addq $1,%rax
ret


# fallo en el 2do for.
fail:
# el último if ( if j == ls return i )
# si es igual a 0 significa que recorrió todo el bucle.
cmpq $0, %rcx
je final
# si no son iguales vuelvo al 1do for.

# antes cargo el rcx y rdi de nuevo, con informacion del i del primer bucle.
# restauro registros
movq %r13,%rcx
movq %r14,%rdi

movq %r9, %rsi
movq %r15,%rdx
jmp aca

final:
subq %rcx,%rdx # es el i
movq %rdx,%rax
ret


Lo implemento usando se, o sea declaro el prototipo en c y llamo a esa funcion, haciendo gcc bf.c bf.s -o bf
Esa primer versión con todo lo que probé funcionó pero esta segunda versión no, capaz me comí algo pero ya me cansé de buscarlo.
Intenté con gdb pero me cansé a ver si alguien me puede dar una manito.
Para usar gdb lo compilaba con -g

Segunda versión:
Código: asm
.text
.global bf
bf:
cld
movq %rcx,%r8

subq %rdx,%rcx # rdx = rdx - rcx
# lS = lS - ls
addq $1, %rdx

movq %rdx,%r9

movq %rdx,%rcx
aca:
lodsb # cargamos el primer caracter de la 2da cadena en el rax.
subq $1,%rsi

_1for:
scasb
je si_eq_s0
loop _1for
movq $-1, %rax
ret

si_eq_s0:
# Para volver al anterior bucle.
movq %rsi, %r14
addq $1,%rsi
movq %rdi, %r12
movq %rcx, %r13 # valor de i.

subq %r13,%r9 # valor de i


movq %r8,%rcx
subq $1,%rcx

_2for:
cmpsb # rsi == rdi?
jne fail
loop _2for
movq %r13,%rax
ret

fail:
cmpq $0,%rcx
je final

movq %r14,%rsi
movq %r12,%rdi
movq %r13,%rcx
jmp aca

final:
movq %r9,%rax
ret


Esta es la imp.

Código: c
#include <stdio.h>
int bf ( char *s1, char *s2, int long_s1, int long_s2);
int main (void){
printf ("Resultado: %d\n",bf("soAdSDsos","sos",9,3));
        return 0;
}



Saludos!


Hola,

no he tenido mucho tiempo para revisar el código entero, pero he encontrado algo a primera vista:

En la 1ra version:
Código: asm
subq %rcx,%rdx  # rdx = rdx - rcx
                        # es decir: lS = lS - ls


En la 2da version:
Código: asm
subq %rdx,%rcx  # rdx = rdx - rcx
                        # lS = lS - ls



En la segunda versión obtienes rcx = rcx - rdx, osea, ls = ls - lS

Saludos

Octubre 01, 2016, 09:20:15 PM #2 Ultima modificación: Octubre 01, 2016, 09:32:22 PM por _ggz
Sí, de todos modos no es el problema.
Ya lo había visto, me lo habían mencionado.

¿Podés programarlo desde 0?, sin necesariamente ver el mío y veo que estoy haciendo mal.

Recién cuando lo estaba haciendo denuevo, me doy cuenta que el rcx va hasta más de 0, y eso no lo entiendo.
A ver si me explico.

Código: asm
.text
.global bf
bf:
cld
movq %rcx,%r8

subq %rcx,%rdx
incq %rdx

movq %rdx,%rcx

aca:
lodsb
_1for:
scasb
je Si_eq_s0
loop _1for

movq $-1,%rax
ret

Si_eq_s0:
movq %rcx,%r13
movq %rsi,%r11
movq %rdi,%r12

# comprobamos denuevo letra anterior porque sino queda vacio y da true.
incq %rcx
decq %rsi
decq %rdi

subq %rcx,%rdx # este es la posición.

# esta bucle se repite ls-1 veces.
movq %r8,%rcx # r8=ls
decq %rcx
decq %rcx

_2for:
cmpsb
jne fail
loop _2for
movq %rdx,%rax
ret

fail:
movq $1337,%rax
ret


Probado con "sHsosz" y "z"
Lo miré con gdb y rcx va hasta -2 ¿por qué?, me parece que debería usar repe.

Octubre 01, 2016, 10:02:04 PM #3 Ultima modificación: Octubre 01, 2016, 10:13:35 PM por ggz
Ayudame a calcular la posición del i del primer for.
Funciona perfecto todo, pero me tira mal la posición del i, del primer for.

Mirá este código lo debuggié con gdb, de todos modos no pude sacar.
Capaz que sea una cuenta mal hecha, este código está ya funcionando.

Código: asm
.text
.global bf
bf:
cld
movq %rcx,%r8

subq %rcx,%rdx
incq %rdx

movq %rdx,%rcx

aca:
lodsb
_1for:
scasb
je Si_eq_s0
loop _1for

movq $-1,%rax
ret

Si_eq_s0:
movq %rcx,%r13
movq %rsi,%r11
decq %r11 # siempre apunta al primero
movq %rdi,%r12

# comprobamos denuevo letra anterior porque sino queda vacio y da true.
# incq %rcx # VER
decq %rsi
decq %rdi

subq %rcx,%rdx # este es la posición.

# esta bucle se repite ls-1 veces.
movq %r8,%rcx # r8=ls
decq %rcx

_2for:
repe cmpsb
jne fail

jmp final

fail:
cmpq $0,%rcx
je final

movq %r13,%rcx
movq %r11,%rsi
movq %r12,%rdi
jmp aca

final:
subq %rcx,%rdx
movq %rdx,%rax
ret

Octubre 02, 2016, 08:49:49 AM #4 Ultima modificación: Octubre 02, 2016, 09:15:33 AM por ggz
Al final me quedó así, alguien puede probar con todo lo que se le ocurra y compararlo con el hecho en C, yo lo probé con varios y funcionaban.

Código: asm
.text
.global bf
bf:
cld
movq %rcx,%r8
subq %rcx,%rdx
incq %rdx

movq %rdx,%rcx
aca:
lodsb
_1for:
scasb #repne
je Si_eq_s0
loop _1for

movq $-1,%rax
ret

Si_eq_s0:
# el valor de i:
movq %rdx,%r9
subq %rcx,%rdx

movq %rdx,%r15
movq %rcx,%r13
decq %r13
movq %rsi,%r11
decq %r11 # siempre apunta al primero
movq %rdi,%r12

# comprobamos denuevo letra anterior porque sino queda vacio y da true.
# incq %rcx # VER
decq %rsi
decq %rdi

subq %rcx,%rdx # este es la posición.

# esta bucle se repite ls-1 veces.
movq %r8,%rcx # r8=ls


_2for:
cmpsb
jne fail
loop _2for

movq %r15,%rax
ret

fail:
movq %r13,%rcx
movq %r11,%rsi
movq %r12,%rdi
movq %r9,%rdx
jmp aca


Es oro puro.

PUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUMMMM