# İkili Modüllerle Fonksiyon Detour Etme

- **İngilizce aslı:** https://wiki.facepunch.com/gmod/Binary_Modules_Detouring_Functions
- **Çeviri tarihi:** 2025-09-08

## Navigasyon

- [Bazı Bilgiler](https://gmod.tr/wiki/Binary_Modules_Detouring_Functions#someinformation)
- [Başlarken](https://gmod.tr/wiki/Binary_Modules_Detouring_Functions#gettingstarted)
- [İmzayı Alma](https://gmod.tr/wiki/Binary_Modules_Detouring_Functions#gettingthesignature)

  - [Linux](https://gmod.tr/wiki/Binary_Modules_Detouring_Functions#linux)

    - [HxD](https://gmod.tr/wiki/Binary_Modules_Detouring_Functions#hxdlinux)
    - [IDA](https://gmod.tr/wiki/Binary_Modules_Detouring_Functions#idalinux)
  - [Windows](https://gmod.tr/wiki/Binary_Modules_Detouring_Functions#windows)
- [Fonksiyonları saptırma](https://gmod.tr/wiki/Binary_Modules_Detouring_Functions#detouringfunctions)

## Bazı Bilgiler

Bu sayfa, [garrysmod_common](https://github.com/danielga/garrysmod_common) için her şeyi açıklayacaktır.
Bu ayrıca [HxD](https://mh-nexus.de/de/hxd/) ve [IDA](https://hex-rays.com/ida-free/) ile imzaların nasıl bulunacağını da anlatacaktır. Hangisini kullanmak istediğinize karar vermekte özgürsünüz.

## Başlarken

Eğer halihazırda bir projeniz yoksa, [bu sayfayı](https://gmod.tr/wiki/Creating_Binary_Modules:_Premake) takip ederek bir tane oluşturabilir veya [bunun gibi](https://github.com/RaphaelIT7/gmod-common-module-base) bir şablon kullanabilirsiniz.

`premake5.lua` dosyanızı açın ve `CreateProject`'ten sonra bu fonksiyonları çağırın.

```lua
IncludeHelpersExtended()
IncludeDetouring()
IncludeScanning()
```

Bu, fonksiyonları saptırmak için ihtiyaç duyacağımız genişletilmiş yardımcıları, saptırma ve tarama alt modüllerini ekleyecektir.

Dosyanız şuna benzer bir görünüme sahip olmalıdır:

```lua
CreateWorkspace({name = "[Projeniz]", abi_compatible = false})
    CreateProject({serverside = [true or false], manual_files = false})
		[Dahil ettikleriniz ...]
        IncludeHelpersExtended()
        IncludeDetouring()
        IncludeScanning()
```

## İmzayı Alma

Bu bölüm, belirtilen platform için bir imzanın nasıl alınacağını açıklayacaktır.

### Linux

İlk olarak, içinde arama yapmak istediğiniz .so dosyalarından birini açın.
Arama yapmak istediğiniz dosyanın bir _srv.so sürümü olabilir. Eğer varsa, o dosyayı kullanın.

Bu örnek için, `garrysmod/bin/server_srv.so` dosyasından `CServerGameDLL::ShouldHideServer` için imzayı alacağız.

#### HxD (Linux)

İlk olarak, `server_srv.so` dosyasını açın.
ctrl + o tuşlarına basarak veya Dosya->Aç menüsüne giderek bir dosya açabilirsiniz.

Şimdi şuna benzer bir görünüme sahip olmalıdır:

![image.png](https://gmod.tr/api/uploads/wiki/551bcb28483ee875d4d2.png)

Şimdi sadece istediğimiz fonksiyonu aramamız gerekiyor.
Arama kutusunu ctrl + f tuşlarına basarak veya Ara->Ara menüsüne giderek açın.
Şimdi `ShouldHideServer` yazın ve aratın.
Şimdi, `ShouldHideServer` içeren bölüm seçilidir.

![image.png](https://gmod.tr/api/uploads/wiki/3fdc829e26d9b62dcb63.png)

Son nokta ile bir sonraki nokta arasındaki her şeyi seçin, böylece imzamızı elde etmiş oluruz.

![image.png](https://gmod.tr/api/uploads/wiki/f33359459fcc5e580cbe.png)

Ve şimdi `CServerGameDLL::ShouldHideServer` için imzayı elde ettik. Bu durumda imza `_ZN14CServerGameDLL16ShouldHideServerEv`'dir

#### IDA (Linux)

İlk olarak, `server_srv.so` dosyasını açın.
Eğer dosyayı ilk kez açıyorsanız, tüm dosyanın yüklenmesi ve analiz edilmesi biraz zaman alabilir.
Yükleme bittikten sonra şuna benzer bir görünüme sahip olmalıdır:

![image.png](https://gmod.tr/api/uploads/wiki/a9057f318b8db00363b1.png)

Şimdi alt + t tuşlarına basarak veya Ara->Ara menüsüne giderek arama kutusunu açın.
`CServerGameDLL::ShouldHideServer` yazın ve arayın.

![image.png](https://gmod.tr/api/uploads/wiki/cd484df2e12a81e1db08.png)

Şimdi fonksiyon sol listede seçili olmalıdır ve üzerine çift tıklamanız gerekir.

![image.png](https://gmod.tr/api/uploads/wiki/f6deb5eaf18de06f9255.png)

Şimdi bize fonksiyonu ve imzayı bu şekilde göstermelidir.

![image.png](https://gmod.tr/api/uploads/wiki/833af5692b929c6ea876.png)

Ve şimdi `CServerGameDLL::ShouldHideServer` için imzayı elde ettik. Bu durumda imza `_ZN14CServerGameDLL16ShouldHideServerEv`'dir

![image.png](https://gmod.tr/api/uploads/wiki/e49a16c8665d4b4cfb69.png)

### Windows

Yapılacak: Windows için imzanın nasıl alınacağını öğrenin ve belgeleyin.

## Fonksiyonları saptırma.

İlk olarak, gereken her şeyi dahil ediyoruz.

```lua
#include <GarrysMod/FactoryLoader.hpp>
#include <scanning/symbolfinder.hpp>
#include <GarrysMod/Symbol.hpp>
#include <detouring/hook.hpp>
```

Bundan sonra, `Symbol`'ümüzü şu şekilde tanımlıyoruz:

```lua
typedef bool (*ShouldHideServer)();
Detouring::Hook detour_ShouldHideServer;
const std::vector<Symbol> ShouldHideServerSyms = {
	Symbol::FromName("_ZN14CServerGameDLL16ShouldHideServerEv"), // CServerGameDLL::ShouldHideServer için imzamız
};
```

Şimdi sadece onu değiştirmek istediğimiz fonksiyonu tanımlamamız gerekiyor.

```lua
bool hide_server = true;
bool hook_ShouldHideServer()
{
	if (hide_server) {
		return true;
	}

	// Sunucuyu zorla gizli tutmak istemiyorsak, orijinal fonksiyona geri dönebiliriz.
	return detour_ShouldHideServer.GetTrampoline<ShouldHideServer>()();
}
```

Sunucuyu sunucu listesinden gizlemek için true döndürüyoruz.
Bu, hiçbir oyuncunun sunucunuzu bulmasını istemiyorsanız kullanışlıdır.

Geriye kalan tek şey, şimdi asıl fonksiyonu saptırmaktır.

```lua
SourceSDK::ModuleLoader server_loader("server_srv");
SymbolFinder symfinder;

void* sv_shserver = nullptr;

for (const auto& sym : ShouldHideServerSyms) {
	sv_shserver = symfinder.Resolve(server_loader.GetModule(), sym.name.c_str(), sym.length);

	if (sv_shserver)
		break;
}

if (sv_shserver == nullptr) {
	Msg("CServerGameDLL::ShouldHideServer sembolü bulunamadı!\n");
} else {
	Msg("CServerGameDLL::ShouldHideServer bulundu\n");
}

detour_ShouldHideServer.Create(reinterpret_cast<void*>(sv_shserver), reinterpret_cast<void*>(&hook_ShouldHideServer));
detour_ShouldHideServer.Enable();
if (detour_ShouldHideServer.IsValid()) {
	Msg("CServerGameDLL::ShouldHideServer için geçerli saptırma\n");
} else {
	Msg("CServerGameDLL::ShouldHideServer için geçersiz saptırma\n");
}
```

Ayrıca Sunucuyu gizlemek için bir Lua fonksiyonu da ekleyebiliriz.
Sonunda, dosyanız şuna benzer bir görünüme sahip olabilir:

```lua
#include <GarrysMod/FactoryLoader.hpp>
#include <scanning/symbolfinder.hpp>
#include <GarrysMod/Symbol.hpp>
#include <detouring/hook.hpp>

typedef bool (*ShouldHideServer)();
Detouring::Hook detour_ShouldHideServer;
const std::vector<Symbol> ShouldHideServerSyms = {
	Symbol::FromName("_ZN14CServerGameDLL16ShouldHideServerEv"), // CServerGameDLL::ShouldHideServer için imzamız
};

bool hide_server = true;
bool hook_ShouldHideServer()
{
	if (hide_server) {
		return true;
	}

	// Sunucuyu zorla gizli tutmak istemiyorsak, orijinal fonksiyona geri dönebiliriz.
	return detour_ShouldHideServer.GetTrampoline<ShouldHideServer>()();
}

// Sunucuyu gizlemek için bir Lua fonksiyonu. game.HideServer()
LUA_FUNCTION(HideServer)
{
	LUA->CheckType(1, Type::Bool);
	hide_server = LUA->GetBool(1);

	return 0;
}

GMOD_MODULE_OPEN()
{
	LUA->PushSpecial(GarrysMod::Lua::SPECIAL_GLOB);
		LUA->GetField(-1, "game");
			LUA->PushCFunction(HideServer);
			LUA->SetField(-2, "HideServer");
	LUA->Pop(2);

	SourceSDK::ModuleLoader server_loader("server_srv");
	SymbolFinder symfinder;

	void* sv_shserver = nullptr;

	for (const auto& sym : ShouldHideServerSyms) {
		sv_shserver = symfinder.Resolve(server_loader.GetModule(), sym.name.c_str(), sym.length);

		if (sv_shserver)
			break;
	}

	if (sv_shserver == nullptr) {
		Msg("CServerGameDLL::ShouldHideServer sembolü bulunamadı!\n");
	}
	else {
		Msg("CServerGameDLL::ShouldHideServer bulundu\n");
	}

	detour_ShouldHideServer.Create(reinterpret_cast<void*>(sv_shserver), reinterpret_cast<void*>(&hook_ShouldHideServer));
	detour_ShouldHideServer.Enable();
	if (detour_ShouldHideServer.IsValid()) {
		Msg("CServerGameDLL::ShouldHideServer için geçerli saptırma\n");
	}
	else {
		Msg("CServerGameDLL::ShouldHideServer için geçersiz saptırma\n");
	}

	return 0;
}

GMOD_MODULE_CLOSE()
{
	detour_ShouldHideServer.Destroy(); // Saptırmamızı kaldırıyoruz.

	return 0;
}

[...]
```

Şimdi her şeyi test edebilirsiniz ve beklendiği gibi çalışmalıdır.

- [GMod Wiki ana sayfası](https://gmod.tr/wiki)

---

[Tüm sunucular](https://gmod.tr/) · [GmodTR Launcher](https://gmod.tr/launcher) · [Rehber](https://gmod.tr/rehber) · [GMod Wiki](https://gmod.tr/wiki) · [GmodTR nedir?](https://gmod.tr/hakkinda) · [Sunucu ekle](https://gmod.tr/sunucu-ekle) · [Discord](https://discord.gg/gmodtr)

Kaynak: https://gmod.tr/wiki/Binary_Modules_Detouring_Functions
