Isse Kun
Emektar Üye
Hedef: Bu konumuzdaki hedefimiz, Diablo gibi oyunlarla bir çok özelliği paylaşan bir ARPG olan
Tanımlama: Flare ve diğer APHC'lerde altın ve deneyim kazanmak için oyuncuların düşmanları tekrar tekrar öldürmeleri gerekir. Buradaki amacımız, ekrandaki düşmanlar otomatik olarak bulacak ve oyucumuzu onlara saldırmaya gönderecek bir bot yazmaktır. Bu projede sadece düşmanlar öldürecek olsak da, aynı yaklaşım düşürülen eşyalar toplamak için genişletilebilir.
Anlatım: Bir tarım botu (Farm Bot) yazmak için önce bellekte üç öğe bulmamız gerekir:
1. Oyuncumuzun pozisyonu
2. Bir düşmanın konumu
3. Fare veya imleç konumumuz
Bu eşyaları bulduktan sonra, oyuncumuzdan düşmana giden yönü belirleyebiliriz. Flare ve Diablo gibi oyunlarda, bir noktaya tıklayarak hareket edersiniz. Bu nedenle, imleç konumumuzu düşmana bakan yöne ayarlayabilir ve bir tıklama olayı gönderebiliriz. Düşman ve oyuncu hareket ettikçe yönü sürekli olarak ayarlamak için bu mantığı bir tür döngüye yerleştireceğiz.
Oyuncu Pozisyonunu Bulma: Oyuncumuzun X ve Y pozisyonunu bularak başlayacağız. İlk olarak, Flare'ı başlatın ve yeni bir karakter oluşturun. Oyundaki ilk alanın düşmanı yoktur ve konumumuzu bulmak için mükemmeldir. Oyuncunun pozisyonunun tam değerini bilmesek de, pozisyonun büyük olasılıkla bir float değeri olarak saklandığını varsayabiliriz. Bu nedenle, Değer Türü Float olarak ayarlanmış bir Bilinmeyen değer türü için tarama yapacağız.
İlk taramadan sonra, karakterinizi haritada aşağı taşıyın ve tarama türünü Artan değer olarak değiştirin ve sonuçları filtreleyin. Ardından, karakterinizi haritada yukarı taşıyın ve tarama türünü Azalan değer olarak değiştirin. Yaklaşık 150 sonuç kalana kadar bu işlemi tekrarlayın.
Bu noktada, tüm sonuçlarımız aynı değeri içerecek ve sonuç kümemizi daha fazla filtreleyemeyeceğiz. Ancak, bu adreslerden yalnızca birinin oyuncunun pozisyonunun gerçek değerini saklaması gerektiğini biliyoruz. Bu adresi manuel olarak tanımlamamız gerekecek. Bunu hızlı bir şekilde yapmak için, tüm sonuçları alt bölmeye getirin. Ardından, adreslerin yaklaşık yarısını seçin ve değerlerini başka bir değere ayarlayın:
Oyundaki karakteriniz aniden farklı bir konuma ışınlanırsa, gerçek adresin seçilen adreslerde bir yerde olduğunu bilirsiniz. Değilse, bu adreslerin hiçbirinin oyuncunun pozisyonunu tutmadığını ve silinebileceğini biliyorsunuzdur. Bu işlemi kullanarak, adres listesini hızlı bir şekilde kırpabilir ve oyuncunun pozisyonundan sorumlu olanı bulabilirsiniz. Bu laboratuvarda tespit edilen adres . DMA nedeniyle, adresiniz büyük olasılıkla farklı olacaktır. 0x0AE6931C
Adres tanımlandığında, Cheat Engine'in Bu adrese ne yazdığını bul seçeneğini kullanabiliriz, bu da hangi kodun belleği değiştirdiğini belirlemek için işleme bir hata ayıklayıcı ekleyecektir:
Bu setle Flare'a geri dönün ve karakterinizi ekranda hareket ettirin. Adrese tek bir konumun yazdığını görmelisiniz. Oyunda kodun dinamik olarak yüklenmesi nedeniyle adresiniz büyük olasılıkla farklı olacaktır.
Hile Motorunu kapatın ve x64dbg'yi çalıştırın. Flare'a taktıktan sonra, Cheat Engine'de tanımladığınız konumdaki kodu görüntüleyin.
Bir araya getirildiğinde, kayan nokta sayıları benzersiz bir şekilde ele alınır ve bunlarla ilişkili birkaç talimat içerir. Bu proje için sadece fstp talimatını anlamamız gerekecek. Bu talimat bir mov talimatı gibi çalışır ve st0 içindeki değeri belirtilen diğer adrese kopyalar (dword ptr ds:[ebx] gibi). st0 özel bir kayan nokta kaydıdır. Kayan nokta operasyonlarını No Recoil hakkında açacağım konuda daha fazla inceleyeceğiz.
Yukarıda vurgulanan koddan, kayan nokta değerlerinin ebp ve ebx'e yerleştirildiğini görebiliriz. Eğer fstp dword ptr ss:[ebp],st(0) talimatı üzerinde bir kesme noktası ayarlarsak ve ardından karakterimizi hareket ettirirsek, kesme noktamız açılır. Açtıktan sonra, ebx'e sağ tıklayın ve Dökümde takip et'i seçin. Döküm bölümünde aşağıdakine benzer değerler görürsünüz:
Bu değerler, float değerlerinin DWORD gösterimini temsil eder. Kayan nokta değerini, değere sağ tıklayıp Float -> Float (32-bit) seçeneğini belirleyerek görüntüleyebiliriz:
Bunu yapmak, Cheat Engine'de daha önce gördüğümüz değerleri ortaya çıkaracaktır:
Bundan, yürütmenin bu noktasında, ebp ve ebx'in oyuncunun X ve Y pozisyonunu tuttuğunu varsayabiliriz.
Flare Koordinatları: Flare'da doğrudan yukarı ve aşağı hareket ederseniz, hem X hem de Y konum değerlerinin değiştiğini fark edeceksiniz. Benzer şekilde, sola ve sağa hareket ederseniz, her iki değer de değişir. Bu iki durumda da değerlerden yalnızca birinin değişmesini bekleriz. Bu nedenle oyundaki koordinat sistemini kısaca incelememiz gerekiyor
Flare, birçok ARPG gibi, izometrik bir perspektifte işlenir. Amaçlarımız için bu, X ve Y eksenlerinin 45 derece döndürüldüğü anlamına gelir, örneğin:
Karakterinizi bu eksenler boyunca hareket ettirirseniz, yalnızca bir değer değişikliği fark edeceksiniz.
Düşman Pozisyonunu Bulma: Önceki bölümde tanımladığımız kod, kayan nokta işlemlerinin miktarı ve dallanma veya çağrı talimatlarının olmaması nedeniyle daha düşük düzeyde görünüyordu. Flare'daki fonksiyon zincirini göz önünde bulundurursak, şöyle görünebilir:
Tanımlanan kodumuz büyük olasılıkla update_position() yönteminde bulunur. Genellikle oyunlar, birden fazla varlık için update_position() gibi düşük düzeyli kodları yeniden kullanır. Örneğin, düşmanları güncellemek için kullanılan işlev zinciri şöyle görünür:
Flare bu modeli kullanıyorsa, düşmanlarımızı da bulmak için oynatıcımızı ararken bulduğumuz kodu kullanabiliriz. Bu her oyunda böyle olmayacak, ancak geri dönüşü kolaylaştırmaya çalışmaya değer.
lk olarak, daha önce tanımladığımız fstp yönergesinde yeniden bir kesme noktası ayarlayın. Flare'da, kesme noktasının öne çıkmasını sağlamak için karakterinizi ekranda hareket ettirin. Olduğunda, geri dönene kadar yürütün ve tek bir kod düzeyine çıkmak için üzerine gidin:
Çağrının üstüne bakarsak, aşağıdaki kodu görürüz:
Vurgulanan kodu incelediğimizde, eax ve ebx'in birbirlerinin 4 bayt içindeki değerlere ayarlandığını görüyoruz. Bu, X ve Y konumları arasında gözlemlediğimiz mesafeyle eşleşir. EBX, 240 talimatı ekle ve dökümde ebx'i görüntüleyecek olursak, eax ve ebx'in oyuncumuzun X ve Y konumunu içerdiğini doğrulayabiliriz.
Ardından, kesme noktasını devre dışı bırakın ve Flare'a geri dönün. Oyunda, birkaç düşmanı olan bir sonraki ekrana geçin. Oraya vardığınızda, oynatıcınızı hareket ettirmeyi bırakın ve ebx, 240 ekleme talimatındaki kesme noktasını yeniden etkinleştirin. Bir süre sonra, kesme noktası tekrar açılmalıdır. Dökümdeki eax ve ebx'i incelerseniz, oyuncumuzun X ve Y konumundan farklı bir adreste olduklarını, ancak benzer değerler içerdiklerini görmelisiniz:
Bu kodun hem oyuncular hem de düşmanlar için çağrılmış olması, oyunun bu kodu paylaştığını ve farklı konumlardan çağırdığını gösteriyor. Bu davranışı önce kesme noktasını devre dışı bırakarak ve karakterimizi düşmansız ilk ekrana geri taşıyarak gözlemleyebiliriz. Ardından, kesme noktasını yeniden etkinleştirin ve karakterinizi hareket ettirerek patlamasına neden olun. Bunu yaptıktan sonra, geri dönene kadar execute'u kullanın ve oyuncunun arama koduna bir seviye yukarı gitmek için üzerine çıkın:
Ardından, kesme noktasını devre dışı bırakın ve karakterinizi düşmanlarla birlikte ekrana geri taşıyın. Kesme noktasının tekrar açılmasını sağlamak için yukarıdakiyle aynı işlemi yapın ve ardından bir düzey yukarı gidin. Bu konumun oyuncunun konumundan farklı olduğunu fark edeceksiniz:
Bu farklılıkları, düşman pozisyonlarını belirlemek için hack'imizi programlarken kullanacağız.
Fare Konumunu Belirleme: Oyuncu ve düşman konumlarımız artık bulunduğundan, fare konumumuzu hafızada bulmamız gerekiyor. Bu, hack'imizi yazarken fare konumunu düşmana doğru ayarlamamıza izin verecektir.
Windows, SetCursorPos gibi bir pencerenin içindeki fare konumunu değiştirmek için birkaç
Bilinmeyen değer türü için bir tarama ile başlayın. Ardından, imlecinizi sağa kaydırın ve Artan değer'i arayın. Pencerenin kenarına geldiğinizde, imlecinizi sola getirin ve Azalan değer'i arayın. Sonunda, sonuçlarınızı birkaç adrese daraltmanız gerekir:
Her girişi değiştirerek ve imlecin ne zaman hareket ettiğini gözlemleyerek tam adresi belirleyebilirsiniz. Ardından, önceki laboratuvarlarda yaptığımız gibi, bu adrese yazma konusunda bir kesme noktası ayarlayın ve farenizi Flare'da hareket ettirin. Kesme noktası hemen aşağıdaki konumda açılır:
Dökümdeki ebp+0x644 bakarsanız, farenin X ve Y koordinatlarının yan yana depolandığını görebiliriz.
Kanca (Hook) Ve Dinamik Kod: Bu konumlar belirlendikten sonra, hack'imizi programlamaya başlayabiliriz. Bu hack için 3 kod mağarası kullanacağız:
Bağlantıları görmek için lütfen
Giriş Yap
olacak. Oyuna dair bir çok açık kaynak bulunabilir ayrıca hedefimiz hile karşıtı (AntiCheat) tarafından korunmamaktadır.Tanımlama: Flare ve diğer APHC'lerde altın ve deneyim kazanmak için oyuncuların düşmanları tekrar tekrar öldürmeleri gerekir. Buradaki amacımız, ekrandaki düşmanlar otomatik olarak bulacak ve oyucumuzu onlara saldırmaya gönderecek bir bot yazmaktır. Bu projede sadece düşmanlar öldürecek olsak da, aynı yaklaşım düşürülen eşyalar toplamak için genişletilebilir.
Anlatım: Bir tarım botu (Farm Bot) yazmak için önce bellekte üç öğe bulmamız gerekir:
1. Oyuncumuzun pozisyonu
2. Bir düşmanın konumu
3. Fare veya imleç konumumuz
Bu eşyaları bulduktan sonra, oyuncumuzdan düşmana giden yönü belirleyebiliriz. Flare ve Diablo gibi oyunlarda, bir noktaya tıklayarak hareket edersiniz. Bu nedenle, imleç konumumuzu düşmana bakan yöne ayarlayabilir ve bir tıklama olayı gönderebiliriz. Düşman ve oyuncu hareket ettikçe yönü sürekli olarak ayarlamak için bu mantığı bir tür döngüye yerleştireceğiz.
Oyuncu Pozisyonunu Bulma: Oyuncumuzun X ve Y pozisyonunu bularak başlayacağız. İlk olarak, Flare'ı başlatın ve yeni bir karakter oluşturun. Oyundaki ilk alanın düşmanı yoktur ve konumumuzu bulmak için mükemmeldir. Oyuncunun pozisyonunun tam değerini bilmesek de, pozisyonun büyük olasılıkla bir float değeri olarak saklandığını varsayabiliriz. Bu nedenle, Değer Türü Float olarak ayarlanmış bir Bilinmeyen değer türü için tarama yapacağız.
İlk taramadan sonra, karakterinizi haritada aşağı taşıyın ve tarama türünü Artan değer olarak değiştirin ve sonuçları filtreleyin. Ardından, karakterinizi haritada yukarı taşıyın ve tarama türünü Azalan değer olarak değiştirin. Yaklaşık 150 sonuç kalana kadar bu işlemi tekrarlayın.
Bu noktada, tüm sonuçlarımız aynı değeri içerecek ve sonuç kümemizi daha fazla filtreleyemeyeceğiz. Ancak, bu adreslerden yalnızca birinin oyuncunun pozisyonunun gerçek değerini saklaması gerektiğini biliyoruz. Bu adresi manuel olarak tanımlamamız gerekecek. Bunu hızlı bir şekilde yapmak için, tüm sonuçları alt bölmeye getirin. Ardından, adreslerin yaklaşık yarısını seçin ve değerlerini başka bir değere ayarlayın:
Oyundaki karakteriniz aniden farklı bir konuma ışınlanırsa, gerçek adresin seçilen adreslerde bir yerde olduğunu bilirsiniz. Değilse, bu adreslerin hiçbirinin oyuncunun pozisyonunu tutmadığını ve silinebileceğini biliyorsunuzdur. Bu işlemi kullanarak, adres listesini hızlı bir şekilde kırpabilir ve oyuncunun pozisyonundan sorumlu olanı bulabilirsiniz. Bu laboratuvarda tespit edilen adres . DMA nedeniyle, adresiniz büyük olasılıkla farklı olacaktır. 0x0AE6931C
Adres tanımlandığında, Cheat Engine'in Bu adrese ne yazdığını bul seçeneğini kullanabiliriz, bu da hangi kodun belleği değiştirdiğini belirlemek için işleme bir hata ayıklayıcı ekleyecektir:
Bu setle Flare'a geri dönün ve karakterinizi ekranda hareket ettirin. Adrese tek bir konumun yazdığını görmelisiniz. Oyunda kodun dinamik olarak yüklenmesi nedeniyle adresiniz büyük olasılıkla farklı olacaktır.
Hile Motorunu kapatın ve x64dbg'yi çalıştırın. Flare'a taktıktan sonra, Cheat Engine'de tanımladığınız konumdaki kodu görüntüleyin.
Bir araya getirildiğinde, kayan nokta sayıları benzersiz bir şekilde ele alınır ve bunlarla ilişkili birkaç talimat içerir. Bu proje için sadece fstp talimatını anlamamız gerekecek. Bu talimat bir mov talimatı gibi çalışır ve st0 içindeki değeri belirtilen diğer adrese kopyalar (dword ptr ds:[ebx] gibi). st0 özel bir kayan nokta kaydıdır. Kayan nokta operasyonlarını No Recoil hakkında açacağım konuda daha fazla inceleyeceğiz.
Yukarıda vurgulanan koddan, kayan nokta değerlerinin ebp ve ebx'e yerleştirildiğini görebiliriz. Eğer fstp dword ptr ss:[ebp],st(0) talimatı üzerinde bir kesme noktası ayarlarsak ve ardından karakterimizi hareket ettirirsek, kesme noktamız açılır. Açtıktan sonra, ebx'e sağ tıklayın ve Dökümde takip et'i seçin. Döküm bölümünde aşağıdakine benzer değerler görürsünüz:
Bu değerler, float değerlerinin DWORD gösterimini temsil eder. Kayan nokta değerini, değere sağ tıklayıp Float -> Float (32-bit) seçeneğini belirleyerek görüntüleyebiliriz:
Bunu yapmak, Cheat Engine'de daha önce gördüğümüz değerleri ortaya çıkaracaktır:
Bundan, yürütmenin bu noktasında, ebp ve ebx'in oyuncunun X ve Y pozisyonunu tuttuğunu varsayabiliriz.
Flare Koordinatları: Flare'da doğrudan yukarı ve aşağı hareket ederseniz, hem X hem de Y konum değerlerinin değiştiğini fark edeceksiniz. Benzer şekilde, sola ve sağa hareket ederseniz, her iki değer de değişir. Bu iki durumda da değerlerden yalnızca birinin değişmesini bekleriz. Bu nedenle oyundaki koordinat sistemini kısaca incelememiz gerekiyor
Flare, birçok ARPG gibi, izometrik bir perspektifte işlenir. Amaçlarımız için bu, X ve Y eksenlerinin 45 derece döndürüldüğü anlamına gelir, örneğin:
Karakterinizi bu eksenler boyunca hareket ettirirseniz, yalnızca bir değer değişikliği fark edeceksiniz.
Düşman Pozisyonunu Bulma: Önceki bölümde tanımladığımız kod, kayan nokta işlemlerinin miktarı ve dallanma veya çağrı talimatlarının olmaması nedeniyle daha düşük düzeyde görünüyordu. Flare'daki fonksiyon zincirini göz önünde bulundurursak, şöyle görünebilir:
C++:
game_loop()->handle_input()->update_character()->update_position()
Tanımlanan kodumuz büyük olasılıkla update_position() yönteminde bulunur. Genellikle oyunlar, birden fazla varlık için update_position() gibi düşük düzeyli kodları yeniden kullanır. Örneğin, düşmanları güncellemek için kullanılan işlev zinciri şöyle görünür:
C++:
game_loop()->handle_input()->update_enemies()->update_position()
Flare bu modeli kullanıyorsa, düşmanlarımızı da bulmak için oynatıcımızı ararken bulduğumuz kodu kullanabiliriz. Bu her oyunda böyle olmayacak, ancak geri dönüşü kolaylaştırmaya çalışmaya değer.
lk olarak, daha önce tanımladığımız fstp yönergesinde yeniden bir kesme noktası ayarlayın. Flare'da, kesme noktasının öne çıkmasını sağlamak için karakterinizi ekranda hareket ettirin. Olduğunda, geri dönene kadar yürütün ve tek bir kod düzeyine çıkmak için üzerine gidin:
Çağrının üstüne bakarsak, aşağıdaki kodu görürüz:
Vurgulanan kodu incelediğimizde, eax ve ebx'in birbirlerinin 4 bayt içindeki değerlere ayarlandığını görüyoruz. Bu, X ve Y konumları arasında gözlemlediğimiz mesafeyle eşleşir. EBX, 240 talimatı ekle ve dökümde ebx'i görüntüleyecek olursak, eax ve ebx'in oyuncumuzun X ve Y konumunu içerdiğini doğrulayabiliriz.
Ardından, kesme noktasını devre dışı bırakın ve Flare'a geri dönün. Oyunda, birkaç düşmanı olan bir sonraki ekrana geçin. Oraya vardığınızda, oynatıcınızı hareket ettirmeyi bırakın ve ebx, 240 ekleme talimatındaki kesme noktasını yeniden etkinleştirin. Bir süre sonra, kesme noktası tekrar açılmalıdır. Dökümdeki eax ve ebx'i incelerseniz, oyuncumuzun X ve Y konumundan farklı bir adreste olduklarını, ancak benzer değerler içerdiklerini görmelisiniz:
Bu kodun hem oyuncular hem de düşmanlar için çağrılmış olması, oyunun bu kodu paylaştığını ve farklı konumlardan çağırdığını gösteriyor. Bu davranışı önce kesme noktasını devre dışı bırakarak ve karakterimizi düşmansız ilk ekrana geri taşıyarak gözlemleyebiliriz. Ardından, kesme noktasını yeniden etkinleştirin ve karakterinizi hareket ettirerek patlamasına neden olun. Bunu yaptıktan sonra, geri dönene kadar execute'u kullanın ve oyuncunun arama koduna bir seviye yukarı gitmek için üzerine çıkın:
Ardından, kesme noktasını devre dışı bırakın ve karakterinizi düşmanlarla birlikte ekrana geri taşıyın. Kesme noktasının tekrar açılmasını sağlamak için yukarıdakiyle aynı işlemi yapın ve ardından bir düzey yukarı gidin. Bu konumun oyuncunun konumundan farklı olduğunu fark edeceksiniz:
Bu farklılıkları, düşman pozisyonlarını belirlemek için hack'imizi programlarken kullanacağız.
Fare Konumunu Belirleme: Oyuncu ve düşman konumlarımız artık bulunduğundan, fare konumumuzu hafızada bulmamız gerekiyor. Bu, hack'imizi yazarken fare konumunu düşmana doğru ayarlamamıza izin verecektir.
Windows, SetCursorPos gibi bir pencerenin içindeki fare konumunu değiştirmek için birkaç
Bağlantıları görmek için lütfen
Giriş Yap
Bu API, X ve Y parametreleri olarak iki ints alır. Sonuç olarak, 4 Bayt olarak ayarlanmış bir Değer Türünü tarayabileceğimizi biliyoruz.Bilinmeyen değer türü için bir tarama ile başlayın. Ardından, imlecinizi sağa kaydırın ve Artan değer'i arayın. Pencerenin kenarına geldiğinizde, imlecinizi sola getirin ve Azalan değer'i arayın. Sonunda, sonuçlarınızı birkaç adrese daraltmanız gerekir:
Her girişi değiştirerek ve imlecin ne zaman hareket ettiğini gözlemleyerek tam adresi belirleyebilirsiniz. Ardından, önceki laboratuvarlarda yaptığımız gibi, bu adrese yazma konusunda bir kesme noktası ayarlayın ve farenizi Flare'da hareket ettirin. Kesme noktası hemen aşağıdaki konumda açılır:
Dökümdeki ebp+0x644 bakarsanız, farenin X ve Y koordinatlarının yan yana depolandığını görebiliriz.
Kanca (Hook) Ve Dinamik Kod: Bu konumlar belirlendikten sonra, hack'imizi programlamaya başlayabiliriz. Bu hack için 3 kod mağarası kullanacağız:
- Farenin X ve Y koordinatlarını almak için bir kod mağarası.
- Oyuncunun X ve Y koordinatlarını almak için bir kod mağarası.
- Düşman X ve Y koordinatlarını almak için update_position yöntemdeki bir kod mağarası.
Daha sonra, update_position yöntemindeki mevcut varlığın bir oyuncu mu yoksa düşman mı olduğunu kontrol edecek bir iş parçacığı oluşturacağız. Eğer bir düşmansa, iplik faremizin X ve Y koordinatlarını düşmanın yönüne ayarlayacaktır. Kod mağaralarımız için aşağıda ki 3 talimatı yeniden yönlendireceğiz.
- Fare - çağrı 0x8842100x91CBC8
- Oyuncu - çağrı 0x8508400x83CAC4
- Döngü - çağrı 0x89B1800x89BA94
Bu talimatların tümü, bu laboratuvarın önceki bölümünde tersine çevirirken tanımladığımız talimatlara yakındır.
İlk olarak, önceki laboratuvarlarda gördüğümüz DLL yapısına başlayacağız:
İlk olarak, önceki laboratuvarlarda gördüğümüz DLL yapısına başlayacağız:
C++:
#include <Windows.h>
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
DWORD old_protect;
if (fdwReason == DLL_PROCESS_ATTACH) {
//hooking code
}
return true;
}
Ardından, önceki laboratuvarlarda kancaları nasıl oluşturduğumuzla aynı şekilde, yukarıda tanımlanan 3 talimatı bağlayacağız:
C++:
HANDLE flare_base;
DWORD mouse_call_address;
DWORD mouse_return_address;
DWORD player_call_address;
DWORD player_return_address;
DWORD loop_call_address;
DWORD loop_return_address;
...
if (fdwReason == DLL_PROCESS_ATTACH) {
//hooking code
flare_base = GetModuleHandle(L"flare.exe");
// mouse hook
mouse_call_address = (DWORD)flare_base + 0x54210;
unsigned char* hook_location = (unsigned char*)((DWORD)flare_base + 0xECBC8);
mouse_return_address = (DWORD)hook_location + 5;
VirtualProtect((void*)hook_location, 5, PAGE_EXECUTE_READWRITE, &old_protect);
*hook_location = 0xE9;
*(DWORD*)(hook_location + 1) = (DWORD)&mouse_codecave - ((DWORD)hook_location + 5);
// player hook
player_call_address = (DWORD)flare_base + 0x20840;
hook_location = (unsigned char*)((DWORD)flare_base + 0xCAC4);
player_return_address = (DWORD)hook_location + 5;
VirtualProtect((void*)hook_location, 5, PAGE_EXECUTE_READWRITE, &old_protect);
*hook_location = 0xE9;
*(DWORD*)(hook_location + 1) = (DWORD)&player_codecave - ((DWORD)hook_location + 5);
// game loop hook
loop_call_address = (DWORD)flare_base + 0x6B180;
hook_location = (unsigned char*)((DWORD)flare_base + 0x6BA94);
loop_return_address = (DWORD)hook_location + 5;
VirtualProtect((void*)hook_location, 5, PAGE_EXECUTE_READWRITE, &old_protect);
*hook_location = 0xE9;
*(DWORD*)(hook_location + 1) = (DWORD)&loop_codecave - ((DWORD)hook_location + 5);
DllMain işlevimizi tamamlamak için, iş parçacığımızı da oluşturmak istiyoruz:
Fare Kodu Mağarası: Fare kodu mağaramız yürütüldüğünde, ebp+0x664 imlecin X konumunu ve ebp+0x668 imlecin Y konumunu korur. Kod mağaramız bu değerleri alır ve konumlarına, mouse_x ve mouse_y iki işaretçi atar:
C++:
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)injected_thread, NULL, 0, NULL);
Fare Kodu Mağarası: Fare kodu mağaramız yürütüldüğünde, ebp+0x664 imlecin X konumunu ve ebp+0x668 imlecin Y konumunu korur. Kod mağaramız bu değerleri alır ve konumlarına, mouse_x ve mouse_y iki işaretçi atar:
C++:
DWORD* mouse_x = NULL;
DWORD* mouse_y = NULL;
__declspec(naked) void mouse_codecave() {
__asm {
call mouse_call_address
pushad
mov eax, ebp
add eax, 0x664
mov ebx, ebp
add ebx, 0x668
mov mouse_x, eax
mov mouse_y, ebx
popad
jmp mouse_return_address
}
}
Oyuncu Kodu Mağarası: Fare kodu mağaramıza benzer şekilde, oyuncu kodu mağaramız yürütüldüğünde, ecx+0x240 oyuncunun X pozisyonunu ve ecx+0x244 oyuncunun Y pozisyonunu tutar. Kod mağaramız bu değerleri alır ve konumlarına iki işaretçi atar:
C++:
float* player_x = NULL;
float* player_y = NULL;
__declspec(naked) void player_codecave() {
__asm {
pushad
mov eax, ecx
add eax, 0x240
mov player_x, eax
add eax, 4
mov player_y, eax
popad
call player_call_address
jmp player_return_address
}
}
Döngü Kodu Mağarası: Döngü kodu mağaramız, bir konumu güncellemek için oyuncu ve düşman yöntemleri arasında paylaşılan konumu bağlayacaktır. Bu kod mağarası yürütüldüğünde, ebx oyuncunun veya düşmanın Y konumunu saklar ve ebx - 4 X konumunu saklar. Önceki iki kod mağarasında olduğu gibi, şu adreslere işaretçiler atayacağız:
C++:
float* enemy_x = NULL;
float* enemy_y = NULL;
__declspec(naked) void loop_codecave() {
__asm {
pushad
mov eax, ebx
sub eax, 4
mov enemy_x, eax
mov enemy_y, ebx
popad
call loop_call_address
jmp loop_return_address
}
}
Bot İş Parçacığı (Thread): Atanan tüm işaretçilerimizle nihayet botun ana mantığını oluşturabiliriz. Bu iş parçacığı, tüm işaretçilerin atanıp atanmadığını görmek için sürekli olarak denetler. Eğer öyleyse, konu daha sonra güncellenen karakterin oyuncu olmadığından emin olmak için kontrol edecektir. Son kontrol olarak, botumuzun değiştirilebilmesi için "M" tuşunun basılı tutulduğundan emin oluruz:
C++:
void injected_thread() {
while (true) {
if (player_x != NULL && player_y != NULL && enemy_x != NULL && enemy_y != NULL
&& player_x != enemy_x && player_y != enemy_y
&& mouse_x != NULL && mouse_y != NULL && GetAsyncKeyState('M')) {
// move player
}
Sleep(1);
}
}
Tüm bu koşullar yerine getirilirse, bir düşmanın oyuncumuzla aynı ekranda hareket ettiğini biliyoruz ve oyuncumuzu düşmana doğru hareket ettirmeye başlamak istiyoruz. Bu laboratuvarda, botumuz düşmana doğrudan bir yol izlemeye çalışacaktır, çünkü bu uygulanması en kolay mantıktır. Daha eksiksiz bir tarım botu için, oyuncu karakterimizi engeller etrafında yönlendirdiğimizden emin olmamız gerekir.
Flare'daki hareket, çoğu ARPG gibi, hareket etmek istediğiniz yöne tıklayarak yapılır. Botumuz, daha önce tartıştığımız eksenlere dayanarak dört yönde hareket edecektir:
Doğrudan bir yol izlediğimizden, fare imlecini düşmanın oyuncumuza göre konumuna göre ayarlayabiliriz. Örneğin, düşman solumuzdaysa, fare imlecimizi oyuncumuzun soluna getireceğiz. Fare konumu değerleri, fareyi yukarıda vurgulanan konumların üzerine getirerek ve x64bg dökümündeki fare adresindeki değeri görüntüleyerek alınabilir:
Flare'daki hareket, çoğu ARPG gibi, hareket etmek istediğiniz yöne tıklayarak yapılır. Botumuz, daha önce tartıştığımız eksenlere dayanarak dört yönde hareket edecektir:
Doğrudan bir yol izlediğimizden, fare imlecini düşmanın oyuncumuza göre konumuna göre ayarlayabiliriz. Örneğin, düşman solumuzdaysa, fare imlecimizi oyuncumuzun soluna getireceğiz. Fare konumu değerleri, fareyi yukarıda vurgulanan konumların üzerine getirerek ve x64bg dökümündeki fare adresindeki değeri görüntüleyerek alınabilir:
C++:
if (*enemy_x < *player_x) {
*mouse_x = 490;
}
else {
*mouse_x = 560;
}
if (*enemy_y > *player_y) {
*mouse_y = 270;
}
else {
*mouse_y = 330;
}
Son olarak, oyuna sola doğru fareyle aşağı bir etkinlik göndermek için
Bağlantıları görmek için lütfen
Giriş Yap
API'sini kullanacağız. SendInput, birden fazla olay göndermenize olanak tanıyan bir dizi giriş olayı alır. Bu, saldırmak ve sonra büyü yapmak gibi aynı anda birden fazla eylem yapmak istiyorsak yararlı olabilir. Bu laboratuvarda, fare aşağı veya fare yukarı olayı olan yalnızca bir giriş göndereceğiz:
C++:
input.type = INPUT_MOUSE;
input.mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
SendInput(1, &input, sizeof(INPUT));
Artık bu DLL'yi oluşturabilir ve oyunumuza enjekte edebiliriz. Oyunda, düşmanı olan bir ekrana gidin ve "M" tuşunu basılı tutun. Karakteriniz düşmana doğru koşmalı ve yeterince yakın olduğunda saldırmalıdır.
Bu dersin tam kaynak kodu
Bu dersin tam kaynak kodu
Bağlantıları görmek için lütfen
Giriş Yap