Inżynieria wsteczna AVR, część druga

Beacony na 3 cm i 23 cm nauczyły się już piszczeć nowym znakiem i lokatorem, na placu boju pozostała tylko radiolatarnia na pasmo 13 cm (2,3 GHz). W trakcie dzisiejszego spotkania w klubie, z Pavlem SP3MC przystąpiliśmy do działania.

Sprawa była, a przynajmniej wydawała się być bardziej skomplikowana – mikrokontroler w tym beaconie sterował syntezerem częstotliwości na układzie LMX2320, a nie tylko “kluczował” stopień mocy.

Początek był standardowy – identyfikacja połączeń pomiędzy pinami attiny2313 a złączem goldpin, wpinka programatorem USBasp, odczyt flasha za pomocą avrdude.

Pierwszy, oczywisty rzut oka niestety nie ujawnił żadnych stringów w dumpie. Wytoczyliśmy więc cięższą artylerię w postaci avr-objdump i Ghidry.

Ważną rzeczą było dla nas ustalenie czy kluczowanie CW odbywa się za pomocą sterowania syntezą, czy też jest realizowane na końcówce mocy. Rzut oka na PCB uwidocznił idący do sekcji PA przewód oznaczony jako “PTT”. Za pomocą woltomierza ustawionego w tryb pomiaru przejścia (beeep) szybko ustaliliśmy, że kluczowanie jest realizowane w “analogowy” sposób. Uf!

Analizując zdeasemblowany kod, przez dłuższą chwilę gapiliśmy się na tą sekcję. Jeśli coś miało realizować nadawanie, to musiał być ten fragment, ale w żaden prosty i logiczny sposób nie mogliśmy przełożyć tych instrukcji na CW.

Małym przełomem (z perspektywy czasu aż ciężko uwierzyć że nie wpadliśmy na to od razu) było odkrycie, że cała pierwsza sekcja (0x142 - 0x16c) powtarza się dokładnie od adresu 0x172. Z pewnością jest to fragment odpowiedzialny za nadawanie znaku, a dwie identyczne sekcje rcall niżej – lokatora.

Pozostało rozebrać więc fragment nadający znak na części pierwsze. Wołanych jest 21 funkcji, co jak bardzo dobrze zauważyl Pavel, zgadza się z ilością symboli (kropek i kresek) w telegraficznej reprezentacji ciągu “SR3YOR”. Tak czy siak, telegrafia ma dwa symbole, a wołane są cztery funkcje…

0x228 (A)   .
0x228 (A)   .
0x254 (B)   .
0x228 (A)   .
0x23e (C)   _
0x254 (B)   .
0x228 (A)   .
0x228 (A)   .
0x228 (A)   .
0x23e (C)   _
0x26a (D)   _
0x23e (C)   _
0x228 (A)   .
0x23e (C)   _
0x26a (D)   _
0x23e (C)   _
0x23e (C)   _
0x26a (D)   _
0x228 (A)   .
0x23e (C)   _
0x254 (B)   .

Po rozpisaniu kropek i kresek obok wywołań funkcji szybko staje się widoczne, że funkcja “A” (0x228) nadaje kropkę, a “B” (0x254) kropkę i przerwę pomiędzy literami, analogicznie działają funkcje “C” i “D” dla kresek.

Bogatsi o tą wiedzę (i zaskoczeni pomysłowością autora kodu) przystąpiliśmy do modyfikacji kodu za pomocą hexedytora. Należało zmienić wartości skoków dla instrukcji rcall, tak aby litery w lokatorze układały się w nową wartość. Nie jest to czynność odkrywcza, a wskazówki dostarczane przez avr-objdump wystarczą aby szybko wyliczyć nowe wartości. Przykładowo, spójrzmy na instrukcję:

 15c:   65 d0           rcall   .+202           ;  0x228

Znajduje się ona w pamięci pod adresem 15c, skąd skaczemy pod adres 0x228, czyli:

>>> hex((0x228 - 0x15c)//2)
'0x66'

Uzyskaną wartość 0x66 należy pomniejszyć o jeden i uzyskujemy naszą pożądaną instrukcję maszynową: 65 d0.

Chcąc skoczyć spod tego samego adresu (15c) w inne miejsce, np. 26a, należy obliczyć offset, tak samo jak wyżej:

>>> hex((0x26a - 0x15c)//2-1)
'0x86'

Zamieniamy więc 65 d0 na 86 d0 i pięknie – wywołanie funkcji nadającej kropkę zamieniło się w wywołanie funkcji kreska-z-pauzą. Przy edycji plików HEX należy pamiętać o przeliczeniu checksum na końcu każdej linii. Po zaprogramowaniu procesora zmienionym wsadem zaczął on, oczywiście, nadawać nowy lokator.

/de SQ3SWF

This entry was posted in Bez kategorii. Bookmark the permalink.