您的位置:首页 > 其它

非调用手法获取API

2007-04-10 19:29 337 查看
使用非调用手法获取API,其实是PE病毒的基本手段之一。

搜索输出表,导出GetModuleHandle,LoadLibraryA,GetProcAddress函数的地址,然后用LoadLibraryA调用USER32.DLL,然后再使用GetProcAddress得到MessageBoxA()的函数,得到输出框。
GetModuleHandle暂时没用到。。。汗一个。

.386
.model flat

;kernel_ equ 0BFF70000h

.data
szTitle db "Test for GetApi",0
szMessage db "perfect,we got the api!",0
u32 db "User32.dll",0
kernel dd ?
Counter dd 00000000h

heap_start label byte

dd 00000000h
AddressTableVA dd 00000000h
OrdinalTableVA dd 00000000h
NameTableVA dd 00000000h

@@Offset label byte
_MessageBoxA dd 00000000h
@@Namez label byte
@MessaeBoxA db "MessageBoxA",0

_Namez label byte
@GetModuleHandle db "GetModuleHandleA",0
@GetProcAddress db "GetProcAddress",0
@LoadLibraryA db "LoadLibraryA",0
@ExitProcess db "ExitProcess",0
db 0BBh

_Offsetz label byte
_GetModuleHandle dd 00000000h
_GetProcAddress dd 00000000h
_LoadLibraryA dd 00000000h
_ExitProcess dd 00000000h
;_MessageBoxA dd 00000000h

heap_end label byte

.code

s_start label byte

test1:
call delta
delta:
pop ebp ;重定位
sub ebp,offset delta ;ebp得到修正值

mov esi,[esp] ;Kernal32的地址
and esi,0ffe00000h ;数据对齐
call GetK32 ;返回EAX=得到的 KENNEL地址

; mov dword ptr [ebp+kernel],eax
; mov dword ptr [ebp+kernel],eax

lea edi,[ebp+kernel]
stosd

lea edi,[ebp+_Offsetz]
lea esi,[ebp+_Namez]
call GetAPIs
push offset u32
call dword ptr [ebp+_LoadLibraryA]
lea edx,[ebp+@MessaeBoxA]
push edx
push eax
mov eax,dword ptr [ebp+_GetProcAddress]
call eax

xor ebx,ebx
push ebx
push offset szTitle
push offset szMessage
push ebx
call eax
push 00h
call [ebp+_ExitProcess]
GetK32:
_1:
cmp word ptr [esi],"ZM" ;对照是否MZ
jz CheckPE
_2:
sub esi,10000h ;不是就减去一页再次对比
jmp _1
CheckPE:
mov edi,[esi+3ch] ;找到对应PE
add edi,esi ;相对地址转绝对地址
cmp dword ptr [edi],"EP" ;对照是否“PE”
jz WeGotK32 ;是,我们得到K32地址。
jmp _2 ;不是。。。汗一个。重来。。
;WeFailed: 暂时没用它。。
; mov esi,0BFF70000h

WeGotK32:
xchg eax,esi ;eax= address of k32
ret
GetAPI proc

mov edx,esi ; Save ptr to name
@_1: cmp byte ptr [esi],0 ; Null-terminated char?
jz @_2 ; Yeah, we got it.
inc esi ; Nopes, continue searching
jmp @_1 ; bloooopz...
@_2: inc esi ; heh, don't forget this ;)
sub esi,edx ; ESI = API Name size
mov ecx,esi ; ECX = ESI :)

xor eax,eax ; EAX = 0
mov word ptr [ebp+Counter],ax ; Counter set to 0

mov esi,[ebp+kernel] ; Get kernel's PE head. offset
add esi,3Ch
lodsw ; in AX
add eax,[ebp+kernel] ; Normalize it

mov esi,[eax+78h] ; Get Export Table RVA
add esi,[ebp+kernel] ; Ptr to Address Table RVA
add esi,1Ch

lodsd ; EAX = Address Table RVA
add eax,[ebp+kernel] ; Normalize
mov dword ptr [ebp+AddressTableVA],eax ; Store it in VA form

lodsd ; EAX = Name Ptrz Table RVA
add eax,[ebp+kernel] ; Normalize
push eax ; mov [ebp+NameTableVA],eax

lodsd ; EAX = Ordinal Table RVA
add eax,[ebp+kernel] ; Normalize
mov dword ptr [ebp+OrdinalTableVA],eax ; Store in VA form

pop esi ; ESI = Name Ptrz Table VA

@_3: push esi ; Save ESI for l8r restore
lodsd ; Get value ptr ESI in EAX
add eax,[ebp+kernel] ; Normalize
mov esi,eax ; ESI = VA of API name
mov edi,edx ; EDI = ptr to wanted API
push ecx ; ECX = API size
cld ; Clear direction flag
rep cmpsb ; Compare both API names

pop ecx ; Restore ECX
jz @_4 ; Jump if APIs are 100% equal
pop esi ; Restore ESI
add esi,4 ; And get next value of array
inc word ptr [ebp+Counter] ; Increase counter
jmp @_3 ; Loop again

@_4: pop esi ; Avoid shit in stack
movzx eax,word ptr [ebp+Counter] ; Get in AX the counter
shl eax,1 ; EAX = AX * 2
add eax,dword ptr [ebp+OrdinalTableVA] ; Normalize
xor esi,esi ; Clear ESI
xchg eax,esi ; EAX = 0, ESI = ptr to Ord
lodsw ; Get Ordinal in AX
shl eax,2 ; EAX = AX * 4
add eax,dword ptr [ebp+AddressTableVA] ; Normalize
mov esi,eax ; ESI = ptr to Address RVA
lodsd ; EAX = Address RVA
add eax,[ebp+kernel] ; Normalize and all is done.
ret

GetAPI endp

;---------------------------------------------------------------------------
;---------------------------------------------------------------------------

GetAPIs proc

@@1: push esi
push edi
call GetAPI
pop edi
pop esi
stosd

@@2: cmp byte ptr [esi],0
jz @@3
inc esi
jmp @@2
@@3: cmp byte ptr [esi+1],0BBh
jz @@4
inc esi
jmp @@1
@@4: ret
GetAPIs endp

;kernel dd kernel_
;kernel_ equ 077e60000h

;@@Namez label byte
;@MessaeBoxA db "MessageBoxA",0

align dword
s_end label byte

end test1

最后我们看到了感动的弹出框,perfect,we got the api。

是不是应该激动一下。应该是。因为我们并没有调用任何的函数,挺不容易的,一个小程序耗费了很长时间,

其实还是基础太差。。加强ING。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: