Unreal Engine Reflection Nedir? ORGA Hub’da Subnautica 2 Trainerinde Nasıl Kullanıyorum?

Araç & yöntem #unreal-engine#reflection#subnautica-2#trainer-gelistirme#orga-hub 0 cevap 18 okunma

Unity Mono tarafını anlattıktan sonra ORGA Hub’da kullandığım bir diğer ilginç sisteme geçelim: Unreal Engine Reflection.

Özellikle Unreal Engine kullanan oyunlarda her şeyi sabit adresler, pointer zincirleri veya tek tek AOB imzalarıyla çözmek zorunda değiliz.

Unreal Engine kendi içerisinde nesneleri, sınıfları ve property’leri tanımlayan oldukça geniş bir runtime yapısına sahip.

Eğer bu yapıya doğru şekilde ulaşabilirsek bazı değerleri:

Player + 0x3A8

gibi anlamsız bir offset üzerinden değil,

Şu sınıftaki şu property

mantığıyla bulabiliriz.

ORGA Hub’da Subnautica 2 traineri için geliştirdiğim sistem de büyük ölçüde bu mantıktan faydalanıyor.

🟪 Önce Unreal Engine Reflection Nedir?

Reflection kelimesini basitçe:

Programın çalışma sırasında kendi yapısı hakkında bilgi verebilmesi

şeklinde düşünebilirsiniz.

Unreal Engine içerisinde sınıflar, nesneler ve property’lerle ilgili metadata bulunuyor.

Örneğin oyun tarafında şöyle bir yapı olduğunu düşünelim:

PlayerCharacter

ve bunun içerisinde:

Health

Oxygen

MovementSpeed

gibi property’ler var.

Klasik memory trainer yaklaşımında bunların adreslerini ve offsetlerini tek tek bulmaya çalışabiliriz.

Reflection tarafında ise uygun yapıya ulaşabilirsek:

PlayerCharacter içerisindeki Health property’sini bul.

gibi çok daha anlamlı bir yaklaşım kullanabiliriz.

🧠 Neden Bu Kadar Değerli?

Çünkü sabit offsetler her zaman stabil değil.

Örneğin eski sürümde:

Health = Player + 0x2F0

olsun.

Geliştirici yeni güncellemede sınıfa birkaç yeni property ekledi.

Artık Health:

Player + 0x308

olabilir.

Hardcoded olarak 0x2F0 kullanıyorsak trainer yanlış yere bakmaya başlar.

Ama trainer runtime sırasında:

Health property’sinin gerçek offset’ini

bulabiliyorsa bu tarz değişikliklerden bazıları bizi hiç etkilemeyebilir.

Tabii bu sistem traineri tamamen güncellemelerden bağımsız yapmıyor.

Ama sabit adres bağımlılığını azaltabiliyor.

🏗️ Unreal Engine’de Nesne Mantığı

Unreal Engine oyunlarında dünyadaki birçok şey bir UObject yapısından türeyebilir.

Örneğin:

  • Oyuncu

  • Silah

  • Envanter

  • Araç

  • Yaratık

  • Component

  • Attribute sistemi

farklı UObject tabanlı yapılardan oluşabilir.

Bir trainer geliştirirken sadece değeri değil, o değerin hangi gerçek nesneye ait olduğunu bulmak önemli.

Çünkü bellekte aynı sayı yüzlerce farklı yerde bulunabilir.

Mesela oyuncunun canı:

100

olsun.

Bellekte 100 aradığımızda:

  • düşmanın canı,

  • item miktarı,

  • UI değeri,

  • maksimum stamina,

  • animasyon parametresi

gibi yüzlerce farklı sonuç çıkabilir.

Ama:

PlayerHealthComponent → Health

yapısına ulaşırsak hangi 100’ü değiştirdiğimiz çok daha net olur.

🔎 ORGA Hub’daki UE RTTI Katmanı

ORGA Hub içerisinde Unreal Engine oyunları için geliştirdiğim ayrı bir UE RTTI / reflection katmanı bulunuyor.

Buradaki amaç runtime sırasında oyunun Unreal yapısını çözerek trainer özelliklerinin kullanabileceği sınıf ve field bilgilerine ulaşmak.

Sistem sayesinde bazı trainer işlemlerini doğrudan:

  • sınıf,

  • property,

  • attribute,

  • runtime field

üzerinden tanımlayabiliyorum.

Bu özellikle Subnautica 2 tarafında kullandığım sistemin temelini oluşturuyor.

🌊 Neden Subnautica 2?

Subnautica 2 Unreal Engine tabanlı olduğu için klasik Subnautica oyunlarından teknik olarak farklı bir yapıya sahip.

Trainer geliştirirken de bunu dikkate almak gerekiyor.

Oyunun Unreal tarafındaki runtime yapılarını kullanabildiğim için birçok özelliği klasik pointer scan yaklaşımından farklı şekilde hazırladım.

Subnautica 2 trainerinde ORGA Hub tarafında şu tarz özel işlemler bulunuyor:

  • ueAttrFreeze

  • ueFieldSet

  • ueTimeFreeze

  • uePos

Bunların her biri Unreal yapısını farklı amaçlarla kullanıyor.

❤️ ueAttrFreeze Nedir?

Bazı Unreal Engine oyunlarında karakter istatistikleri normal bir float field’dan daha karmaşık tutulabiliyor.

Özellikle attribute sistemlerinde bir değerin:

  • Current

  • Base

  • Max

gibi birden fazla bölümü olabilir.

Örneğin can:

Current Health: 80
Base Health: 100
Max Health: 100

şeklinde tutulabilir.

Trainer sadece ekranda gördüğümüz Current değerini değiştirirse oyun bir sonraki hesaplamada bunu tekrar Base veya başka bir sistem üzerinden değiştirebilir.

Bu yüzden ORGA Hub’daki ueAttrFreeze işlemi attribute yapısını daha doğru şekilde ele almak için geliştirdiğim yöntemlerden biri.

Trainer ilgili attribute’u bulup gerekli bölümlerini kontrol altında tutabiliyor.

Kullanıcı açısından sonuç örneğin:

Sınırsız can

oluyor.

Ama arka tarafta sadece rastgele bir float değeri 999’a sabitlemekten daha kontrollü bir işlem yapılabiliyor.

📌 ueFieldSet Nedir?

Bazı özelliklerde sürekli freeze yapmak gerekmiyor.

Sadece ilgili Unreal property’sini bulup bir değer yazmak yeterli.

Burada ueFieldSet kullanabiliyorum.

Örneğin:

şu nesneyi bul
şu property’yi çöz
şu değeri yaz

mantığında ilerliyor.

Bu bir buton işlemi de olabilir veya trainer özelliğinin ihtiyaç duyduğu başka bir ayar olabilir.

Yine avantaj aynı:

Hardcoded adres yerine mümkün olduğunca Unreal’ın kendi property yapısından faydalanmak.

⏱️ ueTimeFreeze

Zamanla ilgili sistemler oyunlarda bazen düşündüğümüzden daha karmaşık oluyor.

Bir değeri doğrudan bellekte freeze etmek her zaman yeterli olmayabiliyor.

Subnautica 2 trainerinde zamanla ilişkili özellikler için Unreal tarafına özel ayrı bir yöntem de bulunuyor.

ueTimeFreeze işlemi oyunun runtime yapısındaki ilgili zaman değerlerini kontrol altında tutmak için kullanılıyor.

Buradaki amaç yine aynı:

Oyunun kendi yapısına mümkün olduğunca yakın noktadan müdahale etmek.

📍 uePos ve Pozisyon Sistemi

Trainerlerde en sevdiğim özelliklerden biri teleport. 😄

Ama teleport yapmak için önce oyuncunun gerçek dünya pozisyonunu güvenilir şekilde bulmanız gerekiyor.

Unreal Engine’de karakterlerin transform ve location bilgileri motorun kendi nesne yapıları üzerinden yönetiliyor.

Subnautica 2 tarafında geliştirdiğim uePos sistemi de oyuncunun konum bilgisine ulaşabilmek için bu Unreal yapısından faydalanıyor.

Böylece trainer:

  • mevcut pozisyonu okuyabiliyor,

  • pozisyon kaydedebiliyor,

  • gerektiğinde tekrar aynı noktaya taşıyabiliyor

gibi işlemler gerçekleştirebiliyor.

Bu tarz sistemlerde doğrudan rastgele X/Y/Z float değerlerini aramaktansa gerçek oyuncu nesnesinin konum yapısını bulmak çok daha sağlıklı.

🧩 Property İsmiyle Bulmak Ne Kazandırıyor?

Diyelim geliştirici sınıf yapısını değiştirdi.

Eski sürüm:

Health = +0x310

Yeni sürüm:

Health = +0x328

Eğer trainer:

+0x310

kullanıyorsa özellik kırılır.

Ama runtime’da:

Health

property’sini bulup gerçek offset’i çözüyoruz diyelim.

Property adı ve genel yapı aynı kaldığı sürece yeni offset otomatik olarak bulunabilir.

Bu da trainer güncelleme işini bazı durumlarda ciddi şekilde kolaylaştırabiliyor.

⚠️ Reflection Kullanmak Traineri Ölümsüz Yapmıyor

Bunu özellikle belirtmek lazım.

Reflection kullanıyorsak:

Oyun bir daha ne kadar güncellenirse güncellensin trainer bozulmaz.

gibi bir durum yok.

Geliştirici:

  • sınıf adını değiştirebilir,

  • property adını değiştirebilir,

  • sistemi başka component’e taşıyabilir,

  • veri tipini değiştirebilir,

  • attribute sistemini yeniden yazabilir,

  • Unreal sürümünü değiştirebilir,

  • runtime yapısını ciddi şekilde değiştirebilir.

Bu durumda trainer yine güncellenmek zorunda kalabilir.

Ama küçük yapısal değişikliklerde hardcoded offset kullanmaya göre daha dayanıklı olma ihtimali yüksek.

🔍 Peki Her Property Reflection ile Bulunabilir mi?

Hayır.

Unreal Engine’de gördüğümüz her değer mutlaka trainer tarafından kolayca isim üzerinden çözülebilecek bir property olmak zorunda değil.

Bazı şeyler:

  • native kod içerisinde hesaplanabilir,

  • local değişken olabilir,

  • optimize edilmiş olabilir,

  • runtime’da farklı bir yapıya dönüşebilir,

  • doğrudan uygun metadata sunmayabilir.

Böyle durumlarda yine klasik yöntemlere dönmek gerekebilir.

Mesela:

  • AOB

  • pointer

  • code cave

  • runtime capture

hala gerekli olabilir.

Yani Reflection çok güçlü bir sistem ama yine bütün problemlerin tek çözümü değil.

🆚 Unreal Reflection ile Pointer Arasındaki Fark

Pointer yaklaşımı genellikle:

Şu adres zincirini takip ederek değere ulaş.

der.

Reflection ise daha çok:

Oyunun kendi nesne sisteminden şu sınıfı/property’yi çöz.

mantığında çalışır.

Pointer:

Game.exe + X → Y → Z → +0x328

gibi olabilir.

Reflection tarafında ise daha anlamlı şekilde:

Player → HealthComponent → Health

gibi düşünebiliriz.

İkisi sonunda aynı değere çıkabilir ama oraya ulaşma yöntemleri farklı.

🆚 Unreal Reflection ile AOB Arasındaki Fark

AOB:

makine kodu veya byte desenini arar.

Reflection:

oyunun nesne/property metadata’sını kullanır.

Örneğin hasar fonksiyonunun davranışını değiştireceksem AOB + Code Cave daha uygun olabilir.

Ama sadece oyuncunun bir property’sini okuyup yazmam gerekiyorsa Reflection daha mantıklı olabilir.

Bu yüzden çoğu trainer tek bir yöntemden oluşmaz.

🔥 Birlikte Kullanmak da Mümkün

Aslında en güçlü taraf burada.

Diyelim Unreal reflection üzerinden oyuncu nesnesini bulabiliyorum.

Ama yapmak istediğim özellik için belirli bir native fonksiyonu hooklamam gerekiyor.

O zaman:

Reflection → Player nesnesi

ve:

AOB → ilgili native fonksiyon

birlikte kullanılabilir.

Trainer geliştirirken yöntemleri birbirine rakip sistemler olarak değil, elimizdeki farklı araçlar olarak görüyorum.

🎮 Subnautica 2 Trainerinde Bunun Avantajı

Subnautica 2 tarafında bu sistem sayesinde trainerin önemli bölümünü oyunun Unreal yapısına özel hazırlayabildim.

Bu hem trainer tanımlarını daha anlaşılır hale getiriyor hem de bazı işlemleri klasik memory yöntemlerine göre daha temiz yapmamı sağlıyor.

Örneğin:

Attribute Freeze

normal freeze’den farklı davranabiliyor.

Position

doğrudan Unreal’ın gerçek konum yapısı üzerinden yönetilebiliyor.

Field Set

property çözümü üzerinden çalışabiliyor.

Böylece trainer engine içerisinde:

Bu oyun Unreal Engine, o zaman onun yapısını kullan.

diyebildiğimiz ayrı bir katman oluşuyor.

🧠 Neden ORGA Hub’da Motorlara Özel Sistemler Geliştiriyorum?

Çünkü bütün oyunları aynı memory engine ile zorlamaya çalışmak bana mantıklı gelmiyor.

Unity Mono bize metadata veriyorsa kullanmak lazım.

Unreal Engine bize reflection yapısı sunuyorsa değerlendirmek lazım.

CryEngine’in kendi console sistemi varsa bundan yararlanabiliriz.

The Sims 4 zaten Python çalıştırıyorsa Python tarafıyla iletişim kurmak daha mantıklı olabilir.

Benim ORGA Hub trainer sisteminde yapmak istediğim şey tam olarak bu:

Oyunu kendi yapısına göre ele almak.

Her oyunda illa aynı yöntem kullanılacak diye bir kural koymamak.

🔄 Güncelleme Geldiğinde Ne Kontrol Ediyorum?

Subnautica 2 gibi Reflection kullanan bir trainer güncellendiğinde genel olarak:

  • Aradığımız sınıflar hâlâ var mı?

  • Property isimleri değişmiş mi?

  • Property tipleri aynı mı?

  • Attribute yapısı değişmiş mi?

  • Oyuncu nesnesine ulaşma yolu değişmiş mi?

  • Position sistemi aynı mı?

  • Trainer özellikleri hâlâ doğru nesne üzerinde çalışıyor mu?

gibi şeylere bakmak gerekiyor.

Sadece:

Trainer açıldı, crash olmadı.

demek yeterli değil.

Her özelliği tekrar oyun içinde test etmek gerekiyor.

❤️ Kısaca Özetlersek

Unreal Engine Reflection bize bazı trainer özelliklerinde oyunun kendi runtime yapısını kullanma imkanı veriyor.

Yani:

Sabit offset kullanmak yerine → Property çöz.

Rastgele değer aramak yerine → Gerçek nesneyi bul.

Her şeyi pointer scan ile çözmek yerine → Unreal metadata’dan faydalan.

ORGA Hub’daki Subnautica 2 trainerinde de bu nedenle Unreal’a özel ayrı bir altyapı kullanıyorum.

Ama yine temel prensip aynı:

Tek bir yönteme bağlı kalmak yerine oyun hangi yönteme uygunsa onu kullanmak.

Bazı oyunlarda AOB en iyi yöntem.

Bazılarında Mono.

Bazılarında Unreal Reflection.

Bazılarında ise oyunun kendi script veya konsol sistemi.

Bence trainer geliştirmeyi ilginç yapan taraflardan biri de bu. Her oyun farklı bir problem ve her oyunun çözümü aynı değil.

Cevap yazmak için giriş yapmalısın. Okumak için giriş gerekmez.

Giriş yap