Skocz do zawartości

Ranking

Popularna zawartość

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

  1. 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ę...