programy w .net a crackowanie

0

Zastanawia mnie jedno.

Zalozmy, ze pisze cos w c# .net. Robie jakos zabezpieczenie shareware. Zalozmy, ze klasyczny numerek seryjny.

Skoro kod kompilowany jest najpierw do IL a dopiero w trakcie uruchomienia do konkretnego kodu maszynowego, to jak wyglada crackowanie takiego programu? Oczywiscie z wyjatkiem znalezienia numeru - tylko np. jak zmienic skok warunkowy na bezwarunkowy, skoro tak mozemy zmienic w tym ostatecznym tylko?

Interesuje mnie to glownie, bo za niedlugo bede cos takiego pisal i sie zastanawiam jak bardzo uprzykrzyc zycie crackerom

pozdrawiam
johny

0

Zamieniaj if warunkowy na if bezwarunkowy. :D

0
johny_bravo napisał(a)

jak zmienic skok warunkowy na bezwarunkowy, skoro tak mozemy zmienic w tym ostatecznym tylko?

skad to przekonanie? wystarczy debuger dla IL.

0

skad to przekonanie? wystarczy debuger dla IL.

A sa? To w takim razie zmienia postac rzeczy :P Nie jestem w temacie crackowania, wiec nie znam dostepnym 'narzedzi' :P, ale dobrze wiedziec. Czyli rozumiem, przy budowaniu zabezpieczen obowiazuja te same zasady - im trudniej tym lepiej...

pozdrawiam
johny

0

Można też dokonać dekompilacji [nie mylić z disasemblacji | deasemblacji | łorewa].
Zabezpieczyć przed tym powinien obfuskator?.

0

A co sadzicie o takim zabezpieczeniu, gdzie numer seryjny stanowi integralna czesc aplikacji. Np. po jakims rozkodowaniu to operacja arytmetyczna konieczna do uruchomienia aplikacji. Nie chroni to przed po prostu podaniem swojego numerka innym osobom, ale przynajmniej nie ma porownywania numeru z prawidlowa wersja. No i przydalby sie zbior roznych numerow kodujacych te sama operacje...

pozdrawiam
johny

0

To dla mnie standard - nihil novi.
Bo takie coś:

if (masakryczne_mieszanie(kod_usera) == wynik_masakrycznego_mieszania) {zarejestrowane}

to stara szkoła i totalnie bezużyteczna. Zmiana jednego bajtu [np. 74 -> eb] i cała nasza masakryczna funkcja staje się bezużyteczna.

Dlatego numer jako kawałek algorytmu to lepsze rozwiązanie i żadna innowacja.

0

Hmm... Ze tez nie ma idealnego rozwiazania... :P

Co do tego rozkompilowywania - dziala to bardzo sensownie? W przypadku javy z tego co pamietam calkiem niezle efekty to dawalo, ale IL to nie mam pojecia - pewnie podobnie.

pozdrawiam
johny

0

A czy to tak łatwo znaleźć to masakryczne_mieszanie - zwłaszcza jeśli rozbić to na etapy?
Można to jeszcze rozrzucić w kilku wątkach - wtedy debager nic nie pomoże. :)

0

A czy to tak łatwo znaleźć to masakryczne_mieszanie - zwłaszcza jeśli rozbić to na etapy?
Można to jeszcze rozrzucić w kilku wątkach - wtedy debager nic nie pomoże.

Ooooo... Pare watkow to jest ciekawy pomysl. Co na to specjalista od crackowania? - bo jak widze temat zna od podszewki. Tylko pogratulowac.

Co do szkoly if(mieszanie(kod)==wynik_mieszania) to rzeczywiscie nawet ja to potrafie zcrackowac :P

pozdrawiam
johny

0

Taki sposób:

void getKeys(int haslo=0)
{

TKey p = new TKey(b); // klucz do sprawdzania, czy zarejestrowany

 p.idkey = hash();  // jakieś parametry sprzętu
 p.regkey = czytaj(haslo); // haslo = 0, to czyta je z rejestru - wcześniej zapisane
// teraz obliczam: 

 p.u = mix(p.idkey, p.regkey, 1);
 p.v = mix(p.idkey, p.regkey, 2);
// później będzie sprawdzana zależność między u i v, np.: 2u + v = 567;

 delete globalKey;

 globalKey = p;     // dane zajmują inny obszar pam.
}

// teraz gdzieś dalej: blokowanie opcji w menu, itp.

if( cosik ) getKeys(); // nie musi, ale może zmienić...

TKey &p = globalnyKey;

if( p.u + 2*p.v != cosik ) return; // tak w kilku miejscach programu

// tutaj dojdzie jedynie gdy jest zarejestrowany.

Trudno takie coś rozpracować?

0

No właśnie problem jest w tej linii:

if( p.u + 2*p.v != cosik ) return;

Co prawda nie atakowałem jeszcze programów .NET, ale w zwykłych Win32 wyglądałoby to tak na oko:

mov eax,[pu]
mov ebx,[pv]
shl ebx,1
add eax,ebx
cmp eax,[cosik]
jne dalej
ret
dalej:
...

więc całe to mieszanie (tu p.u+2*p.v) nie ma sensu, jeśli linijkę
jne dalej
zamienię na:
jmp dalej
czyli zmiana 1 bajtu.

To oczywiście bardzo ogólny przykład - ale tak to właśnie wygląda :)
A jeśli więcej jest takich miejsc, to jest kilka podejść:

  1. znaleźć wszystkie takie miejsca i je podmienić
  2. wersja mądrzejsza: wpisać jakieś klucze i zobaczyć, co daje pu+2pv i to wpisać na stałe do 'cosik'
  3. wersja najlepsza: mając 'cosik' możemy obliczyć pu i pv jeśli oczywiście nie są jakoś liczone z serialu funkcją jednostronną (jakiś hash)

Zawsze można złamać program - kwestia, czy czas na to potrzebny jest wart samego programu :)

0

A co powiesz na te watki?
Gdyby zsynchronizowac ich dzialanie, to w kodzie dosc latwo sie polapac, ale czy w assemblerze tez?

Przykladowo jeden watek pobiera zawartosc okienka, drugi pobiera to z tego miejsca w pamieci i przeklada w kilka miejsc, trzeci pobiera z ktoregos z nich i podaje czwartemu. Ten ostatni robi cos z numerkiem (zakladamy, ze ten numerek to wlasnie integralna czesc algorytmu - czyli zly numerek spowoduje nie wykonanie jakiejs metody) i podaje wynik pierwszemu. Zakrecone, ale takie ma byc :P

Fakt, ze kazdy program da sie zlamac, ale nie kazdemu sie chce dlugo siedziec. W tym nasza nadzieja :P

pozdrawiam
johny

0

więc całe to mieszanie (tu p.u+2*p.v) nie ma sensu, jeśli linijkę
jne dalej
zamienię na:
jmp dalej
czyli zmiana 1 bajtu.

Dobra, to dość łatwo można podmienić, co prawda mogę sprawdzać czy kod został zmieniony wcześniej... itd.

Teraz wersja doskonała

robię tak:

PostMessage(hwindow, WM_XYZ, u+2v);

i nie ma tu czego szukać. [!!!]

Ten WM_XYZ w najprostrzym przypadku może być: WM_USER+num,
ale także standardowy komunikat - nawet WM_QUIT. :)
A do tego - to okno, do którego to wyślę, jest w innym wątku! :)

0
wil napisał(a)

Teraz wersja doskonała
Skomentuję tylko ten kawałek: [rotfl] [rotfl]
Sorry, ale nie ma doskonałego zabezpieczenia.

Na więcej chwilowo nie mam czasu. Liczę na odpowiedź Deusa :)

0

Sorry, ale nie ma doskonałego zabezpieczenia.

To jedynie takie hasło dopingowe dla hakera, które chce wmówić także innym.
Później ma ułatwione zadanie - nie można skutecznie zabezpieczyć,
więc szkoda na to czasu - i robimy prowizorkę. :d

0

a widzieliście jakie ścierwo z kodu robi execryptor? imho i tak się da złamać, ale przez uścierwienie kodu nikt nie stosuje...

0
johny_bravo napisał(a)

Przykladowo jeden watek pobiera zawartosc okienka, drugi pobiera to z tego miejsca w pamieci i przeklada w kilka miejsc, trzeci pobiera z ktoregos z nich i podaje czwartemu. Ten ostatni robi cos z numerkiem (zakladamy, ze ten numerek to wlasnie integralna czesc algorytmu - czyli zly numerek spowoduje nie wykonanie jakiejs metody) i podaje wynik pierwszemu. Zakrecone, ale takie ma byc :P

w tym przypadku wystarczy zmienic jeden bajt w tym ostatnim watku (a wlasciwie w procedurze, ktora jest wywolywana jako watek). Oczywiscie wprowadzenie watkow to zawsze jakies zaciemnienie schematu dzialania programu (trzeba sledzic kilka procedur naraz) wiec moim zdaniem mozna z powodzeniem to stosowac.

Mozna tez np. wprowadzic watek sprawdzajacy sume kontrolna kodu, jesli ktos cos zmieni np. rodzaj skoku mozna to wykryc i np. zakonczyc dzialanie programu. Oczywiscie zawsze mozna go "wylaczyc" :> . Ale to moze sprawdzac nastepny watek ;)

0

Program nie może być zbyt dobrze zabezpieczony przed rozpowrzechnianiem.

A. Program bez zabezpieczeń - klient myśli, że to marny towar, dlatego brak zabezp.

B. Program zabezpieczony maksymalnie - tracimy 90% kilentów lub ponosimy olbrzymie nakłady na reklamę.

C. Program średnio zabezpieczony - klient zadowolony a reklama lekko zainicjowana sama się rozkręca - 10% z milionów sztuk sprzedanych, a to wystarczy. :)

Chytry dwa razy traci, a nawet trzy, jeśli mu coś zostanie. :D
Zresztą, dawać zawsze jest przyjemniej niż brać - należy to sprawdzić doświadczalnie!

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