Os dejo algunas funciones en FASM que e ido haciendo desde que empece con asm.
Función que compara dos cadenas:
proc Comparar,cadena1,cadena2
;Si son iguales EAX = 1
;Si son diferentes EAX = 0
mov esi,[cadena1]
mov ecx,[cadena2]
dec ecx
bucle:
inc ecx
lodsb
cmp byte[ecx],al
jne diferentes
cmp al,0
je comprovar
jmp bucle
comprovar:
cmp byte[ecx],0
je iguales
jne diferentes
diferentes:
mov eax,0
ret
iguales:
mov eax,1
ret
endp
Ejemplo de su uso:
include 'win32ax.inc'
.data
palabra db 'Drinky94',0
palabra2 db 'Drinky94',0
.code
start:
stdcall Comparar,palabra,palabra2
.if eax = 0
invoke MessageBoxA,0,'Son Diferentes',0,0
.else
invoke MessageBoxA,0,'Son Iguales',0,0
.endif
ret
proc Comparar,cadena1,cadena2
;Si son iguales EAX = 1
;Si son diferentes EAX = 0
mov esi,[cadena1]
mov ecx,[cadena2]
dec ecx
bucle:
inc ecx
lodsb
cmp byte[ecx],al
jne diferentes
cmp al,0
je comprovar
jmp bucle
comprovar:
cmp byte[ecx],0
je iguales
jne diferentes
diferentes:
mov eax,0
ret
iguales:
mov eax,1
ret
endp
.end start
Función que mide la longitud de una cadena:
proc Len,Cadena
;ECX = Longitud de la cadena.
mov eax,[Cadena]
mov ecx,-1
bucle:
inc ecx
cmp byte[eax+ecx],0
jne bucle
ret
endp
Ejemplo de su uso:
include 'win32ax.inc'
.data
palabra db 'Drinky94',0
longitud dd ?
.code
start:
stdcall Len,palabra
mov [longitud],ecx
invoke GlobalAlloc,GPTR,1024
push eax
invoke wsprintfA,eax,"%d",[longitud]
pop eax
invoke MessageBox,0,eax,0,MB_OK
leave
ret
proc Len,Cadena
;ECX = Longitud de la cadena
mov eax,[Cadena]
mov ecx,-1
bucle:
inc ecx
cmp byte[eax+ecx],0
jne bucle
ret
endp
.end start
Función que puede servir de remplazo a GlobalAlloc:
proc DGlobalAlloc,cantidad
sub esp,[cantidad]
mov eax,esp
ret
endp
Ejemplo de su uso:
include 'win32ax.inc'
.data
palabra db 'Drinky94',0
longitud dd ?
.code
start:
stdcall Len,palabra
mov [longitud],ecx
stdcall DGlobalAlloc,1024
push eax
invoke wsprintfA,eax,"%d",[longitud]
pop eax
invoke MessageBox,0,eax,0,MB_OK
leave
ret
proc Len,Cadena
mov eax,[Cadena]
mov ecx,-1
bucle:
inc ecx
cmp byte[eax+ecx],0
jne bucle
ret
endp
proc DGlobalAlloc,cantidad
sub esp,[cantidad]
mov eax,esp
ret
endp
.end start
Código para saber si nos están debuggeando (usa el PEB):
format PE GUI 4.0
entry start
include 'win32ax.inc'
SiDbg db 'Hay Debugger',0
NoDbg db 'No hay Debugger',0
start:
mov eax,dword[fs:18h]
mov eax,dword[eax+30h]
mov bl,byte[eax+2] ; si bl = 1 Nos estan debujeando.
.if bl = 1
invoke MessageBoxA,0,SiDbg,0,0
.else
invoke MessageBoxA,0,NoDbg,0,0
.endif
ret
data import
library user32,'user32.dll'
import user32,MessageBoxA,'MessageBoxA'
end data
Simple cifrado Xor:
proc Cifrar,Cadena
xor ecx,ecx
mov eax,[Cadena]
.bucle:
.if byte[eax+ecx] = 0
jmp .salir
.endif
xor byte[eax+ecx],7
inc ecx
jmp .bucle
.salir:
ret
endp
Ejemplo de su uso:
include 'win32ax.inc'
.data
hola db 'hola',0
.code
start:
stdcall Cifrar,hola
invoke MessageBoxA,0,eax,0,0
ret
proc Cifrar,Cadena
xor ecx,ecx
mov eax,[Cadena]
.bucle:
.if byte[eax+ecx] = 0
jmp .salir
.endif
xor byte[eax+ecx],7
inc ecx
jmp .bucle
.salir:
ret
endp
.end start
Función que pasa un número entero a cadena:
proc NumToString,Numero
;Función creada por Drinky94. Agradecimientos a Jep.
locals
divisor dw ?
; buffer rb 20 Agregar esta variable en la sección data
; El numero 20 es la longitud que tendra la cadena
;si nuestro numero tiene 4 cifras tendremos que poner 4
; CadenaFinal rb 20 ; lo mismo que con la variable buffer.
endl
mov [divisor],10
xor eax,eax
xor ebx,ebx
mov eax,[Numero]
bucle:
xor edx,edx
div [divisor]
add dl,0x30
mov byte[buffer+ebx],dl
inc ebx
cmp eax,0
jne bucle
inc ebx
mov byte[buffer+ebx],0x0
mov eax,buffer
mov ecx,-1
buclelen:
inc ecx
cmp byte[eax+ecx],0
jne buclelen
xor ebx,ebx
dec ecx
reverse:
xor edx,edx
mov dl,byte[eax+ecx]
mov byte[CadenaFinal+ebx],dl
inc ebx
sub ecx,1
cmp ecx,-1
jne reverse
mov eax,CadenaFinal
ret
endp
Ejemplo de su uso:
include 'win32ax.inc'
.data
buffer rb 4
CadenaFinal rb 4
.code
start:
stdcall NumToString,1994
invoke MessageBoxA,0,eax,0,0
ret
proc NumToString,Numero
;Función creada por Drinky94. Agradecimientos a Jep.
locals
divisor dw ?
; buffer rb 20 Agregar esta variable en la sección data
; El numero 20 es la longitud que tendra la cadena
;si nuestro numero tiene 4 cifras tendremos que poner 4
; CadenaFinal rb 20 ; lo mismo que con la variable buffer.
endl
mov [divisor],10
xor eax,eax
xor ebx,ebx
mov eax,[Numero]
bucle:
xor edx,edx
div [divisor]
add dl,0x30
mov byte[buffer+ebx],dl
inc ebx
cmp eax,0
jne bucle
inc ebx
mov byte[buffer+ebx],0x0
mov eax,buffer
mov ecx,-1
buclelen:
inc ecx
cmp byte[eax+ecx],0
jne buclelen
xor ebx,ebx
dec ecx
reverse:
xor edx,edx
mov dl,byte[eax+ecx]
mov byte[CadenaFinal+ebx],dl
inc ebx
sub ecx,1
cmp ecx,-1
jne reverse
mov eax,CadenaFinal
ret
endp
.end start
Cuando valla haciendo mas las voi posteando :P
saludos.
Ret Exe corruption
;///////////////////////////////////////////////////////////////////////////////
;//// Ret Exe Corruption: corrompe los exe poniendo un 0xC3 (ret) en el ////
;//// entry point. Este código no funciona con algunos ejecutables para ////
;//// ello habría que hacer algunos modificaciones. ////
;//// Programado por Drinky94 a 13 - Septiembre - 2011 ////
;///////////////////////////////////////////////////////////////////////////////
include 'win32ax.inc'
.data
manija dd ?
larchivo dd ?
espacio dd ?
bleidos dd ?
PE dd ? ; puntero a NT
EP dd ? ; EntryPoint
wb dd ?
.code
start:
invoke CreateFileA,'g:\bowser.exe', GENERIC_READ, FILE_SHARE_READ, 0,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0
mov [manija],eax
invoke GetFileSize,[manija],0
mov [larchivo],eax
invoke GlobalAlloc,GPTR,[larchivo]
mov [espacio],eax
invoke ReadFile,[manija],[espacio],[larchivo],addr bleidos,0
invoke CloseHandle,[manija]
leave
mov eax,[espacio]
cmp word[eax],'MZ'
jne salir
mov ecx,eax
add eax,dword[eax+0x3C] ; EAX = PE
mov [PE],eax
cmp word[eax],'PE'
jne salir
add eax,0x28
mov ebx,dword[eax]
mov [EP],ebx ;EP = EntryPoint
mov ebx,ecx ; EAX = puntero inicio
add ecx,[EP]
mov word[ecx],0xC3
;// Aquí tendríamos que eliminar el viejo archivo y generar nuestro Exe modificado con el mismo nombre.
invoke CreateFile,"g:\NuevoRET.exe",GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,0
push eax
invoke WriteFile,eax,ebx,[larchivo],wb,NULL
pop eax
invoke CloseHandle,eax
invoke MessageBoxA,0,"FIN",0,0
salir:
leave
ret
.end start