Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

[C++] 2 pytania


Rekomendowane odpowiedzi

Opublikowano

Siema, to znowu ja :p mam 2 problemy. Jak zrobic program w c++ ktory bedzie klikal klawisz w co 5 sek. 2 pytanie to jak zrobic program w ktorym bedzie 2 +2 ktos musi wpisac 4 i jak bedzie zkle to wyskoczy popraw sie jak zwrocic tu false.

Opublikowano

I takiego czegoś nie umiesz?

 

#include <Windows.h>
#include <iostream>

void main()
{
    int liczba;
    poczatek:
    std::cout << "2 + 2 = ";
    std::cin >> liczba;
    if(liczba == 4)
        std::cout << "Brawo!!\n";
    else{
        std::cout << "Fail\n";
        goto poczatek;
    }
    return;
}

Nie pomagam na PW, od tego macie forum!!!

 

#PHP-things

 

 

08FMpDu.png

 

Opublikowano

 

I takiego czegoś nie umiesz?

 

#include <Windows.h>
#include <iostream>

void main()
{
    int liczba;
    poczatek:
    std::cout << "2 + 2 = ";
    std::cin >> liczba;
    if(liczba == 4)
        std::cout << "Brawo!!\n";
    else{
        std::cout << "Fail\n";
        goto poczatek;
    }
    return;
}

Poco #include <Windows.h> ?

Opublikowano

 

I takiego czegoś nie umiesz?

 

#include <Windows.h>
#include <iostream>

void main()
{
    int liczba;
    poczatek:
    std::cout << "2 + 2 = ";
    std::cin >> liczba;
    if(liczba == 4)
        std::cout << "Brawo!!\n";
    else{
        std::cout << "Fail\n";
        goto poczatek;
    }
    return;
}

2 błędy kolego. Dopiero teraz sprawdziłem bo przedtem na telefonie siedziałem. zamiast void - int i return 0 :)

Opublikowano

Może po prostu tak ?

 

#include <iostream>

int main()
{
    while(true)
    {
        int liczba;
        std::cout << "2 + 2 = ";
        std::cin >> liczba;
        if(liczba == 4)
        {
            std::cout << "Brawo!!\n";
            return false;
        }else{
            std::cout << "Fail\n";
        }
    }
    int a;
    std::cin >> a;
    return 0;
}
 

 

W dodatku if można zamienić na switch.

brzydkie2_ewareap.png

Opublikowano

2 błędy kolego. Dopiero teraz sprawdziłem bo przedtem na telefonie siedziałem. zamiast void - int i return 0 :)

 

Chciałem tylko pokazać jak to można zrobić :)

I jak już to jeden błąd, void nie może zwracać wartości :)

 

Edit

Zapomniałem dodać wiem, że standardem jest int main() lub int main(arg..), ale w Visualu void przechodzi więc jest prawidłowo :)

Nie pomagam na PW, od tego macie forum!!!

 

#PHP-things

 

 

08FMpDu.png

 

Opublikowano

Ale Ty nic nie zwrociles z tej funkcji przeciez ;) void z returna jest jak najbardziej poprawny. Nie jest to zwrocenie wartosci a po prostu powrot do adresu +1 od adresu gdzie wykonany byl skok funkcji. Taka skladnia byla uzywana raczej w starym c niz c++. Do tego goto to takie assemblerowe rozwiazanie ;p Nie uzywamy tego przy programowaniu wysokopoziomowym, w c++ to jedynie pozostalosc. Standardow jako tako nie ma, do tego malo ktory program uzywa tak na prawde tego return 0 z maina zeby cos sprawdzic. Mozesz pisac void i nie jest to bledem. Wazne zebys byl swiadom kiedy uzyc konstrukcji int main() int main(args...) jesli sa Ci potrzebne.

Opublikowano

 

Może po prostu tak ?

 

#include <iostream>

int main()
{
    while(true)
    {
        int liczba;
        std::cout << "2 + 2 = ";
        std::cin >> liczba;
        if(liczba == 4)
        {
            std::cout << "Brawo!!\n";
            return false;
        }else{
            std::cout << "Fail\n";
        }
    }
    int a;
    std::cin >> a;
    return 0;
}
 

 

W dodatku if można zamienić na switch.

a gdyby tak break? zamiast return false;

Opublikowano

a gdyby tak break? zamiast return false;

Też prawda, po prostu jak ktoś zaczyna to lepiej wziąć całość na logikę, jeśli while istnieje dopóki jest true, to po zwróceniu false przestanie działać. ^_^

brzydkie2_ewareap.png

Opublikowano

Ale Ty nic nie zwrociles z tej funkcji przeciez ;) void z returna jest jak najbardziej poprawny. Nie jest to zwrocenie wartosci a po prostu powrot do adresu +1 od adresu gdzie wykonany byl skok funkcji. Taka skladnia byla uzywana raczej w starym c niz c++. Do tego goto to takie assemblerowe rozwiazanie ;p Nie uzywamy tego przy programowaniu wysokopoziomowym, w c++ to jedynie pozostalosc. Standardow jako tako nie ma, do tego malo ktory program uzywa tak na prawde tego return 0 z maina zeby cos sprawdzic. Mozesz pisac void i nie jest to bledem. Wazne zebys byl swiadom kiedy uzyc konstrukcji int main() int main(args...) jesli sa Ci potrzebne.

 

Co do "I jak już to jeden błąd, void nie może zwracać wartości" tutaj chodziło mi o to że nie można dać return 0; itp.

I nie "powrot do adresu +1 od adresu gdzie był wykonany skok" tylko skok do następnej instrukcji, czyli ze zwykłym call'em to będzie 4-6 bajtów :)

Jak użyjesz pętli to po skompilowaniu będzie wyglądać prawie tak samo co z goto, więc pod względem wydajności różnicy nie będzie.

Ja wolę iść z programowaniem w dół :)

Nie pomagam na PW, od tego macie forum!!!

 

#PHP-things

 

 

08FMpDu.png

 

Opublikowano

ale return nie działa na pętle tylko na funkcje, więc wyłączy cały program i nie uruchomi ostatnich 2linijek zatrzymujących

konsola poza IDE wyłącza się instead więc nikt nie zobaczy "Brawo"(no chyba ze fart, nerd albo wodden pc)

Opublikowano

ale return nie działa na pętle tylko na funkcje, więc wyłączy cały program i nie uruchomi ostatnich 2linijek zatrzymujących

konsola poza IDE wyłącza się instead więc nikt nie zobaczy "Brawo"(no chyba ze fart, nerd albo wodden pc)

Aha, no cóż dzięki :) Nie wiedziałem o tym.

brzydkie2_ewareap.png

Opublikowano

Co do "I jak już to jeden błąd, void nie może zwracać wartości" tutaj chodziło mi o to że nie można dać return 0; itp.

I nie "powrot do adresu +1 od adresu gdzie był wykonany skok" tylko skok do następnej instrukcji, czyli ze zwykłym call'em to będzie 4-6 bajtów :)

Jak użyjesz pętli to po skompilowaniu będzie wyglądać prawie tak samo co z goto, więc pod względem wydajności różnicy nie będzie.

Ja wolę iść z programowaniem w dół :)

Ale zdajesz sobie sprawe ze kazdy program zawiera kilka segmentow? CS,DS,SS itd. W segmencie kodu sa przechowywane instrukcje a zeby bylo wiadomo skad je czytac sa one zapisywane normalnie w pamieci jak wszystko inne. Tak wiec skok oczywiscie ze odbywa sie do adresu +1

 

Dajmy na to mamy cos takiego

00800000 CALL XXX

...

00AFFFFF mov...

00B00000 ret

...

00800004 ... dalsze wykonanie

 

Oczywiscie te adresy i zmiany sa zalezne od instrukcje roznia sie wielkoscia, w sensie ile bajtow jest potrzebne na zapisanie takiej instrukcji. Tak wiec, wbrew pozorom nie jest to skok do nastepnej instrukcji a odczytanie z adresu polozonego krok dalej nastepne instrukcji, a dopiero potem jej wykonanie. Nalezy pamietac ze wszystkie dane sa zapisane w pamieci, maja swoj adres. Dlatego przy np. hookach podmieniamy dane przypisane do adresu, jmp patch podmienia instrukcje w pamieci na far jmp, ktora jak dobrze pamietam potrzebuje wlasnie 5 bajtow na zapisanie.

Opublikowano

Ale zdajesz sobie sprawe ze kazdy program zawiera kilka segmentow? CS,DS,SS itd. W segmencie kodu sa przechowywane instrukcje a zeby bylo wiadomo skad je czytac sa one zapisywane normalnie w pamieci jak wszystko inne. Tak wiec skok oczywiscie ze odbywa sie do adresu +1

 

Dajmy na to mamy cos takiego

00800000 CALL XXX

...

00AFFFFF mov...

00B00000 ret

...

00800004 ... dalsze wykonanie

 

Oczywiscie te adresy i zmiany sa zalezne od instrukcje roznia sie wielkoscia, w sensie ile bajtow jest potrzebne na zapisanie takiej instrukcji. Tak wiec, wbrew pozorom nie jest to skok do nastepnej instrukcji a odczytanie z adresu polozonego krok dalej nastepne instrukcji, a dopiero potem jej wykonanie. Nalezy pamietac ze wszystkie dane sa zapisane w pamieci, maja swoj adres. Dlatego przy np. hookach podmieniamy dane przypisane do adresu, jmp patch podmienia instrukcje w pamieci na far jmp, ktora jak dobrze pamietam potrzebuje wlasnie 5 bajtow na zapisanie.

 

Nie do końca :)

 

Weźmy np

0040131D |. FFD0 CALL EAX
Tak więc ta instrukcja zajmuje 2 bajty. Czyli jak skoczy CALL + 1 to zostanie wywołana instrukcja z adresu 0040131E, dla tego musi pominąć CALL EAX i skacze o 2 bajty dalej.
Co do hooka, długość może mieć nawet i 48 bajtów i tak musi te zabrane bajty gdzieś do pamięci skopiować.
Mamy funkcje(z IDA):

 

00401000                 push    esi
00401001                 mov     esi, [esp+4+size]
00401005                 push    edi
00401006                 mov     edi, [esp+8+Dest]
0040100A                 lea     eax, [esp+8+arg_C]
0040100E                 push    eax 
0040100F                 push    [esp+0Ch+format]
00401013                 push    esi 
00401014                 push    edi
00401015                 call    __vsnprintf
0040101A                 add     esp, 10h
0040101D                 mov     byte ptr [edi+esi-1], 0
00401022                 pop     edi
00401023                 pop     esi
00401024                 retn
 

 

No i zakładamy hooka.

 

00401000                 JMP 00521451
00401005                 NOP ;nie jestem pewny
00401006                 mov     edi, [esp+8+Dest]
0040100A                 lea     eax, [esp+8+arg_C]
0040100E                 push    eax 
0040100F                 push    [esp+0Ch+format]
00401013                 push    esi 
00401014                 push    edi
00401015                 call    __vsnprintf
0040101A                 add     esp, 10h
0040101D                 mov     byte ptr [edi+esi-1], 0
00401022                 pop     edi
00401023                 pop     esi
00401024                 retn
 

 

Nasza funkcja:

 

00521451               rzeczy typu PUSHAD POPAD
....
00521448              JMP 07987450     
 

 

Zaalokowana pamięć na skopiowane instrukcje:

 

 079874560                 push    esi 
 079874561                 mov     esi, [esp+4+size]
 079874565                 push    edi
 079874567                 JMP     00401006
 

 

To jest przykład dla "gołej" (naked) funkcji.

Nie pomagam na PW, od tego macie forum!!!

 

#PHP-things

 

 

08FMpDu.png

 

Opublikowano

Wiem jak dzialaja hooki, nieraz robilem takie rzeczy jak mid function hooking, iat/eat itd. Napisalem nizej wyraznie ze adres w pamiec ktory przechowuje nastepna instrukcje jest zalezny od wielkosci instrukcji. Nie musi to byc +1, jest to jedynie ogolne stwierdzenie. Moze sie okazac ze zostanie wywolany call w stylu jmp near wtedy chyba taki jmp potrzebuje 2b E9 opcode jmp jak dobrze pamietam + adres. Chociaz moze przyjac rozne argumenty BYTE,WORD. Far jmp potrzebuje akurat 5b wiec, albo bierzemy tyle z instrukcji, albo wiecej i podmieniamy je. Mi chodzilo o pokazanie ze nie jest to po prostu skok do nastepnej instrukcji, bo widze, sam wiesz ze te dane sa przechowywane normalnie w segmencie kodu pod danymi adresami i skok odbywa sie z powrotem pod pewien adres gdzie sa te instrukcje przechowywane. Do tego wszystko jest zalezne od konwencji wywolania czy jest to stdcall czy fastcall itp. Czy funkcja sama musi posprzatac po sobie czy nie. Duzo teoretycznych pierdol, ktore i tak wiekszosci tutaj sie nie przydadza, bo nie kodza takich rzeczy.

Opublikowano

Zwracam honor, trochę zaspany byłem wtedy. Nie łatwiej napisać że procesor wywołuje instrukcje po kolei?
Spotka CALL,a ładuje rejestry do stosu, skacze do podanego adresu, po ret wraca do następnej instrukcji.

Nie pomagam na PW, od tego macie forum!!!

 

#PHP-things

 

 

08FMpDu.png

 

Opublikowano

Chciałem tylko pokazać jak to można zrobić :)

I jak już to jeden błąd, void nie może zwracać wartości :)

 

Edit

Zapomniałem dodać wiem, że standardem jest int main() lub int main(arg..), ale w Visualu void przechodzi więc jest prawidłowo :)

a ja mam code::block , a int main ( arg.. ) wystepuje jezeli sie programuje w jezyku C

 

Ale Ty nic nie zwrociles z tej funkcji przeciez ;) void z returna jest jak najbardziej poprawny. Nie jest to zwrocenie wartosci a po prostu powrot do adresu +1 od adresu gdzie wykonany byl skok funkcji. Taka skladnia byla uzywana raczej w starym c niz c++. Do tego goto to takie assemblerowe rozwiazanie ;p Nie uzywamy tego przy programowaniu wysokopoziomowym, w c++ to jedynie pozostalosc. Standardow jako tako nie ma, do tego malo ktory program uzywa tak na prawde tego return 0 z maina zeby cos sprawdzic. Mozesz pisac void i nie jest to bledem. Wazne zebys byl swiadom kiedy uzyc konstrukcji int main() int main(args...) jesli sa Ci potrzebne.

tylko jak pisze void to code::block nie kompiluje ;)

Opublikowano

a int main ( arg.. ) wystepuje jezeli sie programuje w jezyku C

nie

 

tylko jak pisze void to code::block nie kompiluje ;)

bo c++ jest kompatybilny wstecz z C

Opublikowano

a int main ( arg.. ) wystepuje jezeli sie programuje w jezyku C

 

Nie chce nic mówić ale C był tworzony z myślą o mikroprocesorach, a tam argumenty w mainie raczej nie potrzebne :)

Nie pomagam na PW, od tego macie forum!!!

 

#PHP-things

 

 

08FMpDu.png

 

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

×
×
  • Dodaj nową pozycję...