Zczytywanie danych z innej aplikacji

0

Witam

  1. Mam problem z pewnym zgadanieniem, prubowalem juz sam to rozwiazac jednak chyba nie dam rady, zatem prosze Was o pomoc... chcialbym w swojej aplikacji w C++ Builderze miec mozliwosc odczytywania wartosci z konkretnego adresu pamieci uzywanego przez inna aplikacje(gre). Np w komorce o adresie 912FE60 mam wartosc 395 i chcialbym, zeby powiedzmy co 1sek(wykorzystujac timer) wpisywalo mi do Edita ta wartosc... wykorzystujac asm'a otrzymuje oczywiscie access violation w tym adresie i nie mozna w zaden sposob przeslac wartosci tego adresu do zmiennej. Z tego co czytalem trzeba jakims sposobem podpiac sie pod aplikacje i wtedy mozna zczytywac z niej dane, prosilbym o najprostszy sposob zczytywania z konkretnego adresu pamieci wartosci.

  2. Jesli juz znajdzie sie sposob na zagadnienie powyzej, chcilabym tez prosic o jakis prosty sposob symulowania konkretnych przyciskow dla konkretnych aplikacji (wiem jak symulowac przyciski w momencie gdy mam aktywne okno, w ktorym chce to robic), chcialbym aby w aplikacji co 10s naciskalo mi np. klawisz W, a ja w tym czasie molgbym rozmawiac czy przegladac strony

Z gory dziekuje za pomoc i pozdrawiam

0

oj Boże, Boże... czy nie łaska poczytać dokumentację M$ i Intela? To nie te czasy, że asemblerem można grzebać wszędzie /no prawie... /. Tryb chroniony nakłada piękne ograniczenia - każdy proces ma własną przestrzeń adresową. W każdym razie ReadProcessMemory - odsyłam na msdn i do intelowskiego IA-32 Software Developer's Manual Volume 1 i 3.
Ad. 2: Wysyłasz do okna odpowiedni komunikat - jak chcesz wcisnąć buttona albo element menu to wysyłasz WM_COMMAND. Zasymulować naciśnięcie klawisza? WM_KEYDOWN, WM_CHAR itd...

0

Ok doszedlem do czegos takiego:

Pobieram PID aplikacji za pomoca nazwy jej okna wykorzystujac funkcje:

GetWindowThreadProcessId(FindWindow(NULL,"Nazwa okna np. Kalkulator"), &PID); // gdzie PID to zmienna typu DWORD zadeklarowana wczesniej

Nastepnie otwieram process z prawami do odczytu za pomoca funkcji:

hProcess = OpenProcess(PROCESS_VM_READ,false,PID); // deklaru
jac wczesniej: HANDLE hProcess

I moj problem polega na dokenczeniu funkcji:

ReadProcessMemory(hProcess,BASE_ADRESS,BUFFER,4,NULL) - jak zastapic BASE_ADRESS konkretnym adresem pamieci? Chce pprzeczytac 4 bajty do zmiennej typu WORD o nazwie BUFFER z adresu pamieci 90DE538 (prubowalem juz 0x090DE538, 0x90DE538, 90DE538h - nie da sie ich tak wpisac), prubowalem konwersji np. (LPCVOID *)BUFFER lub (LPCVOID *)0x097685, program sie uruchamial ale funkcja ReadProcessMemory zwrcala wartosc 0 wiec nie przeczytalo. Prosze o pomoc

0

Po pierwsze WORD ma 2 bajty. Ale to szczegół. Ten adres, który podałeś jest jakiś taki 'niewyraźny' - albo to dll'ka albo dynamicznie alokowany bufor. I tu zaczynają się schody - dllka może być ładowana pod różne adresy, nie ma gwarancji, że przy następnym uruchomieniu programu nie będzie gdzieś indziej, co do dynamicznych buforów to jest to raczej pewne. Ale jeżeli uważasz, że adres jest właściwy... Coś takiego powinno zadziałać:

DWORD dLiczba;
ReadProcessMemory(hProcess, (const void*)0x90DE538, &dLiczba, sizeof(dLiczba), NULL);

DWORD ma 4 bajty... ale sizeof nie zaszkodzi. Jeżeli to jednak adres zawadza, obadaj czego częścią jest - weź powiedzmy jakiś debugger i oglądnij pamięć procesu. Pewnie to część dll'a - odczytasz jakiego i po problemie. No, prawie - trzeba znać adres tego dlla w pamięci przy każdym uruchomieniu - albo użyć api do wyliczania albo zrobić sztuczkę z LoadLibrary... gdzieś ją podawałem... jak znajdę to dopiszę...

dopisane:

Wspomniana sztuczka z LoadLibrary: LoadLibrary albo ładuje bibliotekę albo zwraca adres już załadowanej . Jako, że LL trzeba wywołać w kontekście 'atakowanego' procesu - a ma identyczny prototyp jak procka wątku - robimy z niej zdalny wątek dodając zawczasu malutki kawałek danych - nazwę biblioteki.

void* InjectDll (HANDLE hProcess, char* pLibName)
{
  DWORD ExitCode;

        FARPROC LoadLib = GetProcAddress (GetModuleHandle ("kernel32.dll"), "LoadLibraryA");

        void* pMem = VirtualAllocEx (hProcess, 0, MAX_PATH, MEM_COMMIT, PAGE_READWRITE);

        WriteProcessMemory(hProcess, pMem, pLibName, lstrlen (pLibName), 0);

        HANDLE hThread = CreateRemoteThread (hProcess, 0, 0, (LPTHREAD_START_ROUTINE) LoadLib, pMem, 0, &ExitCode);
        WaitForSingleObject (hThread, INFINITE);
        GetExitCodeThread (hThread, &ExitCode);
       
        VirtualFreeEx (hProcess, pMem, MAX_PATH, MEM_DECOMMIT);
        /* ExitCode zawiera adres zaladowanej biblioteki lub 0 jesli zaladowanie sie nie powiodlo */       
        return (void*) ExitCode;
};

wywołanie:

void* pDllBase = InjectDll(hProcess, "sciezka\\do\\jakiegos.dll");

W sumie to raczej bajer niż metoda. Może lepiej byłoby to standardowo załatwić poprzez CreateToolhelp32Snapshot i Module32First lub podobne funkcje.

0

Dziekuje bardzo, a molgbym jeszcze prosic o pomoc w takiej sprawie:

ReadProcessMemory(hProcess, (const void*)0x90DE538, &dLiczba, sizeof(dLiczba), NULL);

I teraz zebym zamiast wpisywania do kodu tego 0x90DE538 mogl to zczytywac z Edita, np. wpisuje do Edita: 90DE538, robie jakiegos stringa(??), ktory zamieni mi to na 0x90DE538, tylko nie wiem jak to wrzucic do tej funkcji teraz. Z gory dziekuje

Edit: Jeszcze jedna mala prosba, jak zrobic zeby okienko pozostawalo na ekranie dopuki sie go samemu nie zminimalizuje? Chodzi mi oto ze naciskajac alt+tab i przechodzac do innego pelnoekranowego programu moje okno z programem znika, a chcialbym zeby zostawalo

Pozdrawiam

0

zamiast wpisywania do kodu tego 0x90DE538 mogl to zczytywac z Edita

Z Edita zczytujesz oczywiscie text (String, AnsiString, PChar lub inne w zaleznosci od IDE). Teraz musisz napisac funkcje ktora zamieni tekst na unsigned int pamietajac, ze tekst jest w systemie szesnastkowym (czyli zwykla zamiana hex->dec - algorytm jest prosciutki wiec nie powinno byc problemu). A potem nazwe tej zmiennej wrzucasz do

ReadProcessMemory(hProcess, (const void*)0x90DE538, &dLiczba, sizeof(dLiczba), NULL);
zamiast
0x90DE538
.
Ustaw okienko na AlwaysOnTop (albo jakos tak). W Builderze jest to we wlasciwosci (chyba WindowStyle), a w WinApi ustawiasz to przy tworzeniu okna albo przez SetWindowLong.

0

Ok zrobilem juz prawie wszystko co chcialem, jeszcze tylko prosba o pomoc w jednej sprawie. A wiec:

SendMessage(Form1->hwndProcess,WM_LBUTTONUP,0,1300);

Pierwsza wartosc w tej funkcji to uchwyt okna i to dziala, dalej wysylany komunikat(pominalem MOUSEDOWN bo dzialalo bez), i dalej sa dwa parametry MSG. Nie wiem jak wrzucic do tego konkretne wspolrzedne na ekranie (np. chcialbym aby kliknelo mi myszka w punkcie (800,1300)) Jesli robie WM_LBUTTONUP,900,1300 to przesuwa mi sie jedynie w poziomie na wspolrzedne (0,1300), jedyna mozliwosc to wpisywanie jakis wielkich wartosci wtedy kursor idzie troche w dol ale jakby "za bardzo". Moje pytanie: Co wstawic do funkcji zeby kliknelo mi w zadanym punkcie?? - Prubowalem juz przerabiac TPoint na LParam ale tez nie wychodzilo.

P.S. Rozdzielczosc w windzie i w programie to 1600x1200.

Pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1