Trainer geliştirirken bazen sadece bir değeri bulup değiştirmek yeterli olmuyor.
Mesela oyunda can değerini buldunuz ve 999 yaptınız. Güzel.
Ama bazı özelliklerde asıl istediğiniz şey:
Hasar alınmasını tamamen engellemek
Belirli bir fonksiyonun davranışını değiştirmek
Oyuncu nesnesini runtime sırasında yakalamak
Sadece belirli şartlarda kod çalıştırmak
Oyunun hesapladığı bir sonucu değiştirmek
olabiliyor.
İşte burada Code Cave devreye giriyor.
İlk bakışta biraz korkutucu bir konu gibi görünebilir ama mantığı aslında oldukça net.
🕳️ Code Cave Nedir?En basit haliyle Code Cave, oyunun normal kod akışını kısa süreliğine bizim kontrol ettiğimiz başka bir kod alanına yönlendirmek demek.
Normalde oyun şöyle çalışıyor olabilir:
Oyunun kodu → işlemi yap → devam et
Code Cave kullandığımızda ise:
Oyunun kodu → bizim kodumuza git → istediğimiz işlemi yap → oyunun koduna geri dön
şeklinde bir yapı oluşuyor.
Yani oyunun bütün fonksiyonunu baştan yazmıyoruz.
Sadece istediğimiz noktada araya giriyoruz.
🎮 Basit Bir God Mode ÖrneğiDiyelim oyun hasar aldığınızda şöyle bir işlem yapıyor:
Can = Can - Hasar
Buradaki instruction'ı bulduk.
Normal şartlarda düşman bize 30 hasar verdiğinde:
100 - 30 = 70
oluyor.
God Mode yapmak için birkaç farklı yöntem kullanabiliriz.
En kaba yöntemlerden biri can değerini sürekli 100'e yazmak.
Ama bu bazen kötü sonuç verebilir.
Oyun bir anlığına:
Can = 0
yapıp ölüm fonksiyonunu çalıştırdıktan sonra trainer tekrar 100 yazarsa artık çok geç olabilir.
Code Cave ile daha temiz bir yaklaşım kullanabiliriz.
Oyunun hasar koduna araya girip:
God Mode açıksa hasarı uygulama.
Kapalıysa normal kodu çalıştır.
diyebiliriz.
Mantık kabaca:
Hasar fonksiyonu
↓
God Mode açık mı?
↓
Evet → Hasarı atla
Hayır → Normal işlemi yap
↓
Oyunun koduna geri dön
Bu durumda can değerini sürekli spam şeklinde yazmak yerine hasarı kaynağında engellemiş oluruz.
🔀 Oyunun Kodunu Kendi Kodumuza Nasıl Yönlendiriyoruz?Genellikle değiştirmek istediğimiz instruction'ın bulunduğu noktaya bir jump yerleştirilir.
Örneğin oyun normalde:
A
B
C
D
şeklinde ilerliyor olsun.
Biz B noktasına geldiğinde:
JMP CodeCave
diyoruz.
Akış artık:
A
↓
Code Cave
↓
Bizim işlemler
↓
B'de ezdiğimiz orijinal işlemler
↓
C
↓
D
şeklinde devam ediyor.
Buradaki önemli nokta oyunun normal akışını mümkün olduğunca bozmamak.
⚠️ Ezdiğimiz Orijinal Kod Ne Oluyor?Jump yazabilmek için oyunun mevcut instruction'larından birkaç byte'ın üzerine yazmamız gerekiyor.
Bu yüzden ezdiğimiz orijinal instruction'ları çöpe atmıyoruz.
Çoğu durumda onları Code Cave içerisinde tekrar çalıştırıyoruz.
Örneğin orijinal kod:
mov eax,[rcx+120]
sub eax,edx
olsun.
Biz burayı jump ile değiştirdiysek Code Cave içerisinde gerekli koşullar bittikten sonra bu instruction'ları tekrar çalıştırıp oyuna dönmemiz gerekebilir.
Aksi halde yalnızca trainer özelliğini değil oyunun normal davranışını da bozabiliriz.
🔙 Sonra Oyuna Nasıl Dönüyoruz?Code Cave'in sonunda tekrar bir jump kullanıyoruz.
Ama bu kez hedefimiz:
patch yaptığımız kodun hemen sonrası.
Yani:
Oyunun kodu
→ Code Cave
→ Bizim işlemler
→ Orijinal işlemler
→ Return Jump
→ Oyunun devamı
Bu yapıya genel olarak trampoline mantığı da denebilir.
🔎 Code Cave'in Yerini Nasıl Buluyoruz?Burada önceki konuda anlattığımız AOB Signature devreye girebiliyor.
Mesela stamina azaltan instruction'ın her açılışta farklı bir adreste olduğunu düşünelim.
Düz adres kullanmak yerine AOB ile:
F3 0F 11 83 ?? ?? ?? ?? 48 8B
gibi bir kod imzasını arıyoruz.
İmza bulunduğunda trainer:
Code Cave'i buraya bağlayacağım.
diyebiliyor.
Bu yüzden ORGA Hub tarafında:
AOB + Code Cave
birlikte oldukça kullanışlı bir yöntem.
🧠 Code Cave Sadece Kod Değiştirmek İçin DeğilCode Cave'in en güzel taraflarından biri sadece:
Bu instruction'ı değiştireyim.
demek zorunda olmamamız.
Çalışan kodun içindeki register'lara da erişebiliyoruz.
Örneğin:
rcx
register'ı o anda gerçek oyuncu nesnesini tutuyor olabilir.
Bu durumda Code Cave içerisinde:
rcx'i benim ayırdığım alana kaydet.
diyebiliriz.
Artık trainer gerçek oyuncu pointer'ını yakalamış olur.
Buna runtime pointer capture diyebiliriz.
🎯 Player Pointer Yakalama ÖrneğiDiyelim oyuncunun canını güncelleyen kod:
mov [rcx+120], eax
Burada test ettik ve gördük ki:
rcx = Player
Code Cave oluşturuyoruz.
Çalıştığında:
SavedPlayerPointer = rcx
diyoruz.
Daha sonra trainer:
SavedPlayerPointer + 0x120
üzerinden cana,
SavedPlayerPointer + 0x124
üzerinden stamina'ya,
SavedPlayerPointer + 0x128
üzerinden açlığa
ulaşabilir.
Tabii offsetler tamamen örnek.
Ama mantık bu.
Bir tek Code Cave sayesinde aynı nesne üzerindeki birçok özelliği kontrol etmek mümkün olabilir.
🎚️ Trainer Seçeneklerini Code Cave İçinden Kontrol EtmekCode Cave'in bir başka güzel tarafı tek kod içerisinde farklı seçenekleri kontrol edebilmek.
Mesela:
GodModeEnabled
InfiniteStaminaEnabled
DamageMultiplier
gibi trainer tarafından yönetilen değerlerimiz olabilir.
Code Cave çalıştığında bunlara bakabilir.
Örneğin:
GodModeEnabled = 1 ise
→ oyuncuya gelen hasarı engelle.
InfiniteStaminaEnabled = 1 ise
→ stamina tüketimini atla.
Bu durumda kullanıcı checkbox'a bastığında trainer oyunun kodunu tekrar tekrar patchlemek yerine sadece ilgili flag'i değiştirebilir.
⚡ Çarpan Sistemlerinde de KullanılabilirCode Cave sadece:
açık / kapalı
özellikler için kullanılmaz.
Örneğin:
XP Çarpanı
özelliği yapıyoruz.
Oyun normalde:
XP += KazanılanXP
yapıyor.
Code Cave ile:
KazanılanXP = KazanılanXP × TrainerMultiplier
işlemi eklenebilir.
Kullanıcı 2 seçerse:
100 XP → 200 XP
5 seçerse:
100 XP → 500 XP
gibi.
Benzer şekilde:
Para çarpanı
Hasar çarpanı
Kaynak çarpanı
Hız çarpanı
gibi özelliklerde kullanılabilir.
🚀 Teleport Sistemlerinde de İşe YarayabiliyorOyuncu koordinatlarını doğrudan stabil şekilde bulamıyorsak hareket veya pozisyon güncelleme fonksiyonundan pointer yakalayabiliriz.
Mesela oyuncu hareket ettiğinde oyun sürekli:
X
Y
Z
koordinatlarını işliyordur.
Bu koddan gerçek pozisyon nesnesini yakalarsak trainer:
Pozisyon kaydet
Pozisyona geri dön
Teleport
Yukarı/aşağı taşı
gibi işlemleri gerçekleştirebilir.
ORGA Hub'daki bazı native trainerlerde capture ve teleport sistemlerinin birlikte kullanılmasının sebeplerinden biri bu.
🧩 Shared Code Cave Nedir?Bazen aynı kod noktasından birden fazla trainer özelliği faydalanabilir.
Her özellik için ayrı ayrı hook kurmak yerine tek bir Code Cave oluşturup farklı seçenekleri onun içinde yönetmek daha mantıklı olabilir.
Mesela aynı fonksiyon:
Health
Mana
Stamina
değerlerini işliyor olabilir.
Tek cave içinde hangi stat'ın işlendiğini kontrol edip ilgili trainer ayarını uygulayabiliriz.
Bu yaklaşım doğru kullanıldığında daha temiz olabilir.
Ama cave büyüdükçe karmaşıklık da artar.
🛑 NOP ile Code Cave Arasındaki FarkBazen kullanıcıların karıştırdığı bir konu bu.
Örneğin stamina azaltan instruction'ı bulduk.
Çok basitse:
NOP
yapabiliriz.
Yani instruction'ı tamamen etkisiz hale getiririz.
Bu durumda Code Cave'e gerek olmayabilir.
Ama NOP bize sadece:
Bu kodu çalıştırma.
der.
Code Cave ise:
Bu kod çalışmadan önce şu kontrolü yap, şu değeri değiştir, şu pointer'ı kaydet, sonra gerektiğinde orijinal kodu çalıştır.
diyebilmemizi sağlar.
Yani Code Cave çok daha esnek.
🤔 O Zaman Neden Her Şeyde Code Cave Kullanmıyoruz?Çünkü gereksiz.
Bir özellik:
Player + 0x120
değerini 100 yapmak kadar basitse bunun için onlarca instruction'lık cave hazırlamak mantıklı olmayabilir.
Aynı şekilde Unity Mono üzerinden direkt field'a erişebiliyorsak Code Cave'e ihtiyaç olmayabilir.
Ya da CryEngine'in kendi komutu zaten istediğimiz şeyi yapabiliyorsa oyunun kodunu hooklamak gereksiz.
Benim yaklaşımım yine aynı:
Problemi çözmek için en uygun ve en sade yöntemi kullanmak.
⚠️ Code Cave Riskli Bir Teknik mi?Yanlış yapılırsa evet.
Çünkü doğrudan oyunun çalışan makine koduna müdahale ediyoruz.
Örneğin:
Eksik instruction kopyalarsak
Yanlış jump oluşturursak
Register'ları bozarsak
Stack'i yanlış kullanırsak
Dönüş adresini yanlış hesaplarsak
oyun direkt crash olabilir.
Daha kötüsü bazı hatalar hemen crash oluşturmaz.
Oyunun state'ini sessizce bozabilir ve problem birkaç dakika sonra ortaya çıkabilir.
Bu yüzden Code Cave testleri sadece:
Özelliği açtım, çalıştı.
şeklinde yapılmamalı.
🧠 Register'ları Korumak Neden Önemli?CPU register'ları oyunun çalışan kodu için önemlidir.
Biz Code Cave'e girip örneğin:
rax
register'ını kendi hesaplamamız için kullanırsak ve oyunun devamındaki kod o değeri bekliyorsa oyunu bozabiliriz.
Bu yüzden ihtiyaç halinde register'ları saklayıp sonra geri yüklemek gerekiyor.
Aynı durum flags ve stack için de geçerli olabilir.
Bu biraz assembly tarafına giriyor ama Code Cave geliştirirken en kritik konulardan biri.
📏 Instruction Uzunluğu da Önemlix86/x64 instruction'lar sabit uzunlukta değildir.
Bir instruction 2 byte olabilir.
Diğeri 7 byte.
Jump yazmak için belirli miktarda alan gerekiyorsa instruction'ın ortasını kesemeyiz.
Örneğin 7 byte'lık instruction'ın ilk 5 byte'ını ezip son 2 byte'ını bırakmak oyunun artık tamamen anlamsız makine kodu çalıştırmasına neden olabilir.
Bu yüzden hook yerleştirirken instruction sınırlarını doğru hesaplamak gerekiyor.
🔄 Özellik Kapatıldığında Ne Oluyor?İyi bir trainer yalnızca özelliği açabilmemeli.
Temiz şekilde kapatabilmeli de.
Code Cave tabanlı bir özellik kapatıldığında iki yaklaşım kullanılabilir.
Birincisi hook yerinde durur ama trainer flag'i:
0
olduğu için cave normal oyunun davranışını uygular.
İkincisi ise hook tamamen kaldırılır ve oyunun orijinal byte'ları geri yazılır.
Hangisinin daha mantıklı olduğu özelliğe göre değişebilir.
Ama orijinal byte'ların kaybolmaması önemli.
🔄 Oyun Güncellenince Code Cave Neden Bozulabiliyor?Geliştirici patch yaptığımız fonksiyonu değiştirebilir.
Örneğin eski sürüm:
mov eax,[rcx+120]
iken yeni sürüm:
mov eax,[rcx+128]
olabilir.
Daha büyük değişiklikte instruction sırası tamamen değişebilir.
Bu durumda:
AOB signature kırılabilir
Ezilen instruction'ların uzunluğu değişebilir
Register kullanımı değişebilir
Return noktası değişebilir
Dolayısıyla eski Code Cave'i yeni sürüme kör şekilde uygulamak doğru değildir.
İlgili fonksiyonu tekrar incelemek gerekir.
🎮 ORGA Hub'da Code Cave KullanımıORGA Hub'daki trainerlerin özellikle native memory tarafında Code Cave önemli bir yöntem.
Örneğin sistem içerisinde bazı trainerlerde:
Pointer capture
Değer yakalama
Patch mantığı
Teleport verisi yakalama
Fonksiyon davranışını değiştirme
gibi işlemlerde cave tabanlı yöntemlerden yararlanıyorum.
Death Stranding 2, The Witcher 3, Schedule I ve Cyberpunk 2077 gibi oyunlarda klasik memory işlemleriyle birlikte bu tarz yöntemler de bulunuyor.
Ama her trainerde kullanmıyorum.
Örneğin The Sims 4 tarafında Python runtime kullanmak çok daha mantıklı.
Kingdom Come tarafında CryEngine sistemleri var.
Unity Mono oyunlarında bazı işlemleri doğrudan runtime metadata üzerinden yapabiliyorum.
Yani Code Cave benim için güçlü bir araç ama tek araç değil.
❤️ Kısaca ÖzetlersekCode Cave'in temel mantığı:
Oyunun kod akışına kontrollü şekilde gir → kendi işlemini yap → oyunun normal akışına geri dön.
Bu sayede basit bir value freeze'den çok daha gelişmiş şeyler yapılabiliyor.
Özellikle:
God Mode
Hasar engelleme
Çarpanlar
Pointer capture
Teleport
Koşullu patch
Runtime veri yakalama
gibi işlemlerde oldukça kullanışlı.
Ama aynı zamanda trainer geliştirirken dikkat edilmesi gereken en hassas yöntemlerden biri.
Yanlış hazırlanmış bir cave oyunu kolayca çökertebilir.
Doğru hazırlandığında ise oyunun davranışını oldukça kontrollü şekilde değiştirebilmemizi sağlar.
Gringos