WİNDOWS API

İremDamar
7 min readMay 29, 2024

--

Bu blog yazısında Windows API dünyasını derinlemesine inceleyerek onun temellerini, faydalarını ve çeşitli kullanım örneklerini anlayacağız. İster deneyimli bir geliştirici olun ister yolculuğunuza yeni başlıyor olun, bu makale size Windows API’ye kapsamlı bir giriş sağlayacaktır.

Windows API Nedir?

Windows API (Application Programming Interface), Microsoft’un Windows işletim sistemi için geliştirdiği bir dizi yazılım kütüphanesi ve fonksiyonudur. Geliştiricilerin, Windows işletim sistemi üzerinde çalışan uygulamalar oluşturabilmesi için kullandıkları bir ara yüzdür.

Windows API’nin başlıca özellikleri şunlardır:

  1. İşletim Sistemi Entegrasyonu: Windows API, işletim sisteminin çekirdek bileşenleri ve işlevlerini kullanılabilir hale getirir. Bu sayede geliştiriciler, örneğin dosya işlemleri, ağ bağlantıları, grafik ara yüzü ve diğer sistem kaynaklarına erişebilirler.
  2. Programlama Dili Bağımsızlığı: Windows API, C, C++, C#, VB.NET gibi çeşitli programlama dilleri tarafından kullanılabilir. Bu, geliştiricilere geniş bir seçenek yelpazesi sunar.
  3. Standartlaşma: Windows API, Windows işletim sistemi için ortak bir programlama ara yüzü sağlar. Bu, uygulamaların farklı Windows sürümlerinde tutarlı ve uyumlu çalışmasını sağlar.
  4. Esneklik ve Genişletilebilirlik: Windows API, yeni işlevlerin ve bileşenlerin eklenmesine olanak tanır. Bu sayede, işletim sisteminin yetenekleri zaman içinde genişletilebilir.
  5. Performans Optimizasyonu: Windows API, Windows işletim sisteminin kaynaklarını en verimli şekilde kullanmak için tasarlanmıştır. Bu, uygulamaların yüksek performans sunmasına yardımcı olur.

Geliştiriciler, Windows API’yi kullanarak, işletim sistemi özellikleri ve kaynaklarına erişebilir, kullanıcı ara yüzleri oluşturabilir, ağ iletişimi sağlayabilir ve daha birçok işlevi yerine getirebilirler. Bu, Windows uygulamalarının güçlü ve etkili bir şekilde geliştirilmesine olanak tanır.

Windows API Temellerini Anlayalım

  • DLL (Dinamik Bağlantılı Kütüphaneler): Windows API fonksiyonları, DLL dosyalarında tanımlanır. Uygulamalar, bu DLL’leri çağırarak Windows işletim sistemi işlevlerini kullanır.
  • Fonksiyon Çağrıları: Windows API fonksiyonlarını kullanmak için, geliştiriciler bu fonksiyonları programlarında çağırır. Fonksiyon parametreleri, dönüş değerleri ve hata kodları önemlidir.
  • Veri Tipleri: Windows API, C dilindeki veri tiplerini kullanır. Bu tiplerin anlaşılması, API fonksiyonlarını doğru şekilde kullanmak için önemlidir.
  • Hata İşleme: Windows API fonksiyonları, hata durumlarında belirli hata kodları döndürür. Geliştiricilerin, bu hata kodlarını doğru şekilde yakalayıp işlemesi gerekir.
  • Bellek Yönetimi: Windows API, bellek yönetimi için fonksiyonlar sunar. Uygulamaların, bu fonksiyonları kullanarak belleği doğru şekilde ayırması ve serbest bırakması önemlidir.
  • Olay Yönetimi: Birçok Windows API fonksiyonu, olay tabanlı çalışır. Uygulamalar, bu olayları doğru şekilde yakalayıp işlemelidir.
  • Güvenlik ve Yetkilendirme: Windows API, güvenlik ve yetkilendirme ile ilgili fonksiyonlar sunar. Uygulamaların, bu fonksiyonları kullanarak gerekli erişim haklarını alması gerekir.
  • Programlama Modelleri: Windows API, farklı programlama modelleri (örneğin Win32, .NET) sunar. Geliştiriciler, uygulamalarına uygun programlama modelini seçmelidir.

Windows API Kullanmak Neden Önemlidir ?

  1. İşletim Sistemi Entegrasyonu: Windows API, Windows işletim sistemi ile doğrudan entegre çalışır. Bu sayede, uygulamalar işletim sistemi kaynaklarına (dosya sistemi, ağ, grafikler vb.) doğrudan erişebilir ve sistem özellikleri kullanabilir. Bu, daha güçlü ve daha etkin uygulamalar geliştirmeyi sağlar.
  2. Performans Optimizasyonu: Windows API, Windows işletim sisteminin alt seviye bileşenleriyle etkileşim kurduğu için, uygulamaların yüksek performans göstermesine yardımcı olur. Doğrudan sistem kaynaklarına erişebildikleri için, uygulamalar daha hızlı ve verimli çalışabilir.
  3. Uyumluluk ve Standartlaşma: Windows API, Windows işletim sistemi için ortak bir programlama ara yüzü sağlar. Bu sayede, uygulamalar farklı Windows sürümlerinde tutarlı ve uyumlu çalışır. Ayrıca, geliştiriciler Windows API’yi kullanarak, diğer Windows uygulamaları ile uyumlu yazılımlar geliştirebilirler.
  4. Genişletilebilirlik: Windows API, yeni işlevlerin ve bileşenlerin eklenmesine olanak tanır. Bu, işletim sisteminin yeteneklerini zaman içinde geliştirmeye ve güncelleştirmeye imkan sağlar. Geliştiriciler, bu yeni özellikleri kullanarak uygulamalarını da geliştirebilirler.
  5. Güvenlik ve Yetkilendirme: Windows API, güvenlik ve yetkilendirme ile ilgili işlevler sunar. Geliştiriciler, bu işlevleri kullanarak, uygulamalarının güvenli ve doğru yetkilendirmelerle çalışmasını sağlayabilirler.
  6. Geniş Destek Topluluğu: Windows API, Microsoft tarafından uzun yıllardır kullanılan ve geliştiriciler tarafından yaygın olarak kullanılan bir ara yüzdür. Dolayısıyla, geliştiriciler, API hakkında geniş bir bilgi birikimi ve destek topluluğuna erişebilirler.

Windows API Geliştirmede Temel Kavramlar

  1. Windows Handle’ları (Kolları): Windows API’de birçok kaynak, bir “kolla” (handle) adı verilen bir türle temsil edilir. Bir kolla, işletim sistemi tarafından atanmış benzersiz bir tanımlayıcıdır ve kaynağa erişim sağlar. Örneğin, pencere kolları (HWND), dosya kolları (HANDLE) ve süreç kolları (HANDLE) gibi çeşitli türlerde kollar bulunur.

2. Windows Mesaj Döngüsü: GUI (Grafiksel Kullanıcı Arayüzü) uygulamalarında, Windows iletişim kurmak için bir mesaj döngüsü kullanılır. Bu döngü, Windows işletim sistemi tarafından oluşturulan olayları (örneğin, fare tıklamaları, klavye girişleri) işler ve uygun işlem kodunu çalıştırır.

3. Pencere Prosedürleri (WndProc): Her pencere, bir pencere prosedürü adı verilen bir işlevle ilişkilendirilir. Pencere prosedürü, pencereye gönderilen mesajları işler ve uygun yanıtları üretir. Örneğin, bir pencere prosedürü, kullanıcının bir düğmeye tıklamasını veya bir pencereyi taşımasını işleyebilir.

Kötü Amaçlı Yazılımlarda Windows API Hashing

Kötü amaçlı bir yazılım geliştiricisi, Windows API’deki fonksiyonları tespit edip bunları sağlayacağı zarar için kullanmayı planlamaktadır. Bu kapsamda, aşağıdaki adımları izleyebilir:

  • Windows API Fonksiyonlarını Tespit Etme: Kötü amaçlı yazılım geliştiricisi, Windows API’deki fonksiyonların listesini elde eder. Bunun için MSDN, Windows SDK veya diğer kaynaklardaki belgeleri kullanabilir.
  • Fonksiyonların Tanınmasını Zorlaştırma: Kötü amaçlı yazılımın tespitini güçleştirmek için, API fonksiyonlarının adlarını hash değerleriyle değiştirebilir. Bu sayede, statik analiz araçlarının fonksiyonları tanıması zorlaşır.

Örneğin, “CreateProcessW” fonksiyonunu aşağıdaki gibi bir hash değeriyle değiştirebilir:

DWORD hash_CreateProcessW = 0xF2D82A45;
  • Dinamik Çağrı Mekanizması Oluşturma: Kötü amaçlı yazılım, API fonksiyonlarını hash tabanlı olarak çağıran bir mekanizma geliştirir. Buna göre, fonksiyonun adı yerine hash değeri kullanılır.

Örnek uygulama kodu:

DWORD hash_CreateProcessW = 0xF2D82A45;

BOOL RunMaliciousProcess() {
typedef BOOL(WINAPI* PFN_CreateProcessW)(
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
);

PFN_CreateProcessW pfnCreateProcessW = (PFN_CreateProcessW)GetProcAddress(GetModuleHandleA("kernel32.dll"), (LPCSTR)hash_CreateProcessW);
if (pfnCreateProcessW) {
// Kötü amaçlı işlem başlatma kodları...
return pfnCreateProcessW(/* parametreler */);
}
return FALSE;
}

Bu şekilde, kötü amaçlı yazılım geliştiricisi Windows API fonksiyonlarına erişebilir ve bunları kötü amaçlı eylemler için kullanabilir. Statik analiz araçlarının tespitinden kaçınmak için fonksiyon adları yerine hash değerlerini kullanır.

Senaryo1: Bir güvenlik analisti, kötü amaçlı bir yazılımın Taşınabilir Yürütülebilir Dosyasının (PE dosyası) İçe Aktarma Adres Tablosundan (IAT) gizlenmiş olan API çağrılarını keşfetmek ve analiz etmek için bir laboratuvar oluşturur.

int main()
{
/*
malware analysis
*/
Create Thread(NULL,NULL,NULL,NULL)
return1 ;
}

Yukarıdaki kodu derleyip PE parser ile incelediğimizde kernel32 kütüphanesinden ithal edilmiş 27 fonksiyonun olduğunu görüyoruz. Create Thread bunlardan birisidir.

Bazı durumlarda, kötü amaçlı yazılım analistlerinin, kötü amaçlı yazılımın tespiti için genellikle kullanılan yöntemlerden kaçınmasını isteyebiliriz. Özellikle, kötü amaçlı yazılımımızın, ikili dosyanın IAT’sini inceleyerek veya dize karşıtı analizi yaparak kolayca tespit edilmesini istemeyebiliriz. Bu tür bir tespit riskini azaltmanın bir yolu, API karma yöntemini kullanmaktır. Bu yaklaşım, kötü amaçlı yazılımın çalışma zamanında API işlevlerine olan bağımlılığını azaltarak, örneğin CreateThread gibi, API işlevlerinin doğrudan adreslerini çözerek yapılabilir. Bu şekilde, kötü amaçlı yazılımın IAT’sinden bağımsız olarak API işlevlerini çağırabiliriz. Bu laboratuvarın amacı da, bu tür bir tekniğin gerçek dünyada nasıl etkili olduğunu görmektir.

API karma işlemi arbitrary, belirli bir metin dizesi için karma değerini hesaplayan (kendi başımıza oluşturabileceğimiz) bir işlev/algoritmadır.

# İşlev adını alın
$APIsToHash = @("CreateThread")

# Her bir API için karma değerini hesapla
$APIsToHash | ForEach-Object {
$api = $_

# Karma değerini başlangıç değeriyle başlat
$hash = 0x35

# Karakterleri diziye dönüştür
$apiChars = $api.ToCharArray()

# Her bir karakteri döngüye al
$apiChars | ForEach-Object {
$char = $_

# Karakterin onaltılı gösterimini al
$charHex = '0x{0:x}' -f [int]$char

# Karma hesaplama
$hash = ($hash * 0xab10f29f + [int]$char) -band 0xffffff
}

# Karma değerini yazdır
Write-Host "$api : $('0x00{0:x}' -f $hash)"
}

Bu PowerShell betiği, belirli bir işlev adının karma değerini hesaplamak için kullanılabilir. Örneğin, “CreateThread” işlevi için karma değerini hesaplamak için bu betiği kullanabilirsiniz. Bu betik, verilen işlev adı için karma değerini doğru bir şekilde hesaplar.

Bu örnekte, Windows API’yi kullanarak bir uygulama penceresi oluşturup, dosya işlemleri, ağ iletişimi ve güvenlik özelliklerini kullanarak bir demo sunacağım.

#include <windows.h>
#include <iostream>
#include <fstream>
#include <winsock2.h>
#include <security.h>

// Dosya İşlemleri
void WriteToFile(std::string filename, std::string content) {
std::ofstream file(filename, std::ios::out | std::ios::trunc);
if (file.is_open()) {
file << content;
file.close();
std::cout << "Dosya yazıldı: " << filename << std::endl;
} else {
std::cerr << "Dosya açılamadı: " << filename << std::endl;
}
}

// Ağ İletişimi
bool ConnectToServer(std::string host, int port) {
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
std::cerr << "WSAStartup failed." << std::endl;
return false;
}

SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sock == INVALID_SOCKET) {
std::cerr << "Socket creation failed." << std::endl;
WSACleanup();
return false;
}

SOCKADDR_IN addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(host.c_str());
addr.sin_port = htons(port);

if (connect(sock, (SOCKADDR*)&addr, sizeof(addr)) == SOCKET_ERROR) {
std::cerr << "Connection failed." << std::endl;
closesocket(sock);
WSACleanup();
return false;
}

std::cout << "Bağlantı kuruldu." << std::endl;
return true;
}

// Güvenlik Özellikleri
bool GrantAccessToFile(std::string filename, std::string accountName) {
SECURITY_ATTRIBUTES securityAttributes;
securityAttributes.nLength = sizeof(SECURITY_ATTRIBUTES);
securityAttributes.bInheritHandle = FALSE;
securityAttributes.lpSecurityDescriptor = NULL;

HANDLE hFile = CreateFile(
filename.c_str(), GENERIC_WRITE, 0, &securityAttributes,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
);

if (hFile == INVALID_HANDLE_VALUE) {
std::cerr << "Dosya oluşturulamadı: " << filename << std::endl;
return false;
}

PSECURITY_DESCRIPTOR pSD = NULL;
if (!ConvertStringSecurityDescriptorToSecurityDescriptor(
accountName.c_str(), SDDL_REVISION_1, &pSD, NULL)) {
std::cerr << "Güvenlik tanımı dönüştürülemedi." << std::endl;
CloseHandle(hFile);
return false;
}

if (!SetFileSecurity(filename.c_str(), DACL_SECURITY_INFORMATION, pSD)) {
std::cerr << "Dosya güvenlik ayarları güncellenemedi." << std::endl;
LocalFree(pSD);
CloseHandle(hFile);
return false;
}

LocalFree(pSD);
CloseHandle(hFile);
std::cout << "Dosya güvenlik ayarları güncellendi." << std::endl;
return true;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
// Dosya İşlemleri
WriteToFile("example.txt", "Merhaba Dünya!");

// Ağ İletişimi
if (ConnectToServer("example.com", 80)) {
std::cout << "Sunucuya bağlanıldı." << std::endl;
}

// Güvenlik Özellikleri
if (GrantAccessToFile("example.txt", "DOMAIN\\username")) {
std::cout << "Dosya güvenlik ayarları güncellendi." << std::endl;
}

return 0;
}

Bu örnekte, aşağıdaki Windows API işlevlerini kullanıyoruz:

Dosya İşlemleri:

  • CreateFile: Dosya oluşturmak veya açmak için kullanılır.
  • WriteFile: Dosyaya veri yazmak için kullanılır.

Ağ İletişimi:

  • WSAStartup: Winsock başlatmak için kullanılır.
  • socket: Soket oluşturmak için kullanılır.
  • connect: Sunucuya bağlanmak için kullanılır.

Güvenlik Özellikleri:

  • ConvertStringSecurityDescriptorToSecurityDescriptor: Güvenlik tanımını dönüştürmek için kullanılır.
  • SetFileSecurity: Dosya güvenlik ayarlarını güncellemek için kullanılır.

Bu örnekte, önce bir dosyaya “Merhaba Dünya!” yazısını yazıyoruz. Ardından, örnek bir sunucuya bağlanıyoruz. Son olarak, oluşturduğumuz dosyanın erişim haklarını belirli bir kullanıcıya veriyoruz.

Böylece, Windows API’nin temel özellikleri olan dosya işlemleri, ağ iletişimi ve güvenlik özelliklerini bir arada kullanmış olduk.

--

--