Skocz do zawartości

Ranking

Popularna zawartość

Treść z najwyższą reputacją w 05.06.2011 uwzględniając wszystkie działy

  1. A więc witam na moim nowym blogu, poświęconym głównie programowaniu i tematom pochodnym, czy też, podobnym. Że to tak, delikatnie rzecz biorąc, ujmę. Igraszki z notatnikiem #1, czyli jak pisać w notatniku bez użycia notatnika? Wstęp Życie pokazuje mi że programowanie(szczególnie w liceum, pozdrawiam wszystkich z profilu mat-fiz-inf) jest sprowadzone wyłącznie do naku...robienia algorytmów, rozwiązywania problemów, dopasowywania się do standardów. Ale gdzie w tym wszystkim trochę funu? Takiej beztroskiej, wręcz trochę bezcelowej zabawy, ale jakże fascynującej - bo związane z (jak dla mnie) najciekawszą stroną programowania.Ale bez zbędnych wstępów, przejdźmy do części właściwej cóż chcę pokazać: Zamierzam poprowadzić chociaż trochę serię artykułów która będzie się opierać...o notatnik. Tak, ten uroczy plik notepad.exe, który każdy ma na swoim komputerze. I pokażę cóż można z nim zrobić..A uwierzcie mi, że można, sporo, a jak ktoś się uprze, to praktycznie wszystko(przykład Anonimowych którzy niedawno włamali się do Sony jest wprost idealny, nieprawdaż?). A zacznę od czegoś prostego, czego nie da się wytłumaczyć prosto, chociaż w jakimś stopniu sens przekazuje tytuł tego wpisu : D Użyte narzędzia? Olly Dev-C++ Wspomnę jedynie że działam na maszynie wirtualnej z Windowsem XP, SP3 Parę słów wyjaśnienia, czym jest Olly - jest to debugger, za sjp.pwn.pl: Ale oprócz identyfikacji błędów, potrafi pokazać nam, ludziom, pliki exe, które zwykle są niekoniecznie czytelne, w miarę zrozumiałej formie: Rys. 1 - Notatnik otwarty w notatniku(???) Rys. 2 - Notatnik otwarty w Ollym No ale coś za coś: Olly pokazuje nam programy w asemblerze, którego wypada się jednak nauczyć(albo mieć wyczucie i znać nieco angielski, jak ja ), żeby pogrzebać nieco głębiej w systemie. Żeby zrozumieć głębsze przesłanie kryjące się za tym artykułem warto znać też conieco podstawy pisania aplikacji GUI w Windowsie...oczywiście będę starał się tłumaczyć wszystko na bieżąco, ale wiecie, jak to jest >.> Rozpoznanie Więc chcemy dobrać się do notatnika, okeej...nasz cel wygląda tak: Rys. 3 - Cel. Straszny, nie? I co my właściwie chcemy zrobić? Powiedzmy, że chcemy znaleźć jakąś unikatową drogę, żeby pisać w notatniku...ale nie, nie satysfakcjonuje nas symulowanie jakichś durnych naciśnięć klawiszy, chcemy znaleźć coś ciekawszego żeby wpisać tam, powiedzmy, "PWND LOL NOOB, HEHE". Okej, cel mamy, teraz pora zacząć prawdziwą zabawę! Let's rock, czy jakoś tak Żeby mieć się do czegoś odnieść skorzystam po drodze z pewnej aplikacji która jest dorzucona do AutoIt i zobaczę, co ona mówi na temat tegóż editboxa: Rys 22 - profesjonalne rozpoznanie sponsorowane by AutoIt Więc okno to, do którego możemy beztrosko przelewać swoje myśli, robić ascii-arty albo odrabiać pracę domową jest..Editem! Szybki look w google na hasło "kurs winapi", i wpadamy na taką stronę...Ciekawe, CreateWindow? Zajrzyjmy do msdn(jeżeli jeszcze nie znacie tej strony, to znaczy że nigdy nie programowaliście na poważnie w Windowsie albo macie linuxa) - no proszę, na stronie poświęconej CreateWindow jest uwaga brzmiąca tak: Iii...bingo. Teraz pora odpalić Olly'ego i poszukać wywołania tej funkcji w programie. Z tego miejsca teoretycznie mam dwie drogi - Olly, jak każdy debugger posiada dwie bardzo ciekawe "instrukcje", dzięki którym mogę poruszać się po programie - jest to Step Over i Step In. O co chodzi, czym to się różni? Spieszę z wyjaśnieniami: Każdy program ma wywołania jakichś funkcji, procedur, itd. I Step Over pozwala nam "przejść nad" wywołaniem takiej procedury, a "Step In" zagłębić się, cóż się w takiej procedurze dzieje...I mógłbym sobie od początku robić "Step Over", aż nie pojawiłoby się okno, wtedy zapamiętywałbym funkcję która okno stworzyła i wchodził do niej, a tam znów bawił się w StepOver...i tak w kółko, aż trafię na moją lubą, CreateWindowEx. : d Aczkolwiek muszę was zasmucić, jestem zbyt leniwy żeby bawić się w coś takiego i zrzucę trochę roboty na debugger - znajdę wywołania mojej funkcji i ustawię na niej tzw.breakpointy(to są miejsca, w których debugger z normalnego działania programu "staje" i oddaje pełnię władzy nam), Otwieramy Olly'ego, drugim klawiszem myszki klikamy w okienku "CPU"->Search For->Intermodular calls. W okienku które następnie nam wyskoczy wpisujemy nazwę naszej funkcji(Intermodular - tj.z innego modułu, a funkcje z WinApi są jakby "importowane" z systemu)..ii...wiola! ewentualnie, krystyna: Rys. 5 - Hyhyhyh :> Klikamy na tym drugim klawiszem myszki ii.."Set breakpoint on every call to CreateWindowEx". Teraz Naciskamy "Play" i szukamy szczęścia w polu...właściwie, w programie. Żeby wywołanie było z jakimś editem, miejmy nadzieję... *chwila trwogi*(klikamy play póki nie natrafimy na właściwe wywołanie) JEEEST! Rys. 6 - nanan ** I co my tu mamy? Uchwyt(to jest jakby numer identyfikacyjny tego editboxa, bo jak wiadomo, nic w przyrodzie(czy też windowsie) nie ginie, nawet taki editbox musi gdzieś się chować : D) jest zwracany pod jakiś STAŁY! adres(czyli możemy się do niego odwołać za każdym razem!)...może wykorzystajmy go w C(++)? ;> Tylko wstępna uwaga - widzimy że w SetWindowText jest taki fragment: .Więc odpada wywoływanie SetWindowText, trzeba wysłać im WM_SETTEXT przez SendMessage...Ale cóż to dla nas, nie? Spisujemy sobie adres gdzie uchwyt siedzi w pamięci notatnika...i napiszmy coś! Rys. któryś z rzędu - kod. Dlaczego nie daję w postaci tekstowej? Bo po pierwsze nie chce mi się kopiować z maszyny wirtualnej, a po drugie przepisanie samemu też ma walory edukacyjne Moje małe niedopatrzenie - zamiast liniki z GetWindowText powinno być SendMessage(editBox, WM_GETTEXT, 256, (LPARAM)out); I zobaczmy, jak działa... Rys. A - przed uruchomieniem... Rys. B - po uruchomieniu Jak widzimy, wszystko pięknie działa. : d I to by było właściwie na tyle, być może kiedyś będzie jakaś następna część, poruszająca inne techniki/rzeczy.Ale to w przyszłości. Komentarze oczywiście mile widzane. Dziękuję za uwagę i pozdrawiam, Piotr Fronczewski
    1 punkt
  2. Wiemy już, jak pisać do notatnika bez użycia notatnika. To może teraz czas na coś zgoła innego, jak przypuśćmy...uruchomienie notatnika z notatnika? [tut]Igraszki z notatnikiem #2, czyli jak uruchomić notatnik z notatnika? Wstęp W dzisiejszym artykule spróbujemy jakoś kreatywnie wykorzystać to, czego dowiedzieliśmy się w poprzednim artykule, tj. gdzie jest editBox Notatnika, jak czytać z niego informacje i jak do niego pisać. Pytanie tylko, jak to możemy wykorzystać żeby uruchomić notatnik... ...Każdy, dosłownie każdy miał styczność z czymś tak fajnym jak interpeter poleceń, vel cmd.exe. Bardziej dociekliwe osoby wiedzą że jest coś takiego jak przełącznik /C... Rys. 1 - Przełącznik /C. Ciekawy, prawda? ...który moglibyśmy wykorzystać wraz z tzw.przekierowaniem strumieni/potoku do pliku... Rys. 2 - Przkierowanie wyjścia danego programu do pliku. Bardzo przydatna rzecz. Jakiś niecny pomysł zaczyna się klarować, prawda? Pomyślmy, timer, który w krótkich odstępach czasu(powiedzmy, 100ms) za pomocą GetAsyncKeyState sprawdzałby czy użytkownik nacisnął jakiś z góry ustalony klawisz(np.klawisz tab). Jak tak, odpalałby funkcję z DLL'ki, która za pomocą GetWindowText pobierałaby zawartość editBoxa, wrzucała jego zawartość do parametru lpCommandLine funkcji CreateProcess, i przekierowałaby jego zawartość do wcześniej utworzonego pliku tymczasowego(a co, konspiracja na sto procent), a później za pomocą odpowienich funkcji z WinApi ładowałaby do pamięci, a stamtąd za pomocą SetWindowText do editBoxa...no cóż, cel i kroki mamy, teraz pora nałożyć buty i... W drogę! Więc jak nie wspomniałem wcześniej, to wspomnę teraz - cały nasz niecny plan będzie opierać się na technice DLL Injection. Nie będę wdawał się w opisy, bo z pewnością powstało na ten temat dużo ciekawych poradników, znacznie lepszych niż mój. Wspomnę jedynie, że nie będę trudził się z pisaniem własnego szkieletu - wykorzystam sobie gotowy projekt z Dev-C++(tyle że dla języka C - tworzenie własnych obiektów mnie przeraża), a za injector posłuży mi poczciwy Cheat Engine w wersji 5.6.1(jakoś nie pałam szczególną miłością do LUA). Okej, na rozgrzewkę napiszmy sobie jakąś prostą dllkę... Rys. 3 - przykładowa dllka. Śpieszę z wyjaśnieniami cóż to robi - w naszej ulubionej case(eee....wiecie jak się nazywa ) zarzucam funkcję SetTimer, gdzie jako uchwyt okna stosuję FindWindow z podaną wcześniej klasą "Notepad", a jako ostatni parametr podaję adres callbacku który SetTimer przyjmuje, tj.TimerProc.A sam timer...no cóż, jak widać tylko śmieci. ' Szast-prast, piszemy dalej: Rys. 22 - bardziej zaawansowany szkic dllki, który właściwie robi wszystko co chcemy. Oprócz tego, że nie wywołuje cmd. >.> Pierwsza linijka robi tzw.wskaźnik - z uwagi na to, że działamy już w obrębie notatnika, to możemy się pokusić o coś takiego. Dlaczego sprawdzam czy GetAsyncKeyState jest mniejsze od zera? Ponieważ ta funkcja "zapala" pierwszy bajt(który świadczy o tym, czy liczba jest dodatnia, czy ujemna - pozdrawiam wszystkich z profilu mat-fiz-inf!). Reszta rzeczy jest raczej zrozumiała, więc przejdę do finalnej części, czyli o finalnym proof-of-concept: /* Replace "dll.h" with the name of your header */ #include "dll.h" #include <windows.h> #include <stdio.h> #include <stdlib.h> #include <Windows.h> HWND *editBox = (HWND*)0x01009838; //ach, te pisanie dllek ^_^ char hTempName[128]; void cdUp() { char *temp = malloc(128); int licznik = 0, i; GetCurrentDirectory(128, temp); for(i = 0; i < strlen(temp); i++) if(temp[i]=='\\') licznik = i; temp[licznik] = 0; SetCurrentDirectory(temp); //zeby nie bylo, to jeszcze sobie wyczyscimy editboxa ZeroMemory(temp, 128); SetWindowText(*editBox, temp); //dzialamy na wskazniku, wiec powinnismy go sobie "luskac",jak chcemy z niego skorzystac free(temp); //na wszelki wypadek } void cdDown(char *katalog) { char *temp = malloc(128); GetCurrentDirectory(128, temp); strcat(temp,"\\"); strcat(temp, katalog); SetCurrentDirectory(temp); ZeroMemory(temp, 128); SetWindowText(*editBox, temp); free(temp); } void executeCommand(char *command) { char *output = (char*)malloc(2048); //a teraz dla odmiany czyste c... PROCESS_INFORMATION pi; STARTUPINFO si; DWORD dwRead; ZeroMemory(output, 2048); command[strlen(command)-1] = 0; //tutaj usuwamy znak tabulatora, ktory zwykle jest na koncu if(command[0] == 'c' && command[1] == 'd') if(command[3] == '.' && command[4] == '.' && command[2] == ' ') {cdUp();return;} else {cdDown((command+3));return;} //zakrawa na memory leak, ale co tam, to raptem 3 bajty strcat(output, "/C \""); //strcat(a, ; - do ciagu "a" dolacza ciag "b", na koniec, oczywiscie strcat(output, command); strcat(output, " >"); strcat(output, hTempName); ZeroMemory(&si, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); //wymagane przez system si.dwFlags = STARTF_USESHOWWINDOW; //ta flaga mowi Windowsowi zeby patrzyl na ponizsza zmienna si.wShowWindow = SW_HIDE; //A tu mowimy zeby kazde wywolanie konsoli mialo flage SW_HIDE, czyli zeby nam nie migalo CreateProcess( "C:\\windows\\system32\\cmd.exe", output, NULL, NULL, FALSE, 0, NULL, NULL, &si, π); ZeroMemory(output, 2048); //zeby bylo oszczedniej to korzystam z jednej zmiennej - a co! //Flagi ponizej dobrze tlumaczy MSDN HANDLE hTempFile = CreateFile(hTempName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0); ReadFile(hTempFile, output, 2048, &dwRead, 0); CloseHandle(hTempFile); SetWindowText(*editBox, output); free(output); } void CALLBACK SprawdzCzyUzytkownikWcisnalKlawisz(HWND hWnd,UINT uMsg,UINT_PTR idEvent,DWORD dwTime) { char *input = (char*)malloc(128); ZeroMemory(input,128); if(GetAsyncKeyState(VK_TAB)<0) //jezeli jest mniejsze od zera, znaczy ze wcisniete { GetWindowText(*editBox, input, 128); executeCommand(input); } free(input); } void getTemp() { char *currentdir = (char*)malloc(128); ZeroMemory(currentdir, 128); ZeroMemory(hTempName, 128); GetTempPath(128, currentdir); //zwraca folder z plikami tymczasowymi GetTempFileName(currentdir, 0, 0, hTempName); //zwraca nazwę } BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ , DWORD reason /* Reason this function is being called. */ , LPVOID reserved /* Not used. */ ) { switch (reason) { case DLL_PROCESS_ATTACH: getTemp(); SetTimer(FindWindow("Notepad", 0), 0, 100, SprawdzCzyUzytkownikWcisnalKlawisz); break; case DLL_PROCESS_DETACH: break; case DLL_THREAD_ATTACH: break; case DLL_THREAD_DETACH: break; } /* Returns TRUE on success, FALSE on failure */ return TRUE; } To teraz pora to potłumaczyć... FAQ Q:Do czego służą funkcje cdUp i cdDown? A:Zacznę od początku - żeby nasza "nowoczesna konsola" mogła poruszać się pomiędzy katalogami, to trzeba było wymyślić jakiś sposób, dzięki któremu mogłaby to zrobić - odpowiedzią jest właśnie CreateProcess, który każdy utworzony proces wywołuje w tzw. current working directory, czyli w katalogu którym teoretycznie sam się odpalił, i który możemy dowolnie zmieniać za pomocą funkcji SetCurrentDirectory i GetCurrentDirectory. Funkcja cdUp szuka pozycji ostatniego slasha - "\" w tym co zwróci nam GetCurrentDirectory i w jego pozycję wstawia nam 0, vel null. Co to daje? C jest tak fajnym językiem, że każdy ciąg znaków jest zakończony tym właśnie zerem(możemy się spotkać chociażby na msdnie z określeniami "null terminated string") i resztę po zerze po prostu nie bierze pod uwagę. cdDown porusza się "w dół", dodając jednego slasha i nazwę katalogu do którego chcemy się przenieść. Q:Dlaczego za każdym razem tworzę sobie uchwyt do pliku tymczasowego? A:Bo inaczej nie działa. Tzn. nie chciało, u mnie. :< I tak to mniej-więcej działa. Chociaż działa trochę dziwnie, co można zaobserwować na filmiku(oj tam, wpisywanie dwa razy każdej komendy to nie problem!): No i cóż, to by było na tyle. Komentarze(i odpowiedź, jak rozwiązać problem z podwójnym wpisywaniem komend) mile widzane, jak zwykle. : D Pozdrawiam, JP na 100%
    1 punkt
×
×
  • Dodaj nową pozycję...