- Katılım
- 26 Eki 2021
- Konular
- 132
- Mesajlar
- 827
- Çözüm
- 6
- Online süresi
- 3mo 5d
- Reaksiyon Skoru
- 938
- Altın Konu
- 39
- Başarım Puanı
- 184
- Yaş
- 28
- MmoLira
- 4,960
- DevLira
- 6
ROHAN2 WORLD 1-120 TR TİPİ OFFICIAL YOHARA, BALATHOR VE AMON! 80. GÜNÜNDE! +10.000 ONLİNE! HİLE VE BOT %100 ENGELLİ HEMEN TIKLA!
Fixledim diye düşünmeyin hiç bir zaman her zaman bir açık muhakkak oluyor. Desc.cpp'yi zaten detaylı olarak incelerseniz hiç dokunmamış olan birinin yaşama şansı bırakmıyor direkt tamamıyla açık.
@RASCALAC dostum ile birebir ele aldığımız bir konuydu.
Çok uzatmayacağım, neyden olduğunu zaten sorunu yaşayanlar iyi bilecektir. Burada yapmış olduğum düzenlemedeki değerleri kendinize göre düzenlemeyi unutmayın.
Buffer fixidir. Handhsake Login olayını da ilk müsaitlikte paylaşacağım.
Not : Bu 15 Mart Pazar günü olan Tayland biletimin iptal olması nedeniyle Iran ve Israil'e olan nefretle hazırlanmış bir şeydir.
libthecore/src/buffer.cÇok uzatmayacağım, neyden olduğunu zaten sorunu yaşayanlar iyi bilecektir. Burada yapmış olduğum düzenlemedeki değerleri kendinize göre düzenlemeyi unutmayın.
Buffer fixidir. Handhsake Login olayını da ilk müsaitlikte paylaşacağım.
Not : Bu 15 Mart Pazar günü olan Tayland biletimin iptal olması nedeniyle Iran ve Israil'e olan nefretle hazırlanmış bir şeydir.
Şunu bul :
Kod:
#define __LIBTHECORE__
#include "stdafx.h"
static LPBUFFER normalized_buffer_pool[32] = { NULL, };
#define DEFAULT_POOL_SIZE 8192
Altına ekle
Kod:
#define MAX_NETWORK_BUFFER (8 * 1024 * 1024)
Şunu bul :
Kod:
LPBUFFER buffer_new(int size)
{
if (size < 0) {
return NULL;
}
Altına ekle
Kod:
if (size > MAX_NETWORK_BUFFER)
{
sys_err("buffer_new: size too large (%d)", size);
return NULL;
}
Şuna gel
Kod:
void buffer_write(LPBUFFER& buffer, const void *src, int length)
Komple değiştir
Kod:
void buffer_write(LPBUFFER& buffer, const void *src, int length)
{
if (!buffer || !src)
return;
if (length <= 0)
return;
if (length > MAX_NETWORK_BUFFER)
{
sys_err("buffer_write: requested length too large (%d)", length);
return;
}
if (buffer->write_point_pos > MAX_NETWORK_BUFFER - length)
{
sys_err("buffer_write: write_point_pos overflow (%d + %d)", buffer->write_point_pos, length);
return;
}
if (buffer->write_point_pos + length > MAX_NETWORK_BUFFER)
{
sys_err("buffer_write: buffer limit exceeded (%d + %d > %d)",
buffer->write_point_pos, length, MAX_NETWORK_BUFFER);
return;
}
if (buffer->write_point_pos + length > buffer->mem_size)
{
buffer_realloc(buffer, buffer->write_point_pos + length + MIN(10240, length));
if (!buffer)
return;
if (buffer->write_point_pos + length > buffer->mem_size)
{
sys_err("buffer_write: realloc failed (%d + %d > %d)",
buffer->write_point_pos, length, buffer->mem_size);
return;
}
}
thecore_memcpy(buffer->write_point, src, length);
buffer_write_proceed(buffer, length);
}
Şunu bul
Kod:
void buffer_read_proceed(LPBUFFER buffer, int length)
İçerisinde şu var
Kod:
if (length < buffer->length)
{
if (buffer->read_point + length - buffer->mem_data > buffer->mem_size)
{
sys_err("buffer_read_proceed: buffer overflow! length %d read_point %d", length, buffer->read_point - buffer->mem_data);
abort();
}
buffer->read_point += length;
buffer->length -= length;
Şununla değiştir
Kod:
if (length < buffer->length)
{
if (buffer->read_point + length - buffer->mem_data > buffer->mem_size)
{
sys_err("buffer_read_proceed: buffer overflow! length %d read_point %d",
length, (int)(buffer->read_point - buffer->mem_data));
buffer_reset(buffer);
return;
}
buffer->read_point += length;
buffer->length -= length;
Şunu bul
Kod:
void buffer_write_proceed(LPBUFFER buffer, int length)
Şununla komple değiş
Kod:
void buffer_write_proceed(LPBUFFER buffer, int length)
{
if (!buffer)
return;
if (length < 0)
{
sys_err("buffer_write_proceed: negative length %d", length);
return;
}
if (buffer->write_point_pos + length > buffer->mem_size)
{
sys_err("buffer_write_proceed: overflow (%d + %d > %d)",
buffer->write_point_pos, length, buffer->mem_size);
return;
}
buffer->length += length;
buffer->write_point += length;
buffer->write_point_pos += length;
}
Şunu bul
Kod:
void buffer_adjust_size(LPBUFFER& buffer, int add_size)
Şununla değiştir
Kod:
void buffer_adjust_size(LPBUFFER& buffer, int add_size)
{
if (!buffer)
return;
if (add_size <= 0)
return;
if (buffer->write_point_pos > MAX_NETWORK_BUFFER - add_size)
{
sys_err("buffer_adjust_size: overflow (%d + %d)",
buffer->write_point_pos, add_size);
return;
}
if (buffer->mem_size >= buffer->write_point_pos + add_size)
return;
sys_log(0, "buffer_adjust %d current %d/%d", add_size, buffer->length, buffer->mem_size);
buffer_realloc(buffer, buffer->write_point_pos + add_size);
}
Şunu bul
Kod:
void buffer_realloc(LPBUFFER& buffer, int length)
{
Başına ekle
Kod:
if (length > MAX_NETWORK_BUFFER)
{
//sys_err("buffer_realloc overflow attempt %d", length);
return;
}
game/src/desc.cpp
Bul
Kod:
void DESC::Initialize()
{
m_bDestroyed = false;
Altına ekle
Kod:
m_dwConnectTime = 0;
m_dwPacketTick = 0;
m_iPacketCounter = 0;
Bul
Kod:
bool DESC::Setup(LPFDWATCH _fdw, socket_t _fd, const struct sockaddr_in & c_rSockAddr, DWORD _handle, DWORD _handshake)
İçinde şu ikisini bul
Kod:
m_lpFdw = _fdw;
m_sock = _fd;
Altına ekle :
Kod:
m_dwConnectTime = get_global_time();
Tekrar ::Setup içinde arat
Kod:
m_lpOutputBuffer = buffer_new(DEFAULT_PACKET_BUFFER_SIZE * 2);
Altına ekle
Kod:
m_lpInputBuffer = buffer_new(MAX_INPUT_LEN);
if (!m_lpOutputBuffer || !m_lpInputBuffer)
{
sys_err("DESC::Setup: failed to allocate buffers for %s", m_stHost.c_str());
return false;
}
Tüm fonksiyon örnek olması için :
Kod:
bool DESC::Setup(LPFDWATCH _fdw, socket_t _fd, const struct sockaddr_in & c_rSockAddr, DWORD _handle, DWORD _handshake)
{
m_lpFdw = _fdw;
m_sock = _fd;
m_dwConnectTime = get_global_time();
m_stHost = inet_ntoa(c_rSockAddr.sin_addr);
m_wPort = c_rSockAddr.sin_port;
m_dwHandle = _handle;
m_lpOutputBuffer = buffer_new(DEFAULT_PACKET_BUFFER_SIZE * 2);
m_lpInputBuffer = buffer_new(MAX_INPUT_LEN);
if (!m_lpOutputBuffer || !m_lpInputBuffer)
{
sys_err("DESC::Setup: failed to allocate buffers for %s", m_stHost.c_str());
return false;
}
m_SockAddr = c_rSockAddr;
fdwatch_add_fd(m_lpFdw, m_sock, this, FDW_READ, false);
desc_event_info* info = AllocEventInfo<desc_event_info>();
info->desc = this;
assert(m_pkPingEvent == nullptr);
m_pkPingEvent = event_create(ping_event, info, ping_event_second_cycle);
SetPhase(PHASE_HANDSHAKE);
StartHandshake(_handshake);
sys_log(0, "SYSTEM: new connection from [%s] fd: %d handshake %u output input_len %d, ptr %p",
m_stHost.c_str(), m_sock, m_dwHandshake, buffer_size(m_lpInputBuffer), this);
Log("SYSTEM: new connection from [%s] fd: %d handshake %u ptr %p", m_stHost.c_str(), m_sock, m_dwHandshake, this);
return true;
}
Şunu tamamen değiştir :
Kod:
int DESC::ProcessInput()
Şu şekilde :
Kod:
int DESC::ProcessInput()
{
if (!m_lpInputBuffer)
{
sys_err("DESC::ProcessInput : nil input buffer");
return -1;
}
const DWORD now = get_dword_time();
if (now - m_dwPacketTick >= 1000)
{
m_dwPacketTick = now;
m_iPacketCounter = 0;
}
if (++m_iPacketCounter > 256)
{
sys_err("DESC::ProcessInput: packet flood from %s", GetHostName());
return -1;
}
if (m_iPhase == PHASE_HANDSHAKE)
{
if (get_global_time() - m_dwConnectTime > 10)
{
sys_err("DESC::ProcessInput: handshake timeout %s", GetHostName());
return -1;
}
}
buffer_adjust_size(m_lpInputBuffer, m_iMinInputBufferLen);
ssize_t bytes_read = socket_read(
m_sock,
(char*)buffer_write_peek(m_lpInputBuffer),
buffer_has_space(m_lpInputBuffer)
);
if (bytes_read < 0)
return -1;
if (bytes_read == 0)
return 0;
buffer_write_proceed(m_lpInputBuffer, bytes_read);
if (buffer_size(m_lpInputBuffer) > (2 * 1024 * 1024))
{
sys_err("DESC::ProcessInput: input buffer too large (%u) from %s",
(unsigned)buffer_size(m_lpInputBuffer), GetHostName());
return -1;
}
if (!m_pInputProcessor)
{
sys_err("DESC::ProcessInput: no input processor");
return -1;
}
int iBytesProceed = 0;
while (!m_pInputProcessor->Process(
this,
buffer_read_peek(m_lpInputBuffer),
buffer_size(m_lpInputBuffer),
iBytesProceed))
{
// Infinite loop protection
if (iBytesProceed <= 0)
{
sys_err("DESC::ProcessInput: invalid proceed size %d from %s",
iBytesProceed, GetHostName());
return -1;
}
buffer_read_proceed(m_lpInputBuffer, iBytesProceed);
iBytesProceed = 0;
}
if (iBytesProceed > 0)
buffer_read_proceed(m_lpInputBuffer, iBytesProceed);
return bytes_read;
}
game/src/desc.h
Bul :
Kod:
LPBUFFER m_lpBufferedOutputBuffer;
LPBUFFER m_lpOutputBuffer;
Üstüne dahil et :
Kod:
DWORD m_dwConnectTime;
DWORD m_dwPacketTick;
int m_iPacketCounter;
game/src/desc_manager.cpp
Şunu komple değiştir :
Kod:
LPDESC DESC_MANAGER::AcceptDesc(LPFDWATCH fdw, socket_t s)
Şununla :
Kod:
#include <map>
static std::map<std::string, int> s_ipConnectionCount;
struct IPFloodInfo
{
DWORD lastTime;
int count;
};
static std::map<std::string, IPFloodInfo> s_ipRate;
static DWORD s_lastAcceptTime = 0;
static int s_acceptPerSec = 0;
#define MAX_CONNECTION_PER_IP 20
#define MAX_ACCEPT_PER_SEC 200
#define MAX_ACCEPT_PER_IP_PER_SEC 10
LPDESC DESC_MANAGER::AcceptDesc(LPFDWATCH fdw, socket_t s)
{
socket_t desc;
LPDESC newd;
static struct sockaddr_in peer;
static char host[MAX_HOST_LENGTH + 1];
if ((desc = socket_accept(s, &peer)) == -1)
return nullptr;
strlcpy(host, inet_ntoa(peer.sin_addr), sizeof(host));
DWORD now = get_dword_time();
if (now - s_lastAcceptTime >= 1000)
{
s_lastAcceptTime = now;
s_acceptPerSec = 0;
}
if (++s_acceptPerSec > MAX_ACCEPT_PER_SEC)
{
socket_close(desc);
return nullptr;
}
IPFloodInfo& info = s_ipRate[host];
if (now - info.lastTime < 1000)
{
if (++info.count > MAX_ACCEPT_PER_IP_PER_SEC)
{
socket_close(desc);
return nullptr;
}
}
else
{
info.count = 1;
info.lastTime = now;
}
int& count = s_ipConnectionCount[host];
if (count >= MAX_CONNECTION_PER_IP)
{
socket_close(desc);
return nullptr;
}
++count;
if (g_bAuthServer)
{
if (IsBanIP(peer.sin_addr))
{
socket_close(desc);
return nullptr;
}
}
if (!IsValidIP(admin_ip, host))
{
if (m_iSocketsConnected >= MAX_ALLOW_USER)
{
socket_close(desc);
return nullptr;
}
}
newd = M2_NEW DESC;
crc_t handshake = CreateHandshake();
if (!newd->Setup(fdw, desc, peer, ++m_iHandleCount, handshake))
{
socket_close(desc);
M2_DELETE(newd);
return nullptr;
}
m_map_handshake.emplace(handshake, newd);
m_map_handle.emplace(newd->GetHandle(), newd);
m_set_pkDesc.emplace(newd);
++m_iSocketsConnected;
return newd;
}
Şunun da başına ekle
Kod:
void DESC_MANAGER::DestroyDesc(LPDESC d, bool bEraseFromSet)
{
Şunu
Kod:
if (d->GetHostName() && *d->GetHostName())
{
auto it = s_ipConnectionCount.find(d->GetHostName());
if (it != s_ipConnectionCount.end())
{
if (--it->second <= 0)
s_ipConnectionCount.erase(it);
}
}
Bilgilendirme:
Bu düzenlemeyi yaptığınız ve saldırıyı simule ettiğiniz zaman CPU değerlerinizde hiç bir oynama olmadığını göreceksiniz.
Mantık çok basit, Network Buffer'in maksimum boyutunu 8 MB ile sınırlandırıyoruz. Bu düzenlemeden önce biri ize 50MB, 100MB ya da çöp packet gönderirse buffer büyüyordu. Sonuç olarak da RAM şişmesi, Buffer Overflow ile karşılaşıyordunuz.
Ayrıca bir başkasının paylaştığı düzenlemede şu var:
Bu düzenlemeyi yaptığınız ve saldırıyı simule ettiğiniz zaman CPU değerlerinizde hiç bir oynama olmadığını göreceksiniz.
Mantık çok basit, Network Buffer'in maksimum boyutunu 8 MB ile sınırlandırıyoruz. Bu düzenlemeden önce biri ize 50MB, 100MB ya da çöp packet gönderirse buffer büyüyordu. Sonuç olarak da RAM şişmesi, Buffer Overflow ile karşılaşıyordunuz.
Ayrıca bir başkasının paylaştığı düzenlemede şu var:
Kod:
if (buffer->read_point + length - buffer->mem_data > buffer->mem_size)
{
sys_err("buffer_read_proceed: buffer overflow! length %d read_point %d",
length, buffer->read_point - buffer->mem_data);
abort();
}
Bu direkt kontrolsüz bir büyüme ile crash yemenizi sağlardı.
Desc üzerinde yaptığımız düzenlemede de saniyede 256 paket limit koyuyoruz. Yani biri spam packet gönderirse bu doğrudan connection drop olarak sonuçlanıyor.
Ayrıca bir başka fantastik durum kendimiz simule ederken keşfettiğimiz bağlantı kurup handshake yapmadan socket açık bırakma olayını da yukarıda verdiğimiz if (get_global_time() - m_dwConnectTime > 10) ile engelliyoruz.
Input üzerinde de if (buffer_size(m_lpInputBuffer) > (2 * 1024 * 1024)) ile 2 MB'den büyük pakete müsade etmiyoruz. Gerisi zaten IP başına max 20 bağlantı izni gibi standart flood v.s. korumaları.
Desc üzerinde yaptığımız düzenlemede de saniyede 256 paket limit koyuyoruz. Yani biri spam packet gönderirse bu doğrudan connection drop olarak sonuçlanıyor.
Ayrıca bir başka fantastik durum kendimiz simule ederken keşfettiğimiz bağlantı kurup handshake yapmadan socket açık bırakma olayını da yukarıda verdiğimiz if (get_global_time() - m_dwConnectTime > 10) ile engelliyoruz.
Input üzerinde de if (buffer_size(m_lpInputBuffer) > (2 * 1024 * 1024)) ile 2 MB'den büyük pakete müsade etmiyoruz. Gerisi zaten IP başına max 20 bağlantı izni gibi standart flood v.s. korumaları.
Linkleri görebilmek için Turkmmo Forumuna ÜYE olmanız gerekmektedir.
Son düzenleme:
En Çok Reaksiyon Alan Mesajlar
"Rascal'ın Korumayı Geliştirirken Dinlediği Müzikler"i dinlemek için geldim. Elinize sağlık.
m_lpInputBuffer = buffer_new(MAX_INPUT_LEN);
if (!m_lpOutputBuffer || !m_lpInputBuffer) { sys_err("DESC::Setup: failed to allocate buffers for %s", m_stHost.c_str()); return false; }
m_lpInputBuffer = buffer_new(MAX_INPUT_LEN);
Default bir source dosyasını kontrol ettiğimde "buffer_new" pool'dan buffer return eden tipik bir "allocator". Pool içinde uygun bir buffer bulamazsa "allocation" yapıyor
Senayo şu;
1.satır çalıştı -> size bir adres return etti (örn. 0x0..)
if condition geçildi, kod akışı devam ediyor
3.satır çalıştı -> "buffer_new" fonksiyonu size yeni bir adres return etti (örn. 0x0...)
"m_lpInputBuffer" member variable artık "0x02" adresini gösteriyor, 0x01 ise allocate edildi ve geri verilmedi(buffer_delete). Her connection için 2 kez buffer ayırıp(double allocation) 1 tanesini geri veriyorsunuz kısaca. Büyük ihtimalle copy paste hatasıdır. Olası sirkülasyonunda başınızı ağrıtır...
Uzun süre sonra "buffer.c" dosyasına bakmak bile Metin2'nin "yazılım mühendisliği" açısından ne kadar berbat bir codebase olduğunu hatırlattı...
Eline sağlık , yine tam anlamıyla a dan z ye bir fix değil ama oyunu girişleri ayakta tutabildiği kadar tutar.
+ olarak konuda da geçen bunları yapmak src üzerinden sizleri yorar asıl en büyük fixi sunucu aldığınız yer fixler.
Türk Lokasyon ( Emre ) kökten sunucu tabanından bunu fixledi.
Çok fazla kasmamak lazım
Senin mantık bu galiba :
Öğeyi görmek için üye olmalısınız.
silverhand bu s1nwar yaptığı saldırıları engeller mi
Bu doğrudan bufferinize saldırarak CPU'unu fulleyen, herkesin gündeminde olan buffer exploti engeller.
Unutmaman gereken!
Bu saldırı da bir DDoS saldırısıdır. Sana bu konuda en çok yardımcı olması gereken kişi de parasını verip korumalı sunucu aldığın firmadır.
Sonuçta bir sürü IP adresi oyununa paket gönderiyor. Senin sunucunla bağlantı kurabiliyor ki bunu yapabiliyor.
- Katılım
- 30 Ocak 2026
- Konular
- 44
- Mesajlar
- 462
- Çözüm
- 1
- Online süresi
- 2d 19h
- Reaksiyon Skoru
- 276
- Altın Konu
- 0
- Başarım Puanı
- 73
- MmoLira
- 2,596
- DevLira
- 18
Teşekkürler paylaşım için.
- Katılım
- 26 Eki 2021
- Konular
- 132
- Mesajlar
- 827
- Çözüm
- 6
- Online süresi
- 3mo 5d
- Reaksiyon Skoru
- 938
- Altın Konu
- 39
- Başarım Puanı
- 184
- Yaş
- 28
- MmoLira
- 4,960
- DevLira
- 6
Teşekkürler paylaşım için.
Yav dur her konuya spam atma post kasıcam diye ölüleri diriltiyon
- Katılım
- 30 Ocak 2026
- Konular
- 44
- Mesajlar
- 462
- Çözüm
- 1
- Online süresi
- 2d 19h
- Reaksiyon Skoru
- 276
- Altın Konu
- 0
- Başarım Puanı
- 73
- MmoLira
- 2,596
- DevLira
- 18
Herkes yararlansın amaç farkındalık hocamYav dur her konuya spam atma post kasıcam diye ölüleri diriltiyon
- Katılım
- 9 Ocak 2019
- Konular
- 229
- Mesajlar
- 1,347
- Çözüm
- 27
- Online süresi
- 1y 21d
- Reaksiyon Skoru
- 1,295
- Altın Konu
- 2
- TM Yaşı
- 7 Yıl 4 Ay 29 Gün
- Başarım Puanı
- 309
- MmoLira
- 8,336
- DevLira
- 143
m_lpInputBuffer = buffer_new(MAX_INPUT_LEN);
if (!m_lpOutputBuffer || !m_lpInputBuffer) { sys_err("DESC::Setup: failed to allocate buffers for %s", m_stHost.c_str()); return false; }
m_lpInputBuffer = buffer_new(MAX_INPUT_LEN);
Default bir source dosyasını kontrol ettiğimde "buffer_new" pool'dan buffer return eden tipik bir "allocator". Pool içinde uygun bir buffer bulamazsa "allocation" yapıyor
Senayo şu;
1.satır çalıştı -> size bir adres return etti (örn. 0x0..)
if condition geçildi, kod akışı devam ediyor
3.satır çalıştı -> "buffer_new" fonksiyonu size yeni bir adres return etti (örn. 0x0...)
"m_lpInputBuffer" member variable artık "0x02" adresini gösteriyor, 0x01 ise allocate edildi ve geri verilmedi(buffer_delete). Her connection için 2 kez buffer ayırıp(double allocation) 1 tanesini geri veriyorsunuz kısaca. Büyük ihtimalle copy paste hatasıdır. Olası sirkülasyonunda başınızı ağrıtır...
Uzun süre sonra "buffer.c" dosyasına bakmak bile Metin2'nin "yazılım mühendisliği" açısından ne kadar berbat bir codebase olduğunu hatırlattı...
Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)
Benzer konular
- Cevaplar
- 3
- Görüntüleme
- 386
- Cevaplar
- 0
- Görüntüleme
- 266
- Cevaplar
- 1
- Görüntüleme
- 52
- Cevaplar
- 8
- Görüntüleme
- 387