Trainer geliştirirken en sık kullandığım yöntemlerden biri AOB Signature.
İlk bakışta biraz karmaşık görünebilir ama mantığı aslında oldukça basit:
Oyundaki bir adresi ezberlemek yerine, o adresin çevresindeki ayırt edici byte dizisini bulup her açılışta tekrar arıyoruz.
Bu sayede oyun bellekte farklı bir yere yüklense bile aradığımız kodu yeniden bulabiliyoruz.
🧠 Önce Sabit Adres Problemini AnlayalımDiyelim oyunda canı azaltan kod şu adreste:
0x7FF6A1234567
İlk testte bu adresi bulduk ve traineri buraya göre hazırladık.
Oyunu kapatıp yeniden açtığımızda aynı kod artık:
0x7FF6B8412390
adresine taşınabilir.
Bu çok normal.
Modern işletim sistemlerinde ve oyunlarda bellek adresleri her çalıştırmada aynı kalmak zorunda değil.
Eğer trainer doğrudan eski adresi kullanıyorsa artık yanlış yere bakar ve özellik çalışmaz.
İşte AOB burada devreye giriyor.
🔎 AOB Ne Demek?AOB, Array of Bytes ifadesinin kısaltması.
Türkçeye kabaca:
Byte Dizisi
diye çevrilebilir.
Bir program çalışırken işlemcinin çalıştırdığı makine kodları bellekte byte'lar halinde bulunur.
Mesela şöyle bir kod düşünün:
48 8B 83 90 01 00 00 48 85 C0 74 0F
Trainer bu byte dizisini oyunun belleğinde arayabilir.
Bulduğunda:
Aradığım kod burada.
diyebilir.
Adres değişmiş olsa bile byte dizisi aynı kaldığı sürece kod tekrar bulunabilir.
🎯 Signature Nedir?Her byte dizisini aramak yeterli değil.
Çünkü seçtiğimiz dizi oyunun belleğinde yüzlerce kez geçebilir.
Bu yüzden mümkün olduğunca benzersiz bir desen seçmeye çalışıyoruz.
İşte buna signature yani imza diyebiliriz.
İyi bir AOB signature'ın amacı şudur:
Oyunda mümkünse yalnızca aradığımız kodu bulmak.
Örneğin:
48 8B 05 12 34 56 78
dizisi oyunda birçok kez bulunabilir.
Ama biraz daha geniş bir desen:
48 8B 05 12 34 56 78 48 85 C0 74 0F 8B 48 20
yalnızca bir yerde bulunabilir.
Bu durumda ikinci desen daha kullanışlıdır.
❓ Peki?? Ne Anlama Geliyor?AOB imzalarında sık sık şöyle şeyler görürsünüz:
48 8B 05 ?? ?? ?? ?? 48 85 C0 74 ??
Buradaki ?? bölümleri wildcard.
Yani:
Burada hangi byte olduğuyla ilgilenmiyorum.
demek.
Bunun önemli bir nedeni var.
Bazı byte'lar adres, offset veya derleme sırasında değişebilecek değerler içerir.
Örneğin:
48 8B 05 12 34 56 78
bir sürümde böyle olabilir.
Yeni sürümde:
48 8B 05 A2 91 45 7C
olabilir.
Eğer bütün byte'ları birebir ararsak imza bozulur.
Ama:
48 8B 05 ?? ?? ?? ??
şeklinde ararsak değişebilecek bölümü görmezden gelmiş oluruz.
Bu da imzayı daha dayanıklı hale getirebilir.
⚠️ Ama Her Şeyi Wildcard YapamayızŞöyle bir imza hazırlarsak:
48 ?? ?? ?? ?? ?? ?? ??
büyük ihtimalle binlerce sonuç buluruz. 😄
Çünkü artık yeterince ayırt edici değildir.
Buradaki iş biraz denge kurmak.
İmza:
yeterince benzersiz,
ama değişebilecek byte'lara karşı da yeterince esnek
olmalı.
İyi AOB hazırlamanın önemli kısmı da burada.
🎮 Basit Bir ÖrnekDiyelim oyunda mermi azaltan kod şu:
89 83 A4 00 00 00 48 8B 5C 24 30
Burada:
A4 00 00 00
bir field offset'i olabilir.
Oyun güncellemesinde geliştirici sınıfa yeni bir alan eklerse bu offset:
A8 00 00 00
olabilir.
Eski imza:
89 83 A4 00 00 00 48 8B 5C 24 30
artık bulunmaz.
Ama baştan:
89 83 ?? ?? ?? ?? 48 8B 5C 24 30
şeklinde hazırladıysak yeni sürümde çalışmaya devam etme ihtimali vardır.
Tabii bu her zaman mümkün değil.
🧩 AOB Sadece Değer Bulmak İçin KullanılmazAOB'yi sadece:
Can değerini bulayım.
diye düşünmemek lazım.
Aslında çoğu zaman AOB ile doğrudan oyunun kodunu buluyoruz.
Örneğin:
can azaltan fonksiyon,
mermi düşüren kod,
stamina tüketen işlem,
item miktarını değiştiren fonksiyon,
oyuncu nesnesine erişen kod,
hareket hızını hesaplayan fonksiyon
bulunabilir.
Daha sonra o noktadan farklı işlemler yapılabilir.
🕳️ AOB + Code CaveORGA Hub trainerlerinde sık kullandığım kombinasyonlardan biri bu.
Önce AOB ile ilgili kod bulunuyor.
Sonra o noktadan bir code cave oluşturuluyor.
Örneğin normal kod:
Oyuncu hasar aldı → canı azalt
şeklinde ilerliyor olabilir.
Biz AOB ile bu kodu bulup akışı kendi kodumuza yönlendirebiliriz.
Kendi tarafımızda:
God Mode açıksa hasarı uygulama.
kontrolünü yaparız.
Sonra oyunun normal koduna geri döneriz.
AOB burada code cave'in nereye yerleştirileceğini bulmak için kullanılmış olur.
🎯 AOB + Pointer CaptureBir başka kullanım alanı oyuncu nesnesini yakalamak.
Diyelim kod:
mov [rcx+120],eax
gibi bir işlem yapıyor.
Burada rcx register'ı o anda gerçek oyuncu nesnesini tutuyor olabilir.
AOB ile bu kodu bulabiliriz.
Daha sonra çalışan fonksiyondan rcx değerini yakalayıp saklayabiliriz.
Artık elimizde:
gerçek player pointer
olur.
Sonrasında aynı nesne üzerinden:
health,
stamina,
hunger,
inventory
gibi alanlara ulaşabiliriz.
Bu yöntem bazı oyunlarda klasik pointer scan'den daha kullanışlı olabiliyor.
🔧 AOB + PatchBazen code cave'e bile gerek yok.
Örneğin oyun şu işlemi yapıyor olabilir:
Enerjiyi azalt.
Bu kodu AOB ile bulup belirli instruction'ları geçici olarak NOP yapmak yeterli olabilir.
Özellik açıldığında patch uygulanır.
Kapatıldığında orijinal byte'lar geri yazılır.
Böylece trainer kapatıldığında oyunun kodu tekrar eski haline döner.
🚀 Neden RVA Yerine AOB?RVA da trainer geliştirmede kullanabileceğimiz bir yöntem.
Örneğin:
Game.exe + 0x123456
şeklinde bir adresimiz olabilir.
ASLR nedeniyle oyunun base adresi değişse bile RVA sayesinde doğru konuma ulaşabiliriz.
Ama problem şu:
Oyun güncellemesi sırasında geliştirici koda birkaç yeni fonksiyon eklerse eski:
0x123456
artık:
0x125A20
olabilir.
RVA değişmiştir.
AOB ise kodun kendisi yeterince benzer kaldığı sürece yeni konumu tekrar bulabilir.
Bu nedenle iyi hazırlanmış bir AOB çoğu durumda düz RVA'dan daha dayanıklı olabilir.
❗ AOB Traineri Güncellemelere Karşı Ölümsüz YapmazBu önemli.
Bazen şöyle bir düşünce oluyor:
AOB kullandıysan oyun güncellense de trainer bozulmaz.
Maalesef öyle değil. 😄
Geliştirici aradığımız fonksiyonu değiştirirse:
instruction'lar değişebilir,
compiler farklı kod üretebilir,
register kullanımı değişebilir,
fonksiyon başka yere taşınabilir,
kod tamamen kaldırılabilir.
Bu durumda AOB signature da bozulur.
Yani AOB'nin avantajı:
güncellemeleri tamamen engellemek değil, gereksiz kırılmaları azaltmak.
🔄 Güncelleme Sonrası Ne Yapıyorum?Bir oyun güncellendiğinde ve bir özellik çalışmamaya başladığında ilk kontrol ettiğim şeylerden biri ilgili AOB imzası.
Eğer sonuç:
0 match
ise imza artık bulunamıyor demektir.
Bu durumda yeni sürümde ilgili fonksiyonu tekrar bulup yeni signature hazırlamak gerekir.
Eğer:
birden fazla match
dönüyorsa imza artık yeterince benzersiz değildir.
Bu durumda da imzayı yeniden düzenlemek gerekir.
İdeal sonuç genellikle:
1 match
olmasıdır.
🧪 Signature Hazırlarken Sadece İlk Çalışan Deseni KullanmıyorumBir signature'ın oyunu bir kere açınca çalışması yeterli değil.
Mümkünse:
oyunu yeniden başlatırım,
farklı save yüklerim,
farklı bölgelere giderim,
traineri birkaç kez açıp kapatırım.
Özellikle signature dinamik bir kod bölgesine denk geldiyse bazı durumlarda beklediğimiz sonucu vermeyebilir.
Amacım mümkün olduğunca gerçekten stabil bir bölge seçmek.
🧠 Motor Bilgisi Burada da İşe YarıyorAOB kullanırken bile oyunun motorunu tanımak avantaj sağlıyor.
Unity Mono kullanan bir oyunda bazı şeyleri doğrudan Mono metadata üzerinden çözebiliyorsam AOB kullanmaya gerek olmayabilir.
Unreal Engine'de property reflection ile ulaşabildiğim bir değer varsa sabit bir kod imzasına bağlanmak gereksiz olabilir.
CryEngine'in kendi CVar sistemi aynı işi yapabiliyorsa oyunun kodunu patchlemek anlamsız olabilir.
Yani benim için AOB:
her sorunun çözümü değil.
Doğru yerde kullanılan araçlardan biri.
🎮 ORGA Hub'da Nerelerde Kullanıyorum?ORGA Hub trainer altyapısında AOB özellikle native memory tarafında oldukça önemli.
Özellikle:
code cave oluştururken,
memory patch uygularken,
çalışma sırasında pointer yakalarken,
oyun fonksiyonlarını bulurken
AOB signature kullanabiliyorum.
The Witcher 3, Death Stranding 2, Schedule I ve diğer native tarafı daha yoğun trainerlerde bu tarz teknikler daha fazla karşımıza çıkıyor.
Ama Unity Mono, Unreal reflection, CryEngine veya Python gibi daha uygun bir runtime erişimi bulunan oyunlarda mümkün olduğunca o sistemlerden de yararlanıyorum.
❤️ Kısaca ÖzetlersekAOB Signature'ın amacı şudur:
Bir adresi değil, o adresi tanımlayan kod desenini bulmak.
Yani:
Sabit adres:
Kod şu adreste.
AOB:
Kodun adresini bilmiyorum ama nasıl göründüğünü biliyorum. Git ve bul.
Trainer açısından bu çok önemli bir fark.
Doğru hazırlandığında oyun yeniden açıldığında ve bazen küçük güncellemelerden sonra bile ilgili fonksiyonu tekrar bulmamızı sağlayabilir.
Ama kötü hazırlanmış bir signature ya hiç sonuç bulur ya da bir sürü yanlış sonuç getirir.
Bu yüzden AOB hazırlamak trainer geliştirmenin basit görünen ama oldukça önemli parçalarından biri.
Bir sonraki konuda da buna çok yakın olan Pointer sistemi ile AOB arasındaki farkı daha net anlatacağım.
Gringos