pojawia sie duzo pytan odnosnie tego czy mozna odzyskac usuniete wiadomosci z archiwum gg, ktore nie zostalo skompaktowane. oto sa nawet 2 sposoby na to. poniewaz nigdzie w sieci nie znalazlem dokladnego opisu tego zagadnienia, postanowilem wkleic opis z jednej stronki ktora znalazlem. opis autorstwa niejakiego Anszoma a strona to:
http://v-lo.krakow.pl/~anszom/ggarch/index.pl.shtml
Niestety nie ma mozliwosci sciagniecia pliku ze zrodlami, moze jednak te informacje posluza komus do napisania malego programiku. Pozdrawiam
Archiwum wiadomości gadu-gadu
Gadu-gadu 5 i starsze przechowywały archiwum w pliku "msgarch.dat". Opis jego struktury znalazłem kiedyś w sieci, a że nie mogę teraz znaleźć tamtej strony to wrzuciłem go tutaj.
Niestety nowsze wersje gg przechowują archiwum w pluku "archives.dat", w zupełnie innym formacie, który (o ile dobrze mi wiadomo) nie został jeszcze nigdzie opisany... Ostatnio chciałem takie archiwum odczytać (klient gg się upierał że nie zaimportuje bo to nie moje archiwum.. miał rację
więc am rozpracowałem format - oto co udało mi się z niego wyciągnąć (wiem, wiem, wystarczy podmienić archives.dat zamiast importować - wtedy gg się nie rzuca o zły uin - chyba...). Tu znajdziesz przykładowy program
Jeśli masz jakieś uwagi/pomysły/cokolwiek - napisz (adres w menu z lewej strony).
Struktura pliku
Plik archives.dat złożony jest z kilku podstawowych części: nagłówka, indeksu i "sekcji danych".
Samo archiwum pod względem "logicznym" jest podzielone na sekcje - nie korzystałem wiele z windowsowego GG więc nie wiem czemu służy ten podział..
Nagłówek jest umieszczony jak się łatwo domyślić na samym początku i zawiera to co zwykle zawierają nagłówki - sumę kontrolną, numer gg właściciela, offsety do pozostałych części pliku, itp..
W indeksie zapisane są nagłówki poszczególnych sekcji. Same sekcje zapisane są w postaci list bloków. W nagłówku sekcji zapisany jest offset do pierwszego bloku (oraz ilość bloków), a w każdym bloku zapisany jest offset do następnego bloku (o ile istnieje). Bloki z kolei zawierają nagłówki wiadomości, które z kolei zawierają wskaźniki do samych wiadomości (które też zawierają dodatkowe informacje) - nie ma to jak prosty format
Aha - wszystko co wymieniłem poza nagłówkami sekcji oraz nagłówkiem pliku siedzi w "sekcji danych" pliku
Nagłówek
Offset rozmiar opis
0x00 4 bajty string "RC03"
0x04 4 bajty ??? - u mnie wynosi 1
0x08 4 bajty offset "indeksu" w pliku
0x0C 4 bajty rozmiar "indeksu" (w bajtach)
0x10 4 bajty rozmiar całego pliku (po co?)
0x14 4 bajty offset "sekcji danych" w pliku
0x18 12 bajtów ??? - u mnie 00 10 00 00 00 10 00 00 00 00 00 00
0x24 4 bajty UIN właściciela XOR 0xFFFFFD66
0x28 4 bajty suma kontrolna
0x2C - koniec -
Na podstawie pola "uin" klient GG sprawdza czy importowane archiwum należy do ciebie.
Suma kontrolna liczona jest standardowym algorytmem CRC-32 z bajtów od początku pliku do początku "sekcji danych" (określony przez pole 0x14 w nagłówku). Przy liczeniu CRC za zawartość pola sumy kontrolnej (0x28) przyjmuje się 0.
Indeks
Indeks zawiera tablicę nagłówków sekcji (ich ilość można obliczyć na podstawie długości indeksu zapisanej w nagłówku pliku): Offset rozmiar opis
0x00 4 bajty numer sekcji
0x04 4 bajty ilość "bloków" tworzących sekcję
0x08 4 bajty offset do pierwszego bloku
0x0C 8 bajtów ??? prawdopodobnie informacje ilości zajętego miejsca
0x14 - koniec -
Numer sekcji powinien odpowiadać jej położeniu w indeksie - jeśli nie, skontaktuj się ze sprzedawcą
albo wymyśl czemu się nie zgadza...
Offset do pierwszego bloku (właściwie każdy offset o którym będę mówił od tego momentu) liczony jest od początku "sekcji danych".
Bloki
Blok składa się z nagłówka bloku oraz tablicy nagłówków wiadomości. Nagłówek bloku wygląda tak: Offset rozmiar opis
0x00 4 bajty suma kontrolna
0x04 4 bajty numer sekcji
0x08 4 bajty długość bloku (w bajtach)
0x0C 4 bajty offset do następnego bloku
0x10 4 bajty ilość "danych" w bloku (w bajtach)
0x14 - koniec -
Suma kontrolna to znów CRC-32 - tym razem wczytuje od 4tego bajtu bloku (czyli tuż za samą sumą) aż do końca bloku (jego długość zapisana jest w polu 0x08).
Numer sekcji powinien się zgadzać z numerem sekcji którą tworzy ten blok - jeśli nie to mamy problem...
Tuż za nagłówkiem zapisana jest tablica nagłówków wiadomości, jej rozmiar określa pole "ilość danych" (0x10) Offset rozmiar opis
0x00 4 bajty flagi?
0x04 4 bajty offset do samej wiadomości
0x08 4 bajty rozmiar wiadomości
0x0C 4 bajty offset do początku bloku
0x10 - koniec -
Pole "flagi" zawiera 1 jeśli wiadomość jest usunięta lub 0 jeśli nie. Niewykluczone że może zawierać też inne informacje... ale na razie nie trafiłem na takie archiwum.
Offset do początku bloku - nie mam pojęcia po co tak marnują miejsce - w każdym razie powinien się zgadzać z offsetem bloku do którego należy ten nagłówek..
Z jakiegoś powodu bloki sekcji nr. 0 nie zawierają prawidłowych nagłówków wiadomości. W archiwach które widziałem wszystkie wiadomości siedza w sekcji nr. 1.
Wiadomości
Sama wiadomość też ma swój nagłówek - inaczej byłoby zbyt łatwo
Wiadomość przychodząca: Offset rozmiar opis
0x00 4 bajty czas wysłania wiadomości
0x04 4 bajty numer nadawcy
0x08 4 bajty zero
0x10 4 bajty czas odebrania wiadomości
0x14 4 bajty długość wiadomości (len)
0x18 [len] bajtów wiadomość
0x18 + [len] - koniec -
Wiadomość wychodząca: Offset rozmiar opis
0x00 4 bajty czas wysłania wiadomości
0x04 4 bajty numer nadawcy
0x08 4 bajty ilość odbiorców
0x10 [n] * 4 bajty numerki odbiorców
0x10 + [n] * 4 4 bajty ??? jakiś czas
0x14 + [n] * 4 4 bajty długość wiadomości (len)
0x18 + [n] * 4 [len] bajtów wiadomość
0x1C + [n] * 4 + [len] - koniec -
Treść wiadomości nie jest oczywiście zapisana bezpośrednio
Odczytujemy ją tak:
out[0] = in[0] xor 0xff
out = in xor in[i-1]
Gdzie in to bajty wiadomości zakodowanej, a out - zdekodowanej.
Mówiąc swoimi słowami każdy bajt jest z-xorowany z poprzednim, a dla pierwszego przyjmujemy że poprzedni = 0xff.
Po zdekodowaniu na końcu wiadomości czasem pojawia się jeden lub więcej bajt 0x00 - ale komu to przeszkadza...
Przykładowe programy
Napisałem kilka prościutkich programów operujących na plikach "archives.dat", ich kod źródłowy można sciągnąć stąd. Aha.. nie próbowałem ich kompilować pod windowsem
ale przy odrobinie dobrej woli powinno się to udać (prawdopodobnie łatwiej będzie pod mingw32 niż msvc).
Krótki opis:
arch_file.h - definiuje struktury danych odpowiadające formatowi pliku
gg.cpp / gg.h - prosta klasa obsługująca odczyt archiwów
crc.cpp / crc.h - nie zgadniesz
main.cpp / ggarch - program wypisujący w "czytelnej" formie zawartość archiwów
a2e.cpp / a2e - program konwertujący archives.dat do formatu archiwów ekg - albo przynajmniej zbliżonego
ggchown.cpp / ggchown - program zmieniający numerek GG właściciela zapisany w pliku archives.dat i poprawiający sumy kontrolne tak, aby klient go "łyknął"
old/crc.* - też nie zgadniesz
old/gg.c - pierwsze podejście do archiwów - program wypisujący różne informacje o pliku
http://v-lo.krakow.pl/~anszom/ggarch/index.pl.shtml
Niestety nie ma mozliwosci sciagniecia pliku ze zrodlami, moze jednak te informacje posluza komus do napisania malego programiku. Pozdrawiam
Archiwum wiadomości gadu-gadu
Gadu-gadu 5 i starsze przechowywały archiwum w pliku "msgarch.dat". Opis jego struktury znalazłem kiedyś w sieci, a że nie mogę teraz znaleźć tamtej strony to wrzuciłem go tutaj.
Niestety nowsze wersje gg przechowują archiwum w pluku "archives.dat", w zupełnie innym formacie, który (o ile dobrze mi wiadomo) nie został jeszcze nigdzie opisany... Ostatnio chciałem takie archiwum odczytać (klient gg się upierał że nie zaimportuje bo to nie moje archiwum.. miał rację
Jeśli masz jakieś uwagi/pomysły/cokolwiek - napisz (adres w menu z lewej strony).
Struktura pliku
Plik archives.dat złożony jest z kilku podstawowych części: nagłówka, indeksu i "sekcji danych".
Samo archiwum pod względem "logicznym" jest podzielone na sekcje - nie korzystałem wiele z windowsowego GG więc nie wiem czemu służy ten podział..
Nagłówek jest umieszczony jak się łatwo domyślić na samym początku i zawiera to co zwykle zawierają nagłówki - sumę kontrolną, numer gg właściciela, offsety do pozostałych części pliku, itp..
W indeksie zapisane są nagłówki poszczególnych sekcji. Same sekcje zapisane są w postaci list bloków. W nagłówku sekcji zapisany jest offset do pierwszego bloku (oraz ilość bloków), a w każdym bloku zapisany jest offset do następnego bloku (o ile istnieje). Bloki z kolei zawierają nagłówki wiadomości, które z kolei zawierają wskaźniki do samych wiadomości (które też zawierają dodatkowe informacje) - nie ma to jak prosty format
Aha - wszystko co wymieniłem poza nagłówkami sekcji oraz nagłówkiem pliku siedzi w "sekcji danych" pliku
Nagłówek
Offset rozmiar opis
0x00 4 bajty string "RC03"
0x04 4 bajty ??? - u mnie wynosi 1
0x08 4 bajty offset "indeksu" w pliku
0x0C 4 bajty rozmiar "indeksu" (w bajtach)
0x10 4 bajty rozmiar całego pliku (po co?)
0x14 4 bajty offset "sekcji danych" w pliku
0x18 12 bajtów ??? - u mnie 00 10 00 00 00 10 00 00 00 00 00 00
0x24 4 bajty UIN właściciela XOR 0xFFFFFD66
0x28 4 bajty suma kontrolna
0x2C - koniec -
Na podstawie pola "uin" klient GG sprawdza czy importowane archiwum należy do ciebie.
Suma kontrolna liczona jest standardowym algorytmem CRC-32 z bajtów od początku pliku do początku "sekcji danych" (określony przez pole 0x14 w nagłówku). Przy liczeniu CRC za zawartość pola sumy kontrolnej (0x28) przyjmuje się 0.
Indeks
Indeks zawiera tablicę nagłówków sekcji (ich ilość można obliczyć na podstawie długości indeksu zapisanej w nagłówku pliku): Offset rozmiar opis
0x00 4 bajty numer sekcji
0x04 4 bajty ilość "bloków" tworzących sekcję
0x08 4 bajty offset do pierwszego bloku
0x0C 8 bajtów ??? prawdopodobnie informacje ilości zajętego miejsca
0x14 - koniec -
Numer sekcji powinien odpowiadać jej położeniu w indeksie - jeśli nie, skontaktuj się ze sprzedawcą
Offset do pierwszego bloku (właściwie każdy offset o którym będę mówił od tego momentu) liczony jest od początku "sekcji danych".
Bloki
Blok składa się z nagłówka bloku oraz tablicy nagłówków wiadomości. Nagłówek bloku wygląda tak: Offset rozmiar opis
0x00 4 bajty suma kontrolna
0x04 4 bajty numer sekcji
0x08 4 bajty długość bloku (w bajtach)
0x0C 4 bajty offset do następnego bloku
0x10 4 bajty ilość "danych" w bloku (w bajtach)
0x14 - koniec -
Suma kontrolna to znów CRC-32 - tym razem wczytuje od 4tego bajtu bloku (czyli tuż za samą sumą) aż do końca bloku (jego długość zapisana jest w polu 0x08).
Numer sekcji powinien się zgadzać z numerem sekcji którą tworzy ten blok - jeśli nie to mamy problem...
Tuż za nagłówkiem zapisana jest tablica nagłówków wiadomości, jej rozmiar określa pole "ilość danych" (0x10) Offset rozmiar opis
0x00 4 bajty flagi?
0x04 4 bajty offset do samej wiadomości
0x08 4 bajty rozmiar wiadomości
0x0C 4 bajty offset do początku bloku
0x10 - koniec -
Pole "flagi" zawiera 1 jeśli wiadomość jest usunięta lub 0 jeśli nie. Niewykluczone że może zawierać też inne informacje... ale na razie nie trafiłem na takie archiwum.
Offset do początku bloku - nie mam pojęcia po co tak marnują miejsce - w każdym razie powinien się zgadzać z offsetem bloku do którego należy ten nagłówek..
Z jakiegoś powodu bloki sekcji nr. 0 nie zawierają prawidłowych nagłówków wiadomości. W archiwach które widziałem wszystkie wiadomości siedza w sekcji nr. 1.
Wiadomości
Sama wiadomość też ma swój nagłówek - inaczej byłoby zbyt łatwo
Wiadomość przychodząca: Offset rozmiar opis
0x00 4 bajty czas wysłania wiadomości
0x04 4 bajty numer nadawcy
0x08 4 bajty zero
0x10 4 bajty czas odebrania wiadomości
0x14 4 bajty długość wiadomości (len)
0x18 [len] bajtów wiadomość
0x18 + [len] - koniec -
Wiadomość wychodząca: Offset rozmiar opis
0x00 4 bajty czas wysłania wiadomości
0x04 4 bajty numer nadawcy
0x08 4 bajty ilość odbiorców
0x10 [n] * 4 bajty numerki odbiorców
0x10 + [n] * 4 4 bajty ??? jakiś czas
0x14 + [n] * 4 4 bajty długość wiadomości (len)
0x18 + [n] * 4 [len] bajtów wiadomość
0x1C + [n] * 4 + [len] - koniec -
Treść wiadomości nie jest oczywiście zapisana bezpośrednio
out[0] = in[0] xor 0xff
out = in xor in[i-1]
Gdzie in to bajty wiadomości zakodowanej, a out - zdekodowanej.
Mówiąc swoimi słowami każdy bajt jest z-xorowany z poprzednim, a dla pierwszego przyjmujemy że poprzedni = 0xff.
Po zdekodowaniu na końcu wiadomości czasem pojawia się jeden lub więcej bajt 0x00 - ale komu to przeszkadza...
Przykładowe programy
Napisałem kilka prościutkich programów operujących na plikach "archives.dat", ich kod źródłowy można sciągnąć stąd. Aha.. nie próbowałem ich kompilować pod windowsem
Krótki opis:
arch_file.h - definiuje struktury danych odpowiadające formatowi pliku
gg.cpp / gg.h - prosta klasa obsługująca odczyt archiwów
crc.cpp / crc.h - nie zgadniesz
main.cpp / ggarch - program wypisujący w "czytelnej" formie zawartość archiwów
a2e.cpp / a2e - program konwertujący archives.dat do formatu archiwów ekg - albo przynajmniej zbliżonego
ggchown.cpp / ggchown - program zmieniający numerek GG właściciela zapisany w pliku archives.dat i poprawiający sumy kontrolne tak, aby klient go "łyknął"
old/crc.* - też nie zgadniesz
old/gg.c - pierwsze podejście do archiwów - program wypisujący różne informacje o pliku