Katılım
20 Aralık 2023
Mesajlar
1.034
Makaleler
20
Çözümler
55
Beğeniler
3.343
Merhaba,

Goley'i bilmeyen yoktur diye düşünüyorum. Bilmeyenler de kısa bir Google araması yaparak ulaşabilir. BGY isimli grupta bu oyun sürekli paylaşılıyor "flood" şeklinde benim de geçen aklıma geldi acaba ne yapabiliriz diye baktım. Tüm süreci adım adım anlatacağım çünkü her aşama kendi içinde ders niteliğinde.

Tam client'ı çıkardım​


buradaki linkten setup dosyasını indirdim.
  • Goley.exe (2.7 MB) > launcher
  • BinaryTr\BinaryTr.bin (8.3 MB) > asıl game code (PE dosyası, sadece .bin uzantısı kamuflaj)
  • BinaryTr\GameGuard\ > anti-cheat (nProtect GameGuard, eski Kore standardı)
  • Data\ ve DataTr\ altında devasa VLH/VLD/VLPH/VLPD dosyaları (toplam yaklaşık 900 MB, hepsi şifreli)
  • GoleyTR.ini > şifreli config dosyası
Engine stack: DirectX 9 + PhysX + Miles Sound System + nProtect GameGuard + MFC native UI. Tipik 2010-2014 Kore MMO stack'i. Yani teknoloji açısından eski ama taş gibi sağlam, modern Win11'de bile launcher'ı açabiliyor.

Network akışını yakaladım​

Goley'i çalıştırıp pktmon ve canlı memory dump kombinasyonu ile launcher'ın ne yaptığını izledim. Çıkan tablo:

Patch sunucusu (HTTP, port 80): http://cdn.joygamedl.com/chagu/Real_Server_Patch/
  • PatchInfo.bin?p=<unix_timestamp> > patch metadata
  • HashV2.VLL?p=<unix_timestamp> > hash verification listesi
  • Goley.exe?p=<unix_timestamp> > self-update için exe karşılaştırması
  • LauncherRestarter.exe?p=<unix_timestamp> > exe replace utility
URL path'inde /chagu/ geçiyor. Korece orijinal ismin izi. cdn.joygamedl.com'un DNS'i ölü ama parent domain joygamedl.com Cloudflare'de hala duruyor.

Launcher arayüzü (HTTPS): https://joygame.com/launchers/cj/goley/
  • "cj" muhtemelen "Chagu Joy" kısaltması
  • Sadece duyuru paneli + nav butonları (statik HTML, AJAX yok)
  • Login formu burada değil, native MFC dialog'da yani (BinaryTr.bin içinde)
Game sunucusu (TCP): 213.74.179.12:2270 (login/auth) + 213.74.179.12:20260 (game/world)
  • Bu IP'nin reverse DNS'i: host-213-74-179-12.superonline.net
  • Yani Joygame Türkiye sunucusunu Superonline'da host etmiş
  • Tabii ki şu an ölü (TCP timeout veriyor), 2018'den beri öyle

Sahte sunucu kurup launcher'ı kandırmaya çalıştım​

hosts dosyasına 127.0.0.1 cdn.joygamedl.com ekleyip port 80'de Python ile basit bir HTTP server kurdum. Launcher gerçekten benim sunucuma istek attı, log'a şöyle düştü:

Kod:
GET /chagu/Real_Server_Patch/PatchInfo.bin?p=1778976811
GET /chagu/Real_Server_Patch/HashV2.VLL?p=1778976811
GET /chagu/Real_Server_Patch/Goley.exe?p=1778976811
GET /chagu/Real_Server_Patch/LauncherRestarter.exe?p=1778976811

User-Agent olarak "Goley" yazıyor. Her seferinde anlık Unix timestamp gönderiyor. Cache-Control: no-cache.

Bu noktada GameGuard araya girdi. hosts dosyası değişikliğini anti-cheat olarak tespit ediyor, oyun açılır açılmaz sessizce kapanıyor.

Memory dump ile içerideki her şeyi açığa çıkardım​


SeDebugPrivilege'i manuel enable edip admin shell'den MiniDumpWriteDump ile 240 MB'lık full memory dump aldım çalışan Goley process'inden. Bu dump göbeği içinde decrypted halde her şey var. Çıkardıklarım:
  • Tüm Goley URL'leri (38 unique)
  • Tüm hostname'ler (12 unique: bill.joygame.com, cdn.joy.ac, promo.joygame.com vs.)
  • Game server IP+port'ları
  • 27 Türkçe UI string'i ("Yama başarısız", "ID/Şifre Girin", "Ana sayfa", "Üye Ol", "Stadyum", "Kart" vs.)
  • Patch flow'unun tam haritası
  • Tam HTTP request örneği (Host header, User-Agent, vs.)
Dump'tan tek bir hata mesajının template'i bile çıktı: "Yama başarısız.\r\nOyunu yeniden çalıştırın.\r\nPatchInfo.bin?p=%d\r\ndosya indirme hatası. Kod (%d)"

Eski launcher HTML'ini Wayback Machine'de buldum.​

15 KB'lık HTML. İçinde Goley'in eski launcher arayüzü tıpkı hatırladığımız gibi: ÜYE OL / JOYPARA / FORUM / SIRALAMA / GÜVENLİK / DESTEK / SSS butonları, "Duyurular" paneli ve sosyal medya linkleri.

Server iskeleti Go ile yazıldı (çalıştığını düşünüyorum)​

Şu an çalışan halde:

Kod:
goley-server/
├── cmd/
│   ├── patch-server/main.go      # Port 80 HTTP cdn.joygamedl.com taklit eder
│   ├── launcher-web/main.go      # Port 8080 joygame.com/launchers/cj/goley/ taklit eder
│   └── login-server/main.go      # Port 2270 + 20260 TCP packet logger
├── internal/common/              # Hexdump, logger
├── web/launcher/index.html       # Wayback Machine'de bulunan launcher HTML
└── scripts/                      # hosts setup, restore, run-all

Bana göre en heyecanlı kısım: Anipark'ın packer'ını kırdım​

İşte burada kafayı yedim. Hem Goley.exe hem BinaryTr.bin packed. Section isimleri rastgele (yehajuci, sidtlktc, wnumgecr, jfsgvjtb), IDA'da sadece 3 fonksiyon görünüyor, hiç string yok, import tablosu 2 fonksiyon (lstrcpy, InitCommonControls) yani gerçek game logic statik analizle okunamıyor.

İlk önce bilinen packer'ları denedim: UPX? Hayır. Themida? Hayır. VMProtect? Hayır. ASPack, ASProtect, WinLicense, FSG, PECompact, Petite, yodaCrypter? Hiçbiri değil. Anipark kendi packer'ını yazmış.

IDA Pro kullanarak ilk entry kısmına baktım:
Kod:
start:
  call sub_197F00B
  int 3              ; debugger trap


Asıl iş sub_197F00B'de. Onu decompile edince algoritma çıktı:

Kod:
sub_197F046(target_addr, 4096, 0x5835B25F, 0x0D971CC0);

int sub_197F046(uint32* ptr, uint size, uint xor_key, uint add_const) {
    for (uint i = size >> 2; i; --i) {
        *ptr ^= 0x5835B25F;        // XOR
        *ptr++ += 0x0D971CC0;      // ADD
    }
}

Yani basit XOR + ADD döngüsü. 4-byte word'ler için. Key'ler sabit: XOR 0x5835B25F, ADD 0x0D971CC0.

Bu cipher'ı Python'da implement edip oyunun ilk 4096 byte'lık şifreli bölgesine uyguladım ve gerçek kod ortaya çıktı.

Stage 2 kodu şöyle görünüyor:

Kod:
sub_18AC000:
  pusha
  jz      loc_18AC072        ; fast path

  ; PE base finder (relocation desteği için)
  call    $+5; pop eax       ; klasik EIP alma trick'i
  and     eax, 0FFFFF000h    ; page align
  cmp     [eax], 'MZ'        ; MZ magic ara
  ...
  cmp     [edx], 'PE'        ; PE magic ara

  ; Stage 3'e atlama
  mov     eax, 17B0014h
  mov     ecx, offset unk_18AC222
  call    sub_18AC0CF        ; <-- STAGE 3 DECRYPTOR

  ; Self-patching (kendi kodunu değiştiriyor)
  mov     [eax+1], ecx
  mov     byte ptr [eax], 0E9h  ; JMP opcode yaz
  popa
  call    sub_18AC0B2        ; <-- STAGE 4, muhtemelen OEP'ye JMP
  retn

Yani packer multi-stage. Birkaç katman var, her biri öbürünü açıyor. Stage 1 stage 2'yi açtı, stage 2 stage 3'ü çağırıyor, stage 3 stage 4'ü açacak, stage 4 muhtemelen OEP'ye JMP atacak.

Tahmin ettiğim üzere, 3-4 stage daha var, sonra OEP'ye ulaşırım. OEP'de 17 MB'lık asıl game code açık halde olacak. VLD/VLH dosyalarının decryption key'i, network packet handler'ları, login protocol falan hepsi orada.

Güncel Durum:

Biten:
  • Recon (URL/IP/port/file format'lar tamamen haritalı)
  • 240 MB memory dump (decrypted strings altın madeni)
  • Patch flow tam haritalı
  • Game server IP onaylı (213.74.179.12, Superonline'da, ölü)
  • Launcher HTML kurtarıldı
  • Go server iskeleti çalışıyor
  • Packer cipher kırıldı, stage 2 deşifre edildi
  • Tüm bulgular doküman halinde
Sırada:
  • Stage 3 + stage 4 + OEP bulma
  • VLD/VLH archive cipher (OEP'den sonra ulaşılabilir)
  • Login packet protokolü (aynı şekilde)
  • GameGuard bypass?
  • Database schema (kullanıcı, kart, takım, sezon, lig tabloları)
  • Match simülasyon engine'i (en zor kısım, oyunun ruhu)
Zor / Belirsiz:
  • Kart havuzunu yeniden oluşturmak (orijinal verilerin VLD'den çıkması lazım)
  • Eski oyuncuların karakter/kart sahipliklerini geri getirmek imkansız (Joygame'in DB'si ölü, kimsenin elinde yok)
  • Lisanslı takım isimleri (Galatasaray, Real Madrid vs.) Jenerik isimler ya da takım rengine göre isim çözümleri lazım
Bu arada, Korece kaynaklarda "차구차구 프리서버" (Chagu Chagu private server) diye aradım hiçbir şey yok. Anipark community RE projesi yok. Magu Magu için bile özel bir RE çalışması bulamadım. Sebebi Korece kaynaklarda yazıldığı gibi lisanslı spor oyunları için özel sunucu kurmak sıkıntlı bi iştir çünkü oyuncu lisansları (futbolcu isimleri vs.) ek bir telif sorunu doğuruyor, bu da topluluğu caydırıyor.

International Soccer Game (ISG) diye bir community projesi Goley'den ilham alarak başlamış ama açık kaynak değil ve son durumu belirsiz. Yani bu projede yalnız ilerliyorum. Bu yüzden buraya yazıyorum.

TLDR;

Şunlardan birinde uzmansan ya da ilgileniyorsan çok yardımcı olursun:
  1. x86 reverse engineering: IDA / Ghidra / x64dbg kullanmasını biliyorsan, packer stage'lerinin kalanını birlikte çözebiliriz. Tek başına yapabilirim ama 2 kişi 3-4 kat hızlı olur.
  2. Go backend: Server iskeleti hazır, üzerine login/lobby/match logic yazılacak.
  3. Eski Goley deneyimi: Kart sistemi, oyuncu seviyeleri, maç akışı nasıldı tam hatırlayan biri lazım dökümantasyon için. Wiki çıkarsak içeriği o belirler.
  4. Web tarafı: Launcher UI'yı modernize etmek eski HTML duruyor ama estetik olması açısından güncellenebilir.
  5. VM uzmanı: Temiz Win10 VM'de GameGuard bypass deneyebilecek biri, server testleri için kritik.
Recon scriptleri, memory dump bulguları, Go server source'u, IDA analiz çıktıları, hepsini yakında bir GitHub repo'sunda public yapacağım. Şu an kod temizliği yapıyorum.

Sorularınızı, önerilerinizi bekliyorum. Özellikle eski Goley oyuncularından "şu özelliği unutma" tarzı katkılar çok iyi olur.

Teşekkür ederim.


Yasal taraf: Bu proje kapanmış bir oyunu hayata döndürme amaçlı, hiçbir ticari kullanım planım yok. Joygame ve Netmarble haklarına saygı duyuyorum, eğer resmi bir itiraz gelirse projeyi tamamiyle kapatırım. Yapıyor olduğum şey "abandonware preservation" kategorisinde server emulation, RetroReversing gibi yıllardır var olan topluluk projeleriyle aynı çizgide. Lisanslı takım isimleri/futbolcu isimleri için jenerik karşılıklar kullanılacak.
 
Son düzenleyen: Moderatör:
Merhaba,

Goley'i bilmeyen yoktur diye düşünüyorum. Bilmeyenler de kısa bir Google araması yaparak ulaşabilir. Bgy isimli grupta bu oyun sürekli paylaşılıyor "flood" şeklinde benim de geçen aklıma geldi acaba ne yapabiliriz diye baktım. Tüm süreci adım adım anlatacağım çünkü her aşama kendi içinde ders niteliğinde.

1) tam Client'ı çıkardım​


Buradaki linkten setup dosyasını indirdim.
  • Goley.exe (2.7 MB) > Launcher.
  • BinaryTr\BinaryTr.bin (8.3 MB) > asıl Game code (pe dosyası, sadece .bin uzantısı kamuflaj)
  • BinaryTr\GameGuard\ > anti-cheat (nprotect gameguard, eski Kore standardı)
  • Data\ ve datatr\ altında devasa VLH/VLD/VLPH/VLPD dosyaları (toplam yaklaşık 900 MB, hepsi şifreli)
  • Goleytr.ini > şifreli Config dosyası.
Engine stack: DirectX 9 + PhysX + miles sound System + nprotect gameguard + mfc native UI. Tipik 2010-2014 Kore MMO Stack'i. Yani teknoloji açısından eski ama taş gibi sağlam, modern Windows 11'de bile Launcher'ı açabiliyor.

2) network akışını yakaladım​

Goley'i çalıştırıp pktmon ve canlı Memory dump kombinasyonu ile Launcher'ın ne yaptığını izledim. Çıkan tablo:

patch sunucusu (HTTP, port 80): http://cdn.joygamedl.com/chagu/Real_Server_Patch/
  • PatchInfo.bin?p=<unix_timestamp> > patch metadata.
  • Hashv2.vll?p=<unix_timestamp> > hash verification listesi.
  • Goley.exe?p=<unix_timestamp> > self-Update için exe karşılaştırması.
  • LauncherRestarter.exe?p=<unix_timestamp> > exe replace Utility.
URL Path'inde /chagu/ geçiyor. Korece orijinal ismin izi. cdn.joygamedl.com'un DNS'i ölü ama parent domain joygamedl.com Cloudflare'de hala duruyor.

Launcher arayüzü (HTTPS): https://joygame.com/launchers/cj/goley/
  • "Cj" muhtemelen "chagu joy" kısaltması.
  • Sadece duyuru paneli + nav butonları (statik HTML, Ajax yok)
  • Login formu burada değil, native mfc Diyalog'da yani (binarytr.bin içinde)
Game sunucusu (TCP): 213.74.179.12:2270 (login/auth) + 213.74.179.12:20260 (game/world)
  • Bu IP'nin reverse DNS'i: host-213-74-179-12.superonline.net
  • Yani Joygame Türkiye sunucusunu Superonline'da host etmiş.
  • Tabii ki şu an ölü (TCP timeout veriyor), 2018'den beri öyle.

3) sahte sunucu kurup Launcher'ı kandırmaya çalıştım​

Hosts dosyasına 127.0.0.1 cdn.joygamedl.com ekleyip port 80'de Python ile basit bir HTTP server kurdum. Launcher gerçekten benim sunucuma istek attı, Log'a şöyle düştü:

Kod:
GET /chagu/Real_Server_Patch/PatchInfo.bin?p=1778976811
GET /chagu/Real_Server_Patch/HashV2.VLL?p=1778976811
GET /chagu/Real_Server_Patch/Goley.exe?p=1778976811
GET /chagu/Real_Server_Patch/LauncherRestarter.exe?p=1778976811

User-agent olarak "goley" yazıyor. Her seferinde anlık UNIX timestamp gönderiyor. Cache-Control: No-cache.

Bu noktada gameguard araya girdi. hosts dosyası değişikliğini anti-cheat olarak tespit ediyor, oyun açılır açılmaz sessizce kapanıyor.

4) Memory dump ile içerideki her şeyi açığa çıkardım​


Sedebugprivilege'i manuel enable edip admin Shell'den minidumpwritedump ile 240 MB'lık Full Memory dump aldım çalışan goley Process'inden. Bu dump göbeği içinde decrypted halde her şey var. Çıkardıklarım:
  • Tüm goley URL'leri (38 unique)
  • Tüm Hostname'ler (12 unique: bill.joygame.com, CDN.joy.AC, promo.joygame.com vs.)
  • Game server IP+port'ları
  • 27 Türkçe UI String'i ("yama başarısız", "ID/Şifre girin", "ana sayfa", "üye ol", "stadyum", "kart" vs.)
  • Patch Flow'unun tam haritası.
  • Tam HTTP request örneği (host header, user-agent, vs.)
Dump'tan tek bir hata mesajının Template'i bile çıktı: "yama başarısız.\r\nOyunu yeniden çalıştırın.\r\nPatchInfo.bin?p=%d\r\ndosya indirme hatası. Kod (%d)"

5) eski Launcher HTML'ini Wayback Machine'de buldum.​

15 KB'lık HTML. İçinde Goley'in eski Launcher arayüzü tıpkı hatırladığımız gibi: Üye ol / joypara / forum / sıralama / güvenlik / destek / SSS butonları, "duyurular" paneli ve sosyal medya linkleri.

6) server iskeleti GO ile yazıldı (çalıştığını düşünüyorum)​

Şu an çalışan halde:

Kod:
goley-server/
├── cmd/
│ ├── patch-server/main.go # Port 80 HTTP cdn.joygamedl.com taklit eder.
│ ├── launcher-web/main.go # Port 8080 joygame.com/launchers/cj/goley/ taklit eder.
│ └── login-server/main.go # Port 2270 + 20260 TCP packet logger.
├── internal/common/ # Hexdump, logger.
├── web/launcher/index.html # Wayback Machine'de bulunan launcher HTML.
└── scripts/ # hosts setup, restore, run-all

7) bana göre en heyecanlı kısım: Anipark'ın Packer'ını kırdım​

İşte burada kafayı yedim. Hem Goley.exe hem binarytr.bin packed. Section isimleri rastgele (yehajuci, sidtlktc, wnumgecr, jfsgvjtb), ıda'da sadece 3 fonksiyon görünüyor, hiç string yok, import tablosu 2 fonksiyon (lstrcpy, InitCommonControls) yani gerçek Game Logic statik analizle okunamıyor.

İlk önce bilinen packer'ları denedim: Upx? Hayır. Themida? Hayır. Vmprotect? Hayır. Aspack, asprotect, winlicense, fsg, pecompact, petite, yodacrypter? Hiçbiri değil. Anipark kendi Packer'ını yazmış.

Ida Pro kullanarak ilk entry kısmına baktım:
Kod:
start:
 call sub_197F00B.
 int 3 ; debugger trap

Asıl iş sub_197F00B'de. Onu decompile edince algoritma çıktı:

Kod:
sub_197F046(target_addr, 4096, 0x5835B25F, 0x0D971CC0);

int sub_197F046(uint32* ptr, uint size, uint xor_key, uint add_const) {
 for (uint i = size >> 2; i; --i) {
 *ptr ^= 0x5835B25F; // XOR.
 *ptr++ += 0x0D971CC0; // ADD.
 }
}

Yani basit xor + add döngüsü. 4-byte Word'ler için. Key'ler sabit: XOR 0x5835B25F, ADD 0x0D971CC0.

Bu Cipher'ı Python'da implement edip oyunun ilk 4096 Byte'lık şifreli bölgesine uyguladım ve gerçek kod ortaya çıktı.

Stage 2 kodu şöyle görünüyor:

Kod:
sub_18AC000:
 pusha.
 jz loc_18AC072 ; fast path.

 ; PE base finder (relocation desteği için)
 call $+5; pop eax ; klasik EIP alma trick'i.
 and eax, 0FFFFF000h ; page align.
 cmp [eax], 'MZ' ; MZ magic ara.
 ...
 cmp [edx], 'PE' ; PE magic ara.

 ; Stage 3'e atlama.
 mov eax, 17B0014h.
 mov ecx, offset unk_18AC222.
 call sub_18AC0CF ; <-- STAGE 3 DECRYPTOR.

 ; Self-patching (kendi kodunu değiştiriyor)
 mov [eax+1], ecx.
 mov byte ptr [eax], 0E9h ; JMP opcode yaz.
 popa.
 call sub_18AC0B2 ; <-- STAGE 4, muhtemelen OEP'ye JMP.
 retn

Yani packer multi-stage. Birkaç katman var, her biri öbürünü açıyor. Stage 1 stage 2'yi açtı, stage 2 stage 3'ü çağırıyor, stage 3 stage 4'ü açacak, stage 4 muhtemelen Oep'ye jmp atacak.

Tahmin ettiğim üzere, 3-4 stage daha var, sonra Oep'ye ulaşırım. Oep'de 17 MB'lık asıl Game code açık halde olacak. VLD/VLH dosyalarının decryption Key'i, network packet handler'ları, login protocol falan hepsi orada.

Güncel durum:

biten:
  • Recon (URL/IP/port/file Format'lar tamamen haritalı)
  • 240 MB Memory dump (decrypted strings altın madeni)
  • Patch Flow tam haritalı.
  • Game server IP onaylı (213.74.179.12, Superonline'da, ölü)
  • Launcher HTML kurtarıldı.
  • GO server iskeleti çalışıyor.
  • packer cipher kırıldı, stage 2 deşifre edildi.
  • Tüm bulgular doküman halinde.
sırada:
  • Stage 3 + stage 4 + oep bulma.
  • VLD/VLH archive cipher (oep'den sonra ulaşılabilir)
  • Login packet protokolü (aynı şekilde)
  • Gameguard bypass?
  • Database schema (kullanıcı, kart, takım, sezon, lig tabloları)
  • Match simülasyon Engine'i (en zor kısım, oyunun ruhu)
zor / belirsiz:
  • Kart havuzunu yeniden oluşturmak (orijinal verilerin Vld'den çıkması lazım)
  • Eski oyuncuların karakter/kart sahipliklerini geri getirmek imkansız (Joygame'in DB'si ölü, kimsenin elinde yok)
  • Lisanslı takım isimleri (Galatasaray, Real Madrid vs.) Jenerik isimler ya da takım rengine göre isim çözümleri lazım.
Bu arada, korece kaynaklarda "차구차구 프리서버" (chagu chagu private server) diye aradım hiçbir şey yok. Anipark community re projesi yok. MAG'u MAG'u için bile özel bir re çalışması bulamadım. Sebebi korece kaynaklarda yazıldığı gibi lisanslı spor oyunları için özel sunucu kurmak sıkıntlı bir iştir çünkü oyuncu lisansları (futbolcu isimleri vs.) Ek bir telif sorunu doğuruyor, bu da topluluğu caydırıyor.

International soccer Game (ısg) diye bir community projesi Goley'den ilham alarak başlamış ama açık kaynak değil ve son durumu belirsiz. Yani bu projede yalnız ilerliyorum. bu yüzden buraya yazıyorum.

Tldr;

Şunlardan birinde uzmansan ya da ilgileniyorsan çok yardımcı olursun:
  1. X86 reverse engineering: ıda / ghidra / X64dbg kullanmasını biliyorsan, packer Stage'lerinin kalanını birlikte çözebiliriz. Tek başına yapabilirim ama 2 kişi 3-4 kat hızlı olur.
  2. GO backend: server iskeleti hazır, üzerine login/lobby/match Logic yazılacak.
  3. eski goley deneyimi: kart sistemi, oyuncu seviyeleri, maç akışı nasıldı tam hatırlayan biri lazım dokümantasyon için. Wiki çıkarsak içeriği o belirler.
  4. web tarafı: Launcher UI'yı modernize etmek eski HTML duruyor ama estetik olması açısından güncellenebilir.
  5. vm uzmanı: temiz Windows 10 Vm'de gameguard bypass deneyebilecek biri, server testleri için kritik.
Recon scriptleri, Memory dump bulguları, GO server Source'u, ıda analiz çıktıları, hepsini yakında bir GitHub repo'sunda public yapacağım. Şu an kod temizliği yapıyorum.

Sorularınızı, önerilerinizi bekliyorum. Özellikle eski goley oyuncularından "şu özelliği unutma" tarzı katkılar çok iyi olur.

Teşekkür ederim.

yasal taraf: bu proje kapanmış bir oyunu hayata döndürme amaçlı, hiçbir ticari kullanım planım yok. Joygame ve netmarble haklarına saygı duyuyorum, eğer resmi bir itiraz gelirse projeyi tamamiyle kapatırım. Yapıyor olduğum şey "abandonware preservation" kategorisinde server emulation, retroreversing gibi yıllardır var olan topluluk projeleriyle aynı çizgide. Lisanslı takım isimleri/futbolcu isimleri için jenerik karşılıklar kullanılacak.


Her ne kadar Goley'i ilk kez duymuş olsam da destekliyorum. Bravo.
 
Oyunda kaç saatim var hatırlamıyorum ama çok güzel bir oyundu Sabri Ugan spikerlik yapıyordu eXtreme serisinden bildiğimiz Hasan Mustan neden yapmadı diye bayağı bir sorgulamıştık :D Tebrik ederim çok güzel bir çalışma. Konudan çok anlamasam bile elimden geleni yapabilirim, yardımcı olmayı çok isterim.
 
Son düzenleme:
Merhaba,

Goley'i bilmeyen yoktur diye düşünüyorum. Bilmeyenler de kısa bir Google araması yaparak ulaşabilir. BGY isimli grupta bu oyun sürekli paylaşılıyor "flood" şeklinde benim de geçen aklıma geldi acaba ne yapabiliriz diye baktım. Tüm süreci adım adım anlatacağım çünkü her aşama kendi içinde ders niteliğinde.

Tam client'ı çıkardım​


buradaki linkten setup dosyasını indirdim.
  • Goley.exe (2.7 MB) > launcher
  • BinaryTr\BinaryTr.bin (8.3 MB) > asıl game code (PE dosyası, sadece .bin uzantısı kamuflaj)
  • BinaryTr\GameGuard\ > anti-cheat (nProtect GameGuard, eski Kore standardı)
  • Data\ ve DataTr\ altında devasa VLH/VLD/VLPH/VLPD dosyaları (toplam yaklaşık 900 MB, hepsi şifreli)
  • GoleyTR.ini > şifreli config dosyası
Engine stack: DirectX 9 + PhysX + Miles Sound System + nProtect GameGuard + MFC native UI. Tipik 2010-2014 Kore MMO stack'i. Yani teknoloji açısından eski ama taş gibi sağlam, modern Win11'de bile launcher'ı açabiliyor.

Network akışını yakaladım​

Goley'i çalıştırıp pktmon ve canlı memory dump kombinasyonu ile launcher'ın ne yaptığını izledim. Çıkan tablo:

Patch sunucusu (HTTP, port 80): http://cdn.joygamedl.com/chagu/Real_Server_Patch/
  • PatchInfo.bin?p=<unix_timestamp> > patch metadata
  • HashV2.VLL?p=<unix_timestamp> > hash verification listesi
  • Goley.exe?p=<unix_timestamp> > self-update için exe karşılaştırması
  • LauncherRestarter.exe?p=<unix_timestamp> > exe replace utility
URL path'inde /chagu/ geçiyor. Korece orijinal ismin izi. cdn.joygamedl.com'un DNS'i ölü ama parent domain joygamedl.com Cloudflare'de hala duruyor.

Launcher arayüzü (HTTPS): https://joygame.com/launchers/cj/goley/
  • "cj" muhtemelen "Chagu Joy" kısaltması
  • Sadece duyuru paneli + nav butonları (statik HTML, AJAX yok)
  • Login formu burada değil, native MFC dialog'da yani (BinaryTr.bin içinde)
Game sunucusu (TCP): 213.74.179.12:2270 (login/auth) + 213.74.179.12:20260 (game/world)
  • Bu IP'nin reverse DNS'i: host-213-74-179-12.superonline.net
  • Yani Joygame Türkiye sunucusunu Superonline'da host etmiş
  • Tabii ki şu an ölü (TCP timeout veriyor), 2018'den beri öyle

Sahte sunucu kurup launcher'ı kandırmaya çalıştım​

hosts dosyasına 127.0.0.1 cdn.joygamedl.com ekleyip port 80'de Python ile basit bir HTTP server kurdum. Launcher gerçekten benim sunucuma istek attı, log'a şöyle düştü:

Kod:
GET /chagu/Real_Server_Patch/PatchInfo.bin?p=1778976811
GET /chagu/Real_Server_Patch/HashV2.VLL?p=1778976811
GET /chagu/Real_Server_Patch/Goley.exe?p=1778976811
GET /chagu/Real_Server_Patch/LauncherRestarter.exe?p=1778976811

User-Agent olarak "Goley" yazıyor. Her seferinde anlık Unix timestamp gönderiyor. Cache-Control: no-cache.

Bu noktada GameGuard araya girdi. hosts dosyası değişikliğini anti-cheat olarak tespit ediyor, oyun açılır açılmaz sessizce kapanıyor.

Memory dump ile içerideki her şeyi açığa çıkardım​


SeDebugPrivilege'i manuel enable edip admin shell'den MiniDumpWriteDump ile 240 MB'lık full memory dump aldım çalışan Goley process'inden. Bu dump göbeği içinde decrypted halde her şey var. Çıkardıklarım:
  • Tüm Goley URL'leri (38 unique)
  • Tüm hostname'ler (12 unique: bill.joygame.com, cdn.joy.ac, promo.joygame.com vs.)
  • Game server IP+port'ları
  • 27 Türkçe UI string'i ("Yama başarısız", "ID/Şifre Girin", "Ana sayfa", "Üye Ol", "Stadyum", "Kart" vs.)
  • Patch flow'unun tam haritası
  • Tam HTTP request örneği (Host header, User-Agent, vs.)
Dump'tan tek bir hata mesajının template'i bile çıktı: "Yama başarısız.\r\nOyunu yeniden çalıştırın.\r\nPatchInfo.bin?p=%d\r\ndosya indirme hatası. Kod (%d)"

Eski launcher HTML'ini Wayback Machine'de buldum.​

15 KB'lık HTML. İçinde Goley'in eski launcher arayüzü tıpkı hatırladığımız gibi: ÜYE OL / JOYPARA / FORUM / SIRALAMA / GÜVENLİK / DESTEK / SSS butonları, "Duyurular" paneli ve sosyal medya linkleri.

Server iskeleti Go ile yazıldı (çalıştığını düşünüyorum)​

Şu an çalışan halde:

Kod:
goley-server/
├── cmd/
│   ├── patch-server/main.go      # Port 80 HTTP cdn.joygamedl.com taklit eder
│   ├── launcher-web/main.go      # Port 8080 joygame.com/launchers/cj/goley/ taklit eder
│   └── login-server/main.go      # Port 2270 + 20260 TCP packet logger
├── internal/common/              # Hexdump, logger
├── web/launcher/index.html       # Wayback Machine'de bulunan launcher HTML
└── scripts/                      # hosts setup, restore, run-all

Bana göre en heyecanlı kısım: Anipark'ın packer'ını kırdım​

İşte burada kafayı yedim. Hem Goley.exe hem BinaryTr.bin packed. Section isimleri rastgele (yehajuci, sidtlktc, wnumgecr, jfsgvjtb), IDA'da sadece 3 fonksiyon görünüyor, hiç string yok, import tablosu 2 fonksiyon (lstrcpy, InitCommonControls) yani gerçek game logic statik analizle okunamıyor.

İlk önce bilinen packer'ları denedim: UPX? Hayır. Themida? Hayır. VMProtect? Hayır. ASPack, ASProtect, WinLicense, FSG, PECompact, Petite, yodaCrypter? Hiçbiri değil. Anipark kendi packer'ını yazmış.

IDA Pro kullanarak ilk entry kısmına baktım:
Kod:
start:
  call sub_197F00B
  int 3              ; debugger trap


Asıl iş sub_197F00B'de. Onu decompile edince algoritma çıktı:

Kod:
sub_197F046(target_addr, 4096, 0x5835B25F, 0x0D971CC0);

int sub_197F046(uint32* ptr, uint size, uint xor_key, uint add_const) {
    for (uint i = size >> 2; i; --i) {
        *ptr ^= 0x5835B25F;        // XOR
        *ptr++ += 0x0D971CC0;      // ADD
    }
}

Yani basit XOR + ADD döngüsü. 4-byte word'ler için. Key'ler sabit: XOR 0x5835B25F, ADD 0x0D971CC0.

Bu cipher'ı Python'da implement edip oyunun ilk 4096 byte'lık şifreli bölgesine uyguladım ve gerçek kod ortaya çıktı.

Stage 2 kodu şöyle görünüyor:

Kod:
sub_18AC000:
  pusha
  jz      loc_18AC072        ; fast path

  ; PE base finder (relocation desteği için)
  call    $+5; pop eax       ; klasik EIP alma trick'i
  and     eax, 0FFFFF000h    ; page align
  cmp     [eax], 'MZ'        ; MZ magic ara
  ...
  cmp     [edx], 'PE'        ; PE magic ara

  ; Stage 3'e atlama
  mov     eax, 17B0014h
  mov     ecx, offset unk_18AC222
  call    sub_18AC0CF        ; <-- STAGE 3 DECRYPTOR

  ; Self-patching (kendi kodunu değiştiriyor)
  mov     [eax+1], ecx
  mov     byte ptr [eax], 0E9h  ; JMP opcode yaz
  popa
  call    sub_18AC0B2        ; <-- STAGE 4, muhtemelen OEP'ye JMP
  retn

Yani packer multi-stage. Birkaç katman var, her biri öbürünü açıyor. Stage 1 stage 2'yi açtı, stage 2 stage 3'ü çağırıyor, stage 3 stage 4'ü açacak, stage 4 muhtemelen OEP'ye JMP atacak.

Tahmin ettiğim üzere, 3-4 stage daha var, sonra OEP'ye ulaşırım. OEP'de 17 MB'lık asıl game code açık halde olacak. VLD/VLH dosyalarının decryption key'i, network packet handler'ları, login protocol falan hepsi orada.

Güncel Durum:

Biten:
  • Recon (URL/IP/port/file format'lar tamamen haritalı)
  • 240 MB memory dump (decrypted strings altın madeni)
  • Patch flow tam haritalı
  • Game server IP onaylı (213.74.179.12, Superonline'da, ölü)
  • Launcher HTML kurtarıldı
  • Go server iskeleti çalışıyor
  • Packer cipher kırıldı, stage 2 deşifre edildi
  • Tüm bulgular doküman halinde
Sırada:
  • Stage 3 + stage 4 + OEP bulma
  • VLD/VLH archive cipher (OEP'den sonra ulaşılabilir)
  • Login packet protokolü (aynı şekilde)
  • GameGuard bypass?
  • Database schema (kullanıcı, kart, takım, sezon, lig tabloları)
  • Match simülasyon engine'i (en zor kısım, oyunun ruhu)
Zor / Belirsiz:
  • Kart havuzunu yeniden oluşturmak (orijinal verilerin VLD'den çıkması lazım)
  • Eski oyuncuların karakter/kart sahipliklerini geri getirmek imkansız (Joygame'in DB'si ölü, kimsenin elinde yok)
  • Lisanslı takım isimleri (Galatasaray, Real Madrid vs.) Jenerik isimler ya da takım rengine göre isim çözümleri lazım
Bu arada, Korece kaynaklarda "차구차구 프리서버" (Chagu Chagu private server) diye aradım hiçbir şey yok. Anipark community RE projesi yok. Magu Magu için bile özel bir RE çalışması bulamadım. Sebebi Korece kaynaklarda yazıldığı gibi lisanslı spor oyunları için özel sunucu kurmak sıkıntlı bi iştir çünkü oyuncu lisansları (futbolcu isimleri vs.) ek bir telif sorunu doğuruyor, bu da topluluğu caydırıyor.

International Soccer Game (ISG) diye bir community projesi Goley'den ilham alarak başlamış ama açık kaynak değil ve son durumu belirsiz. Yani bu projede yalnız ilerliyorum. Bu yüzden buraya yazıyorum.

TLDR;

Şunlardan birinde uzmansan ya da ilgileniyorsan çok yardımcı olursun:
  1. x86 reverse engineering: IDA / Ghidra / x64dbg kullanmasını biliyorsan, packer stage'lerinin kalanını birlikte çözebiliriz. Tek başına yapabilirim ama 2 kişi 3-4 kat hızlı olur.
  2. Go backend: Server iskeleti hazır, üzerine login/lobby/match logic yazılacak.
  3. Eski Goley deneyimi: Kart sistemi, oyuncu seviyeleri, maç akışı nasıldı tam hatırlayan biri lazım dökümantasyon için. Wiki çıkarsak içeriği o belirler.
  4. Web tarafı: Launcher UI'yı modernize etmek eski HTML duruyor ama estetik olması açısından güncellenebilir.
  5. VM uzmanı: Temiz Win10 VM'de GameGuard bypass deneyebilecek biri, server testleri için kritik.
Recon scriptleri, memory dump bulguları, Go server source'u, IDA analiz çıktıları, hepsini yakında bir GitHub repo'sunda public yapacağım. Şu an kod temizliği yapıyorum.

Sorularınızı, önerilerinizi bekliyorum. Özellikle eski Goley oyuncularından "şu özelliği unutma" tarzı katkılar çok iyi olur.

Teşekkür ederim.


Yasal taraf: Bu proje kapanmış bir oyunu hayata döndürme amaçlı, hiçbir ticari kullanım planım yok. Joygame ve Netmarble haklarına saygı duyuyorum, eğer resmi bir itiraz gelirse projeyi tamamiyle kapatırım. Yapıyor olduğum şey "abandonware preservation" kategorisinde server emulation, RetroReversing gibi yıllardır var olan topluluk projeleriyle aynı çizgide. Lisanslı takım isimleri/futbolcu isimleri için jenerik karşılıklar kullanılacak.

Yapın da oynayalım hocam elinize sağlık.
 
Goley Güncellemesi #2 | Cipher kırıldı, Goley'in içinde 5 adet daha dil dosyası varmış.

Önceki postta packer'ı stage 2'ye kadar açtığımı yazmıştım, devamı geldi. Bu kez daha çok ilerleyebildim ancak bazı yerlerde tıkandım.

Anipark'ın VLD/VLH dosyalarını şifrelediği custom cipher'ı çözdüm. Translations.VLH dosyasını açtım. İçinde Goley'in aslında 5 dil için tasarlandığı ortaya çıktı: Korece (orijinal), İngilizce, Endonezce, Çince (Simplified), Türkçe. Joygame sadece TR'yi gösteriyordu, oyun zaten multilingual hazırdı.

VLD content (gerçek text dosyaları) için per-file key derivation hala çıkmadı...

Stage 3 (sub_18AC0CF) için saatlerce manuel decryption yazacağım sandım,
disasm'a baktım:

Kod:
  mov dl, 80h                ; bit accumulator (MSB sentinel)
  add dl, dl
  jnz short loc_18AC0EF
  adc dl, dl                 ; bit reading
  cmp v54, 0x7D00            ; distance threshold
  cmp v54, 0x500
  cmp v54, 0x7F

Bu sayılar tanıdık geldi. 0x7D00, 0x500, 0x7F -> aPLib (Jibz tarafından yazılmış LZSS variant) distance thresholds'ları. Bit accumulator + sentinel pattern de aPLib'in fingerprint'i. Yani stage 3 = decryption değil, decompression. Standart algoritma kullanmışlar.

Bu çok iyi haber çünkü aPLib'i sıfırdan implement etmem gerekmiyor, mevcut çözücüler var.

Sonra fark ettim ki 240 MB memory dump'ı oyun çalışırken almıştım. Yani packer zaten tüm stage'leri bitirmiş, unpacked code RAM'de duruyormuş. Dump'tan çıkarmak, ayrı ayrı stage decrypt etmekten 10 kat daha hızlı.

Yöntem:
  1. Stage 2'nin decrypted bytes signature'ını biliyorum (b8000000 0060 0bc0...)
  2. Bu signature'ı 240MB dump'ta arıyorum (tek bir hit)
  3. Bulduğum offset -> o anki module load base'i hesaplıyorum
  4. Module mapping ile destination region'u dump'tan okuyorum
  5. Stage 3 sonucu zaten orada (252 KB unpacked code)
Bu noktada minidump library ile dump'ı tam parse ettim. Önemli bir bulgu çıktı: BinaryTr.bin module list'te YOK. Sadece Goley.exe loaded module olarak görünüyor.

Yani Goley.exe disk'ten BinaryTr.bin'i okuyup kendi memory'sine manuel kopyalıyor. LoadLibrary kullanmıyor, anti-RE tekniği. Module list temiz görünsün diye.

Sonra Goley.exe için disk vs runtime diff yaptım:
  • Disk: 2.7 MB
  • Runtime: 7.5 MB
  • Fark: 5 MB unpacked code (runtime'da açılan kısım)
İlk PE section (VA 0x401000, 1.66 MB): 254/256 byte FARKLI. Yani disk'te şifreli, runtime'da plain text. Bu region'u dump'tan çıkardım:

goley_real_code.bin -> 1.65 MB plain x86 code
4889 MSVC function prologue (push ebp; mov ebp, esp)
45,526 direct call instruction
Türkçe stringler: "Yama başarısız", "ID/Şifre Girin", "Ana sayfa" vs.

Capstone ile disasm temiz çıktı. Gerçek game logic elimde.

Unpacked code'da string tarayınca şu satır gözüme çarptı:

VolanteEncryptKey_84106141 (VA 0x5769a8)

"Volante" + "Encrypt" + "Key" + 8 haneli numara. Literal hardcoded password. 3 farklı yerde xref var (VA 0x40c7fd, 0x40d1d2, 0x40dbaf).

Korece RE forumlarında "Volante cipher" diye arattım, herhangi bir şey bulamadım.

Password'ün xref'ini takip ettim. Bir hash fonksiyonu çağrılıyor. Onu disasm ettim:

Kod:
  mov dword [ebp-0x5c], 0x67452301
  mov dword [ebp-0x58], 0xefcdab89
  mov dword [ebp-0x54], 0x98badcfe
  mov dword [ebp-0x50], 0x10325476

Bunlar RFC 1321'in MD5 init constants'ı (H0, H1, H2, H3). Yani hash = MD5.

Onu da hızlıca hesapladım:

MD5("VolanteEncryptKey_84106141") = 8f637aa96317a740e2849acce7bebe19

MD5'ten sonra başka bir fonksiyon (0x4194c0) çağrılıyor o da key expansion.

İçinde:

Kod:
  sub edx, 0x61c88647            ; 0x61C88647 = -0x9E3779B9
  lea ebx, [ecx + edi + 0x61c88647]
  add edi, 0x3c6ef373

0x9E3779B9 = floor((√5 - 1)/2 × 2^32). TEA/XTEA ailesinin "golden ratio delta" constant'ı. Bu cipher TEA family'den bir şey.

Kod:
  mov edx, [eax*4 + 0x59e0b0]
  xor edx, [eax*4 + 0x59dcb0]
  xor edx, [eax*4 + 0x59d8b0]
  xor edx, [eax*4 + 0x59d4b0]

4 tane lookup table, her biri 256 entry × 4 byte = 1 KB, toplam 4 KB. Blowfish ailesi F-function pattern'ı.

Yani cipher: 128-bit block + TEA delta + 4 Blowfish tarzı S-box. Standart hiçbir cipher değil. Anipark'ın özel tasarımı.

Biraz daha kurcalayınca, S-box'lar AES T-table tekniği gibi yapılmış olduğunu keşfettim:

Kod:
S3 = ROL16(S1)
S4 = ROL16(S2)

Yani sadece 2 bağımsız S-box var, diğerleri byte rotation ile elde edilmiş. Performance trick'i (Te0..Te3 tarzı). Ama S-box değerleri AES'in standart değerleri DEĞİL.

Encrypt/decrypt fonksiyonları her biri 6-10 KB asm, manuel Python'a çevirmek tehlikeli olduğu için bunun yerine Unicorn engine ile direct CPU emulation yaptım:
  1. goley_real_code.bin'i Unicorn'a load et (base 0x401000)
  2. Stack + heap memory mapping yap
  3. Key schedule fonksiyonunu çalıştır (input: MD5 hash)
  4. Encrypt/decrypt fonksiyonlarını çağır
Round-trip verification:

Kod:
  Plaintext:  "Hello World!!!1\x01"           (16 bytes)
  Encrypt:    1ab3ad512edd7e6d5bdb550aa3cc1be6
  Decrypt:    "Hello World!!!1\x01"           <- EŞLEŞTİ!

Sonra Translations.VLH'yi decrypt ettim. 2800 byte decrypted output:

Kod:
  Data/Translations/Translation_2_SystemMsg_CF.txt
  Data/Translations/Translation_2_SystemMsg_EN.txt
  Data/Translations/Translation_2_SystemMsg_ID.txt
  Data/Translations/Translation_2_SystemMsg_KR.txt
  Data/Translations/Translation_2_SystemMsg_TR.txt
  Data/Translations/Translation_3_UIString_CF.txt
  ...
  Data/Translations/Translation_6_PlayersAndTeams_TR.txt

Sırada:
  • Translations.VLD content açma (per-file key derivation hala net değil, aynı password aynı cipher'la doğrudan çalışmıyor, bir transform daha var)
  • GoleyTR.ini decryption (format farklı, master key tutmadı)
  • Diğer VL pairs: Character, Stadium, UI_Common vs.

Tıkandığım nokta:
VLD content için aynı master password aynı cipher aynı mode'da random output veriyor. Yani VLD'nin per-file key derivation'ı VLH'den farklı. Code'da MD5 incremental update var ama gözlemlediğim tek update sadece VolanteEncryptKey ile beslenmiş, yani VLD muhtemelen ek bir transform veya ikinci bir crypto layer kullanıyor. Bunu izlemek için bir 1-2 saatlik daha trace gerek.

Bir sonraki güncellemede görüşmek üzere!
 
Hocam öncelikler merhabalar. Başlığı gördüğüm gibi içimde bir heyecan oluştu çünkü bu oyun benim çocukluğumun oyunu ve hala açılmasını bir umutla beklediğim bir oyun. Öncelikle oyunun dosyalarını 2021 de internete ben upload etmiştim ki 2-3 farklı setup dosyası ve birtane de bir arkadaşımdan aldıgım dosya vardı. eğer işinize yararsa hala bende mevcut onada bakabilirsiniz. SVG 22 projesinde yer almıştım ama proje birden fazla sebepten dolayı iptal oldu ve projede ben koordinatör olarak yer alıyordum temellerini ben atmıştım.
  1. Eski Goley deneyimi: (Kart sistemi, oyuncu seviyeleri, maç akışı nasıldı tam hatırlayan biri lazım dökümantasyon için. Wiki çıkarsak içeriği o belirler.) Bu konu hakkında size seve seve yardımcı olabileceğimi bilin. Ulaştığınız anda elimden geleni yapmaya hazırım. İyi günler diliyorum
 
Goley Güncellemesi #2 | Cipher kırıldı, Goley'in içinde 5 adet daha dil dosyası varmış.

Önceki postta packer'ı stage 2'ye kadar açtığımı yazmıştım, devamı geldi. Bu kez daha çok ilerleyebildim ancak bazı yerlerde tıkandım.

Anipark'ın VLD/VLH dosyalarını şifrelediği custom cipher'ı çözdüm. Translations.VLH dosyasını açtım. İçinde Goley'in aslında 5 dil için tasarlandığı ortaya çıktı: Korece (orijinal), İngilizce, Endonezce, Çince (Simplified), Türkçe. Joygame sadece TR'yi gösteriyordu, oyun zaten multilingual hazırdı.

VLD content (gerçek text dosyaları) için per-file key derivation hala çıkmadı...

Stage 3 (sub_18AC0CF) için saatlerce manuel decryption yazacağım sandım,
disasm'a baktım:

Kod:
  mov dl, 80h                ; bit accumulator (MSB sentinel)
  add dl, dl
  jnz short loc_18AC0EF
  adc dl, dl                 ; bit reading
  cmp v54, 0x7D00            ; distance threshold
  cmp v54, 0x500
  cmp v54, 0x7F

Bu sayılar tanıdık geldi. 0x7D00, 0x500, 0x7F -> aPLib (Jibz tarafından yazılmış LZSS variant) distance thresholds'ları. Bit accumulator + sentinel pattern de aPLib'in fingerprint'i. Yani stage 3 = decryption değil, decompression. Standart algoritma kullanmışlar.

Bu çok iyi haber çünkü aPLib'i sıfırdan implement etmem gerekmiyor, mevcut çözücüler var.

Sonra fark ettim ki 240 MB memory dump'ı oyun çalışırken almıştım. Yani packer zaten tüm stage'leri bitirmiş, unpacked code RAM'de duruyormuş. Dump'tan çıkarmak, ayrı ayrı stage decrypt etmekten 10 kat daha hızlı.

Yöntem:
  1. Stage 2'nin decrypted bytes signature'ını biliyorum (b8000000 0060 0bc0...)
  2. Bu signature'ı 240MB dump'ta arıyorum (tek bir hit)
  3. Bulduğum offset -> o anki module load base'i hesaplıyorum
  4. Module mapping ile destination region'u dump'tan okuyorum
  5. Stage 3 sonucu zaten orada (252 KB unpacked code)
Bu noktada minidump library ile dump'ı tam parse ettim. Önemli bir bulgu çıktı: BinaryTr.bin module list'te YOK. Sadece Goley.exe loaded module olarak görünüyor.

Yani Goley.exe disk'ten BinaryTr.bin'i okuyup kendi memory'sine manuel kopyalıyor. LoadLibrary kullanmıyor, anti-RE tekniği. Module list temiz görünsün diye.

Sonra Goley.exe için disk vs runtime diff yaptım:
  • Disk: 2.7 MB
  • Runtime: 7.5 MB
  • Fark: 5 MB unpacked code (runtime'da açılan kısım)
İlk PE section (VA 0x401000, 1.66 MB): 254/256 byte FARKLI. Yani disk'te şifreli, runtime'da plain text. Bu region'u dump'tan çıkardım:

goley_real_code.bin -> 1.65 MB plain x86 code
4889 MSVC function prologue (push ebp; mov ebp, esp)
45,526 direct call instruction
Türkçe stringler: "Yama başarısız", "ID/Şifre Girin", "Ana sayfa" vs.

Capstone ile disasm temiz çıktı. Gerçek game logic elimde.

Unpacked code'da string tarayınca şu satır gözüme çarptı:

VolanteEncryptKey_84106141 (VA 0x5769a8)

"Volante" + "Encrypt" + "Key" + 8 haneli numara. Literal hardcoded password. 3 farklı yerde xref var (VA 0x40c7fd, 0x40d1d2, 0x40dbaf).

Korece RE forumlarında "Volante cipher" diye arattım, herhangi bir şey bulamadım.

Password'ün xref'ini takip ettim. Bir hash fonksiyonu çağrılıyor. Onu disasm ettim:

Kod:
  mov dword [ebp-0x5c], 0x67452301
  mov dword [ebp-0x58], 0xefcdab89
  mov dword [ebp-0x54], 0x98badcfe
  mov dword [ebp-0x50], 0x10325476

Bunlar RFC 1321'in MD5 init constants'ı (H0, H1, H2, H3). Yani hash = MD5.

Onu da hızlıca hesapladım:

MD5("VolanteEncryptKey_84106141") = 8f637aa96317a740e2849acce7bebe19

MD5'ten sonra başka bir fonksiyon (0x4194c0) çağrılıyor o da key expansion.

İçinde:

Kod:
  sub edx, 0x61c88647            ; 0x61C88647 = -0x9E3779B9
  lea ebx, [ecx + edi + 0x61c88647]
  add edi, 0x3c6ef373

0x9E3779B9 = floor((√5 - 1)/2 × 2^32). TEA/XTEA ailesinin "golden ratio delta" constant'ı. Bu cipher TEA family'den bir şey.

Kod:
  mov edx, [eax*4 + 0x59e0b0]
  xor edx, [eax*4 + 0x59dcb0]
  xor edx, [eax*4 + 0x59d8b0]
  xor edx, [eax*4 + 0x59d4b0]

4 tane lookup table, her biri 256 entry × 4 byte = 1 KB, toplam 4 KB. Blowfish ailesi F-function pattern'ı.

Yani cipher: 128-bit block + TEA delta + 4 Blowfish tarzı S-box. Standart hiçbir cipher değil. Anipark'ın özel tasarımı.

Biraz daha kurcalayınca, S-box'lar AES T-table tekniği gibi yapılmış olduğunu keşfettim:

Kod:
S3 = ROL16(S1)
S4 = ROL16(S2)

Yani sadece 2 bağımsız S-box var, diğerleri byte rotation ile elde edilmiş. Performance trick'i (Te0..Te3 tarzı). Ama S-box değerleri AES'in standart değerleri DEĞİL.

Encrypt/decrypt fonksiyonları her biri 6-10 KB asm, manuel Python'a çevirmek tehlikeli olduğu için bunun yerine Unicorn engine ile direct CPU emulation yaptım:
  1. goley_real_code.bin'i Unicorn'a load et (base 0x401000)
  2. Stack + heap memory mapping yap
  3. Key schedule fonksiyonunu çalıştır (input: MD5 hash)
  4. Encrypt/decrypt fonksiyonlarını çağır
Round-trip verification:

Kod:
  Plaintext:  "Hello World!!!1\x01"           (16 bytes)
  Encrypt:    1ab3ad512edd7e6d5bdb550aa3cc1be6
  Decrypt:    "Hello World!!!1\x01"           <- EŞLEŞTİ!

Sonra Translations.VLH'yi decrypt ettim. 2800 byte decrypted output:

Kod:
  Data/Translations/Translation_2_SystemMsg_CF.txt
  Data/Translations/Translation_2_SystemMsg_EN.txt
  Data/Translations/Translation_2_SystemMsg_ID.txt
  Data/Translations/Translation_2_SystemMsg_KR.txt
  Data/Translations/Translation_2_SystemMsg_TR.txt
  Data/Translations/Translation_3_UIString_CF.txt
  ...
  Data/Translations/Translation_6_PlayersAndTeams_TR.txt

Sırada:
  • Translations.VLD content açma (per-file key derivation hala net değil, aynı password aynı cipher'la doğrudan çalışmıyor, bir transform daha var)
  • GoleyTR.ini decryption (format farklı, master key tutmadı)
  • Diğer VL pairs: Character, Stadium, UI_Common vs.

Tıkandığım nokta:
VLD content için aynı master password aynı cipher aynı mode'da random output veriyor. Yani VLD'nin per-file key derivation'ı VLH'den farklı. Code'da MD5 incremental update var ama gözlemlediğim tek update sadece VolanteEncryptKey ile beslenmiş, yani VLD muhtemelen ek bir transform veya ikinci bir crypto layer kullanıyor. Bunu izlemek için bir 1-2 saatlik daha trace gerek.

Bir sonraki güncellemede görüşmek üzere!
Oyun photoshoplarında yardımcı olurum hocam.Bu oyunun dönmesi lazım.
 
Hocam öncelikler merhabalar. Başlığı gördüğüm gibi içimde bir heyecan oluştu çünkü bu oyun benim çocukluğumun oyunu ve hala açılmasını bir umutla beklediğim bir oyun. Öncelikle oyunun dosyalarını 2021 de internete ben upload etmiştim ki 2-3 farklı setup dosyası ve birtane de bir arkadaşımdan aldıgım dosya vardı. eğer işinize yararsa hala bende mevcut onada bakabilirsiniz. SVG 22 projesinde yer almıştım ama proje birden fazla sebepten dolayı iptal oldu ve projede ben koordinatör olarak yer alıyordum temellerini ben atmıştım.
  1. Eski Goley deneyimi: (Kart sistemi, oyuncu seviyeleri, maç akışı nasıldı tam hatırlayan biri lazım dökümantasyon için. Wiki çıkarsak içeriği o belirler.) Bu konu hakkında size seve seve yardımcı olabileceğimi bilin. Ulaştığınız anda elimden geleni yapmaya hazırım. İyi günler diliyorum
Bu çok iyi olur. VLD şifrelemesi beni çok zorladı ama onu da kırdım. SVG 22 projesinin dosyaları da varsa çok iyi olur. Birden fazla build, en güncel build hangisi ise onu da paylaşabilirsiniz.

Goley Güncellemesi #3 - Çeviri dosyaları kırıldı, Hakan Şükür geri döndü!

VLD içeriği şifreliydi ve master parolayla açılmıyordu, hatırlarsanız. 25+ farklı türetme denedim hepsi patladı. x64dbg ile canlı debug bile denedim, Themida sürekli işlemi öldürüyordu.

Cevap meğer hep gözümün önündeymiş. Statik analizde fonksiyonu derinlemesine okuyunca anladım: VLH (index dosyası) zaten kendi içinde VLD'nin anahtarını taşıyormuş. İki katmanlı sistem:
  • Binary'de gömülü master parola -> VLH'yi açar
  • VLH'nin ilk 20 byte'ında 16 karakterlik rastgele ASCII parola -> MD5'i VLD'yi açar
  • VLD açılınca art arda dizilmiş zlib stream'leri, her .txt için bir tane
BundleDosyalarKey
Translations
29​
(16-byte ASCII, VLH header'ında)​
Character
1651​
(16-byte ASCII)​

5 paket dosyasının hepsi çözüldü:
  • Translations -> 29 dosya (KR/EN/ID/CF/TR)
  • Character -> 1651 dosya (animasyonlar)
  • CharacterData -> 1269 dosya (3D modeller, doku)
  • Shader -> 33 dosya (.fx shaderları)
  • Stadium -> 119 dosya (top, seyirci, stat ağı)
İlginç bulgular:

Türkçe çeviri tamamen sağlam. "Yetersiz Enerji İçeceği", "Sunucu bağlantısı kesildi. Oyun kapanıyor.", "Takım ismi kullanılıyor" gibi tüm sistem mesajları orada.

Oyuncu listesinde 2002 milli takımı duruyor: KERIMOĞLU.T, ŞÜKÜR.H, BASTÜRK.Y, HAVUTÇU.T, ÖZAT.U, MANSIZ.I, PENBE.E, DAVALA.U, ÇATKIÇ.O, ERCAN.A, ÜNSAL.H eldivenleriyle kalede de var birileri.

Sürpriz olan kısım: Çince çeviri (CF) dosyaları var ama içleri boş. Indekslere bakılırsa Anipark Çin pazarına da çıkmayı planlamış, dosya iskeleti hazırlanmış ama içeriği hiç doldurulmamış.

İsim listesinde bir de Kore lejantları var (LEE.WJ, HYUN.YM, CHOI.SY) orijinal Chagu Chagu kadrosu duruyor demek ki.

Cipher'in encrypt yönü de çalışıyor. Yani sadece okuyamıyoruz, kendi içeriğimizi de paketleyip istemciye yedirebileceğiz. Server emülatör tarafında çok işime yarayacak: PatchInfo.bin'i kendi sunucumuzdan kendi key'imizle imzalayıp göndereceğiz.

Sıradaki adım: Anipark'ın bu özel cipher'ını Unicorn'a bağımlı kalmadan saf Go'ya port etmek, sonra ağ protokolüne dönmek. BinaryTr.bin'i de unpack etmem lazım, asıl protokol mantığı orada.

Türkçe dil dosyaları da ekte.
 

Dosya Ekleri

Son düzenleme:
Bu çok iyi olur. VLD şifrelemesi beni çok zorladı ama onu da kırdım. SVG 22 projesinin dosyaları da varsa çok iyi olur. Birden fazla build, en güncel build hangisi ise onu da paylaşabilirsiniz.

Goley Güncellemesi #3 - Çeviri dosyaları kırıldı, Hakan Şükür geri döndü!

VLD içeriği şifreliydi ve master parolayla açılmıyordu, hatırlarsanız. 25+ farklı türetme denedim hepsi patladı. x64dbg ile canlı debug bile denedim, Themida sürekli işlemi öldürüyordu.

Cevap meğer hep gözümün önündeymiş. Statik analizde fonksiyonu derinlemesine okuyunca anladım: VLH (index dosyası) zaten kendi içinde VLD'nin anahtarını taşıyormuş. İki katmanlı sistem:
  • Binary'de gömülü master parola -> VLH'yi açar
  • VLH'nin ilk 20 byte'ında 16 karakterlik rastgele ASCII parola -> MD5'i VLD'yi açar
  • VLD açılınca art arda dizilmiş zlib stream'leri, her .txt için bir tane
BundleDosyalarKey
Translations


29​


(16-byte ASCII, VLH header'ında)​
Character


1651​


(16-byte ASCII)​

5 paket dosyasının hepsi çözüldü:
  • Translations -> 29 dosya (KR/EN/ID/CF/TR)
  • Character -> 1651 dosya (animasyonlar)
  • CharacterData -> 1269 dosya (3D modeller, doku)
  • Shader -> 33 dosya (.fx shaderları)
  • Stadium -> 119 dosya (top, seyirci, stat ağı)
İlginç bulgular:

Türkçe çeviri tamamen sağlam. "Yetersiz Enerji İçeceği", "Sunucu bağlantısı kesildi. Oyun kapanıyor.", "Takım ismi kullanılıyor" gibi tüm sistem mesajları orada.

Oyuncu listesinde 2002 milli takımı duruyor: KERIMOĞLU.T, ŞÜKÜR.H, BASTÜRK.Y, HAVUTÇU.T, ÖZAT.U, MANSIZ.I, PENBE.E, DAVALA.U, ÇATKIÇ.O, ERCAN.A, ÜNSAL.H eldivenleriyle kalede de var birileri.

Sürpriz olan kısım: Çince çeviri (CF) dosyaları var ama içleri boş. Indekslere bakılırsa Anipark Çin pazarına da çıkmayı planlamış, dosya iskeleti hazırlanmış ama içeriği hiç doldurulmamış.

İsim listesinde bir de Kore lejantları var (LEE.WJ, HYUN.YM, CHOI.SY) orijinal Chagu Chagu kadrosu duruyor demek ki.

Cipher'in encrypt yönü de çalışıyor. Yani sadece okuyamıyoruz, kendi içeriğimizi de paketleyip istemciye yedirebileceğiz. Server emülatör tarafında çok işime yarayacak: PatchInfo.bin'i kendi sunucumuzdan kendi key'imizle imzalayıp göndereceğiz.

Sıradaki adım: Anipark'ın bu özel cipher'ını Unicorn'a bağımlı kalmadan saf Go'ya port etmek, sonra ağ protokolüne dönmek. BinaryTr.bin'i de unpack etmem lazım, asıl protokol mantığı orada.

Türkçe dil dosyaları da ekte.
Tabi hocam elimdeki setup dosyaları ektedir.


SVG 22 için eski ekip arkadaşlarım ile iletişime geçeceğim. Size yardımcı olabileceğim özellikle oyunla ilgili (kart sistemi oyunun mantığı genel yapısı vs) veya sosyal medya PR'ı seve seve yardımcı olurum.

İstediğiniz takdirde sosyal medyadan iletişime geçebiliriz.
 
Son düzenleyen: Moderatör: