Article View: alt.pl.fan.gopher
Article #13551Re: Upload...
From: Adam Wysocki
Date: Wed, 15 Jan 2003 23:08
Date: Wed, 15 Jan 2003 23:08
320 lines
15063 bytes
15063 bytes
15.01.03 Puck wrote:
> Może nie takie hello world... W sumie tego nigdy
> nie udało mi się zrobić, bo nie mogłem się zdecydo-
> wać, jak wyświetlić tekst. :)
Na wspak :P
> W każdym razie jest to mój trzeci programik, ale
> pierwszy tak na prawdę przydatny i skończony.
...piszący hello world ;P
> Najpierw było coś, co miało winampa obsługiwać,
> ale nie dokończyłem, bo miałem stare Delphi,
> a poza tym stanąłem w martwym punkcie. Może
> kiedyś zabiorę się za to od nowa.
Ahh, to api Windows, pozwalające wysłać dowolny komunikat do dowolnego
okienka bez jakiejkolwiek autentykacji, oraz zapisanie dowolnej strony
pamięci, też bez jakiegokolwiek zająknięcia, jak ja kocham ten system
:))) Może coś się zmieniło od czasów Win95/98, ale kiedyś tak było.
A Linux jest taki kochany...
Napiszmy krótki programik w C. Bez zagłębiania się w szczegóły,
wywołujemy go przez podanie w linii poleceń liniowego adresu
w pamięci bajtu, który ma próbować odczytać, po czym zapisać
odczytaną wartość.
int main (int argc, char **argv)
{
char *ptr, bt;
if (argc < 1)
return 0;
ptr = (char *) strtol(argv[1], 0, 0);
printf ("Pobieram bajt...\n");
bt = ptr[0];
printf ("Zapisuję bajt...\n");
ptr[0] = bt;
return 0;
}
Entery w każdej linii, bo informacja o segfaulcie przechodzi do początku
linii bez jej wysunięcia.
Weźmy jakikolwiek proces systemowy, np. sysloga.
$ cd /proc/`/sbin/pidof syslogd`/;pwd
/proc/565
Zobaczmy, jak się ulokował w pamięci.
$ cat maps
08048000-0804e000 r-xp 00000000 03:02 127143 /sbin/syslogd
0804e000-0804f000 rw-p 00006000 03:02 127143 /sbin/syslogd
0804f000-08055000 rwxp 00000000 00:00 0
40000000-40012000 r-xp 00000000 03:02 126666 /lib/ld-2.2.5.so
40012000-40013000 rw-p 00012000 03:02 126666 /lib/ld-2.2.5.so
40013000-40014000 rw-p 00000000 00:00 0
4001d000-4013b000 r-xp 00000000 03:02 126675 /lib/libc-2.2.5.so
4013b000-40140000 rw-p 0011e000 03:02 126675 /lib/libc-2.2.5.so
40140000-40144000 rw-p 00000000 00:00 0
4014e000-40157000 r-xp 00000000 03:02 126699 /lib/libnss_files-2.2.5.so
40157000-40158000 rw-p 00008000 03:02 126699 /lib/libnss_files-2.2.5.so
bfffc000-c0000000 rwxp ffffd000 00:00 0
Jak to słodko wygląda :)) Literki w drugiej kolumnie to prawa dostępu
do podanego po lewej stronie obszaru pamięci, nas interesuje w (zapis).
Teraz spróbujmy coś mu namieszać w pamięci, w której nie możemy mieszać
(nie ma literki w). Zezwalamy na generowanie coredumpów...
$ ulimit -c unlimited
I odpalamy na pierwszym bajcie obszaru, do którego nie możemy pisać.
Niech będzie to pierwszy obszar, czyli 08048000.
$ zrzutek 0x08048000
Pobieram bajt...
Zapisuję bajt...
Segmentation fault (core dumped)
Ha! :) Zobaczmy czemu...
$ gdb zrzutek core* (gwiazdka, bo mam w /etc/sysctl.conf
kernel.core_uses_pid = 1, nieważne)
[chrup]
Błąd wystąpił na:
#0 0x0804849c in main ()
Piszemy disassemble...
Dump of assembler code for function main:
[chrup masa kodu]
0x804849c <main+92>: mov %al,(%edx)
[kolejne chrup]
End of assembler dump.
Przypatrz się zostawionej przeze mnie linijce. Tam był procesor,
kiedy został wygenerowany wyjątek ochrony (wystąpiło naruszenie
ochrony pamięci). Tak się składa, że ta linia powoduje wpisanie
czegoś pod pewien adres w pamięci. Widać coś (hehe ;>) próbowało
wpisać coś do nieuprawnionej strony pamięci, ale odpowiednio ustawiony
przez jądro procesor wychwycił to, wygenerował wyjątek ochrony (page
fault exception), zostało to przechwycone przez jądro (konkretnie
handler o wdzięcznej nazwie do_page_fault(struct pt_regs *regs,
unsigned long error_code), więcej informacji w źródłach jądra,
polecam lekturę arch/i386/mm/fault.c), handler zrobił wiele
miłych rzeczy, typu pobranie evil adresu evil strony z rejestru
CR2, sprawdzenie, czy ten adres jest w obszarze pamięci danego
procesu (swoją drogą na pierwszy rzut oka jest to IDIOTYCZNIE
rozwiązane, ale jak się wczytasz to zobaczysz, że czasami goto
lepiej się kompilują), jeśli tak to prawdopodobnie strona nie
była wyswappowana, zabezpieczona przed zapisem, albo coś podobnego,
zresztą mniejsza z tym. Wspomnę tylko, że wtedy są sprawdzane nawet
szczegóły typu co się stało - czy nie ma takiej strony, czy nastąpił
wyjątek ochrony jakiejś istniejącej strony, czy był to wyjątek zapisu,
odczytu, wykonywania, czy czego, czy był to błąd wywołany przez proces
jądra, użytkownika, itp, oraz robione naprawdę różne inteligentne rzeczy.
Mniejsza z tym. Po wielu zmaganiach jądro wysłało SIGSEGV do procesu (zrób
killall -SEGV `/sbin/pidof nazwa`, wynik będzie ten sam, czyli zrzut
aktualnego stanu procesu - oczywiście jeśli masz uprawnienia do wysyłania
sygnałów procesowi), i dalej tak ładnie to się potoczyło.
Innymi słowy zestaw jądro+CPU nie pozwoli na skrzywdzenie procesu.
Już zrozumiałeś?
To teraz wyobraź sobie, że jądro Windows wszystkie alokowane strony pamięci
domyślnie zaznacza jako w, czyli dowolny proces może tam pisać ile chce.
Zresztą jest tak nie tylko z pamięcią, tak samo jest z przestrzenią I/O
oraz z wywoływaniem przerwań trybu rzeczywistego. Kiedyś, jak byłem
jeszcze linuksianym nielotem, mało wiedziałem o możliwościach trybu
chronionego CPU, ale całkiem dobrze znałem się na pracy w trybie
rzeczywistym (np. DOS), bawiłem się systemem, zaglądałem tam, gdzie
na pewno nikt o zdrowych zmysłach nie powinien, i w pewnym momencie
poczułem się na tyle mocny, że postanowiłem odkryć dziurę :)) Pomyślałem,
że skoro nie da się odczytać pliku procedurami systemowymi, pewnie
nie da się też przez dostęp przez /dev/hda (nie dało, less -f
/dev/hda dawało permission denied), pewnie nie da się także przez
BIOS (int 13h, ale nie sprawdzałem tego pod Linuksem), to pewnie
da się bezpośrednimi odwołaniami do kontrolera dysków. Jakie było
moje zdziwienie jak zobaczyłem, że przy próbie komunikacji z kontrolerem
występuje segfault, nie jesteś sobie w stanie nawet wyobrazić, jak mi
wtedy szczęka opadła :)) Dopiero potem dowiedziałem się, co to są
iopermy, itp. i doceniłem pracę projektantów procesorów i developerów
Linuksa (chociaż wspomniany wyżej kod napisał Linus Torvalds, ojciec
systemu).
> Drugim programikiem był kalkulator (tzn dwa text
> fieldy, które były sumowane). Idea została stwo-
> rzona przez mojego informatyka, a moja inwencja
> polegała na tym, że wszystko robiłem sam (to by-
> ła pierwsza lekcja o Delphi) i dodawałem jakieś
> głupie bajerki (np. ProgresBar - dodawanie dwóch
> liczb trwało ok. 3 sekund).
Szybko :)
> Teraz to. Co, czyli właściwie co? Programik,
> który sprawdza, czy pliki wymagają aktualizac-
> ji, i.e. jeśli timestamp danego pliku nie zga-
> dza się z wcześniej zapisanym (albo z zerem),
> jest wrzucany do osobnego katalogu...
Który timestamp? Utworzenia, dostępu, zmiany? E, no tak, to FAT... :)
Znowu źródła jądra, tym razem plik nagłówkowy.
$ less /usr/src/linux-2.4/include/linux/ext2_fs.h
[chrup]
/*
* Structure of an inode on the disk
*/
struct ext2_inode {
__u16 i_mode; /* File mode */
__u16 i_uid; /* Low 16 bits of Owner Uid */
__u32 i_size; /* Size in bytes */
__u32 i_atime; /* Access time */
__u32 i_ctime; /* Creation time */
__u32 i_mtime; /* Modification time */
__u32 i_dtime; /* Deletion Time */
__u16 i_gid; /* Low 16 bits of Group Id */
__u16 i_links_count; /* Links count */
__u32 i_blocks; /* Blocks count */
__u32 i_flags; /* File flags */
union {
struct {
__u32 l_i_reserved1;
} linux1;
struct {
__u32 h_i_translator;
} hurd1;
struct {
__u32 m_i_reserved1;
} masix1;
} osd1; /* OS dependent 1 */
__u32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
__u32 i_generation; /* File version (for NFS) */
__u32 i_file_acl; /* File ACL */
__u32 i_dir_acl; /* Directory ACL */
__u32 i_faddr; /* Fragment address */
union {
struct {
__u8 l_i_frag; /* Fragment number */
__u8 l_i_fsize; /* Fragment size */
__u16 i_pad1;
__u16 l_i_uid_high; /* these 2 fields */
__u16 l_i_gid_high; /* were reserved2[0] */
__u32 l_i_reserved2;
} linux2;
struct {
__u8 h_i_frag; /* Fragment number */
__u8 h_i_fsize; /* Fragment size */
__u16 h_i_mode_high;
__u16 h_i_uid_high;
__u16 h_i_gid_high;
__u32 h_i_author;
union {
struct {
__u8 l_i_frag; /* Fragment number */
__u8 l_i_fsize; /* Fragment size */
__u16 i_pad1;
__u16 l_i_uid_high; /* these 2 fields */
__u16 l_i_gid_high; /* were reserved2[0] */
__u32 l_i_reserved2;
} linux2;
struct {
__u8 h_i_frag; /* Fragment number */
__u8 h_i_fsize; /* Fragment size */
__u8 l_i_frag; /* Fragment number */
__u8 l_i_fsize; /* Fragment size */
__u16 i_pad1;
__u16 l_i_uid_high; /* these 2 fields */
__u16 l_i_gid_high; /* were reserved2[0] */
__u32 l_i_reserved2;
} linux2;
struct {
__u8 h_i_frag; /* Fragment number */
__u8 h_i_fsize; /* Fragment size */
__u16 h_i_mode_high;
__u16 h_i_uid_high;
__u16 h_i_gid_high;
__u32 h_i_author;
} hurd2;
struct {
__u8 m_i_frag; /* Fragment number */
__u8 m_i_fsize; /* Fragment size */
__u16 m_pad1;
__u32 m_i_reserved2[2];
} masix2;
} osd2; /* OS dependent 2 */
};
Ale fat przy tym blado wygląda... :)
$ less /usr/src/linux-2.4/include/linux/msdos_fs.h
[chrup]
struct msdos_dir_entry {
__s8 name[8],ext[3]; /* name and extension */
__u8 attr; /* attribute bits */
__u8 lcase; /* Case for base and extension */
__u8 ctime_ms; /* Creation time, milliseconds */
__u16 ctime; /* Creation time */
__u16 cdate; /* Creation date */
__u16 adate; /* Last access date */
__u16 starthi; /* High 16 bits of cluster in FAT32 */
__u16 time,date,start;/* time, date and first cluster */
__u32 size; /* file size (in bytes) */
};
:)
> ....po co? Żeby w łatwy sposób sprawdzić, któ-
> re pliki trzeba update'ować na serwerze.
Sort by mtime? ;D
> BTW, nie wiem jeszcze jaka jest zależność pomię-
> dzy zwracanymi wartościami (hs2 a Delphi). Jedna
> wartość jest Unixowym formatem czasu, druga - nie
> pamiętam, w każdym razie są mniej więcej w sto-
> sunku 10:7. :o
Może jedna odczytuje z RTC a druga z zegara systemowego,
praktyka pokazuje, że nawet pod DOSem te zegary lubią
się bahłardzo różnić :P
A poważnie, sprawdź różnicę między tymi wartościami, poczekaj
chwilę i znowu sprawdź, jeśli będzie niezmienna to może jest
inna względność liczenia, wprawdzie pod Linuksem czas zaczął
płynąć od stycznia 1970 (Wielki Wybuch, zwany czasami apcoh,
erm, epoch), a pod DOSem dziesięć lat później... Albo jeden
zwraca czas UTC, drugi CET, trzeci ARC, czwarty SRM, itp.
> Jak dostanę coś, co pakuje exeki,
pklite? :)
> albo dowiem sie, jak zoptymalizować kompilację,
Use the assembly, luke ^_^ Chociaż wszystko zależy od ciebie, znam
idiotów, którzy przestrzeń pod stos (mowa oczywiście o exekach MZ)
wypełniali losowymi wartościami... Gdy spytałem, czemu nie zostawią
zer albo w ostateczności, celami debuggerskimi, nie wpiszą tam Hack
the Stack, odpowiadali `a bo tak jest ciekawiej'. Wtedy już mi wszystko
opadło...
--
Pozdrowienia z Warszawy * Adam `gophi' Wysocki * gophi@studio.tpi.pl
GG# 1234 * RLU# 265791 * ICQ# 173653642 * GSM# +48505439030 * CB# 33
Jesteś Gophim :) Jedynym w swoim rodzaju, niepowtarzalnym (C) Muszek
Masz krok dresiarza, który chciałby komuś wpier*olić. ;) (C) zwiecha
Technical Details
Message-ID:
<gophi.1245333271@gophi.nascom.nasa.gov>Path:
mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!news.atcom.net.pl!wysocki.lodz.pdi.net!gophi.nascom.nasa.gov!gophiReferences:
<20030115.12958@news.blade.net>Show Full Headers
Complete Article Headers
Newsgroups: alt.pl.fan.gopher Subject: Re: Upload... Date: Thu, 16 Jan 2003 00:08:29 +0100 Lines: 321 References: <20030115.12958@news.blade.net> Mime-Version: 1.0 X-Trace: localhost.localdomain 1042672110 5102 127.0.0.1 (15 Jan 2003 23:08:30 GMT) NNTP-Posting-Date: Wed, 15 Jan 2003 23:08:30 +0000 (UTC) In-Reply-To: <20030115.12958@news.blade.net> From: Adam Wysocki <adam@wysocki.lodz.pdi.net> Reply-To: gophiczq <gophi@studio.tpi.pl> Organization: PFT Hacking Group NNTP-Posting-Host: gophi.nascom.nasa.gov X-Complaints-To: news@aramin.one.pl User-Agent: Pine 4.44 / Red Hat Linux 7.3 (Valhalla) / Kernel 2.4.18-3 X-Geek-Code-1: GAT d? s+: a1985 C++ UL+++ P+ L+++ E---- W- N++ K- w--- !O M-- X-Geek-Code-2: V-- PS+ PE+ Y-- PGP- t- !5 X+ R- tv- b+ DI- D+ G e- h* r% y* X-Geek-Code-3: v3.12 X-License: This message is PPL-Licensed, details on http://ppl.7thGuard.net/ X-Hardcore-User: pine X-No-Archive: yes X-Uwaga: O ile nie jest zaznaczone inaczej, poglady wyrazone przeze mnie sa moimi wlasnymi pogladami i moga, ale nie musza, byc zgodne z pogladami moich bylych, obecnych oraz przyszlych pracodawcow. Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!news.atcom.net.pl!wysocki.lodz.pdi.net!gophi.nascom.nasa.gov!gophi Message-ID: <gophi.1245333271@gophi.nascom.nasa.gov> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit