(Long time, no see…)
Recently, there was a bit loud about Immunity's ASLR+DEP bypass. Just out of curiosity I've made
step-by-step (well, gadget-by-gadget) dissection. It's pretty neat.

Michał 'GiM' Spadliński


by Daniel Abraham for free @issuu or @POD Castle.
No i koniec.
Zdaje się, że od XP 'Save As' i 'Open' pamiętają folder, gdzie ostatnio się pracowało. Jest to dość irytujące w z zachowaniem, do którego większość się chyba przyzwyczaiła, gdzie dialogi te startują w aktualnym katalogu.
Żeby to zmienić w Viście, wystarczy odebrać sobie prawa do odczytu klucza: HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\comDlg32\LastVisitedPidlMRU. To pewnie nie jest najlepszy sposób, ale dla aplikacji z których korzystam DZIAŁA :P
Zastanawiam się, dlaczego nie wygooglałem tego wcześniej: Speed up powershell startup
Nie wiem czy da się to zrobić, jakoś prościej, w każdym razie znalazłem takie fajne coś: google calendar week numbers
Każdy problem ma rozwiązanie,
jeśli nie ma rozwiązania, to nie ma problemu, nie ma problemu
Ej, człowieku to jest przecież jakiś horror,
to nie tędy dróżka, jeśli chcesz żeby jakaś fróźka
poszła z tobą do ee kina
Do zapamiętania:
PS> $env:path
PS> $env:path = $env:path + ";c:\blah"
(Long time, no see…)
Recently, there was a bit loud about Immunity's ASLR+DEP bypass. Just out of curiosity I've made
step-by-step (well, gadget-by-gadget) dissection. It's pretty neat.
Jakiś czas temu potrzebowałem napisać małą aplikację, która pozwoliłaby mi na wysyłanie maili poprzez MS Exchange 2007. Udostępnie on po SOAPie api które się zwie EWS (Exchange Web Services)
Głównym celem było zrobienie tego możliwie szybko.
Najpierw próbowałem biblioteki do obsługi SOAPa
w pythonie python-suds.
Po kilku problemach na wstępie (których już dokładnie nie pamiętam)
i chwili googlania, znalazłem coś co się zwie suds-ews, czyli teoretycznie suds ze wsparciem dla EWS.
Z tego co pamiętam dorzucając python-ntlm i korzystając potem z suds.transport.windows udało się nawet połączyć z serwerem exchange'a, ale wyglądało na to, że ten suds-ews, niezbyt obsługuje typy tablicowe, które EWS sobie definiuje, a przynajmniej ja nie miałem pojęcia jak z nich skorzystać.
Skończyło się na tym, że odpaliłem Visuala i napisałem krótki program, który robi to co trzeba.
Najpierw trzeba wygenerować Proxy, można to zrobić przy użyciu narzędzia wsdl, ja to robiłem
z poziomu Visuala, opis jest tutaj.
Istotna informacja, która dla SOAPowców pewnie jest dość oczywista, dla mnie nie była :> :
przy tworzeniu Proxy w Visualu należy podawać ścieżkę do /EWS/Services.wsdl, a w kodzie ściężkę do /ews/Exchange.asmx
Nie ukrywam, że nie znam C#, ale mając przykłady napisanie aplikacji nie było zbyt problematyczne.
Celowo wykomentowałem własny callback do sprawdzania certyfikatu, głównie po to, by móc odpalić to pod mono
(o tym za chwilę) bez konieczności weryfikacji CRL.
Aplikacja jako argument bierze nazwę pliku który będzie wysłany, pierwsza
linijka jest traktowana jako temat wiadomości, dodatkwo potrzebuje pliku config.txt o skomplikowanej postaci:
Kod jest tu: Ews.cs.
Należy sobie zmodyfikować usera, hasło, domenę i hostname w CreateBinding()
(Wszystkie metody są statyczne, bo jak już wspomniałem, jestem leniwy ;p).
Próbowałem wygenerować Proxy, używając narzędzia wsdl, które przychodzi z mono,
ale aktualnie nie działa, bug odnośnie tego wisi półtora roku.
Jeżeli jednak mamy Proxy wygenerowane w Visualu, to można powyższą aplikację skompilować i odpalić w mono
Certyfikat który przychodzi z serwera, nie musi zawierać certyfikatu root'a, więc najlepiej jest dodać ręcznie certyfikat dla CA, którym podpisany jest certyfikat serwera Exchange. W moim przypadku Thawte Premium Server CA
Rozszerzenie certyfikatu ma znaczenie, certmgr, nie łyknie rozszerzenia .pem
...that you might need to know or maybe just forgot
This will be a bit long, longer then I initially expected.
First let's have a look at typical table-based CRC-32 implementation:
This is similar to the implementation that can be found in PNG Specification
But for a few experiments the following implementation will be more suitable. The only difference, is
that instead of using constant values of 0xffffffff, we'll pass them as function arguments.
As you probably know CRC is the remainder polynomial resulting from 'dividing' shifted message's polynomial by some chosen generetor polynomial.
(I'll be talking about 32-bit CRC and I was using the same polynomial that png uses 0xedb88320, but the polynomial itself doesn't change anything that's discussed below.)
Normally to get the remainder crc would be called like: crc32(buffer, buLen, 0, 0). But this causes two problems.
First problem is that if you prepend the message with any number of zeroes it won't change the resulting reminder,
because this will prepend message polynomial with some 0 coefficients, and that obviously won't change the reminder itself.
Below is an example. It creates such messages, calculates crcs and prints them.
And the results:
This is solved by preseting the CRC, but before we'll get to that, let's discuss the second problem.
This brings us to the second problem, if we append any zeroes to message constructed as above, the reminder will still be 0.
And because mesg above has size of 12, and it's initially filled with zeroes, the following two lines, will also print 0x00000000 as a resulting CRC
That's also quite easy to understand. If the resulting reminder is 0 it means that the message polynomial was multiple of our generator, so appending any number of zero coefficients will give a new message that is still mutiple of a generator
The second problem is usually 'fixed' by negating CRC result. In this case that will be calling: crc32(buffer, buLen, 0, 0xffffffff)
So let's fix last example by appending negated CRC:
Of course now the calculation of CRC for that new message won't return 0, so we should calculate the CRC for the first 6 bytes and compare it with appended CRC or... we could calculate so called reciprocal polynomial and as before calculate the CRC for whole the message and compare it with our reciprocal
And here are the results, as you can see the calculated CRCs are no longer the same.
Now back to the first problem which is usually 'fixed' by preseting CRC to -1 (0xffffffff) instead of 0.
This is equivalent to the calling: crc32(buffer, bufLen, 0xffffffff, 0). The following code is almost identical to the
first one presented, the only difference is using the preset value in call to crc32.
And coresponding results:
Preset and post-invert are usually used together. First important observation is that 0xffffffff becomes fixed point of a crc32
0xffffffff is printed to the screen. As you've probably noted this is also reciprocal.
Now take a look at crc32 function, now back here, now back at crc32 function, now back here. Just before returning the value it's xored with 0xffffffff value (or you can say inverted).
That tells us, that after finishing the loop, the value of rCrc variable had to be 0.
That isn't too good, because it basically means, that we can again append any numbers of zeroes, after that value and the result won't change
...or because we know that reciprocal has the same value, we can append calculated CRC after the message. We need to negate the calculated CRC first. Here's the thing:
...and the results:
A friend of mine, had a problem today (with Python) which voils down to the following piece of code:
Don't ask why there is readlines() in the first place, that's not the problem.
The problem was, that c had wrong number of lines.
However answer to that lies in python's documentation:
Read until EOF using readline() and return a list containing the lines thus read. If the optional sizehint argument…
Unfortunatelly the file contained some random bytes, among different bytes there was also character with hex value of 0x1A. Now let me quote everyone's favourite source of information - wikipedia:
In the MS-DOS operating system, this character is used to indicate the end of a file or the end of user input in an interactive command line window. This behavior was borrowed from the earlier CP/M operating system.
Some operating systems such as the pre-VMS DEC operating systems, along with CP/M, tracked file length only in units of disk blocks and used Control-Z (SUB) to mark the end of the actual text in the file. For this reason, EOF, or end-of-file, was used colloquially and conventionally as a TLA for Control-Z instead of SUBstitute.
There is simple "solution" to this problem:
Since CP/M was mentioned twice here, I can't resist to quote famous words of a man I've always regarded as a brilliant visionary - Gary Kildall (but unfortunately rather poor businessman for that matter) (the quote relates to int 21h/AH=09h):
"Ask Bill [Gates] why the string in function 9 is terminated by a dollar sign. Ask him, because he can't answer, only I know that."
Niedawno, przez kilka dni z rzędu właściwie grałem w Lugaru. Kupiłem ją w Humble Indie Bumble.
Pomimo tragicznej grafiki gra jest przyjemna, dość wciągająca i nawet ma zabawną fabułę :).
Oprócz trybu kampanii (tylko jednej) jest jeszcze tryb challanges.
Postaram się nie spoilować (za bardzo).
Na początku zdziwiło mnie, że gra się królikiem (właściwie to chyba raczej zającem, ale niech będzie królik). Do królika człowiek się jednak dość szybko przyzwyczaja, a po kilku nieudanych potyczkach bluzga się pod nosem na pozostałe króliki a później inne stworzenia.
Jest tutorial i jest on wysoce wskazany. Nie ma sejwowania (prawda, że piękne słowo), stan gry jest automatycznie zapisywany po przejściu kolejnego levelu.
W tutorialu brakło kilku rzeczy, z którymi pewnie grałoby się prościej:
Byłbym zapomniał, są 3 poziomy trudności: Easier, Difficult i Insane, zdecydowanie warto spróbować Difficult, Insane, jak ktoś ma silną wolę ;)
(Co do rzucania nożem jeszcze, to zdaża się że przeciwnik złapie ów nóż ;), wygląda na to, że jest to zależne od poziomu trudności i od tego czy przeciwnik stoi do nas przodem)
Have fun!
No i koniec.
Moja zabawka: PixelToastereD i coś co ma robić za doki: Release Notes 0x1
As I've mentioned a while ago, I try to use powershell (1.0) on daily basis.
Recently I had strange problem regarding Execution Policy.
I've started powershell as admin, executed Set-ExecutionPolicy RemoteSigned. Then I've started powershell under console2 as a normal user.
To my suprise running Get-ExecutionPolicy returned Restricted
First explanation, solution below: I'm running 32bit version of Console2 on x64 version of vista. Since console2 starts powershell, it's also treated* as a 32bit application, so requests to HKLM\Software\ because of WOW64 goes to HKLM\Software\Wow6432Node.
These are totally independent registry keys, so when I've started powershell as Admin, changing execution-policy, changed only the first key (since powershell.exe is a 64bit application).
*Edit: Of course under console2, 32bit version of powershell is also started due to WOW64.
Solution is pretty simple, start Console2 as Admin, and then change execution policy.
Hope that helps anybody ;)
Chciałem się koniecznie podzielić tym znaleziskiem. Dzisiaj trafiłem na plugin Vrapperdo eclipsa. Umożliwia on (podstawową) edycję vim-like w eclipsie.
Wcześniej testowałem też vimplugin i eclima chyba również. Jest też płatny viPlugin, tego nie widziałem.
Vrapper ma inne podejście niż dwa wyżej wymienione pluginy. Zamiast osadzać vim'a
w eclipsie, imituje on edycję w stylu vim-a w eclipse'owych edytorach.
Lista komend trybu normal jest aktualnie niewielka, ale są najczęściej (przynajmniej przeze mnie) używane :). Nie rozminę się z prawdą, jeśli powiem, że komend vim-owego command-line'a praktycznie nie ma.
Dość specyficzne jest też 'aktywowanie' plugina, trzeba włączyć przełącznik na toolbarze (albo w menu edit) i dopiero NOWO otwarte okna edytora będą miały włączony vim-mode.
Chciałem się podzielić, bo na pierwszy rzut oka Vrapper przypadł mi bardziej do gustu niż vimplugin, a na joggerze, chyba nie było o nim wzmianki.
Ten kod paskowy, który widać dziś na google, to Code128.
Na zakodowanie pojedyńczego symbolu składają się
szerokości sześciu pasków (3 czarne, 3 białe).
Na kodzie (czego nie można się w żadne sposób domyślić) jest zakodowane Google :]
Notacja poniżej oznacza grubośći kolejnych pasków.
pierwsze 3+3 paski to kod startowy, kolejno są litery:
Ostatni symbol to suma kontrolna którą można policzyć jakoś tak:
[104 to wartość kodu startowego B]
U mnie wychodzi 71, w tabelce z wikipedii 71 to 122114 i tak też jest na obrazku.
Ostatnie 4 paski to kod końcowy.
Truly saying I'm not much interested in C++0x (or rather C++1x :P).
Today I've stumbled upon few examples of delegates:
In the second code & refers to 'full closure' (so sum and prod are variables from that closure, accessed by reference), and foo is copied from the closure by value (i.e. any changes to foo inside the delegate won't be seen outside the delegate).
Truly saying, I don't mind it, but ...
C++ already has awful syntax (you can argue, but that's a fact :P)
Am I wrong or is the proposal (?) of delegates' syntax are is just über-crappish?
If you look at above samples and your answer is nope, here's one more for you:
P.S. Your comments will be appreciated
Zdaje się, że od XP 'Save As' i 'Open' pamiętają folder, gdzie ostatnio się pracowało. Jest to dość irytujące w z zachowaniem, do którego większość się chyba przyzwyczaiła, gdzie dialogi te startują w aktualnym katalogu.
Żeby to zmienić w Viście, wystarczy odebrać sobie prawa do odczytu klucza: HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\comDlg32\LastVisitedPidlMRU. To pewnie nie jest najlepszy sposób, ale dla aplikacji z których korzystam DZIAŁA :P
Zastanawiam się, dlaczego nie wygooglałem tego wcześniej: Speed up powershell startup
Wpis u zdzicha zachęcił mnie, żeby się podzilić, może komuś się przyda.
Od grudnia ubiegłego roku, korzystam z iplusa na modemie e169 (z różnych przyczyn musiałem wybrać modem na usb).
E169 to je flip flop device, który równocześńie robi za memory sticka (z kartą 2G micro sd w środku) i modem.
Korzystam z dwóch genialnych i prostych narzędzi:
GUI umtsmona jest na tyle intuicyjne, że chyba nie trzeba niczego tłumaczyć. Ja sobie wywołanie usb_modeswitcha dodałem do udeva.
At work I try to use powershell just to learn at least a few things about it. Of course I could use zsh, bash or any other unix shell, but that would be no fun, would it?
Nie wiem czy da się to zrobić, jakoś prościej, w każdym razie znalazłem takie fajne coś: google calendar week numbers
This is first of promissed posts about DDL under Linux.
If you haven't read previous
post, please do so now, so I won't have to repeat myself.
If you have copy of team0xf ext repo, run hg pull; hg up;
if you don't have it yet, grab it:
I've added some new examples in ext/ddl/ddl/Sample subdir.
I've already described how to compile host application in previous post.
Compilation of testPlug01.d and testPlug02_c.c plugins is easy as a pie :]:
testHost01.d
is a sample host application. It loads plugin calls a function from the plugin, creates
an object of class conforming to specified interface, and call some method of that object.
testHost02.d
host application declares a variable that will be accessible by a plugin written in C.
It loads plugin finds a symbol of a function (declared in that plugin) and executes
that function.
Function in plugin changes the variable that is provided by host application
Sorry for short post, but I don't have much time :}.
Currently there is only basic support for object files, some more things are waiting for
being comitted, so again, stay tuned :)
Od czasu do czasu, zdarza mi się ściągać pliki z wrzuty (bo to najprostszy sposób na znalezienie niektórych rzeczy, szczególnie jak się szuka jednego kawałka).
Od jakiegoś czasu metoda aud/file, vid/file, średnio działa, na kilku forach widziałem nawet teorie spiskowe, jakoby miałoby to być nowe zabezpieczenie.
Nie proszę państwa (chcę być tak 1337 jak g. dlatego się do was tak grzecznie zwracam :>), to nie jest żadne zabezpieczenie. Wygląda na to, jakby panowie
od wrzuty wprowadzali sobie swoisty (albo mają zamiar) load-balancing (zobaczcie sobie po wygenerowanych linkach), może miejsca zaczyna brakować i jakaś reorganizacja dunno :P
Mniejsza z tym, napisałem mały skrypcik, który daje nowe linki (stare też), skrypcik leży sobie tutaj:
wrzuta.
Sorry za ascetyczny wygląd :P
Gdyby coś nie działało, można drzeć^Wzgłaszać uwagi
P.S. Jakoś dużo nawiasów powychodziło :P
I hear voices, wait a minute, that's not what I've meant.
I've heard there are more and more people interested in DDL (D Dynamic Libraries)
under Linux. This is first of short series of posts that will
describe some changes I've made in h3r3tic's team0xF's repo.
Nice title, huh?
Descent plugin is being cooler and cooler, but you've probably seen it on
videos.
One of the things that was driving me mad and kept me away from descent was compilation process.
Java guys probably know apache ant build system (and if they don't they definitely should). I'm going to describe here, how to force eclipse to use descent plugin's ant tasks to build D projects. I'm using this at least for a few months now and I prefer it much more over rebuild method described on Descent page, I was wondering why this method is not described there.
First there are some basic informations, how to install descent with eclipse 3.4, how to set-up a project, the rest is about ant usage.
I'm using Eclipse ganymede since it's better than its predecessors. First quick installation for all the lazy bastards out there:
One night I was playing with descent jar files and I've noticed interesting jar inside descent.core.
Open up your favourite terminal and extract needed jar.
ECLIPSE_DIR above is of course your eclipse installation dir (~/eclipse in my case :])
Now go back to eclipse, Window->Preferences, Ant->Runtime (Classpath), click Add External JARs and
add your ~/.ant/lib/descent-ant.jar archive.
Next go to Tasks menu we'll add two tasks:
I've entered name "descent.D", choose descent-ant.jar from drop-down list, and click on:
"/descent/ant/tasks" and choose "D.class"
Now do the same using "descent.DBldNum" and choose "DModuleBuildNumber.class" file.
We're going to create ant build file, but before that let's create build.properites file
that will held some basic data in easily editable format.
Press Ctrl+N, choose General->File, and enter build.properties as it's name.
Here is content of my properties file:
compiler.dir is a path to compiler (without dmd/bin/dmd, descent appends it)
Press Ctrl+N and in filter box type xml, and chose XML, click next, and enter build.xml as a filename,
Using bottom tabs choose Source instead of Design
I've created following build.xml (I'm not pasting it here, since
this would be quite senseless, but you can take a look at it at codepad.org.
Build file is specific for linux, if I remember correctly my build.xml under windows was simpler than that one.
As you see most of the file is definition of compile macro which takes one parameter (bldtrg). (EDIT: you can find list of all possible parameters for descent.D task here)
Let's forget about that macro for a moment and take a look down at possible targets:
This looks quite clean don't you think?
Now you could right-mouse-click on the build.xml file, choose Run-as ->Ant build file but this is uber-lame.
Instead go to Window->Show View->Other and select Ant. I like to keep this window in lower-wight corner.
Double click on any listed target will execute it (along with dependencies).
I have binded Ctrl+Shift+Q A to Show View (View: Ant), this way I can fast switch to ant window :).
What's cool about it is that you can have multiple build targets (one can build few executables) and have all of them visible
and easily accessible.
I'm not going to encourage anybody to use ant, but it's really cool tool, take a while to peek into ant's documentation, especially ant tasks.
Ever since I started using Opera I've always had ctrl+d binded with "Paste and Go".
However after upgrade from 9.5 beta to 9.51 behaviour has changed and it seems opera stopped using Xorg clipboard.
I've shed many tears ;) but didn't break down and finally found something that
works the way I like it:
In keyboard setup in Application item add combo you like (I'm using "d ctrl" as I've said) and give the following string "Paste mouse selection & Go".
Remember to use '&' and not 'and'. & is used to separate actions
Znajomi z IRCNetu zarazili mnie tresurehuntem.
| Question name | Correct entry time |
|---|---|
| robot | 2008-05-20 17:40:44.151252 |
| zip | 2008-05-20 17:10:56.126710 |
| network | 2008-05-27 22:47:40.954321 |
| primes | 2008-06-03 00:19:45.691278 |
Widać, że pierwsze zadanie rozwiązałem tego samego dnia co drugie. Drugie zadanie rozwiązałem w shellu: find + sed + awk, pierwsze zadanie z użyciem bc -lq i definicją funkcji factorial, network z ręki, bo wpisów nie było jakoś specjalnie dużo, do primes napisałem programik w D który znalazł się na tango wiki
Do zapamiętania:
PS> $env:path
PS> $env:path = $env:path + ";c:\blah"
Dlaczego taki tytuł? Bo singleton, jest powszechnie
krytykowanym wzorcem projektowym. Dzieje się tak głównie z powodu początkująch, którzy za wszelką
cenę starają się by ich programy były 'obiektowe', a przecież wiadomo, że w programowaniu obiektowym
zmienne globalne są ZŁE. Niewiele mysląc młodzi adepci sztuki, opakowują
zmienne globalne w singleton i są z siebie zadowoleni ;).
"Singleton nie jest odpowiedzią na zmienne globalne, odpowiedzią jest 'Na jaką cholerę Ci zmienne globalne?'"
Na początek pokażę więc, co można zrobić ze zmiennymi globalnymi w D, a dalej dla tych którzy wiedzą
do czego MOŻNA i NALEŻY używać singletona, różne sposoby implementacji w D.
Tak, pozycjonerzy z firmy http://www.technetium.pl zaatakowali mnie wczoraj.
Przy wpisach dopisują komentarze z linkami do stron (chyba nie z automatu, bo
komentarze sprawiają na powiązane pi/drzwi z treścią wpisów).
Firma ma siedziebę w Rzeszowie i stamtąd też pochodziły IPki osób komentujących: jeden z proxy zdaje się w3cache.res.pl,
jeden z czegoś co wygląda na AP do sieci bezprzewodowej:
hansiewicza.res.pl (czy muszę dodawać, że siedziba spamerów mieści się na ulicy Hanasiewicza?) i ostatni: 91.196.9.214.
Dajcie znać jeśli u was również pojawiły się jakieś kryptoreklamy
P.S. Wpis trafia na techblog, bo myślę, że wzbudzi niejakie zainteresowanie
Dawno nic się tu nie działo, głównie dlatego, że nie bardzo mam czas
cokolwiek pisać.
Deely
pisał jakiś czas temu o wyrażeniach lambda w C#. Dzisiaj trochę o różnych bajerach jakie można robić w D.
Na początek zrobimy sobie małe opakowanie na foreach. Jak zwykle najpierw kawałek kodu, potem jak zwykle pseudo wyjaśnienia.
Dziś będzie krótko, jak zacząć programowanie w OpenGLu w D.
Najpierw małe streszczenie z tego co było na warsztatach.
Na trzecich warsztatach D było więcej o klasach, dziedziczeniu, de/kon-struktorach, statycznych de/kon-struktorach, przeciążaniu metod, properties (nie, podobnie jak python nie lubimy setterów i getterów :P, atrybuty/własności w D są banalne do implementacji o czym wspomniałem w pierwszym wpisie). Dalej, o klasach zagnieżdżonych, interfejsach, invariantach (niezmiennikach) obiektów klas, atrybucie scope dla klas, przeciążaniu operatorów, rzutowaniu. uff sporo prawda? :)
Na czwartych warsztatach było natomiast o róznych rodzajach tablic w D o wycinkach tablic i o operatorze konkatenacji, następnie początek zabawy, czyli pierwszy program w OpenGLu.
Zanim jednak stworzymy nasz super ekstra pierwszy projekt, musimy przygotować sobie środowisko pracy :). Zakładam, że tak jak w drugim wpisie o D, masz już zainstalowany kompilator DMD z tango, do tego zainstalowany rebuild.
Potrzebny nam będzie Derelict, czyli zestaw bindingów dla D do różnych (głównie 'multimedialnych' (nie cierpię tego słowa ;)) bibliotek C. Do jego instalacji użyjemy dsssa (można odpalić go z konta użytkownika, wówczas derelict zostanie zainstalowany
w podkatalogu w $HOME, jednak instalując jako administrator, zainstalujemy go 'globalnie'):
Dsss oidp zapyta najpierw o wybór mirrora, następnie ściągnie za nas, skompiluje i stworzy potrzebne biblioteki, oraz zainstaluje wybrane projekty.
Jeżeli wszystko się powiodło i mamy już dsss'a możemy przystąpić do napisania
pierwszego programu. Oto example.d:
Plik wrzucamy do jakiegoś katalogu, w tym samym katalogu tworzymy prosty plik dla dsssa, mianowice
-ll jest to flaga dla dsss'a, która sprawi, że przekaże on podaną bibliotekę do linkera, w tym przypadku libdl, potrzebną do dynamicznego ładowania bibliotek.
Teraz wystarczy jedynie:
I jeżeli mamy potrzebne biblioteki, to dsss powinien skompilować naszą aplikację.
Kod jest wzięty z pierwszego tutoriala ze strony
dmedia i przerobiony, żeby działał z tango zamiast z phobosem (czyt: zamiana writefln na Stdout ;)).
Polecam zapoznanie się z pozostałymi Tutorialami ze strony dmedia.
Dostosowanie ich do tango nie powinno nastarczyć większych trudności.
Wywołanie toStringz można usunąć i dodać na końcu ciągu "\0", lub napisać
własną krótką funkcje np taką:
Nie testowane, ale chyba ok ;).
Przykłady znajdują również na slajdach z czwartych warsztatów team0xf.
P.S. Blog najprawdopodobniej w najbliższym czasie zostanie mocno zaniedbany, a wpisy jeśli się będą pojawiać to sporadycznie, z tej prostej przyczyny, że nie mam czasu :]
Ten wpis miał być, dokończeniem na temat kontraktów (design by contract), ale ponieważ akurat o tym było na
drugich warsztatach, więc odsyłam tam :).
Zacznijmy od czegoś prostego, jak w D zadeklarować i zainicjalizować tablicę? Stwórzymy sobie tablicę stringów:
Przypominam, że literały znaków są w trzymane w pamięci read-only, więc o ile możemy modyfikować sam element pom[0] (czy inne), tak próba zmodyfikowania pom[0][0] skończy się niepowodzeniem (no chyba, że pom[0] został wcześniej podmieniony, na coś innego ;)). Na ten temat wspominałem wcześniej, więc traktuję, że to jasne.
Teraz coś ciekawszego. D, o czym pisałem w pierwszym artykule z tej serii, umożliwia wykonywanie funkcji w czasie kompilacji. Stwórzmy sobie więc tablicę stringów w czasie kompilacji.
Operator ~ to jak już wspominałem, operator konkatenacji. W podnym przykładzie,
użycie ~= powoduje doklejenie kolejnego elementu do tablicy (intuicyjne prawda? :)).
Skąd pewność, że kompilator rzeczywiście stworzy ten kod w trakcie kompilacji? Po pierwsze, celowo
dołożyłem na początku typ składowania const, zmienne które są nim opatrzone muszą być znane
w czasie kompilacji, gdyby więc tak nie było kompilator wyrzuciłby błąd. Po drugie, można się o tym łatwo przekonać.
Wystarczy linijkę pod deklaracją zmiennej arrtest dorzucić, coś w stylu: const char[] temp=arrtest[10].
Ponieważ wynikowa tablica, ma 10 elementów, a D posiada bounds checking zarówno na poziomie kompilacji
(o ile to możliwe) jak i wykonania (chyba, że podamy do kompilatora opcję -release), spowoduje to zatrzymanie kompilacji
(numeracja tablic oczywiście od 0), a w komunikacie z błędem zostanie nam pokazana aktualna zawartość tablicy arrtest :).
W tym przypadku wszystkie elementy są takie same, więc nie jest to jakiś powalający efekt. Dużo ciekawszy jest jednak następny przykład, który w czasie kompilacji wygeneruje nam tablicę int'ów, następnie również w czasie kompilacji, posortuje ją i wrzuci do kolejnej zmiennej :).
D ma wbudowane metody do sortowania tablic, wystarczy dorzucić .sort po nazwie zmiennej która jest tablicą i zostanie ona posortowana w miejscu (oczywiście, tablica może być tablicą dowolnych obiektów, wystarczy przeciążyć jedną metodę :)). Metody tej (.sort) jednak nie możemy użyć w czasie kompilacji, (o ograniczeniach dotyczących funkcji wykonywanych w czasie kompilacji można poczytać w dokumentacji) dlatego napisałem krótką i prostą funkcję.
Acha, polecam na pewno ciekawe doświadczenie i umieszczenie jakiegoś const uint x=one[1111]; za deklaracją one,
oraz odpowiednio z two za deklaracją two.
Dzisiejszy wpis, miał głównie na celu pokazania tablic asocjacyjnych. W D pojawia się jeden mały problem, otóż nie można zainicjalizować zmiennej która jest AA i która jest zadeklarowana na poziomie modułu. Tak więc poniższy kod nie skompiluje się.
Bez problemu jednak, można zainicjalizować zmienną typu AA, tak zwanym AA-literałem (to wyrażenie po prawej stronie znaku równości ;)), o ile znajduje się ona wewnątrz funkcji czy metody, tak więc kod poniżej skompiluje się bez problemu.
Na uwagę zasługuje tutaj jedynie cast(char[]), jest to niezbędne, gdyż kompilator domyślnie przypisuje AA-literałowi typ postaci typ_zew[typ_wew], gdzie zarówno typ_zew jak i typ_wew są typami odpowiednio wartości i klucza, przy czym są one ustalane na podstawie pierwszego elementu AA-literału. Ponieważ typem (literału) "zzz" jest char[3u], kompilator próbowałby zrzutować wszystkie pozostałe klucze do tego typu.
Z tej też przyczyny rzutujemy pierwszy klucz na cast(char[]). To jest bardzo proste, ja tylko utrudniam zrozumienie tego ;). Typ AA-literału jest ustalany na podstawie pierwszego elementu.
Zastanawiałem się, dlaczego tak jest, że nie można zainicjalizować tablicy asocjacyjnej na poziomie modułu. Moim zdaniem (nie wiem czy poprawnym),
wynika to z tego jak AA są reprezentowane w pamięci, w trakcie działania (w przypadku D w postaci drzewa binarnego).
Tak więc, kompilator nie jest stworzyć odpowiedniej struktury dla takiej zmiennej w czasie kompilacji (tak zgaduję), natomiast umieszczenie
takiej zmiennej w jakimkolwiek bloku, powoduje najprawdopodobnie dołożenie kodu, który odpowiednią strukturę stworzy. (Sprawdziłem to i wygląda na to,
że moje rozumowanie jest poprawne)
Jeśli jednak potrzebujemy zmiennych typu AA na poziomie modułu, z pomocą przychodzą nam statyczne konstruktory modułów, tak więc
następujący kod jest poprawny:
Zwracam jeszcze uwagę, (celowo) poprzedziłem zmienną two słówkiem const. Otóż w D, jeżeli zmiennej (na poziomie modułu) o typie przechowywania const nie nadamy wartości w definicji, możemy modyfikować jej wartość, ale tylko w konstruktorze modułu.
Na ostatnich warsztatach (wkrótce powinny się pojawić materiały z warsztatów) było krótko
na temat zagnieżdżonych funkcji i przeciążania funkcji, więcej na temat typów składowania parametrów funkcji,
czyli to o czym ostatnio pisałem, kontraktów, funkcji ze zmienną ilością argumentów,lazy evaluation, czyli leniwym wartościowaniu argumentów krótko o linkowaniu z C.
Także te tematy raczej nie będą tutaj poruszane.
To tyle na dzisiaj :) Have phun programming in D :)
W zeszłym roku, przez semestr, uczęszczałem na takowy przedmiot. Naszym zadaniem było zaimplementowanie serwera takiej bazy.
W implementacji nie korzystaliśmy z przypominającego SQLa OQLa, lecz z pomysłu który próbuje wypromować pan Kazimierz Subieta mianowicie SBQLa (Stack Based Query Language).
W obiektowej bazie danych przechowywane są całe obiekty (super stwierdzenie, nie? ;)).
Pan Subieta a zanim i my rozważa trzy typy obiektów:
Każdy obiekt ma nazwę, oraz unikatowy identyfikator. Obiekt atomowy dodatkowo ma wartość, którą przechowuje, a obiekt pointerowy identyfikator obiektu na który wskazuje.
Przykład (miałem zrobić ładny obrazek, ale jestem leń :P): mamy obiekt złożony typu osoba, który posiada podobiekty atomowe typu imie, nazwisko podobiekt złożony typu adres.
Jeśli się nie mylę, bardziej skomplikowane implementacje posiadają funkcje które można wykonywać na elementach (tak jak w tradycyjnych bazach danych) a także
pozwalają na przechowywanie metod w obiektach i wywoływanie tychże metod.
SBQL pozwala na wyciąganie obiektów z bazy danych. SBQL pozwala tworzyć intuicyjne zapytania (no kompletnie nieintuicyjne również ;)), moja implementacja różni się od tego co promuje pan Subieta, także przedstawione przeze mnie zapytania niekoniecznie mogą być możliwe w implemntacji opisywanej przez niego.
Więcej i ciekawszych przykładów, znajdziecie w...
Nie wiem dlaczego, ale nikt nie zdecydował się udostępnić efektów swojej pracy.
Postanowiłem postawić serwer i napisałem małego pehapa, który pozwala
wykonać na żywo kilka zapytań. Na chwilę obecną nie ma możliwości wykonywania
dowolnych zapytań (gdyż obawiam się evil hax0rów z mr0cku ;)), raczej wątpię, czy wprowadzę w ogóle taką możliwość :>.
Chętnych do pooglądania przygotowanych przeze mnie zapytań odsyłam
tutaj. Jest tam seria kilku
zapytań pod rząd, które zwracają to samo, ale robią to na różne sposoby TIMTOWTDI ;).
Dzisiaj o typach składowania parametrów funkcji, nazywanych również atrybutami. Sporo zastanawiałem się,
czy opisy umieścić tutaj, jednak stwierdziłem, że chyba łatwiej i czytelniej będzie w postaci
komentarzy w kodzie. Mam nadzieję, że taka forma będzie wam odpowiadać.
Omówimy sobie krótko na przykładach trzy typy składowania in, out,
oraz ref (lub jak ktoś woli inout (h3r3tic mnie dziś uświadomił, że inout nie jest aktualnie zalecany i że prawdopodobnie zostanie usunięty, lub zmieni się jego semantyka, także lepiej nie używać). Zastanawiałem się też od którego z nich
zacząć, zdecydowałem się na in. Jeżeli ktoś nie miał do czynienia z programowaniem wcześniej to jego zachowanie,
może wydawać się dość dziwne, w rzeczywistości jest jednak jasne i proste :).
Podając do rebuilda opcję -exec spowodujem odpalenie programu zaraz po kompilacj, tak więc:
Krótkie wyjaśnienie do powyższego kodu. W funkcji main, zaraz za ciągiem znaków widać słówko .dup. Powoduje ono utworzenie kopii
stringa. Jest tak dlatego, że w linuxie literały stringów, są w pamięci read-only (jedno zdanie można znaleźć tutaj),
więc próba modyfikacji elementów takiego stringa, zaowocuje kochanym SIGSEGV. Stąd potrzebujemy wcześniej skopiować ten string :).
Czas na ref, czyli przekazywanie przez referencję.
Chyba nie trzeba nic tłumaczyć :)
Przejdźmy do out. Out jak się można domyślić oznacza, że parametr jest tylko parametrem wyjściowym, to znaczy że dana funkcja czy metoda
ma w nosie wartość jaką tam podamy. Jest przy tym jedna ważna cecha, ale to w komentarzach.
Najpierw kawałek kodu, a poniżej opis, jakie zostawiam zadanie ;)
Małe wyjaśnienie. W main widać deklarację zmiennej a typu void function(),
czyli wskaźnik na funkcję typu void, nie przyjmującą żadnych parametrów. Stąd przed test_a pojawia się &,
czyli pobranie adresu funkcji test_a.
Podobnie funkcja test_change przyjmuje parametr typu wskaźnik na funkcję (typu void, która nie przyjmuje parametrów).
Zadanie jest bardzo skomplikowane, mianowicie potestować, jak ten program będzie się zachowywał, gdy podmienimy atrybut pierwszego parametru funkcji
test_change na inoutref oraz out.
Po zrobieniu zadania można zerknąć na ostatni przykład.
Jedynym nowym elementem, który się tu pojawia jest assert. assert podobnie jak w C sprawdza,
czy podany warunek jest prawdziwy. Jeśli nie jest, 'rzuca' on wyjątkiem (który można oczywiście przechwycić).
assert(0); można używać, do oznaczania fragmentów kodu, do których program nie powinien dotrzeć. Pierwszą
myślą jest, "jak to możliwe, jak może być miejsce, gdzie program ma nie dotrzeć?", jednak chociażby
w przypadku budowania bardziej skomplikowanych parserów, jest to dość przydatne. Więcej na temat
Contract Programming w którymś z kolejnych odcinków
Do powyższego przykładu, proszę spróbować zmienić inout w funkcji baker, na out
i sprawdzić (albo jeszcze lepiej przewidzieć) jaki będzie wynik działania.
Omówiłem tylko trzy podstawowe typy składowania, jest ich jednak więcej i mają różne ciekawe zastosowania. Zaciekawionych odsyłam do dokumentacji:
invariant, const oraz final (const w D jest typem składowania, a nie atrybutem dla typu, więcej na ten temat oraz porównanie do C++ tutaj
lazy (warto wspomnieć, że typ składowania lazy został zasugerowany przez Tomasza 'h3r3tic'a Stachowiaka z Team0xf).
Podane w linkach typy składowania, pewnie pojawią się kiedyś w przykładach ;)
Postaram się w sposób zwięzły opisać jak przejść z OpenLDAPem
na Nową i Lepszą [tm] konfigurację.
Na początku ściągamy i kompilujemy źródła OpenLDAP'a
oczywiście, można też pociągnąć OpenLDAPa z paczek,
jeśli jednak używasz już takiego z paczek w systemie,
to nie doradzałbym na nim testować, żeby nie rozwalić
systemu :>.
Ja instaluję OpenLDAP'a w /opt/openldap.
Dodajemy /opt/openldap/lib do /etc/ld.so.conf i odpalamy ldconfig.
Przechodzimy do katalogu etc/openldap i na początek zmieniamy
domyślny suffix (base DN) i rootdn w slapd.conf
Używając bin/slappasswd generujemy nowe hasło, które ustawiamy jako rootpw w slapd.conf, za database bdb. Do tego na końcu slapd.conf dodajemy dwie linijki:
Hasło można ustawić takie samo jak dla bdb (Berkley DB), lub wygenerować
jakieś nowe, będzie ono służyło do dostania się do konfiguracji z poziomu
serwera.
W ldap.conf ustawiamy tymczasowo URI oraz BASE na base dn, który ustawiliśmy w slapd.conf, czyli:
URI takie, gdyż w celach testowych na tym porcie będziemy startować
serwer ldapa.
Upewnij się, że na wybranym porcie, nic nie chodzi, slapd poinformuje
jeśli się tak zdarzy, ale ponieważ, bedziemy odpalać z włączonym debuggiem,
możesz nie dostrzec tej informacji.
Przechodzimy do /opt/openldap/etc i kopiujemy domyślne ustawienia
dla backendu bdb (Berkeley DB):
W katalogu etc tworzymy katalog slapd.d, następnie konwertujemy konfigurację na 'nową'.
Nowa konfiguracja cechuje się tym, że ma hierarchiczną strukturę, której korzeniem jest cn=config.
(OpenLDAP od jakiegoś czasu do trzymania konfiguracji w pamięci używa backendu, takiego
samego jak do przechowywania innych danych, różnica jest taka, że schema dla konfiguracji
zdefiniowana jest na poziomie samego backendu, natomiast informacje o elementach drzewa
zapisywane są w plikach w katalogu slapd.d a nie w bazie danych).
Po tym kroku możemy wyrzucić slapd.conf oraz katalog schema, gdzie trzymane są schema'y ldapowe
(my jednak w celach testowych zmienimy im jedynie nazwy).
Jeżeli potrzebujesz innych schema' zainclude'uj je w slapd.conf przed zmianą na nową konfigurację.
Nie omawiam tutaj praw dostępu do serwera openldap'a, jeśli potrzebujesz jakieś, również zrób
to przed konwersją, będzie Ci łatwiej.
Nadszedł właściwy moment by uruchomić serwer:
Zostawiamy serwer odpalony, a na konsoli obok, wydamy testowo zapytanie, by sprawdzić, czy serwer działa. Jeśli wszystko poszło gładko, na pierwsze zapytanie powinniśmy w odpowiedzi dostać, to co ustawiliśmy jako base dn. (Po opcje do ldapsearch odsyłam do manuala). Na drugie zapytanie natomiast powinnienneś otrzymać natomiast drzewo konfiguracji:
Możesz też obejrzeć całą konfigurację usuwając słowo configContext.
Tyle na dzisiaj, Dlaczego taka konfiguracja jest jezzi, trendi i lepsza wkrótce.
Obiecany przykład, a potem ciut wyjaśnień.
W D na projekty buduje się z cegłówek zwanych modułami. Każdy plik stanowi osobny moduł. Linijka module jest opcjonalna (w podanym wyżej przykładzie wręcz zbędna). Jeżeli w pliku ma się ona znajdować, nie może przed nią być nic innego (poza komentarzami ow coz :D). Domyślnie nazwa modułu jest tworzona z nazwy pliku po usunięciu rozszerzenia. Moduł dostarcza przestrzeń nazw dla wszystkiego co się z nim znajduje.
W pythonie jeżeli importujemy tak:
To moduł math jest wrzucany do aktualnej przestrzeni nazw statycznie, to znaczy nazwy wszystkich wrzucanych obiektów,
są poprzedzone nazwą modułu, tym samym by odwołać się do jakiegokolwiek elementu tego modułu trzeba podawać pełną nazwę (np math.log).
W D jest odwrotnie domyślnie obiekty danego modułu są wrzucane do bezpośrednio do aktualnej przestrzeni nazw, (dlatego po
import tango.io.Stdout nie musimy się odwoływać do obiektu Stdout tego modułu przez: tango.io.Stdout.Stdout (tak dwa razy Stdout,
bo pierwsze to nazwa modułu, a drugie nazwa obiektu), lecz przez samo Stdout.
W przypadku większych projektów może to prowadzić do kolizji nazw, chcąc więc tego uniknąć (i wymusić zachowanie takie jak w pythonie)
należy poprzedzić nazwę modułu słowem static.
Domyślnie importy w D są prywatne, to znaczy jeśli moduł A imporuje moduł B, który z kolei importuje moduł C, to moduł C nie jest
widoczny bezpośrednio w module A. Dla ułatwienia rozpatrzmy następujący przykład:
Proste prawda? :)
Do tego zostają jeszcze importy przemianowane i wybiórcze, ale w tym momencie odsyłam do dokumentacji :)
Doszliśmy więc do tego, że w pierwszym przykładzie mamy niepotrzebną linijkę import i niepotrzebne kwalifikatory private.
Następnie w funkcji main mamy kilka zmiennych typu double. Po listę typów i ich rozmiary (bo jak mówiłem w D zmienne mają ustalone rozmiary)
odsyłam tutaj.
WAŻNA UWAGA
W D przy deklarowaniu kilku zmiennych, muszą być one tego samego typu (zdaje się, że wcześniej kompilator przed tym nie ostrzegał, teraz traktuje to jako błąd)!
To znaczy:
Wracając do pierwszego kodu, widzimy wiec kilka zmiennych, liczenie delty, dalej w ifie liczenie pierwiastków funkcji kwadratowej z wzorów Viète'a.
sqrt() jest metodą z modułu tango.math.Math,
liczącą oczywiście pierwiastek, toUtf8 jest metodą z modułu tango.text.convert.Float
zamieniająca float na postać tekstową.
~ jest w D operatorem konkatenacji.
Niżej jest identyczne wypisanie ale przy użyciu formattera, podobnego do tego z .neta, szczegóły tutaj.
Team0xf prowadzi warsztaty języka D (w Toruniu). Na stronie Warsztatow znajdziecie opis jak zainstalować dmd z phobosem, materiały z pierwszych warsztatów: filmiki, całą prezentację oraz przykładowe programy. Warsztaty będą się odbywać prawdopodobnie co tydzień i mniej więcej co tydzień na ich stronie pojawiać się będą nowe materiały.
Ponieważ nie zamierzam w żaden sposób konkurować z tym co oni prezentują (tym bardziej, że prezentują wyższy poziom :D), gorąco zachęcam do odwiedzania ich strony.
Jeżeli coś jeszcze będzie się pojawiać na joggu na temat D, to coś, czego (jeszcze) na warsztatach nie było, albo coś czego nie było i nie bedzie ;).
To tyle na dzisiaj, miłej nocy z D :)
Jak wspomniałem w pierwszej części istnieją dwa kompilatory: oficjalny rozwiajny przez digitalmars - dmd oraz nakładka na gcc - gdc. Do tego istnieją trzy biblioteki standardowe phobos, rozwijana przez community tango, oraz z ostatnich warsztatów Team0xf (o nich później) dowiedziałem się, że istnieje coś takiego jak libd.
Tutaj będzie poruszona jedynie kombinacja DMD+tango i tylko pod linuxem.
DMD dlatego, że zazwczaj jest o krok dalej niż gdc, to digitalmars definiuje kierunek rozwoju D, jednak szeroko pojęte 'D community' ma wpływ na rozwój języka
(warto jednak zerknąć na gdc, gdyż poprzez użycie gcc, daje on czasem lepszą optymalizację). Warto może w tym miejscu wspomnieć, że dmd pod linuxem z gcc
ale jedynie w celu linkowania. Pod windowsem korzysta z kompilatora C digitalmars - dmc.
Tango, jeśli się nie mylę wyrosło z dwóch projektów ares
oraz mango.
Dlaczego tango? Głównie dlatego, że mi bardziej przypadła do gustu niż phobos ;)
Jeżeli ktoś jest zainteresowany spróbowaniem phobosa, to pod koniec artykułu w następnym wpisie będzie małe wyjaśnienie gdzie znaleźć ładny opis instalacji i użycia
Będziemy potrzebować dmd i tango, które można ściągnąć w jednej paczce. Dodatkowo do budowania będzie nam potrzebny Rebuild który jest częścią projektu DSSS. (Rebuild jest nam potrzebny, ze względu na pewne problemy z linkerem. Ponadto ułatwia on kompilację dużych projektów. Na dokładkę DSSS zmierza ku temu, by zostać ujednoliconym systemem pozyskiwania, budowania, instalowania i konfiguracji projektów stworzonych w D). Ja wrzucam dmd+tango do /opt/dmd a dsss'a do /opt/dsss rób jak chcesz.
Okej zrobione. Pozostaje dodać /opt/dmd/lib do /etc/ld.so.conf i wydać polecenie ldconfig oraz dodać do PATH /opt/dmd/bin oraz /opt/dsss/bin. Jeśli to czytasz, ufam że sobie poradzisz ;)
Oczywiście zaczniemy od hello world. Normalnie rebuild dość sporo plików obiektowych, więc będziemy podawać do niego opcję -oqlib, żeby wszystkie pliki
obiektowe wrzucał do katalogu lib w katalogu w którym kompilujemy program.
Program w D zaczyna się od funkcji main, która ma 4 określone deklaracje, obowiązują proste zasady:
Powyższe zasady owocują w czterech możliwych deklaracjach funkcji main. My użyjemy najprostszej.
Tak jak wspominałem, pliki obiektowe wrzucamy do katalogu obj. Program wynikowy nazywa się hello
po odpaleniu możemy podziwiać efekty naszej żmudnej pracy ;).
W pierwszej linijce importujemy moduł (o modułach za chwilę) Console, jego dokumentację można znaleźć tutaj.
Console jest klasą niskopoziomową i akceptuje input tylko w postaci tekstu w UTFie.
(Możemy jednak zmusić ją, do wypisania tekstu w iso, konwertując go na hexy: "Za\xbf\xf3\xb3\xe6 g\xea\xb6l\xb1 ja\xbc\xf1" :>)
Dla ciekawych:
Jeśli zajrzymy do dokumentacji zrozumiemy co dzieje się dalej (a jeśli nie zrozumiemy to się domyślimy ;)).
Cout jest statyczną klasą (o tym też może później) typu Output. Wywołanie Cout("tekst") powoduje tak na prawdę wywołanie
Cout.append("tekst"); (o tym też później).
Ponieważ metoda append, zwraca obiekt typu Output możemy całość (Cout.append(...)) potraktować jako klasę i wywołać jedną z jej metod:
newline (w D metody które nie mają parametrów nie muszą mieć nawiasów przy wywoływaniu). Ponieważ metoda newline również zwraca
obiekt typu Output, znów możemy wywołać na nim metodę owej klasy. Jeżeli więc komuś ułatwia to czytanie (chyba może jedynie zaciemnić), można to zapisać tak:
(((Cout ("Zażółć gęślą jaźń")).newline()).append("druga linia")).newline(); // fuj! :>
Tu miał być jeszcze jeden przykład, ale postanowiłem, że zostanie wydzielony do osobnej części ;)
Większość z joggerowiczów słyszała chociaż o pythonie czy rubym.
Niektórzy nawet piszą bardzo ciekawe artykuły na temat jednego bądź drugiego.
Serią kilku artykułów chciałbym natomiast przybliżyć joggerowiczom mniej popularny język -- D.
Mam nadzieję, że uda mi się skłonić chociaż kilka (no choćby jedną) osobę do zapoznania się z tym językiem.
Na wstępie zaznaczam, że nie jestem guru tego języka ;). Artykuł będzie ciut przydługi, prawdziwa przygoda zacznie się dopiero od następnego razu.
D jest językiem mającym poniekąd związek z C i C++. Mającym bo oprócz pewnych podobieństw w składni różni się od nich znacznie. D jest tak zwanym językiem wieloparadygmatowym umożliwiającym: programowanie impreatywne, programowanie obiektowe oraz metaprogramowanie (odsyłam do angielskiej wiki, bo na polskiej ten artykuł praktycznie nie istnieje ;)).
Przede wszystkim: D jest językiem kompilowanym do kodu natywnego (chociaż może być również interpretowany), przy czym szybkość kompilacji bije na głowę szybkość kompilatorów C czy C++. Jeżeli przyjmiemy, że kod w C++ wykonuje się szybciej niż kod w Javie (proszę o nie prowadzenie flame'a na ten temat w komentarzach :>), tak kod w D dorównuje szybkością C++ a nawet przewyższa.
D ma statyczne sprawdzanie typów. W D typy zmiennych podstawowych mają określone rozmiary w przeciwieństwie do C czy C++. D ma wbudowane typy zmiennych, które np w C++ są dostarczane przez biblioteki. Są to m.in: Tablice dynamiczne, stringi (ciągi znaków niespecjalnie pasuje, a każdy programista wie co to string), słowniki, liczby urojone. (Podobnie jak w pythonie, prawda?). D posiada dwie trzy (odmienne) biblioteki standardowe (więcej na ten temat w przyszłym odcinku). Istnieją dwa kompilatory D: oficjalny dmd, oraz nakładka na gcc - gdc.
Nieco więcej o cechach D (część może w chwili obecnej być niezrozumiała, ale może wyjaśni się w przyszłości) (acha, * oznacza, że może kiedyś więcej na dany temat ;)):To oczywiście nie wszystko, starałem się dużą przedstawić dużą część możliwości, stąd ten chaos :> Co dalej? Gdzie udać się z tego miejsca? Oto garść linków:
Dostałem zaproszenie z Powerset do ich właśnie co otwartego dla szerszej rzeszy Powerlabs. O samej firmie i ich pomyśle na 'nową technologię wyszukiwania' było głośno jakiś czas temu.
Daje linki do szotów w tekście , bo flickr brzydko zmienił rozmiary :].
Strona jest zrobiona super-hiper-web2.0 wygląda niemalże jak last.fm :> (Autorzy starają się stworzyć wokół tego community, punkty za komentarze/wkład). Dostępnych jest pięć 'dem'. 4 bazujące na wikipedii Cytaty, Biznes, Sztuka i przygotowany specjalnie Halloween. Pozwalają one wyszukiwać frazy w stylu: "Co ... powiedział ... ?" (cytaty), "Kogo zabił ... ?" (halloween). Dokładnie widać na skrinszotach, nie chce mi się przepisywać, leniwy jestem :>. No więc wpisałem 'Co powiedział Linus Torvalds o BSD' a drugie 'Who killed electric sheep?', muszę powiedzieć, że jestem średnio zadowolony z uzyskanych rezultatów.
Najważniejszym i najbardziej reklamowanym demem jest PowerMouse czyli owa rozreklamowana przeglądarka. Wyszukuje ona na zasadzie połączeń między obiektami. Na skrinszocie widać 3 okienka do wpisania (something connection something), na innym część wyników po wpisaniu boy, oraz po wybraniu konkretnego wyniku.
Jeszcze zanim zapomnę, Powerlabs, jako źródła danych używają wikipedii. (wyniki niektóre są dziwne :>
No więc byłbym zachwycony tym genialnym wynalazkiem. Byłbym. Na pierwszy rzut oka widać, że jeśli jest robiona jakaś analiza tekstów, to jest ona robiona słabo, a szczerze, to wygląda to tak jakby całość głównie się opierała o łapanie kontekstu. Z NLP ma to niewiele wspólnego.
Druga rzecz, tak się nieszczęśliwie składa, że pisałem tekst na temat projektu Microsoftu automatycznego tworzenia bazy semantycznej. Zainteresowanych odsyłam tutaj a wszystkim polecam zebrane tam Przykłady.
Czym się różni projekt Microsoftu od powerset? Otóż Microsoft zatrudnił naukowców, którzy samym tematem zajmują się od kilkudziesięciu lat (chcąc nie chcąc kilka prac musiałem przeczytać), a nad Mindnetem pracują ponad 10 lat. Baza zarówno demonstracyjna jak i ta na której rzeczywiście pracują w MS oparta jest o kilka (czy może nawet kilkanaście) słowników. Mindnet czy też mnex nie jest nastawiony na szybkie wskocznie na rynek z superową web2.0 stroną ;) a tym bardziej na tworzenie wokół tego community.
Dalszy komentarz chyba zbędny ;)
Instalacja vmware server i kompilacja modułów poszła bez problemu, ale vmware nie chciało ruszyć. Zapisuję, żeby nie zapomnieć, najpierw symlink:
a potem albo startować z ustawionym LD_PRELOAD:
albo z racji, że jestem leniwy, a mam nadzieję, że błędów to nie spowoduje, to zrobiłem:
Przez ostatnie dwa miesiące blog był prawie martwy, mam nadzieję, że jednak uda mi się go utrzymać przy życiu. Mam plany, myślę, że ciekawe, na co najmniej kilka wpisów, ale jakoś ciężko mi znaleźć czas (zła organizacja?).
Wszyscy znają Snorta, prawda? A nawet jeśli nie znają, to zapewne słyszeli o czymś takim. W zeszły piątek nastąpiło, to o czym niektórzy wiedzieli już wcześniej, Sourcefire wziął pod opiekę ClamAVa. Co to oznacza dla użytkowników końcowych? ClamAV będzie dalej dostępny na GPLu. Komercyjny support prawdopodobnie spowoduje, że powiększy się ekipa sigmakerów jak i developerów, nie było to możliwe przy funkcjonującym systemie donacji. Zainteresowanych odsyłam do ofert pracy. Szczegółowe informacje na temat przejęcia znajdziecie w linkach:
P.S. Wszystkich fanów ;) i czytelników przepraszam, że ostatnio nie daję znaku życia, ale nie dysponuję zbyt dużą ilością wolnego czasu.
Dwie rzeczy drażniły mnie od dłuższego czasu w gmailu, mianowicie brak czcionki o stałej szerokości przy czytaniu i pisaniu wiadomości. Jakiś czas temu postatnowiłem to zmienić, a teraz podzielę się z wami JTZ w Operze.

Jest jedna rzecz, której strasznie brakuje mi w Operze, mianowicie DOMInspectora, takiego jak ma Firefox. Co prawda jest Opera Developer Console, jednak z pewnych względów, nie wystarcza mi. Zapewne łatwiej byłoby zmodyfikować tamten kod, jednak jest on dość obszerny i nie chciało mi się nad nim siedzieć/czytać, więc napisałem pierwszą wersję mojego małego DOMInspectora dla Opery.
Przez dłuższy czas używałem, zsh, później z powodu problemów z UTFem wróciłem do basha, jednakże ostatnio wróciłem do zsh, jednakże nie z powodów o kŧórych będzie mowa poniżej.
Jakiś czas temu porównywałem różne shelle i postanowiłem się podzielić wynikami.
Niedawno pojawiły się badania megapanelu za kwiecień 2007. Czołówka nie zmieniła się. Co powinno zrobić Google?
W środę pojawił się exploit na Yahoo Messegnger'a 8, w czwartek Yahoo wypuściło patcha na znalezioną lukę (Więcej jest na SecurityFocus.
Bardzo dobrze, że Yahoo zareagowało tak, szybko, gdzyż w trzy dni później (w sobotę), pojawił się malware, wykorzystujący tę lukę.
Shellcode oryginalnego exploita, został podmieniony na złośliwy, który ściąga niewykrywany (w sobotę) malware z rodziny dropperów (czyli taki, który ściąga trojana, backdora lub inny malware). Szczegóły na Sans Security.
Dla nas nie ma to żadnych skutków, gdyż ja osobiście nie mam znajomych uzywających YM, jednakże niepokojące jest tempo, w jakim twórcy wszelkiego rodzaju malware'u wykorzystują nowo odkryte luki.
Prawda, że chwytliwy temat? ;)
Otóż obejrzałem ostatnio 3 Tech Talki, którymi chciałbym się podzielić,
a chwilowo (nadal) mam problemy z dostępem do szortów.
Updejtowałem ostatnio e17 i spotkała mnie miła niespodzianka.
Wpis ten jest odpowiedzią między innymi na komentarze dunDera i Cthulu, do poprzedniego wpisu. Pomyślałem, że zainteresuje to więcej osób, a prędzej ktoś przeczyta wpis niż komentarz.
Piraci, którzy działają na skalę globalną, mają dość kasy żeby wykupić program do dekodowania tego syfu od samych twórców zabezpieczenia cichaczem ;)
Otóż nie jest to takie proste, jak napisałem, system nie został i prawdopodobnie jeszcze 'jakiś czas' nie zostanie złamany.
Jest sobie program napisany przez arnezamiego, do odczytywania: klucza przetwarzania, generwoania z niego klucza nośnika, odczytywania identyfikatora woluminu, generowania unikatowego klucza tytułu i odszyfrowania kluczy utworu (gdyż jest ich kilka).
Jest BackupHDDVD, ale nie jest to narzędzie dla piratów, pozwala on zdeszyfrować film i zapisać na dysku, ALE, trzeba mu podać zestaw kluczy utworu albo o ilę się nie mylę klucz nośnika (stąd strony takie jak zdjęta już hddvdkeys.com).
Pewnie można by połączyć oba programy, ale...
moim zdaniem: firmy odwołają certyfikat dla windvd, wprowadzą jakieś poprawki, które uniemożliwią działanie programowi arnemzaniego (i znowu spowoduje to kłopoty dla zwykłych uzytkowników).
Jak pisałem wcześniej, system nie został złamany i bez posiadania odpowiednich kluczy, nie będzie możliwe dekodowanie, bo pewnych kluczy otrzymać się nie da.
Najprostszym rozwiazaniem, byłoby zakupienie napędu i próby modyfikacji jego firmware'u, to jednak najprawdopodobniej spowodowałoby odwołanie napędu (nie jego certyfikatu, lecz odwołanie go w MKB, co spowodowałoby, że nie mógłby on otrzymać klucza przeodtwarzania, a tym samym, byłby właściwie bezużyteczny).
Ważne, żeby zdać sobie sprawę, że tak na prawdę wytwórniom filmowym, nie zależy na tym, by film nie został spiracony. Ważniejsze jest by:
Co do wykupienia, 'programu do dekodowania' od twórców systemu, trzeba pamiętać, że AACS jest zależny od hardware'u, więc nawet gdyby jakiś magiczny program istniał (np wykorzystujący jakąś nieopublikowaną furtkę), bez odpowiedniego sprzętu sam w sobie pewnie nic nie zrobi.
Zdecydowanie najlepszym wyjściem, byłoby uzyskać klucz, który można by określić głównym kluczem urządzeń. To z tego klucza, zostały poprzez funkcję jednokierunkową używającą AESa w specjalnym procesie, wygenerowane klucze wszystkich urządzeń na rynku. Ponieważ jest to funkcja jednokierunkowa oparta o AESa
posiadając klucze urządzenia, nie jesteśmy w stanie otrzymać tego głównego klucza (no chyba, że ktoś wie jak złamać AESa :)).
Klucz ten znają zapewne 'wybrane osoby', więc najprościej byłoby go od owych osób 'wyciągnąć'.
Spowodowałoby to, że AACSLA, musiałby zmienić klucze wszystkich urządzeń, co jest w praktyce niemożliwe.
Należy zdać sobie sprawę, że łamanie zabezpieczeń to wieczna walka, między twórcami zabezpieczeń, a między tymi, którzy chcieliby je obejść (to tak niekoniecznie odnośnie zabezpieczeń HD-DVD). Tak, ta wojna najpewniej najbardziej odbije się na tych, którzy chcieliby 'po prostu obejrzeć film'.
|