Asm Referat (RE)

Transkrypt

Asm Referat (RE)
Asm Referat (RE)
Wpisany przez Administrator
niedziela, 05 września 2010 18:48
Asembler.
Wykorzystanie Asemblera w kontekście RE
(czyli do czego może przydać się najbardziej abstrakcyjny język programowania)
Informacje wstępne (obowiązkowe) - referat na zajęcia z czegoś tam
1. Kto stworzył język asemblera? && Kiedy (w jakich latach) powstał język
asemblera?
Pierwszym asemblerem był skonstruowany przez Konrada Zuse w 1945 r. układ
elektromechaniczny
przygotowania
taśmy perforowanej
z programem dla maszyny
Z4
Planfertigungsteil
, który umożliwiał wprowadzanie oraz odczyt rozkazów i
adresów
w sposób zrozumiały dla człowieka. (źródło: wikipedia.pl)
1 / 16
Asm Referat (RE)
Wpisany przez Administrator
niedziela, 05 września 2010 18:48
2. Jaki
jest cel Asemblera?
- język komunikacji z procesorem
- wykorzystanie w kodzie o krytycznej wydajności (real-time systems), software pisany w języku
asmeblera jest o wiele szybszy niż ten, pisany w HLL (High-Level-Language)
- ma umożliwić działanie kodu bez systemu operacyjnego
- bezpośrednia komunikacja ze sprzętem (sterowniki)
- wykorzystanie rozkazów procesora niedostępnych w HLL
- pisanie wirusów, bootloaderow, kernelow- reverse engineering ? uzyskiwanie nowego kodu i
zmiana funkcjonalności programu przy pomocy inżynierii wstecznej
- tworzenie oprogramowania o podstawowym znaczeniu dla działania sprzętu komputerowego
- program w asemblerze zapewnia bardzo mały rozmiar pliku wynikowego
- stwarza możliwość pisania takich programów, których nie da się napisać w innych językach
- możliwość pisania nowych języków programowania
3. Jakie
języki poprzedzały Asemblera w rozwoju?
Języki 1st generacji, czyli języki maszynowe (języki procesorów). Instrukcje zapisywane były w
postaci liczb binarnych, np:
Przykładowy kod programu:
2 / 16
Asm Referat (RE)
Wpisany przez Administrator
niedziela, 05 września 2010 18:48
111010100000000000001111111111111111100010011101100000000010100000001
Dopiero potem pojawiły się języki 2nd generacji - języki symboliczne, asemblery. Języki
niskiego poziomu, pod względem składni tożsame z maszynowymi, z tą różnicą że zamiast
liczb używa się tu łatwiejszych do zapamiętania mnemoników.
Przykładowy kod programu:
{codecitation}
jmp ffff:0
mov ax, bx
add ax, 1
{/codecitation}
4. Czy język asemblera przetrwa, czy istnieje jego "następca"?
- ?programowanie w asemblerze nie zniknie i ma przed sobą świetlaną przyszłość? (cytat)
(Why? JMP 2 ; look at point 2 once again)
- Następca? Następstwo w kontekście Asemblera może dotyczyć ewentualnie asemblerow (N
ASM
,
TASM
,
MASM
,
FASM
,
3 / 16
Asm Referat (RE)
Wpisany przez Administrator
niedziela, 05 września 2010 18:48
GASM
, ..).
NASM (Linux) przykładowy kod(y): {codecitation}
section .text global _start
_start:
mov edx,len mov ecx,msg mov ebx,1
mov eax,4 ; system call number (sys_write, in sys/syscall.h) int 0x80
mov eax,1 ; system call number (sys_exit) int 0x80 ; call kernel
section .data msg db 'Hello, world!',0xa ;our dear string len equ $ - msg ;length of our dear string
{/codecitation}
Istotna różnica między dwoma źródłami ? konwencja wywoływania funkcji w przypadku
pierwszego źródła: __fastcall a w przypadku drugim, argumenty odkładane są kolejno (od
prawej->do lewej) na stos zgodnie z konwencją __cdecl. W kontekscie RE warto wiedzieć, jaka
konwencja towarzyszy danej funkcji podczas wywołania. Jeśli zapomnimy uprzątnąć stosu w
przypadku cdecl, system ?nie trafi? w adres powrotu w ramce stosu i program się ?wysypie?.
{codecitation}
call _syscall ;call kernel
add esp,12 ;clean stack (3 arguments * 4)
{/codecitation}
Dopiero teraz program przeskoczy 3 ? czterobajtowe argumenty funkcji by zgodnie z budową
ramki stosu (stack frame) ustawić się na adresie powrotu i wykonac RET ? ?powrót? do miejsca
skad będzie kontynuować działanie programu.
__fastcall {codecitation} mov edx,len ;message length
mov ecx,msg ;message to write
4 / 16
Asm Referat (RE)
Wpisany przez Administrator
niedziela, 05 września 2010 18:48
mov ebx,1 ;file descriptor {/codecitation}
__cdecl {codecitation} push dword len ;message length
push dword msg ;message to write
push dword 1 ;file descriptor {/codecitation}
To nie jedyne konwencje stosowane przez programistów. Jeśli interesuje nas napisanie np.
patcha do programu i potrzebujemy wiedzieć co nie co o funkcji, warto zajrzeć do
przykładowego kodu w debuggerze, wejść w wywołanie funkcji (?trace into?) i zobaczyć jaką
instrukcją się ona kończy.
Jeśli funkcja kończy się instrukcją RETN to na pewno mamy do czynienia z konwencją __cdecl.
(Ewentualnie kompilator Borlanda stosujący konwencję __fastcall również kończy funkcję
instrukcją RETN ale odkłada argumenty w kolejności odwrotnej do __cdecl).
Będzie nam to potrzebne, jeśli np. będziemy chcieli wkleić w sekcję .rdata fragment naszego
kodu napisanego w Asemblerze.
MNEMONIKI && Opcode(s):
5 / 16
Asm Referat (RE)
Wpisany przez Administrator
niedziela, 05 września 2010 18:48
Mikroprocesory współczesnych komputerów rozumieją tylko jeden język programowania binarny kod maszynowy (ang. binary machine code).
W pamięci komputera zapisywane są rozkazy dla procesora w postaci binarnej, czyli przy
pomocy bitów. Procesor odczytuje te kody, dekoduje na
odpowiednie polecenia i wykonuje operacje - w ten właśnie sposób realizowany jest program.
Polecenia binarne mogą wyglądać np. tak:
11010010100010101001010101010111
01010101011110100101111010101110
11101001001011101010101001011110
00011010100111001000101111010011
10100100100010010010111000101010
6 / 16
Asm Referat (RE)
Wpisany przez Administrator
niedziela, 05 września 2010 18:48
Czasy programowania komputerów w binarnym kodzie maszynowym bezpowrotnie skończyły
się na początku lat 50-tych ubiegłego wieku. Chociaż procesory wciąż rozumieją tylko swój kod
binarnych poleceń, to ludzie programują je w językach bardziej zrozumiałych dla siebie.
Pierwszym takim językiem był Asembler - binarne kody instrukcji procesora są w nim
reprezentowane przez nazwy symboliczne, które odzwierciedlają wykonywaną przez procesor
operację.
Na przykład zamiast kodu binarnego (po lewej stronie) programista zapisuje symboliczne nazwy
operacji (po prawej stronie):
11010010100010101001010101010111 ? MOV AX,va
01010101011110100101111010101110 ? ADD AX,vb
11101001001011101010101001011110 ? MUL vc
00011010100111001000101111010011 ? ADD AX,vd
10100100100010010010111000101010 ? MOV ve,AX
7 / 16
Asm Referat (RE)
Wpisany przez Administrator
niedziela, 05 września 2010 18:48
Informacja na temat instrukcji JMP dostepna w I-necie:
{codecitation}Opcode JMP
CPU: i8086+
Type Of Instruction: User
Instruction: JMP address
Physical Forms:
0EBh op8 JMP SHORT op8 - short jump. Allows jumping 128 bytes forward
or backwards from next instruction. (Limited to same segment)
0E9h op16 JMP NEAR op16 - near jump. Relative jump from next instruction. (Limited to same
segment)
0E9h op32 JMP NEAR op32
0FFh mem32 - near jump with address specified in memory.
[Incomplete]
8 / 16
Asm Referat (RE)
Wpisany przez Administrator
niedziela, 05 września 2010 18:48
Affected Flags: None, unless taskswitching.
+++++++++++++++++++++++
Clocks:
JMP short: 2
JMP near: 3
JMP far: 5
{/codecitation}
Co jest tu interesującego w kontekście znajomości Asemblera i RE? Jeśli w debugerze
otworzymy jakiś program do analizy i znajdziemy w nim np. taką instrukcję:
9 / 16
Asm Referat (RE)
Wpisany przez Administrator
niedziela, 05 września 2010 18:48
To widać już, że nawet jeśli nie ma 3rd kolumny to wiemy, ze pod adresem 0040127C w
pamięci procesu widnieje instrukcja skoku JMP: 0Ebh. Przyda nam się to potem.
Do czego jeszcze przydać się może umiejętność znajdowania wartości opcodes, wiedza na
temat budowy ramki stosu w asemblerze albo informacja czym jest wskaźnik do funkcji w
środowisku HLL?
RE umozliwia ingerencje w działanie programu dzięki znajomości i wykorzystaniu Asemblera.
Można zmienić rozkład jazdy programu, kiedy np. uszkodzi mu się w pewnym momencie frame
stack i rozkarze ?powrócić? do specjalnie przygotowanego przez nas fragmentu programu w
pamięci napisanego przy pomocy Asemblera.
Przykład programowego wyjścia z użyciem bezpośredniego wywołania systemowego:
{codecitation}
/*shellcodetest.c*/
char code[] = "bytecode will go here!";
10 / 16
Asm Referat (RE)
Wpisany przez Administrator
niedziela, 05 września 2010 18:48
int main(int argc, char **argv)
{
int (*func)(); // deklaracja wkaźnika na funkcję
func = (int (*)()) code; // przypisanie wskaznikowi adresu funkcji
(int)(*func)(); // wywolanie funkcji
} {/codecitation}
Kompilacja:
{codecitation}
;exit.asm
[SECTION .text]
global _start
_start:
11 / 16
Asm Referat (RE)
Wpisany przez Administrator
niedziela, 05 września 2010 18:48
xor eax, eax
mov al, 1
;exit is syscall 1
;exit is syscall 1
xor ebx,ebx
;zero out ebx
int 0x80 {/codecitation}
Deasemblacja:
{codecitation}
exiter:
file format elf32-i386
Disassembly of section .text:
08048080 <_start>:
8048080:
b0 01
mov
$0x1,%al
8048082:
31 db
xor
%ebx,%ebx
8048084:
cd 80
int
$0x80 {/codecitation}
12 / 16
Asm Referat (RE)
Wpisany przez Administrator
niedziela, 05 września 2010 18:48
!!! b0 01 31 db cd 80 !!!
Interesująca nas funkcja ma następującą postać:
{codecitation} char code[] = "xb0x01x31xdbxcdx80"; {/codecitation}
Można wrzucić na stos funkcji odpowiedni parametr, który spowoduje ?przekierowanie? do
podobnego kodu w pamięci, który może mieć dowolną postać i zrobić dla nas dowolne rzeczy
zgodne z przywilejami danego użytkownika np. root?a.
Każde wywołanie funkcji powoduje utworzenie nowej ramki stosu o następującej budowie
(należy pamiętać, że lista uporządkowana jest w kolejności malejących adresów):
? parametry funkcji,
? adres powrotu funkcji, ! ! !
? wskaźnik ramki,
? ramka procedur obsługi wyjątków,
? lokalnie zadeklarowane zmienne i bufory,
? rejestry zachowane przez funkcję wywołaną.
13 / 16
Asm Referat (RE)
Wpisany przez Administrator
niedziela, 05 września 2010 18:48
Co to jest Hexedytor i do czego się może przydać?
- program przeznaczony do edycji plików binarnych. Jego nazwa pochodzi od tego, iż
zawartość edytowanego pliku jest wyświetlana bajt po bajcie w systemie szestnastkowym. Ale
najpierw o diasemblerze. Diasembler (np. IDA) pozwala podobnie jak debuger obejrzeć kod
programu w formie instrukcji asemblera. Od debuggera różni się w sumie tym, że nie pozwala
na wykonywania programu instrukcja po instrukcji.
Po lewej stronie (kolor blue) widać instrukcję załadowaną pod dany adres w pamięci. Nastepnie
widoczna jest sama instrukcja, oraz po najechaniu na loc_ troche informacji o miejscu w
14 / 16
Asm Referat (RE)
Wpisany przez Administrator
niedziela, 05 września 2010 18:48
programie do którego program skoczy jeśli spełni warunek. O co chodzi z warunkami o tym na
końcu. Wiedza na temat asemblera to wiedza na temat komputera. Wiemy też zatem, ze
instrukcje asemblera to po prostu bajty załadowane do pamięci z pliku. Wiemy też, że możemy
podejrzeć ten plik w Hexedytorze. Wiemy zatem, że możemy zmodyfikować w tym edytotrze
kod i dostosować go do naszych potrzeb. Do tego min przydaje się Asembler. Poszukam
podświetlonej instrukcji w pliku wykonywalnym programu.
Jak może wyglądać? Na start sprawdzam opcode dla instrukcji JZ:
{codecitation} 74 cb
JZ rel8
7+m,3 Jump short if 0 (ZF=1) {/codecitation}
I szukam?
15 / 16
Asm Referat (RE)
Wpisany przez Administrator
niedziela, 05 września 2010 18:48
Znając ramki
wpisać
opcodes
EB i zamiast
mogę
JZedytować
zrobi kodu
mi się
kod
bezwarunkowy
i zmienićwcałkiem
JMP.
działanie programu. Mogę zamiast 74
Charakterystyczne
elementy
przydatne
analizie:
Prolog
stosu:
Testy, skoki :
Odkladanie elementow na stos / calls
P
rzygotowanie
skoku
do
oep
(Original
Entry
Point)
w
przypadku
kompresji
np.
UPX
{codecitation}
005533B0
75
JNZ
SHORT
PROGRAM.005533BA
B8
MOV
EAX,1
005533B7
C2
0C00
RETN
0C
005533B2
68
E405000
PUSH
PROGRAM.0050F0E4
;kodzić
original
oep
005533BA
RETN
{/codecitation}
O
w
kontekście
co
chodziło
Asemblera?
z01000000
tymi
warunkami
przy
skokach
i=
dlaczego
jest
to
kolejna
rzecz
warta
zauważenia
Rejestr
flag
procesora
Rejestr
Ustawienie
operacji
Budowa
zbudowany.
nazywanych
flag
arytmetycznej,
rejestru
wartości
statusu
flagami
danej
rejestr
porównania,
zależy
flagi
lub
statusu
znacznikami,
zależy
od
modelu
niekiedy
-np.
wewnętrzny
od
programowego,
opisujących
trybu
może
pracy
być
rejestr
także
iNIC..
procesora,
kontrolujących
w
według
procesorach,
ustawiana
którego
wyniku
zstan
składająca
dany
ostatnio
procesora.
procesor
programu.
wykonanej
się
zwjest
Przykładowe
flagi
rejestru
statusu
Z
-(lub
wynik
operacji
był
zerem
jeśli
bit
S
N)
-ostatniej
wynik
ostatniej
operacji
był
dodatni
(S)
lub
ujemny
(N,
od
ang.
negative)
bitów
C
-powrót
(więc
przykładowo
przeniesienie,
do
254
aexecu
więc
dodamy
wynik
5)
ostatniej
operacji
jest
większy
niż
dostępnych
?
V
nastąpiło
przepełnienie
rejestru
nieparzysta
P
flaga
pokazująca
czy
liczba
bitów
w
wyniku
ostatniej
operacji
jest
parzysta
czy
(źródło
wikipedia.pl)
Z
wyniku
wykonywania
porównań,
numerowi
miejsca
flagami
ostatniej
w
zaszyfrowanemu
programie
np.
skoków.
numerów
operacji
o
to,
gdzie
że
To
licencyjnych
programu
instrukcja
min
poinformujesz
w
one
je
JNZ
rejestr
zapal
determinują.
programów.
będzie
usera
zero
zero
flag
miała
o1koder
pozytywnej
Jeśli
Flagi
nie
Jeśli
sens
zostanie
numer
te
zero
ustawiane
ilampki
nie
weryfikacji.
wpisany
flag
zostanie
?zapalony?
==
są
1
przez
często
wówczas
opuszczona
?iliczba
usera
to
wnie.
są
przypadku
równy
min
jeśli
do
Podsumowanie
?
czyli
o
czym
było:
1.
podstawowe,
oswojenie
miały
Diasembler
jakąś
zparzystości,
wartość
Asemblerem.
źródlo
i?08
Debugger
praktyczną.
wiedzy
?
Nie
na
wspomniana
trzeba
temat
umieć
języka
IDA
doskonale
asemblera,
oraz
debugger
znacznie
np.
w
Asemblerze,
OllyDbg
ułatwiają
- poziomu
rozumienie
narzędzia
żeby
te
programy
i warunki
2.
Rejestr
flag
koder
musi
wiedzieć
co
się
kiedy
te
się
świecą
lub
3.
gdzie
rejestru
Elementy
ustawić
eax,
charakterystyczne
być
tzw.
może
breakpoint,
w
którymś
żeby
kodu
zwiedza
rejestrów
np.
w
analizie
nie
zgubić
zdoła
?flag.
jakiejś
odczytać
lub
wartości
Reverse
kod
licencyjny
zwróconej
Engineer
programu.
przez
musi
funkcję
wiedzieć
do
4.
umieszczania
program
Shellcode
i chodzi
wykonać
&&
ich
ramka
w
własny
pamięci
stosu
kod
procesu
?
w
znajomość
kontekście
oraz
znajomość
asemblera
innego
użytkownika
ramki
do
pisania
stosu
własnych
np.
pozwala
administratora
np.
funkcji
zkompromitować
iskocz
systemu.
5.
jeśli
Konwencje
zprocesora,
funkcji
wywołania
się
nie
funkcji
uda?
?
właśnie
niezbędna
szkoda,
koderowi
że
ASM?a
przy
pisaniu
patcha,
co
6.
nawet
Hexedytor
cały
ceremoniał
?
wrzucasz
rejestracji.
exec?a
iNo
Save
masz
as..
go
jak
idzieje
po
na
sprawie.
łopatelni,
jeśli
wiesz
gdzie
co
to
ominiesz
Bibliografia:
h
ttp://en.wikipedia.org/wiki/X86_calling_conventions#Caller_clean-up
http://asm.sourceforge.net/intro/hello.html
http://home.elka.pw.edu.pl/~mnazarew/downloads/ochrona-stosu.html
http://edu.i-lo.tarnow.pl/inf/utils/001_2008/0105.php
http://www.vividmachines.com/shellcode/shellcode.html
http://pdos.csail.mit.edu/6.828/2005/readings/i386/Jcc.htm
16 / 16

Podobne dokumenty