Obsługa żądań

https://chacker.pl/

Wykonywanie dowolnego kodu obejmuje dwie operacje: zapisywanie kodu binarnego w pamięci gościa i przekierowywanie przepływu wykonywania do tego obszaru pamięci. Zdefiniujemy żądanie jako listę operacji dowolnego z tych dwóch rodzajów. Jądro przetworzy żądanie, iterując tę ​​listę i stosując każdą operację sekwencyjnie.

Każda operacja pobiera dwa lub więcej elementów z listy: typ operacji i parametry operacji

Po zainicjowaniu komunikacji zaczynamy odbierać żądania zawierające listę operacji. Ważne jest, aby zauważyć, że nie rozróżniamy kompilacji debugowania i wersji wydania, więc wyrażenia wewnątrz assert (1) są zawsze wykonywane. Zaczynamy przetwarzać elementy listy, weryfikując, czy zaczynają się od UInt32 zawierającego prawidłowy OpType (2). Jeśli jest to operacja OpWrite, wywoływana jest funkcja op_write (3). Ta funkcja zużywa dwa kolejne elementy z listy: adres pamięci UInt64 i tablicę. Następnie kopiuje zawartość tablicy do adresu pamięci. W przypadku operacji OpExec wywoływana jest funkcja op_exec (4). Ta funkcja zużywa element UInt64 z listy. Wartość z tego elementu jest rzutowana na wskaźnik funkcji i zostaje wywołana. Gdy którakolwiek z funkcji zwróci wartość, pętla zużywa następną operację i tak dalej, aż do końca listy.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *