C Dilində Yazılmış Proqram ilə Stack Anlayışının Analizi
Buffer Overflow nədir? Stack nədir ? Stack anlayışı nədir? Stack anlayışının analizi necə həyata keçirilir?
Telegram kanalına qoşularaq bu və digər mövzular üzrə quizlərdə iştirak edə bilərsiniz!
Telegram (Kanal): https://t.me/xakeraz_official
C dilində proqramla Stack analizi
Stackin necə işlədiyini yaxşı bir şəkildə başa düşmək üçün onu C dilində yazılmış bir nümunə proqram ilə praktika etmək məsləhətdir. Assembler instruksiyalarını (təlimatlarını) başa düşmək üçün C çox yaxın bir dildir. C dili bilməmək ilə narahat olmağa dəyməz, çünki burada C dilini necə işlədiyini deyil onunla yazılmış kodu sətir sətir izah edib, Assembler ilə necə əlaqəyə girdiyini öyrənəcəyik. Əvvəli paylaşımda HelloWorld.c proqramını yaratmışdıq, bu məsələdə isə bufferin daha yaxşı vizual görünməsi üçün ayrı proqram yazacayıq.
HelloWorld.c paylaşımına keçid etmək üçün: https://xaker.az/2025/07/04/windowsda-c-dilinde-ilk-proqram-yaratmaq-buffer-overflow-hazirligi/
// C setirleri ile islemek ucun string.h kitabxanasi import edilmelidir
#include <string.h>
// metni buffere kocuren funksiya
// char* C dilinde metn informasiyani bildirir
void copy(char* message)
{
//simvol massivini teyin edirik
char buffer[15];
//argumentden gelen metni buffer masivine kopyalayiriq
strcpy(buffer, message);
}
//main funksiyasi proqram icra olunanda ilk icra olunur
int main (int argc, char* argv[])
{
//lokal deyisenin sayilmasi
int local_variable = 1;
//kopyalama funksiyasini cagiririq ve argument veririk.
//istifadeci terefinde daxil edirik
copy (argv[1]);
//proqramdan cixiriq
return 0;
}
Yazdə-ığımız C dilindəki kodlar nəyi ifadə edir? İlkin olaraq biz main funksiyasınl yaradırıq və özünə kommanda sətrindən arqument qəbul edir.argc- arqumentin sayğacıdır, argv – isə massiv simvollarının. Arqumentlərin qiyməti isə 1 dən başlayır həmişə, çünki 0 elə proqramın özünü bildirir. Əsas funksiya olan main funksiyasında biz özümüzdən saxta local_variable dəyişənini təyin etdik ki, reverse engineering zamanı analiz edə bilək. Daha sonra kopyalama funksiyasını çağırır və ona kommanda sətrindən mətn daxil edirik. Funksiya mətn məlumatını alır və yaddaşda saxlayır. Son olaraq daxil edilən məlumatı kommanda sətrindən buffer massivinə qeyd edirik.
Immunity Debugger ilə Bufer Analizi
İndi isə yazmış olduğumuz proqramı İmmunity Debugger ilə daha ətraflı ələ alacayıq. Kodu kompilyasiya etmək üçün bizim əvvəlki paylaşımda HelloWorld.c paylaşımında etdiyimiz əməliyyatları yerinə yetirərək exe faylını əldə edəcəyik. Son olaraq SimpleBuffer.exe ikilik faylını əldə edəcəyik.
Proqramı sınaqdan çıxarmaq üçün İmmunity Debugger alətində Open File deyirik və faylı seçirik, Arguments hissəsində isə ABCD qeyd edirik.

İmmunity Debugger proqramı yüklədikdən sonra instruksiya pəncərəsini (sol yuxarı ) aşağı çəkin və aşağıda instruksiyaları görənədək aşağı düşün.
00401460 /$ 55 PUSH EBP
00401461 |. 89E5 MOV EBP,ESP
00401463 |. 83EC 28 SUB ESP,28
00401466 |. 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8] ; |
00401469 |. 894424 04 MOV DWORD PTR SS:[ESP+4],EAX ; |
0040146D |. 8D45 E9 LEA EAX,DWORD PTR SS:[EBP-17] ; |
00401470 |. 890424 MOV DWORD PTR SS:[ESP],EAX ; |
00401473 |. E8 E8250000 CALL <JMP.&msvcrt.strcpy> ; \strcpy
00401478 |. 90 NOP
00401479 |. C9 LEAVE
0040147A \. C3 RETN
0040147B /$ 55 PUSH EBP
0040147C |. 89E5 MOV EBP,ESP
0040147E |. 83E4 F0 AND ESP,FFFFFFF0
00401481 |. 83EC 20 SUB ESP,20
00401484 |. E8 57050000 CALL SimpleBu.004019E0
00401489 |. C74424 1C 0100>MOV DWORD PTR SS:[ESP+1C],1
00401491 |. 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C]
00401494 |. 83C0 04 ADD EAX,4
00401497 |. 8B00 MOV EAX,DWORD PTR DS:[EAX]
00401499 |. 890424 MOV DWORD PTR SS:[ESP],EAX
0040149C |. E8 BFFFFFFF CALL SimpleBu.00401460
004014A1 |. B8 00000000 MOV EAX,0
004014A6 |. C9 LEAVE
004014A7 \. C3 RETN
00401460 /$ 55 PUSH EBP — bu hissədən başlayaraq kopyalama başlayır.
0040147B /$ 55 PUSH EBP — bu hissədən isə əsas funksiya başlayır.
Saxta say dəyişəni olan yerə saxlama nöqtə qoyuruq ki , hərəkətliyi görə bilək bunun üçün sağ klikləyərək Breakpoint - Toggle seçirik. Saxmala nöqtəsi -proqramın hansı hissədə durmasını istədiyimiz yerdir. Saxta dəyişənin kodda aşağıdakı yerdə yerləşir.
00401489 |. C74424 1C 0100>MOV DWORD PTR SS:[ESP+1C],1
Saxlama nöqtəsini təyin etdikdən sonra Run düyməsini sıxaraq, proqramı icra edir və həmin yerdə saxlanılır.

Saxta dəyişənin stackin işləməsini başa düşmək üçün təyin etmişdik. Həmin yerə proqram çatdıqda stacki anlamaq üçün adim adim icra edək bunun üçün Step Over düyməsindən və ya F8 klavişindən istifadə edə bilərik.
0061FF50 ]0061FF80 €ÿa.
0061FF54 |004012F5 õ@. RETURN to SimpleBu.004012F5 from SimpleBu.004011B0
0061FF58 |00000001 ...
Gördüyümüz kimi 1 ədədi 0061FF58 registrinə mənimsədilmişdir. ESP+1C instruksiyasına uyğun olaraq ikilik say sistemində hesablasaq qiymətin 0061FF54 olacağını təyin edə bilərik.
Daha sonra Step Over komamndasından yenə istifadə edin və növbəti sətirdə dayanaq.Kodda da olduğu kimi bu hissədə funksiya çağırılmalı idi.
00401484 |. E8 57050000 CALL SimpleBu.004019E0
Bu instruksiya kopyalama funksiyasını çağıracaqdır amma bu olmazdan əvvəl stack ABCD veriləninin alınması üzrə yoxlanılmalıdır:
0061F818 00C52D18 -Å. ASCII "ABCD"
0061F81C 00000004 ...
Gördüyümüz kimi daxil edilən ABCD mətn informasiyası kopyalama yerinə yetirilməzdən əvvəl yaddaşda saxlanılır.Səbəb olaraq isə verilə dəyər proqram üçün parametr sayılır və onsuz funksiya işləməyəcəkdir.
Proqramın davamını icra etmək üçün Step İnto (Run menyusunda – proqrama daxil olaraq novbeti addim) düyməsindən istifadə edəcəyik.Klaviş olaraq isə F7 düyməsidir.
Kopyalama funksiyasına fikir verək.
00401460 /$ 55 PUSH EBP
00401461 |. 89E5 MOV EBP,ESP
00401463 |. 83EC 28 SUB ESP,28
ESP və EBP bir birinə bərabər olurlar elə deyilmi? bu kopyalama funskiyasından irəli gəlir. Cari vəziyyətdə stack boşdur, stack yığını və uzunluğu eyni adresi göstərir.Daha sonra kompilyator ESP registerindən 28 sayır və stackin uzunluğunu daha aşağı qiymət olara seçir. Beləliklə kopyalama funksiyasının stack hazırdır.
0061FEFC |004014A1 ¡@. RETURN to SimpleBu.004014A1 from SimpleBu.00401460
0061FF00 |00C52D18 -Å. ASCII "ABCD"
0061FF04 |00401960 `@. SimpleBu.00401960
0061FF08 |0061FF50 Pÿa.
0061FF0C |004019BB »@. RETURN to SimpleBu.004019BB from <JMP.&msvcrt.atexit>
0061FF10 |00401960 `@. SimpleBu.00401960
0061FF14 |00000000 ....
0061FF18 |0021C000 .À!.
0061FF1C |00000001 ...
Daha sonra Assembler ABCD adresini növbəti stack`a kopyalayır.
00401466 |. 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
00401469 |. 894424 04 MOV DWORD PTR SS:[ESP+4],EAX
Növbəti sətirlər isə stack adresini yuxarıya istiqamətləndirir ki, hansı ki mətn ora kopyalanacaqdır.
0040146D |. 8D45 E9 LEA EAX,DWORD PTR SS:[EBP-17]
00401470 |. 890424 MOV DWORD PTR SS:[ESP],EAX
Aşağıdakı yazıdan görünürki, strcpy funksiyası çağırılmış və ABCD mənbəsinin 0061FEE1 hədəfinə stack məlumatı qeyd edilmişdir.
0061FECC 00401478 x@. /CALL to strcpy from SimpleBu.00401473
0061FED0 0061FEE1 áşa. |dest = 0061FEE1
0061FED4 00C52D18 -Å. \src = "ABCD"
Bizi izləyin:
Telegram (Kanal): https://t.me/xakeraz_official
Paylaşımların səliqəli yığılmış halı: https://t.me/xakerazgroup
Fikir və şərhləriniz : https://t.me/xakerazchat