Array Of Byte Dinamik Olarak Nasıl Okunur

Üye
Katılım
24 Ocak 2023
Mesajlar
7
Tepki puanı
1
Ödüller
2
Yaş
35
3 HİZMET YILI
Warspear Online'da varlıkların nasıl depolandığını sonunda çözdüm. EntityList dizi olarak değil, node yapısıyla tutuluyor ve Array of Byte (AoB) taramasıyla varlıkları bulabiliyorum. Ancak bunu programatik olarak nasıl uygulayacağımdan emin değilim. Aşağıda bulduğum pattern ve karşılık gelen offsetler var. Bu patterni kullanarak varlıkları dinamik olarak nasıl bulabilir ve farmbotum için değerlerini okuyabilirim?

Amacım: Karakterimin otomatik olarak yaratıklara saldırıp altın toplamasını sağlayacak bir sistem yapmak.


4D 00 75 00 74 00 61 00 6E 00 74 00 20 00 6F 00
66 00 20 00 43 00 6C 00 6F 00 61 00 63 00 61 00
?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ?? 25 24 00 00 25 24 00 00
64 00 00 00 64 00 00 00 ?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??

Pattern:
4D 00 75 00 74 00 61 00 6E 00 74 00 20 00 6F 00
66 00 20 00 43 00 6C 00 6F 00 61 00 63 00 61 00 // İlk 2 satır (offset 0x0 ile 0x32) - 32-byte UTF-16 yaratık adı
... [wildcard byte'ları] ...
25 24 00 00 25 24 00 00 // Offset 0x184-0x191 - İlk 4 byte: Mevcut HP, sonraki 4 byte: Max HP
64 00 00 00 64 00 00 00 // Offset 0x192-0x200 - İlk 4 byte: Mevcut Mana, sonraki 4 byte: Max Mana

... [wildcard byte'ları] ...
// Ek bilgiler:
// 13. ve 15. byte'lar Position (13=xPos, 15=yPos)
// 9. byte Status : // (1=Meşgul, 0=Boşta)

Bu kodu yazdım, ancak yalnızca statik değerleri okuyor. Otomatik farm sistemi için dinamik olarak varlık verilerini okumam gerekiyor.
#include <iostream>
#include <vector>
#include <string>
#include <thread>
#include <chrono>
#include <iomanip>
#include <cstdlib>

uint32_t readUInt32(const std::vector<uint8_t>& arr, size_t offset) {
return arr[offset] |
(arr[offset + 1] << 8) |
(arr[offset + 2] << 16) |
(arr[offset + 3] << 24);
}

int main() {

std::vector<uint8_t> arr(0x1A1, 0x00);


// UTF-16LE formatında Mob'un adı
std::wstring mobNameStr = L"Mutant of Cloaca";
for (size_t i = 0; i < mobNameStr.size() && i < 16; ++i) {
arr[i * 2] = mobNameStr & 0xFF;
arr[i * 2 + 1] = (mobNameStr >> 8) & 0xFF;
}
// CurrHP & MaxHP (9253 = 0x2425)
arr[0x184] = 0x25; arr[0x185] = 0x24; arr[0x186] = 0x00; arr[0x187] = 0x00;
arr[0x188] = 0x25; arr[0x189] = 0x24; arr[0x18A] = 0x00; arr[0x18B] = 0x00;
// Mana değerleri (100 = 0x64)
arr[0x192] = 0x64; arr[0x193] = 0x00; arr[0x194] = 0x00; arr[0x195] = 0x00;
arr[0x196] = 0x64; arr[0x197] = 0x00; arr[0x198] = 0x00; arr[0x199] = 0x00;
// Status & Position
arr[0x19A] = 0x01; // Durum: Meşgul
arr[0x19E] = 0x0C; // xPos: 12
arr[0x1A0] = 0x22; // yPos: 34
// ----------------------------------------------------------------


if (arr.size() < 0x1A1) {
std::cerr << "Yetersiz buffer boyutu! En az 0x1A1 (" << 0x1A1 << ") byte gereklidir.\n";
return 1;
}


while (true) {
system("cls");


std::wstring mobName;
for (int i = 0; i < 32; i += 2) {
wchar_t ch = arr | (arr[i + 1] << 8);
if (ch == 0) break;
mobName += ch;
}

// Mob özelliklerini oku
uint32_t currentHP = readUInt32(arr, 0x184);
uint32_t maxHP = readUInt32(arr, 0x188);
uint32_t currentMana = readUInt32(arr, 0x192);
uint32_t maxMana = readUInt32(arr, 0x196);
uint8_t status = arr[0x19A];
uint8_t xPos = arr[0x19E];
uint8_t yPos = arr[0x1A0];

// Mob bilgileri
std::wcout << L"Yaratık Adı : " << mobName << std::endl;
std::cout << "Mevcut HP : " << currentHP << std::endl;
std::cout << "Max HP : " << maxHP << std::endl;
std::cout << "Mevcut Mana : " << currentMana << std::endl;
std::cout << "Max Mana : " << maxMana << std::endl;
std::cout << "Durum : " << (int)status << " (" << (status == 1 ? "Meşgul" : "Boşta") << ")" << std::endl;
std::cout << "Pozisyon : " "xPos : "<< (int)xPos << " yPos : "<< (int)yPos << std::endl;


std::this_thread::sleep_for(std::chrono::milliseconds(200));
}

return 0;
}
Bu şekilde patternden statik okuma yapabiliyorum fakat benim verdiğim patterndeki değerleri okutabiliyorum cheat engine ile bu patterni arattığımda bulunduğum alanda bu patterne ait mobdan kaç tane varsa hepsi Cheat Enginede gözüküyor örnek bu patterni arattığımda bulunduğum Alanda 5 tane var ve hepsini gösteriyor.
C++ ile bunu nasıl koda dökebilirim yani bu 5 mob'u kendisi tarayıp ve ona gidecek Oto Saldırı kısmına henüz geçmedim ilk defa AoB kullanıyorum o yüzden burayı yaptıktan sonra geçeceğim.
 
Uzman Üye
Katılım
16 May 2018
Mesajlar
210
Çözümler
1
Tepki puanı
32
Ödüller
10
Yaş
30
8 HİZMET YILI
eğer bu aob dinamikse bu şekilde bi array bulabilirsin 1-2 tane ama diğer entity belleğin başka yerinde olabilir aritmatik değil yani en bilindik node yapısı black-red tree algoritması yapıyı çözüp otomasyonunu sağladıysan moba click atıp gidip saldırıyosa o fonksiyona erişicen öyle bi fonksiyon yoksa oyunda aimbotla aynı mantık en yakın mesafeyi hesaplayıp üçgen hesabı bile yapmana gerek yok 2d oyun zaten move fonksiyonu bulup moba yürütüp attack fonksiyonunu call edicen
 
Üye
Katılım
24 Ocak 2023
Mesajlar
7
Tepki puanı
1
Ödüller
2
Yaş
35
3 HİZMET YILI
Oyunda her entity belirli bir adrese tahsis ediliyor, eğer entity ölürse, tekrar spawn olduğunda bu adres değişiyor. Ben AoB kullanmamdaki amacım bu entitylerin adresini sabit bir şekilde bulabilmekti fakat AoB'yi nasıl kod'a dökeceğimi bilmiyorum. Oyundaki mantık şu şekilde ilerliyor her entitynin CreatureID'si bulunuyor. Oyun zaten 2D olduğu için Cursor (imleç) mantığıyla çalışıyor. Yani CursorID'nin sabit Adresini bulup CreatureID değerini içerisine atadığın zaman otomatik olarak mob'a kilitleniyor fakat input bekliyor yani saldırı fonksiyonunu çağırmanız gerekiyor.

Buraya kadar sıkıntı yok, şimdi ben bu AoB patterni ile ne yapacağım da bu entitylerin CreatureID'sini alıp, gerekli şartlar sağlanıyor mu kontrol edip, sürekli olarak moblara saldırmasını sağlayacağım.

EK BİLGİ : Oyunda karakterin hareket etmesi için Cursor ile tıklamak yetiyor aynı şey saldırı içinde geçerli, rakibin üzerine tıkladığında otomatik saldırıyor.

Pattern bu şekilde:
4D 00 75 00 74 00 61 00 6E 00 74 00 20 00 6F 00
66 00 20 00 43 00 6C 00 6F 00 61 00 63 00 61 00 // İlk 2 satır, yani ilk 0x0 offsetinden 0x32 offsetine kadar. 32 byte Mob Name temsil eden byte dizisi
?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ?? 25 24 00 00 25 24 00 00 // 0x184 offsetinden 0x191 offsetine kadar. Son 8 byte'ın ilk 4 byte'ı CurrentHP, son 4 byte'ı MaxHP değerini tutuyor.
64 00 00 00 64 00 00 00 ?? ?? ?? ?? ?? ?? ?? ?? // 0x192 offsetinden 0x200 offsetine kadar.İlk 8 byte'ın ilk 4 byte'ı CurrentMana, son 4 byte'ı MaxMana değerini tutuyor. - 13 ve 15. bytelar position değerlerini tutuyor 13. byte mob'un xPos değerini 15. byte mob'un yPos değerini tutuyor. - 9. Byte Mob'un Status değeri yani 1 ise Busy, 0 ise Idle
?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??
?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ??

Mob Name : Veri Tipi Unicode String
CurrentHP : Veri Tipi 4 Byte
MaxHP : Veri Tipi 4 Byte
CurrentMana : Veri Tipi 4 Byte
MaxMana : Veri Tipi 4 Byte
xPos : Veri Tipi Byte
yPos : Veri Tipi Byte

Cheat Engine mantığında bir kod yazdım, bu kod warspear.exe adresindeki benim patternim ile eşleşen adresleri buluyor ama benim tek ihtiyacım olan şey bu değil. Bu pattern ile eşleşen adresleri bulup patterndeki byteları örneğin "25 24 00 00 25 24 00 00" buradaki 8 byte okumasını istiyorum bunları dinamik olarak yani bellekteki güncel değeri okuyacağı şekilde nasıl yapabilirim?

Byte dizisinin başlangıç noktasını BaseAdress olarak alıp normal Entity okuma mantığındaki gibi offsetler ile patterni mi gezmem gerekiyor ?

Doğru yöntemin bu olduğundan da emin değilim çünkü bu patterni bellekte tararken çok uzun sürüyor ve basit bir kod olmasına rağmen sistem kaynaklarını fazlasıyla kullanıyor buna ek olarak ben her mob öldürdüğümde bu adresler sürekli değişecek ve ben arka planda pattern'e uygun adresleri tekrar taratacağım yani epey bir sistem yükü getirecek diye düşünüyorum.

Bilgisiyle aydınlatacak birisi yok mu ya da yol gösterecek ?
 
Son düzenleme:
Uzman Üye
Katılım
16 May 2018
Mesajlar
210
Çözümler
1
Tepki puanı
32
Ödüller
10
Yaş
30
8 HİZMET YILI
buldugun bitane entity nin yapısı bunun basesi map vs değişitirince değişmiyosa bikereye mahsus alıcan runtime da sonra offset ekleyip hp pozisyon cart curt yani sürekli aob scan yapan bi loop içinde onları tek tek okumak mantıksız bide inputtan ziyade attack fonksiyonun dışardan tetiklicek bi değişken var mı m_bAttack gibi
 
Üye
Katılım
24 Ocak 2023
Mesajlar
7
Tepki puanı
1
Ödüller
2
Yaş
35
3 HİZMET YILI
"buldugun bitane entity nin yapısı bunun basesi map vs değişitirince değişmiyosa bikereye mahsus alıcan runtime da sonra offset ekleyip hp pozisyon cart curt yani sürekli aob scan yapan bi loop içinde onları tek tek okumak mantıksız"

Burayı anlayamadım, örnek olarak verebileceğin bir kod var mı veya biraz daha detay verir misin?

Attack fonksiyonunu henüz bulmadım çünkü saldırı işlevini sendpacket ile yapmayacağım. CursorID'nin değerine CreatureID değerini atadığın zaman cursor otomatik olarak mob'u takip ediyor. Geriye sadece saldırı yapmak kalıyor bunuda "ENTER" tuşu ile yapabiliyorsun o şekilde yapmayı düşünüyorum.


AoB Patternim ile 1. CE taraması
Bağlantıları görmek için lütfen Giriş Yap


AoB Patternim ile 2. CE taraması (AYNI PATTERN)
Bağlantıları görmek için lütfen Giriş Yap


5 adresin hepsi bulunduğum alandaki mobları temsil ediyor.
 
Son düzenleme:
Uzman Üye
Katılım
16 May 2018
Mesajlar
210
Çözümler
1
Tepki puanı
32
Ödüller
10
Yaş
30
8 HİZMET YILI
Node yapısını çözmekle uğraşma ortak bi fonksiyon bul misal move gibi registere kanca at bütün baseleri çek şunun gibi
 
Banlı Üye
Katılım
6 Mar 2025
Mesajlar
78
Tepki puanı
3
Yaş
34
1 HİZMET YILI
Aob dinamikse, adres değişiyor demektir adres bulmak için pattern scan kullan, offsetlerle işini hallet ya da signature scan dene, belki tutar. Başka yolu yok.
 
Üst