VBIdea
~~~~~~
by bart


VBIdea coz to znaczy?Jest 2 w nocy i jakos nachodza mnie rozne ciekawe pomysly,
pomyslalem sobie dlaczego progi skompilowane w VB stanowia taka bariere dla
przecietnego szarego crackera, pierwsze to biblioteka glowna gdzie zapisane
sa wszystkie funkcje ktore moznaby zrealizowac w kilku rozkazach asm bez potrzeby
odwolywania sie do zewnetrznych modulow, drugie to sposob zapisywania kodu w
exekach skompilowanych w trybie p-code, czyli zamiast normalnych opcodow asm-a
w kodzie exeka jest zapisane cos na wzor skryptu ktory jest interpretowany i
wykonywany przez glowna biblioteke vb, z tego wzgledu odpada analiza takich progow
w tradycyjnych deasemblerach a co za tym idzie latwosc w lamaniu takich progow.
Jak wykorzystac ta idee w naszych programach?Mozna napisac sobie wlasny rodzaj
asemblera i biblioteke/program ktory runtime bedzie analizowal i wykonywal nasz
kod, ale jest tez nieco prostsze wyjscie, mianowicie napisanie wlasnej biblioteki
w ktorej zawarte beda funkcje odpowiedzialne za np. mov eax,ecx, odwolywanie
do funkcji tej biblioteki bedzie realizowane na opcodach asm-a zamiast na jakims
pseudo kodzie np. mamy taka funkcje w naszej bibliotece:

; czysci zadany rejestr, parametr okreslajacy rejestr ktory czyscimy podajemy w
; ebx/bl
;
; AND REG,0
@@emul_0001	proc
	call	@@emul_0001_01
	add	esp,8			; korekcja stosu po 2 push-ach
	ret
@@emul_0001_02:
	db	68h			; push DWORD
	db	0FFh,0E5h		; jmp ebp
	db	0E9h,00h		;

	db	68h			; push	DWORD
	db	83h,0E0h,00h		; and	reg,0
	db	90h			; nop

	or	byte ptr[esp+1],bl	; ustaw rejestr

	jmp	esp			; --> czysc
@@emul_0001_01:
	pop	ebp			; adres powrotu
	jmp	@@emul_0001_02
@@emul_0001	endp

wywolanie tej procki wyglada nastepujaco:

	_EAX	equ 0
	_ECX	equ 1
	_EDX	equ 2
	_EBX	equ 3
	_ESP	equ 4
	_EBP	equ 5
	_ESI	equ 6
	_EDI	equ 7

	mov	ebx,_EDX		; parametr okreslajacy ktory rejestr ma byc
	call	@@emul_0001		; wyzerowany

Zasada dzialania, w ebx podajemy parametr/rejestr dzieki ktoremu bedzie mozliwe
zbudowanie instrukcji and rejestr,0 (w tym przypadku) czyli wyzerowanie zadanego
rejestru.Bajty z ktorych zbudowana jest instrukcja zapisywane sa na stosie,
nastepnie korygowany jest bit ktory okresla na jakim rejestrze ma byc wykonana
operacja, nastepuje skok do miejsca w pamieci okreslanego przez esp wskutek
czego nastepuje wykonanie operacji and i powrot(jmp ebp) do kodu procki.
Najtrudniejsze okazuje sie opanowanie budowy poszczegolnych instrukcji, chociaz
mozna experymentujac dojsc do celu, jako, ze sam lubie experymentowac polecam
jednak poczytanie tutoriali Lorda-Julusa dotyczacych budowania polimorficznych
enginow w magazynie VXTasy#1, to naprawde ulatwia sprawe.Majac takie podstawy
jestesmy w stanie napisac dowolna(no prawie) procedure emulujaca wykonanie
instrukcji asemblera.Pora na przyklady:

; funkcja moze byc wykorzystana na 3 sposoby
; ADD REG,REG 03h
; XOR REG,REG 33h
; SUB REG,REG 2Bh
@@emul_0003	proc
	call	@@emul_0003_01
	mov	byte ptr[@@ALU],03h	; opcode instrukcji ADD
					; ponizsze parametry nie modyfikuja
					; rejestru flag
	pop	ebp
	pop	ebp			; adres powrotu
	jmp	ebp			; powrot z funkcji
@@emul_0003_02:

	db	68h			; push DWORD
@@ALU:	db	03h			; ADD,SUB,XOR REG,REG
	db	0C0h
	db	0FFh,0E5h		; jmp ebp

	or	byte ptr[esp+1],bh	; rejestr zrodlowy
	shl	bl,3
	or	byte ptr[esp+1],bl	; rejestr docelowy
	
	jmp	esp			; --> dodaj
@@emul_0003_01:
	pop	ebp
	jmp	@@emul_0003_02
@@emul_0003	endp

wywolywanie:
	mov	bl,_EDX
	mov	bh,_EAX
	call	@@emul_0003

W tym wypadku nalezy zadbac aby sekcja w ktorej znajduje sie kod procedury posiadala
atrybuty write gdyz nastepuje nadpisanie kodu co spowoduje wyjatek gdy sekcja nie
bedzie posiadala odpowiedniej charakterystyki.Jeszcze jedna procka sluzaca do zapisania
na stosie wartosci danego rejestru oraz wartosci:

; zapisuje na stosie wartosc z zadanego rejestru
; PUSH REG
@@emul_000A	proc
	mov	byte ptr [PUSH_RM],50h	; oryginalna wartosc
	pop	ebp			; adres powrotu
	or	byte ptr[PUSH_RM],bl	; push REG
	db	50h			; tu jest wykonywana instrukcja
PUSH_RM	equ byte ptr $-1
	jmp	ebp
@@emul_000A	endp

Wywolywanie:

	mov	ebx,_ECX
	call	@@emul_000A

; zapisuje na stosie wartosc, ktory podajemy mu w rejestrze ebx
; push DWORD
@@emul_0002	proc
	pop	ebp			; adres powrotu
	push	ebx			; zapamietaj parametr
	jmp	ebp			; powrot do programu
@@emul_0002	endp

Oczywiscie to tylko proste przyklady ale przeciez kod w tych prockach moze byc
np. szyfrowany, wykonywane liczne jmp-y, fake jmpy co sprawi, ze zrozumienie
dzialania tego schematu moze troche zajac dla kogos kto nie bedzie mial pojecia,
ze w rzeczywistosci te procedury wykonuja bardzo proste rzeczy jak dodaj eax do
ebx :)).Aby ulatwic sobie zycie z wywolywaniem funkcji mozna skorzystac z makra:

callD	macro	function,param1,param2
IFNB	<param1>
	IFNB	<param2>		; jesli 2 parametr podany
	db	0BBh			; mov ebx,DWORD
	dd	((param1 shl 8) or param2)
	ELSE				; jesli 2 parametr nie podany
	db	0BBh
	dd	param1			; uzyj tylko jego
	ENDIF
ELSE
ENDIF
	call	function
endm

Droga do zbudowania wlasnego rodzaju programow stoi otworem, tych rozwiazan
chyba nie warto stosowac na szersza skale, ale stanowi ciekawa alternatywe dla
tradycyjnych algorytmow sprawdzania poprawnosci sn ;)

bart^CrackPl
cryogen@poland.com
cryogen@box43.pl
http://www.cryogen.prv.pl
