Debugger na wpisywanie do pamięci pewnej wartości

Debugger na wpisywanie do pamięci pewnej wartości
mwl4
  • Rejestracja:około 12 lat
  • Ostatnio:10 minut
  • Lokalizacja:Wrocław
  • Postów:399
0

Witam,
czy jest jakiś debugger lub inne narzędzie, które na podstawie podanej przeze mnie liczby 32 bitowej jest w stanie sprawdzić gdzie ona jest wpisywana do pamięci podczas działania aplikacji?

O co chodzi?
Niestety ale w dość sporym programie mam gdzieś nadpisywanie pamięci. Problem w tym, że to nie jest taka prosta aplikacja. Problem jest dosyć złożony, bo jest to dllka, która hookuje główną aplikacje (grę zewnętrzną), korzysta z pamięci tej gry, itd. itd.
Problem polega na tym, że czasami pamięć się nadpisze w miejscu jakiegoś arraya, a konkretniej jego rozmiaru. A, że liczba która jest wpisywana zawsze do tego rozmiaru arraya jest konkretnym floatem (1057770468u [0.548032999f]), to pomyślałem, że gdybym miał debugger w którym wpisuję tą wartość a on mi wyprintuje w czasie rzeczywistym gdzie dana wartość jest zapisywana i pod jakim adresem instrukcje ją zapisują to mógłbym już coś zrobić.
Oczywiście można by było jakoś ustawić debuggera na rozmiar tego arraya i czekać, aczkolwiek jest taki problem, że takich arrayów jest dość sporo, a nadpisanie pamięci jest dość rzadkie.
Dodatkowo, wartość ta jest dość unikalna. W czystej grze ona się pojawia dosłownie 6 razy w pamięci, a już po działaniu dllki mojej niestety czasami występuje już 100/200 razy.

Pomysły?


Asm/C/C++
_13th_Dragon
Prawdopodobnie zapomniałeś że tablicy w C/C++ indeksuje się od zera
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 miesiące
0
Kopiuj
#include <iostream>
using namespace std;

int main()
  {
   int x=0;
   cout<<"x="<<x<<"; &x="<<&x<<"; <- czyli adres w pamięci"<<endl;
   return 0;
  }

http://ideone.com/kkeDy4


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
mwl4
  • Rejestracja:około 12 lat
  • Ostatnio:10 minut
  • Lokalizacja:Wrocław
  • Postów:399
0

@_13th_Dragon nie zrozumiałeś moich intencji. Jak mówiłem: problem jest złożony, i prawdę mówiąc to tu nie chodzi o indeksowanie w tablicach.
Warto dodać, że moja dllka dodatkowo wywołuje funkcje z gry w asmie. Poza tym, kod ma grubo ponad 30 tys linii kodu w C++ i asmie, a więc tu nie chodzi o zabawę w kotka i myszkę.

Mi trzeba ustawienie debuggera w taki sposób, że gdy wykryje, że aktualnie wykonywana instrukcja zapisuje do pamięci wartość 1057770468u to daje mi info gdzie ta instrukcja się znajduje i gdzie tą wartość wpisuje.

Edit:
Warto dodać, że tej wartości u mnie w kodzie oczywiście nie ma. Jakby była to bym tutaj nie przychodził.


Asm/C/C++
edytowany 1x, ostatnio: mwl4
_13th_Dragon
  • Rejestracja:ponad 19 lat
  • Ostatnio:2 miesiące
0

Większość współczesnych debugerów ma czujkę na zmianę obszaru pamięci.
Poza tym masz coś takiego jak valgrid.


Wykonuję programy na zamówienie, pisać na Priv.
Asm/C/C++/Pascal/Delphi/Java/C#/PHP/JS oraz inne języki.
Shalom
Czytaj posty ze zrozumieniem. Przecież napisał ze lokacji w pamięci gdzie moze sie to dziać jest dużo i dlatego szuka czujki na wartość a nie na obszar pamieci...
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

Ja o czymś takim nie słyszałem. Zresztą generowałoby masę false-positive a bardzo możliwe że wcale nie znalazłbyś tego czego szukasz. No bo skąd pewność że akurat jest to nadpisywane jednym zapisem do 4 bajtów? Równie dobrze mogą tam lecieć 4 osobne bajty ;) Ja bym na twoim miejscu spróbował się zastanowić CO to jest za wartość i skąd sie wzięła, inaczej może być ciężko.
(ciekawostka: raptem kilka dni temu był tu temat gdzie autor czytal jednego chara za pomocą scanf("%s do zmiennej typu char i nie zauważył że automatycznie dodawany jest \0 na koniec, co nadpisywało mu pewien wskaźnik... ;) )


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
mwl4
  • Rejestracja:około 12 lat
  • Ostatnio:10 minut
  • Lokalizacja:Wrocław
  • Postów:399
0

Jak powiedziałem: problem w tym, że to jest dllka, a ja kodu gry którą hookuje nie mam. (To chyba proste).
Więc w tym przypadku np. Visual Studio Professional 2013 w którym pracuję oczywiście nic nie wykrywa w Debugu jak i w Releasie.
Poza tym, to może być problem nie w moim kodzie, ale w kodzie gry, w złym wywoływaniu funkcji gry, gdzieś pomylony wskaźnik przy wywoływaniu funkcji gry itd. itd. Tutaj łatwo o błąd gdziekolwiek.

Valgrid mówisz.. tylko czy to mi pomoże. Jak mówię: przydałby mi się jak cholera debugger który śledzi wykonywane instrukcje pod kątem co wpisują do pamięci.

@Shalom, pisałem już, że wyszukiwałem tej wartości w np. Cheat Engine, i widziałem że mało jest tych wartości. A konkretniej to w normalnej grze ich jest jedynie 6 sztuk, a już w podczepionej dllce roi się tego od ch**a, i co najważniejsze w ogóle te wartości się nie zmieniają. Są jedynie przypadki, że nieliczne się zmienią na 0 albo na jakiś normalny rozmiar arraya.
Co do tych 4 bajtów: patrzyłem w ogóle jak wygląda pamięć w obrębie tej zmiennej. Cała pamięć w obrębie jest nadpisana jak nic. Poza tym, znowu te wartości to są floaty od 0.f - 1.f. One się znikąd nie wzięły, tylko pytanie skąd i dlaczego. Namierzenie gdzie się zapisuje ta wartość byłoby super wielkim ułatwieniem.

Edit:

  • wcale nie mówię, że nadpisywanie dzieje się przez mov [], x, być może instrukcje floatowe asma są do tego używane.

Asm/C/C++
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

Ale skad wiesz że to są floaty? Przecież równie dobrze nadpisanie może lecieć z innego miejsca. W tej przytoczonej przeze mnie sytuacji równie dobrze scanf mógł nadpisywać tablicę floatów a przecież wpisywał pojedyncze bajty ;)
Poza tym skoro to nie jest skompilowane z symbolami debugera to co chciałbyś osiągnąć? Zatrzymałby ci sie debuger na jakimś mov w assembly i nadal nie wiedziałbyś gdzie jest bląd ;]
Valgrind powinien przynajmniej wykryć zapis w złym miejscu w pamięci, tzn że ktoś np. pisze za tablicę, ale znów bez kodu albo symboli debugera to niewiele ci to da.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 3x, ostatnio: Shalom
mwl4
  • Rejestracja:około 12 lat
  • Ostatnio:10 minut
  • Lokalizacja:Wrocław
  • Postów:399
0

Uwierz mi, że to są floaty :-) Codzienne rozkodowywanie śmieci dało dużo doświadczenia.
Z tym, że scanfa to ja nigdzie nie mam. Takich funkcji u mnie w kodzie nie ma gdzie wykonywać. To jest tryb MP do gry która takiego trybu nie ma. Nadpisanie leci z trochę wcześniejszego miejsca niż ten size oczywiście. Oczywiście podmienia się również vtabela, wskaźnik na wartości itd. w tym arrayu i trochę bajtów wcześniej i później.
"Poza tym skoro to nie jest skompilowane z symbolami debugera to co chciałbyś osiągnąć? Zatrzymałby ci sie debuger na jakimś mov w assembly i nadal nie wiedziałbyś gdzie jest bląd ;]"
Widzisz, to jest zbyt płytkie myślenie... jeśli wiem gdzie jest ten mov no to wiem jedną rzecz: że to jest w grze albo że to jest w dllce. Jeśli to jest w grze no to patrzę disassemblerem w grę co gdzie się wywołuje, i dochodzę do miejsca w którym ja calluję tą funkcje z tej gry. I wiem gdzie jest błąd. No a jeśli to jest w dllce adres, no to znowu biorę disassemblera, i patrzę w dllce w jakiej funkcji, w której linii kodu nawet. I naprawiam. Tylko, że najpierw trzeba wiedzieć gdzie to się nadpisuje :-).


Asm/C/C++
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

Źle mnie trochę zrozumiałeś ;) Ja po prostu przypuszczam że nawet jakbyś znalazł miejsce gdzie to sie nadpisuje to byłoby to z jakiegoś memcpy() albo innej standardowej funkcji, a bez symboli nie będziesz w zasadzie wiedział skąd została wywołana a w calym kodzie jest wołana wiele razy ;) Niemniej zobacz co ci powie valgrind. On wykryje ci, w teorii, każdy nieuprawniony zapis i odczyt.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 2x, ostatnio: Shalom
mwl4
  • Rejestracja:około 12 lat
  • Ostatnio:10 minut
  • Lokalizacja:Wrocław
  • Postów:399
0

Po to jest callstack, żeby namierzyć. Poza tym, w grze nie używa się memcpy i innych tego typu ciekawych rzeczy.
Wiesz.. to, że nie mam symboli to w zasadzie mi to niewiele przeszkadza. Sporo gry ja mam rozkodowanej, więc dla mnie to żaden problem.
Nie pytam was o to jak z adresu wyciągnąć informacje, tylko jak ten adres zdobyć. To pierwsze jest już moim problemem z którym poradzę sobie w 5 minut.


Asm/C/C++
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

Móże @Bartosz Wójcik albo @Gynvael Coldwind coś będą mogli poradzić :)


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
Bartosz Wójcik
  • Rejestracja:około 14 lat
  • Ostatnio:ponad 4 lata
  • Postów:439
0

Zainteresuj się czymś takim jak tracing warunkowy, oferują to debuggery takie jak OllyDbg. Czyli debugujesz sesję, zakładasz warunek śledzenia, np. gdy wartość rejestru będzie mieć jakąś wartość wtedy przerwij, uruchom tracing i czekaj na rezultaty.

Możesz takie coś osiągnąć także łatwo korzystając ze skryptów ODBScript.

Trudniejszym rozwiązaniem, choć całkiem wykonalnym jest własny debugger na WinApi (jeśli to Windows oczywiście), nie jest to takie trudne, odpalasz śledzenie aplikacji i co krok sprawdzasz stan rejestrów (x86, FPU, MMX, SSE etc.).

Wydaje mi się, że najłatwiejszym rozwiązaniem będą skrypty ODBScript.

Ja bym najpierw też najpierw sprawdził w jaki sposób zapisywane są te dane, czy np. kopiowane z innego rejonu pamięci, z rejestru 32 bitowego, z FPU, a dopiero potem mając tą wiedzę przystąpił do pisania skryptu.

mwl4
  • Rejestracja:około 12 lat
  • Ostatnio:10 minut
  • Lokalizacja:Wrocław
  • Postów:399
0

Valgrind z tego co widzę odpada bo to chyba tylko linux. Ja wszystko muszę robić na Windowsie.

Nad własnym debuggerem również się zastanawiałem jako całkiem dobry pomysł, aczkolwiek sporo pisania, a efekt może być marny bo może to być problem znacznie głębszy niż wygląda. W ollym szukałem jakichś opcji ale nic nie znalazłem, w takim razie sprawdzę ten tracing warunkowy.
Nie sprawdzałem jeszcze w WinDbg czy czegoś nie ma, ale pewnie takich opcji to nie oferuje.

Dobra, dzięki za pomoc. Temat jeszcze nie wyczerpany ale wątpię, że ktokolwiek będzie wiedział więcej.


Asm/C/C++
Bartosz Wójcik
  • Rejestracja:około 14 lat
  • Ostatnio:ponad 4 lata
  • Postów:439
0

Nie znalazłeś, bo od tego jest tracing... Jak inaczej wyobrażasz sobie taką funkcjonalność debuggera? Takie coś można wykryć tylko w momencie zapisywania tej wartości. Skoro nie znasz adresów docelowych pamięci to nie możesz również założyć nigdzie breakpointów na zmianę pamięci (także typu hardware breakpoint).

Mówisz też, że to hack do gry, często są one dobrze zabezpieczane przed analizą i debugowaniem, więc polecam też Phant0m Plugin do ukrywania OllyDbg.

Jeśli ten hack nie jest zabezpieczony to ta cała dyskusja jest też zbędna, gdyż mógłbyś tą wartość znaleźć w samym hacku, bez jakiegoś śledzenia czy tracingu. Wstępna statyczna analiza np. w IDA czasami potrafi zaoszczędzić sporo pracy.

mwl4
Gra nie jest zabezpieczona przed analizą i debugowaniem, więc to nie problem. Co do hacka - to ja go pisałem, więc ja wiem co w nim jest, i w nim jak już mówiłem takiej wartości nie ma. Wstępnie już ogarnąłem co nadpisuje pamięć, teraz tylko głębsza analiza mnie czeka dlaczego to się dzieje.
Shalom
  • Rejestracja:około 21 lat
  • Ostatnio:prawie 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

@mwl4 fajnie byłoby jakbyś podzielił sie później wynikami analizy ;)


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
mwl4
Pamięć była zapisywana przez grę w clone unitu core_camera i innych pochodnych, jakimś cudem w zaalokowanej uprzednio pamięci, czyli array jakimś cudem był wcześniej zwalniany, i przydzielany w klonowaniu, nadpisywany, a ja i tak brałem później ten sam pointer, w którym już były inne dane. No cóż.. trzeba hookować w takim razie systemowe calle RtlAllocateHeap/RtlFreeHeap i sprawdzać jakim cudem pamięć się zwalnia.
Shalom
Czyli pamiętałeś sobie jakieś wskaźniki a gra robiła realokacje a potem znów alokowała ten obszar pamieci? :D To faktycznie ciężka sprawa, bo w takiej sytuacji wykrycie tego nawet valgrindem mogloby być problemem - bo przecież cały czas odwołujesz się do "swojego" bloku pamięci.
mwl4
Może nie tyle realokację tylko pamięć się zwalniała jakimś cudem tego arraya w jakiś piękny sposób, przydzielana była do klonowania, klonowanie nadpisało pamięć i ja już miałem problem, bo ciągle miałem wskaźnik do tego samego obszaru. Teraz tylko szukać jakim sposobem... autorzy gry używają rzecz jasna coś w rodzaju shared pointerów, tylko u nich to się nazywa owner_ptr_t, i to posiada tylko wskaźnik i kiedy jest przydzielany wskaźnik no to w tym obiekcie do którego prowadzi wskaźnik zwiększamy referencję i flagi. Oczywiście do tych ptrów jest klasa podstawowa.
mwl4
I prawdopodobnie w tym tkwi błąd, ja muszę tworzyć obiekty tak jak oni sobie życzą aby to działało i sam muszę obsługiwać referencje i flagi, i pewnie tutaj się coś pieprznęło i pamięć się uwalnia samoistnie w tamtym miejscu.
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)