Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Исходник [Сурс] Arena Breakout Infinite — SDK Reference: Оффсеты, GNames XOR и W2S

Sloppy
Начинающий
Начинающий
Статус
Оффлайн
Регистрация
13 Фев 2026
Сообщения
395
Реакции
8
Народ, кто сейчас ковыряет ABI под свежие патчи, ловите скомпилированный SDK Reference. Собрал в одну кучу оффсеты, логику декрипта имен и нормальный W2S, чтобы не изобретать велосипед.

Техническое мясо
В этом патче разрабы немного подвинули структуры. Основные моменты:
  1. CameraCachePrivate уехал с 0x20E0 на 0x20F0. Если у вас игроки и лут рисуются в одной точке или под текстурами — дело в этом.
  2. FNameID теперь строго 0x20 (раньше был 0x18). Если вместо имен акторов летит мусор — обновляйте.
  3. Для корректного W2S на ультрашироких мониторах и растянутом разрешении (stretched) добавил Hor+ скейлинг.

Актуальные оффсеты
Код:
Expand Collapse Copy
// UAGame.exe base + offset
GWorld:         0xA36B8B8
GObjects:       0xA5C1E28
GNames:         0xA88C4C0
FNameXORKey:    0xA8444DC
UObjectFNameID: 0x20
 
// UWorld
PersistentLevel:    0x30
OwningGameInstance: 0x180
GameState:          0x120
 
// ULevel
ActorArray:  0x98
ActorCount:  0xA0
 
// Chain: GameInstance -> LocalPlayers -> PlayerController
LocalPlayers:       0x38
PlayerController:   0x30
 
// APlayerController
CameraManager:      0x3B0
AcknowledgedPawn:   0x348    // 0 in menu, valid in-game
 
// APawn
PlayerState:    0x340
RootComponent:  0x170
Mesh:           0x380
 
// USceneComponent (RootComponent)
RelativeLocation:   0x16C   // NOT 0x140 (old dump)
ComponentVelocity:  0x18C
 
// APlayerCameraManager
CameraCachePrivate:          0x20F0   // NOT 0x20E0 (shifted this patch)
CameraCachePrivate_Rotation: 0x20FC
CameraCachePrivate_FOV:      0x2108
 
// APlayerState
TeamIndex: 0x598
 
// ASGCharacter
DeathComponent:     0x1888
CurrentTotalValue:  0x1B5C
WeaponManager:      0x1880
 
// WeaponManager
CurrentWeapon: 0x1F8

Декрипт GNames (XOR)
В ABI имена зашифрованы, просто так их не вытянуть. Вот рабочий алгоритм для обхода этой темы:
Код:
Expand Collapse Copy
void DecryptFName(char* buf, int len, uint8_t xor_key) {
    uint8_t* p = reinterpret_cast<uint8_t*>(buf);
    for (int i = 0; i < len; ++i) {
        uint8_t dl = static_cast<uint8_t>(((xor_key >> 1) & 0x08) ^ xor_key);
        uint8_t cl = static_cast<uint8_t>(dl ^ ((dl & 0x08) << 1));
        uint8_t al = cl;
        al &= 0x10;
        al ^= 0xEF;
        al >>= 1;
        p[i] ^= al;
        p[i] ^= cl;
    }
}
 
std::string GetNameFromIndex(HANDLE h, uintptr_t base, int key) {
    if (key <= 0) return "";
 
    unsigned int chunkIdx = (unsigned int)(key >> 16);
    unsigned short nameIdx = (unsigned short)key;
 
    uintptr_t gnames = base + 0xA88C4C0; // GNAMES
    uintptr_t poolChunk = Read<uintptr_t>(h, gnames + ((chunkIdx + 2) * 8));
    if (!poolChunk) return "";
 
    uintptr_t entry = poolChunk + (2 * nameIdx);
    int16_t header = Read<int16_t>(h, entry);
    int len = header >> 6;
 
    if (len > 0 && len < 256) {
        char buf[256] = {};
        ReadProcessMemory(h, (LPCVOID)(entry + 2), buf, len, NULL);
        buf[len] = '\0';
 
        uint8_t xor_key = Read<uint8_t>(h, base + 0xA8444DC); // FNAME_XOR_KEY
        DecryptFName(buf, len, xor_key);
        return std::string(buf, len);
    }
    return "";
}
}

Универсальный WorldToScreen
Математика под UE4 с учетом коррекции аспекта. Работает на 16:9, 21:9 и кастомных разрешениях:
Код:
Expand Collapse Copy
struct RotMatrix {
    float _11, _12, _13;
    float _21, _22, _23;
    float _31, _32, _33;
};
 
RotMatrix BuildRotationMatrix(FRotator rot) {
    float p = rot.Pitch * (M_PI / 180.f);
    float y = rot.Yaw   * (M_PI / 180.f);
    float r = rot.Roll  * (M_PI / 180.f);
 
    float sp = sinf(p), cp = cosf(p);
    float sy = sinf(y), cy = cosf(y);
    float sr = sinf(r), cr = cosf(r);
 
    RotMatrix m;
    m._11 = cp * cy;     m._12 = cp * sy;             m._13 = sp;
    m._21 = sr*sp*cy - cr*sy;  m._22 = sr*sp*sy + cr*cy;  m._23 = -sr * cp;
    m._31 = -(cr*sp*cy + sr*sy); m._32 = cy*sr - cr*sp*sy;  m._33 = cr * cp;
    return m;
}
 
bool WorldToScreen(FMinimalViewInfo cam, FVector world, FVector2D& screen, int w, int h) {
    RotMatrix m = BuildRotationMatrix(cam.Rotation);
 
    FVector d = { world.X - cam.Location.X, world.Y - cam.Location.Y, world.Z - cam.Location.Z };
 
    float right   = d.X * m._21 + d.Y * m._22 + d.Z * m._23;
    float up      = d.X * m._31 + d.Y * m._32 + d.Z * m._33;
    float forward = d.X * m._11 + d.Y * m._12 + d.Z * m._13;
 
    if (forward < 0.01f) return false;
 
    float fov = cam.FOV;
    if (fov <= 0.0f || fov > 170.0f) fov = 90.0f;
 
    float cx = (float)w / 2.0f;
    float cy = (float)h / 2.0f;
    float aspect = (float)w / (float)h;
    float tanHFOV = tanf(fov * 0.5f * (M_PI / 180.0f));
 
    // Hor+ scaling: fixes ultrawide and stretched
    screen.X = cx + (right / forward) * (cx / tanHFOV);
    screen.Y = cy - (up / forward) * (cx / tanHFOV) * aspect;
 
    return (screen.X >= 0 && screen.X <= w && screen.Y >= 0 && screen.Y <= h);
}

Важное по античиту (ACE)
Метод через ReadProcessMemory сейчас — это гарантированный инста-детект. ACE триггерится на хендлы и RPM очень быстро. Для тестов на твинках пойдет, но если планируете делать что-то серьезное, смотрите в сторону Kernel-драйверов или DMA.

Код:
Expand Collapse Copy
// After getting hProc and base:
uintptr_t world  = Read<uintptr_t>(hProc, base + 0xA36B8B8);
uintptr_t level  = Read<uintptr_t>(hProc, world + 0x30);
uintptr_t actors = Read<uintptr_t>(hProc, level + 0x98);
int count        = Read<int>(hProc, level + 0xA0);
 
for (int i = 0; i < count && i < 2000; i++) {
    uintptr_t actor = Read<uintptr_t>(hProc, actors + (i * 8));
    if (!actor || actor < 0x10000) continue;
 
    int nameID = Read<int>(hProc, actor + 0x20); // UObjectFNameID
    std::string name = GetNameFromIndex(hProc, base, nameID);
    if (name.empty()) continue;
 
    uintptr_t root = Read<uintptr_t>(hProc, actor + 0x170);
    if (root && root > 0x10000) {
        FVector pos = Read<FVector>(hProc, root + 0x16C);
        printf("[%4d] %-40s  pos(%.0f, %.0f, %.0f)\n", i, name.c_str(), pos.X, pos.Y, pos.Z);
    } else {
        printf("[%4d] %-40s  (no root)\n", i, name.c_str());
    }
}

Также учитывайте, что AcknowledgedPawn (0x348) обнуляется в меню и во время загрузки, обязательно ставьте проверку, иначе словите краш.

Кто уже дампил список имен для лут-фильтра, отпишитесь в теме.
 
Назад
Сверху Снизу