DOS ortamında disk erişimi ve disk kullanımı

Diskin yapısı şu şekildedir.

            


 Yukarıdaki şekilde gördüğünüz gibi disklerin üzerindeki dairesel izlere Track veya cylinder denir. Birden fazla disk kullanılırsa bunlar üzerindeki okuyucu kafalara ise head okudukları yüze Side denmektedir. Bir dairesel iz açısal olarak eş bölümlere ayrılmıştır. Bu bölümlere ise Sector denmektedir. Bütün bunlar göz önüne alındığında bir bilginin adresini vermek için kafa veya yüz numarası, izin numarası ve sektor numarası verilmelidir. Genel olarak bir track üzerinde bir sektörün belirlediği alan 512 byte'tır. Ancak bazı SCSI disklerde bu boyut değişebilmektedir. Bir disk üzerindeki
Sektör_Sayısı = (Kafa_Sayısı x Silindir_Sayısı x Sektor_Sayısı)
Bu rakamla bir sektörün boyutu çarpıldığında diskin kapasitesi bulunur.
Diske erişimi kolaylaştırmak için sektörler gruplanarak CLUSTER'lara bölünür. Cluster sektörden farklıdır. Ve formatlama esnasında bir cluster'ın kaç sektör olacağı belirlenir. Mesala bir cluster 8 sektörden oluşuyorsa cluster boyutu 4 KB olarak belirlenir.
Diskin üzerinde belli bloklar vardır. Bunlar
Partition: Partition disk üzerindeki bölümlendirme için kullanılır. Diskin 0. Sektör, 1. Cylinder, 0. Head'de bulunur. Burada bir kod bulunur. Bu kod üzerindeki bilgileri inceleyerek diskin üzerindeki boot sector bulunur. Boot sector belleğe yüklenir. Daha sonra buradaki kod sistemi yükler.
Boot: Her partition'ın başlangıç adresi olarak verilen adreste bulunur. Buradaki bilgi Partition'daki kod tarafından belleğe alınır. Buradaki program önce root dizine bakar. Burada IO.SYS, IO.COM isimli dosyalar aranır. Burada eğer bulunursa FAT'teki başlangıç noktasına gidilir. Buradan bir sonraki devam edeceği yer tespit edilir. Ve okunan Fat başlangıç adresinden data bloğu üzerindeki bilgi okunarak belleğe alınır. Sonrasını ise IO.SYS halleder.
FAT: (File Allocation Table) Burası tüm diskin yerleşim planını içerir. Bir kodla başlar bu FAT'in özelliğini belirtir. Genelde 0F8h değerini taşır. Buna Media Id Byte denir. Herhangi bir sakatlık durumuna karşı FAT 2 kopyadır. Silinen dosyanın adının ilk harfi alt-229 (sigma) yapılır. Dos baktığında eğer ilk harfi sigma ise dosyanın silindiğini kabul ederek bunu listelemez. Silinen bir dosyanın geri getirilmesi işlemi ise şu şekildedir. Dosyanın kaydındaki Fat'teki başlangıç noktası bilgisi alınır. Bu noktadan itibaren dosya boyunu kapsayacak sayıdaki Fat hücresi eğer boş ise dosya geri getirilebilir. Değilse getirilemez. Eğer dosya bölük pörçük yani dosyanın bölümleri diskin bir kaç bölgesinde yer alıyorsa dosya bozuk olarak undelete yapılabilir. Aşağıda örnek bir Root yapısı ve dosyaların yerlerini gösteren bir FAT görülmektedir.
ROOT ENTRY:
Dosya Adı
Dosyanın Fatteki Başlangıç Noktası
Fat Hücre Sayısı
IO.SYS
1
4
MSDOS.SYS
5
1
ÕOMMAND.COM
6
3
ÕONFIG.SYS
8
1
FAT:
Fat Hücre No
1
2
3
4
5
6
7
8
9
İçeriği
2
3
4
0FFFFh (Eof)
0FFFFh (Eof)
0
0
0
0FFFFEh (Bad Sector)
IO.SYS isimli dosya disk üzerinden okunmaya çalışıldığında öncelikle 1. Fat hücresinin işaret ettiği cluster okunur. Daha sonra 1. nolu fat hücresinin işaret ettiği 2 nolu Fat hücresinin işaret ettiği Cluster okunur. Arkasından 3. Hücre işlem görür. 4. Hücredeki EOF ifadesine istinaden okuma işlemi durur.
MSDOS.SYS isimli dosya ise doğrudan 5. nolu fat hücresinin işaret ettiği cluster üzerinden okunur ve işlem sonlanır.
COMMAND.COM ve CONFIG.SYS isimli dosyalar silinmiştir. Eğer en son config.sys dosyası kopyalanmışsa ve ilkin command.com dosyası undelete yapılırsa command.com dosyasının son bölümünde CONFIG.SYS olacak şekilde dosya bozuk olarak undelete yapılır. Eğer geri getirilmezde CONFIG.SYS dosyası istenirse bu durumda CONFIG.SYS dosyası başarıyla geri getirilecektir. Ama eğer COMMAND.COM tekrar undelete yapılmaya kalkılırsa undelete işlemin gerçekleştirilemeyeceğini söyleyerek çıkacaktır.
9 nolu fat hücresi ise o cluster'ın bozuk olduğuna işaret eder.
WIN 95 ve NT 4.0 dosyalar silindiğinde Recycle.bin isimli görünmez bir dizine taşır. ve nereden attığını bir yere kaydeder. eğer dosya geri getirilirse aynen yerine yerleşir. Eğer Recycle.bin boşaltılmışsa dosyalar o zaman silinmiş demektir.
Dosyaların güvenliği için ve daha hızlı erişmek için dosyaları bir bütün halinde tutmak tavsiye edilir. Bu işlem içinde en azından haftada bir defa DEFRAG programının çalıştırılması yeterli olacaktır.
Elbetteki bu yapıda bir dosyayı okumak için diskin kafası bir ileri bir geri gidip gelecektir. Bunu hızlandırmak amacıyla smartdrv gibi programlar diskin çok okunup yazılan bölümlerini belleğe alır. Diske yazıyorum deyip kandırıp belleğinde bir süre saklar. Disk serbest kaldığı anda bunları yazar. Bu şekilde işlemler yaklaşık 2-50 misli hızlanmaktadır. Ancak bunların sakatlığıda eğer yazmadan makine kapatılırsa yazmak üzere olduğu bilgiler silinir. ve eski durumlarında kalır. Bundan korunmak için makineyi doğrudan kapatmak yerine CTRL-ALT-DEL tuşlarına basarak makinenin en tekrar açılma işlemini başlatmak daha sonra kapatmaktır. Smartdrv türü programlar bu tuşu kontrol ederek eğer belleğinde bir şey kalmışsa bunu diske yazıp ondan sonra makinenin kapanmasını sağlarlar.
Root: Ana dizin veya kök dizine Root adı verilir. Burada dosyaların isimleri ve bazı bilgileri tutulmaktadır. Yapısı şu şekildedir.
İsmi
Boyu
Açıklama
Dosya adı
8 byte
Dosyanın ismi burada tutulur.
Uzantısı
3 byte
Dosyanın uzantısı burada tutulur.
Özellikleri
1 byte
Dosyanın Read only hidden ve bunun gibi bilgileri burada tutulur.
Ayrılmış alan
8 byte
Bu alan DOS tarafından boş bırakılır. Burası NT ve WIN95 türü programlar tarafından uzun dosya isimlerinin kontrolü için kullanılır.
Tarih ve Saat
4 byte
Dosyanın son değiştiği tarih ve saat
Başladığı Yer
2 byte
Dosyanın FAT üzerinde başlangıç noktası
Uzunluğu
4 byte
Dosyanın kaç byte olduğu
Toplam
32 byte

Burada aynı zamanda diskin etiketide saklanır. dosya boyu 0, uzunluğu 0, saat ve tarih bos ve ozelliginde sadece Etiket bilgisi olduğu yazılıdır. Aslında dizinlerde dosyalar gibi disk üzerinde saklanır. ilk açıldıklarında bir cluster boyundadır. Daha sonra yetmediği zaman sanki dosyaya ek yapılıyor gibi eklentiler yapılır. Ancak özelliği Dizin olan bu dosyalar DOS tarafından farklı değerlendirilerek içinin gösterilmesi gibi fonksiyonlar yerine getirilir. Bunun dışında Root dizinin farklı bir özelliği boyu sabittir değişmez. Bu sebeble bazı virüsler kendilerini Root'un en alt kısmına yerleştirirler. Böylece kendilerini gizlemiş olurlar. Win 95 ve NT uzun dosya isimleri için silinmiş dosya kayıtları yaratırlar. ilk byte 0E5h değeridir. Dosya adı, uzantısı ve diğer bilgilerinin yerine dosyanın uzun adının bir kısmı tutulur.
Data: Burada diske kayıtlı dosyaların ve dizinlerin içerikleri kaydedilir.

Dos'ta diske erişim için int 25h ve int 26h kullanılır. Sector No verilerek herhangi bir adrese ulaşılır.
Bunun dışında diske erişmek için Int 13h kullanılır. Bu servis BIOS tarafından hazırlandığından Dos'tan bağımsız olarak kullanılabilir. Bunun dışında CD'ye erişmek için MSCDEX (Microsoft Compact Disk Extention)'in hazırladığı Int 2Fh kullanılır. Bu arada Int 2F çok amaçlı bir servistir. Bu servis içerisinde microsoft'un undocumented (Saklı) servisleride mevcuttur.
DOS'ta iken bir dosya açılması için gereken aşamalar aşağıdaki gibidir.
x Int 21h Servisi üzerinden dosya aç komutu çalıştırılır.
x Int 25h Servisi üzerinden diskten directory entry okunur. Buraya bir dosya kaydı açılır. Bu kayıt 32 byte boyundadır. Öncelikle directory'deki bilgiler okunur. Sonra en alta dosya ile alakalı bilgi eklenir.
x Int 25h kullanılarak FAT okunur buradan boş olan bir Fat hücresi seçilerek bu seçilen hücreye ilkin (EOF) bilgisi kaydedilir. Sonra int 26h ile yazılır.
x Directory entry'e eklenen satıra başlangıç fat hücreno kaydedilerek Int 26h ile yazılır.
x Seçilen başlangıç Fat hücresinin işaret ettiği Data bölgesine dosyanın içeriği yazılır.
x Eğer bu hücrenin belirttiği yer yeterli gelmezse Fat üzerinden tekrar boş bir hücre aranır. Bu hücreye (Eof) ifadesi yazılır. Başladığı fat hücresine de buranın adresi yazılır. Bu hücrenin işaret ettiği yerde kullanılır.
x Dosyayı kapat komutu gelir. Bu komutla dizindeki dosya kaydındaki dosyanın boyu güncellenir.
x Bütün bu işlemler esnasında INT 25h ve INT 26h BPB (Bios Parameter Block)'taki bilgilere uygun olarak adres hesaplamasına gider. Hesapladığı adrese göre INT 13h'ı çağırarak buraya yazma işini gerçekleştirir. INT 13h diske erişmek için gerekli programa sahiptir. Diskin I/O adresine gerekli bilgileri vererek diskin bu adresteki bilgileri okumasını ve aktarmasını sağlar.
x WIN 95 ve NT 4.0 diske erişimi kısıtlamak amacıyla INT 13h'ı kendi üstüne alır ve çağrıları kendisi değerlendirir. Eğer sakatlık yapacak bir çağrı alırsa bunu engeller. Bunun dışında 95 DOS modunda açıldığından uzun dosya isimlerini korumak için diske doğrudan erişimi engellemiştir. Bu engeli kaldırmak için LOCK komutu kullanılır. Engeli tekrar koymak için UNLOCK komutu vardır.

Anti-Debug, Anti-Trace ve Anti Sourcer Metodları

Bilindiği gibi yazılan programlar debug programları ile işleyişleri incelenip farklı işlere zorlanabilirler. Diğer taraftan sourcer türü programlar aracılığıyla yazılan programların kaynak kodları çıkartılabilir. Burada bu türlü işlemlerin nasıl engelleneceği anlatılmaktadır.
Anti-Debugging metodları iki katagoride incelenebilir:
1. Koruma Amaçlı;
2. Kendi Kendini Değiştiren Kodlar.
Bu tür koruma metodları bugünlerde en fazla virüslerde kullanılmaktadır. Bu tür trikler virüsün yaptığı işin çözülmesini engeller böylece virüsün nasıl bulaştığı ve orjinal kodu çözülemez. Ayrıca kaynak kodu da çıkartılamaz. Bu tür örneklere ait kaynak kodlar dökümanın sonuna doğru verilmiştir.
Bu tür triklerin en fazla kullanım alanı bulduğu başka bir alan ise kopyalamaya karşı koruma programlarıdır. Bu tür programlar içeride nasıl kontrol yaptıkları tespit edilemesin diye Anti-Debug, Anti-Trace ve Anti-Source metodlarıyla korunmaktadırlar. Dolayısı ile kırılmaları oldukça güçleşmektedir.
1. Koruma Amaçlı:
Koruma amaçlı metodlar kullanıcının kodu debug etmesi veya kaynak kodunu çıkartmasını engelemek için kullanılır. Bu tür metodlar normal çalışma esnasında düzgün çalışmasına rağmen Debug yapılırken sistemi sakatlamakta veya Debug programını göçertmektedirler.
1.1. Interrupt'ların devre dışı bırakılması:
Interrupt'ların devre dışı bırakılması en çok kullanılan metodlardan biridir. Değişik metodları vardır.
1.1.1. Donanım kontrolü ile interrupt'ın devre dışı bırakılması:
Port 21h üzerinden kontrol edilen 8259 Interrupt kontrolcüsüne komut göndererek IRQ hatlarının devre dışı bırakılması esasına dayanır. Port 21h adresindeki her bit bir IRQ hattını kontrol eder. Bit 0 IRQ 0'ı, Bit 1 IRQ 1'i şeklinde. Buradan 0-7 arası IRQ'lar kontrol edilebilir. Bu arada IRQ 1 klavye kontrolcüsünden gelen sinyali taşır. Klavyeden her tuşa basılışta IRQ1 çağrılır. Bu IRQ'nun karşılığı olan INTERRUPT CPU tarafından çağrılarak basılan tuşla ilgili bilginin klavyenin belleğinden alınması sağlanır. Böylece her tuşa bastığınızda bilgi uçmaz. Belleğe alınır. Eğer Debug işlemi esnasında bir sonraki komuta geç komutu verilemezse program debug edilemez. Basitçe klavyeyi kilitleyerek kullanıcının bir sonraki tuşa basması engellenir. Böylece program korunmuş olur.
Örnek:
Adres
Hex
Instruction
CS:0100
E4 21
IN AL,21
CS:0102
0C 02
OR AL,02
CS:0104
E6 21
OUT 21,AL
Diğer taraftan, Klavyeye ait PPI (Programmable Peripheral Interface)'ın bulunduğu Port 61h'a komut gönderilerekte klavye kilitlenebilir.
Örnek:
Adres
Hex
Instruction
CS:0100
E4 61
IN AL,61
CS:0102
0C 80
OR AL,80
CS:0104
E6 61
OUT 61,AL

1.1.2. Yazılımla Interrupt'ın devre dışı bırakılması:
Bu biraz daha kolay bir anti-debugging metodu'dur. Tüm yapmanız gereken Debugger'lar tarafından kullanılabileceğini düşündüğünüz interrupt vektörlerini farklı adreslere yöneltmek veya boşaltmak. Bir başka metod ise hataları kontrol eden interrupt vektörlerini kendi üzerinize alarak üstünüze aldığınız hata konrolcüsünün hatasını devreye sokmak. Unutmamanız gereken işlem bittikten sonra eski vektörleri yerine getirmenizdir. Interrupt vektörünü Int 21h'ın 25h fonksiyonunu kullanmak yerine kendinizin değiştirmesi.Çünki Int 21h'ı çağırdığınızda debugger bunu anlayıp kendisini zincire ekleyerek sizi kandırabilir. Bu sebeble gidip kendiniz değiştirmeniz önerilir. Aşağıdaki örnek interrupt 03h - Breakpoint interrupt'ının ele geçirilmesi gösterilmektedir.
Örnek:
Adres
Hex
Instruction
CS:0100
EB 04
JMP 0106
CS:0102
00 00
ADD [BX+SI],AL
CS:0104
00 00
ADD [BX+SI],AL
CS:0106
31 C0
XOR AX,AX
CS:0108
8E C0
MOV ES,AX
CS:010A
26 8B 1E 0C 00
MOV BX,ES:[000C]
CS:010F
89 1E 02 01
MOV [0102],BX
CS:0113
26 8B 1E 0E 00
MOV BX,ES:[000E]
CS:0118
89 1E 04 01
MOV [0104],BX
CS:011C
26 C7 06 4C 00 00 00
MOV Word Ptr ES:[000C],0000
CS:0123
26 C7 06 4E 00 00 00
MOV Word Ptr ES:[000E],0000
1.1.3. Vektör Ayarlamaları
Bu metod interrupt vektörleri üzerinde oynayarak, bu vektörlere akışı yönlendirmeye dayanır. Bu tür bir işlem kodçözücü kodda da kullanılmaktadır. (Bkz. 2.1) Bu metodda bilgiler interrupt vektörlerinin işaret ettiği yerde tutulur. Elbetteki normal çalışma esnasında 01h, 03h kullanılmaz. Tabi debug etmeyi düşünmüyorsanız. Bu metod gayet güzel çalışmaktadır.
Örnek:
Adres
Hex
Instruction
CS:0100
31 C0
XOR AX,AX
CS:0102
8E D0
MOV SS,AX
CS:0104
BC 0E 00
MOV SP,000E
CS:0107
2E 8B 0E 34 12
MOV CX,CS:[1234]
CS:010C
50
PUSH AX
CS:010D
31 C8
XOR AX,CX
CS:010F
21 C5
AND BP,AX
CS:0111
58
POP AX
CS:0112
E2 F8
LOOP 010C
1.1.4. Interrupt Yerdeğiştirme
Bu biraz çatlakça bir trik. Ve sadece programınızın artık daha fazla debug istemediğini düşünüyorsanız kullanın. Interrupt 16h ve 21h'ın vektörlerini 01h ve 03h'a kopyalamakla ne yapılabilir. Normal bir çalışmada böyle bir şey yapılmaz. Eğer kullanıcı programı debug etmek isterse programın içinde geçen INT 01 komutları normal bir INT komutuna döndürmek zorundadır. Bu trik çok etkili olabilir. Çünki herhangi bir şekilde CD01(INT 01)'i CD16 (INT 16)'ya değiştirmek kolaydır. Ancak Int 03'için özel komut olan 0CCh tek byte'tır. ve iki byte'lık bir komutla değiştirilemez.
Örnek:
Adres
Hex
Instruction
CS:0100
FA
CLI
CS:0101
31 C0
XOR AX,AX
CS:0103
8E C0
MOV ES,AX
CS:0105
26 A1 84 00
MOV AX,ES:[0084]
CS:0109
26 A3 04 00
MOV ES:[0004],AX
CS:010D
26 A1 86 00
MOV AX,ES:[0086]
CS:0111
26 A3 06 00
MOV ES:[0006],AX
CS:0115
B4 4C
MOV AH,4C
CS:0117
CD 01
INT 01
1.2. Zaman Kontrolü:
Nispeten daha az kullanılan bir metoddur. Ancak programın çalışması esnasında tüm interrupt'ları devre dışı bırakan debuggerları (Örnek: Borland Turbo Debugger) devre dışı bırakmak için gayet kullanışlı bir metoddur. Bu metod basitçe saati kontrol eder ve değişene kadar kısır döngüde bekler. Bu değer interrupt 08h tarafından değiştirilir. Diğer bir örnek eğer Port 21h'dan okunan değer (IN) 01h ile OR'lanır ve tekrar Port 21h'a yazılsa bile (IRQ 0'ı devreye sokar) Eğer hala devreye girmemiş ise o zaman debugger aktiftir. Şunu dikkate almak gerekiyor. Bu metod RUN yapılıyorsa etkindir. Eğer TRACE veya STEP by STEP çalıştırılsa çalışmaz.
Örnek:
Adres
Hex
Instruction
CS:0100
2B C0
SUB AX,AX
CS:0102
FB
STI
CS:0103
8E D8
MOV DS,AX
CS:0105
8A 26 6C 04
MOV AH,[046C]
CS:0109
A0 6C 04
MOV AL,[046C]
CS:010C
3A C4
CMP AL,AH
CS:010E
74 F9
JZ 0109
1.3. Debugger'ı yanıltmak:
Bu metod gayet güzel bir tekniktir. Turbo Debugger ve benzeri debugger'lar için kullanılır. Bu işlem bir komutun ortasına atlayarak yapılır. Aslında bir sonraki komut aptal bir komuttur. ve içerisinde başka bir komutu içerir. Siz aptal komutu atlayıp gerçek komuta atladığınızda debugger'ı yanıltmış olursunuz. Ancak normal step debugger kullanıyorsanız (Örnek Debug veya SymDeb) bu işe yaramayacaktır. Çünki komutlarınız komut komut çalıştırıldığından jump ettiği noktada sizi bekleyecektir.
Örnek:
Adres
Hex
Instruction
CS:0100
E4 21
IN AL,21
CS:0102
B0 FF
MOV AL,FF
CS:0104
EB 02
JMP 0108
CS:0106
C6 06 E6 21 00
MOV Byte Ptr [21E6],00
CS:010B
CD 20
INT 20
Şuna dikkat edin :
Adres
Hex
Instruction
CS:0108
E6 21
OUT 21,AL
Dikkat:
Bu trik herhangi bir debugger'ın çalışmasını etkilemez. Bu sadece kullanıcının başka bir komutun çalıştırldığını düşünürken başka bir komut çalıştırılır.
1.4. Check CPU Flags:
This is a nice trick, effective against almost any real mode debugger. What you should do is simply set the trace flag off somewhere in your program, and check for it later. If it was turned on, a debugger runs in the background...
Örnek:
Adres
Hex
Instruction
CS:0100
9C
PUSHF
CS:0101
58
POP AX
CS:0102
25 FF FE
AND AX,FEFF
CS:0105
50
PUSH AX
CS:0106
9D
POPF
Programın ortasında :
Adres
Hex
Instruction
CS:1523
9C
PUSHF
CS:1524
58
POP AX
CS:1525
25 00 01
AND AX,0100
CS:1528
74 02
JZ 152C
CS:152A
CD 20
INT 20
1.5. Debugger'ın çalışmasını kesme:
Bu teknik debugger RUN modunda iken çalışmasını keser. Yapacağınız şey programın içerisinde rastgele yerlere INT 3 komutu yerleştirmek. RUN modunda olduğunuz halde program hep bir yerlerde kesilir ve siz sürekli RUN demek durumunda kalırsınız. Bu ise oldukça sıkıcı bir durum. Eğer debugger dışında iseniz bu bir çırpıda geçecektir.
Örnek:
Adres
Hex
Instruction
CS:0100
B9 64 02
MOV CX,0264
CS:0103
BE 10 01
MOV SI,0110
CS:0106
AC
LODSB
CS:0107
CC
INT 3
CS:0108
98
CBW
CS:0109
01 C3
ADD BX,AX
CS:010B
E2 F9
LOOP 0106

1.6. Bilgisayarı Stack kullanarak çökertmek:
Bu trik debugger'ların kendi stack'larını kullanmak yerine kullanıcı programının stack'ını kullanması esasına dayanır. Eğer debug çalışıyorsa stack değişecektir. Stack kod alanını gösterdiğinden komutlar işletilirken aradaki stack bölgesindeki abuk sabuk komutlar sistemi çökertir. Böylece debug yapılırken sistem çöker. Eğer debug çalışmıyorsa bu alanlar değişmeyeceğinden program normal çalışır ve bu alanı geçer.
Önemli not: Bu kodu çalıştırırken CLI yapıp iş bittikten sonra STI yapmayı unutmayın. Eğer bu komut aralığında herhangi bir interrupt çağrılırsa bu alan değişeceğinden bilgisayar olmadık bir yerde çöker.
Örnek:
Adres
Hex
Instruction
CS:0100
8C D0
MOV AX,SS
CS:0102
89 E3
MOV BX,SP
CS:0104
0E
PUSH CS
CS:0105
17
POP SS
CS:0106
BC 0B 01
MOV SP,010B
CS:0109
90
NOP
CS:010A
90
NOP
CS:010B
EB 02
JMP 010F
CS:010D
90
NOP
CS:010E
90
NOP
CS:010F
89 DC
MOV SP,BX
CS:0111
8E D0
MOV SS,AX
1.7. TD386'yı V8086 modundayken çökertmek:
Bu Turbo Debugger'ın V8086 modulü (TD386)'nü çökertmek için güzel bir metoddur. Temeli sıfıra bölme işlemidir. Sıfıra bölme işlemi sistemi çökertip programın kesilmesine neden olur. Halbuki sıfıra bölme işlemi INT 00h'ı çağırır. Eğer siz INT 00h vektörünü bir sonraki komuta getirirseniz böylece sistem çakılmadan yoluna devam eder. Halbuki Turbo Debugger bunu farkettiği anda programı keser. Normal çalışırken ise sorun çıkmaz.
Önemli not: Eski INT 00h vektörünü kaydetmeniz gerekiyor. İşiniz bittiğinde bu vektörünü düzeltin. Eğer bunu yapmazsanız sistem bir sonraki INT 00h çağrısında çökecektir.
Örnek:
Adres
Hex
Instruction
CS:0100
31 C0
XOR AX,AX
CS:0102
8E D8
MOV DS,AX
CS:0104
C7 06 00 00 12 01
MOV WORD PTR [0000],0112
CS:010A
8C 0E 02 00
MOV [0002],CS
CS:010E
B4 00
MOV AH,00
CS:0110
F6 F4
DIV AH
CS:0112
B8 00 4C
MOV AX,4C00
CS:0115
CD 21
INT 21
1.8. Herhangi bir V8086 Prosesini çökertme:
TD386'yı göçertme metodlarından biri Hatalı Komut işletmektir. Ne yazıkki, V8086 ortamında çalışan başka bir program tarafından işletilen bir hatalı komut ta sizin sisteminizi etkileyebilir. Metod sıfıra bölme metodu ile aynıdır. Ancak bu metodda interrupt 0Dh (13) kullanılır. İşletilen hatalı bir komut programda bir sonraki satırdan devam etmenizi sağlar. Ancak Debugger üzerinden çalıştırıyorsanız işletilen komutla debugger duracak ve programı kesecektir. Böylece debug yapılması engellenmiş olur.
Önemli not: Orjinal interrupt vektörlerini eski değerlerine döndürmezseniz herhangi bir sakatlık durumunda sistemin çakılmasına neden olur.
Örnek:
Adres
Hex
Instruction
CS:0100
31 C0
XOR AX,AX
CS:0102
8E D8
MOV DS,AX
CS:0104
C7 06 34 00 13 01
MOV WORD PTR [0034],0113
CS:010A
8C 0E 36 00
MOV [0036],CS
CS:010E
83 3E FF FF 00
CMP WORD PTR [FFFF],+00
CS:0113
B8 00 4C
MOV AX,4C00
CS:0116
CD 21
INT 21
2. Kendi Kendini Değiştiren Kodlar:
2.1. Şifreleme / Çözme algoritmaları :
İlk katagori basit bir kod, bu kod şifrelidir ve basit bir çözme rutini eklenmiştir. Bu arada eğer debugger bir breakpoint koymuşsa buda arada kaynayacağından farklı bir komuta dönüşecektir. Dolayısıyla sistemin çakılmasına neden olur. Böylece debugging işlemi kesilir. Aşağıdaki örnek Haifa virüsünden alınmıştır. Eğer siz CS:0110 adresine breakpoint koyacak olursanız, asla bu adrese ulaşamazsınız. Sebebi işlemin sonucunda ne olacağı kimse tarafından bilinemez.Dolayısıyla ne kod işletileceği bilinemez.
Not: eğer trace işlemi için çok fazla uğraşmak istemiyorsanız. çözme işlemini kodun sonundan itibaren başlatın. Böylece enazından çok fazla uğraşmadan debug işlemini gerçekleştirebilirsiniz.
Örnek:
Adres
Hex
Instruction
CS:0100
BB 71 09
MOV BX,0971
CS:0103
BE 10 01
MOV DI,0110
CS:0106
91
XCHG AX,CX
CS:0107
91
XCHG AX,CX
CS:0108
2E 80 35 97
XOR Byte Ptr CS:[DI],97
CS:010C
47
INC DI
CS:010D
4B
DEC BX
CS:010E
75 F6
JNZ 0106
CS:0110
07
POP ES
CS:0111
07
POP ES
2.2. Kendini-Değiştiren Kodlar
2.2.1. Basit Kendini Değiştirme:
Bu metod basit bir şifreleme metodlarına dayanır. Bir komutu işletmeden evvel değiştirmeye dayanır. Aşağıdaki örnekte Call işlemi yapıldıktan sonra Call'dan sonra gelen komut değiştirilir. Eğer 'P'/Debug veya F8/Turbo Debugger ile işletirseniz programın bir anda sonlandığını göreceksiniz. Trace yaparsanız CD 20 olan bir sonraki komut trace işlemi esnasında CC 20'ye dönecektir. CC Int 03h'ı çağırdığından debugger kontrolü ele alabilir. Oysa burası CALL yapıldıktan sonra rutinin içerisinde başka bir kod ile değiştirilir.
Örnek:
Adres
Hex
Instruction
CS:0100
E8 04 00
CALL 0107
CS:0103
CD 20
INT 20
CS:0105
CD 21
INT 21
CS:0107
C7 06 03 01 B4 4C
MOV Word Ptr [0103],4CB4
CS:010D
C3
RET
Dikkat:
Adres
Hex
Instruction
CS:0103
B4 4C
MOV AH,4C

2.2.2. The Running Line (Kendi kendini şifreleme):
Bu örnek Kendi kendini kontrol eden ve kendi kendini değiştiren bir koddur. Bazen "The Running Line" ismiyle anılıur. Bu Serge Pachkovsky tarafından kodlanmıştır.Basit trik noktaları olan bir gösterimdir. Ancak burada bahsedilen diğer tekniklerden farklı olarak, Bu göreceli olarak vektör tablosundaki korumaları engeller. Bu son derece basitleştirilmiş bir örnektir.
XOR AX, AX
MOV ES, AX
MOV WORD PTR ES:[4*1+0],OFFSET TRACER
MOV WORD PTR ES:[4*1+2],CS
MOV BP, SP
PUSHF
XOR BYTE PTR [BP-1], 1
POPF
MOV AX, 4C00H ; This will not be traced!
DB 3 DUP ( 98H )
DB C5H, 21H
TRACER:
PUSH BP
MOV BP, SP
MOV BP, WORD PTR [BP+2]
XOR BYTE PTR CS:[BP-1], 8
XOR BYTE PTR CS:[BP+0], 8
POP BP
IRET
2.2.3. Prefetch Instruction Queue (PIQ) Ayarlamaları
Bu metod herhangi bir debugger'ı atlatabilir. veya herhangi bir bir seferde bir işlem yapan debugger'ları atlatabilir.PIQ CPU üzerinde bulunur. Komutları işletmeden evvel belleğe çekilir. Böylece işletmek için tekrar çağrı yapılmaz. Zaten CPU içerisinde mevcuttur. Eski CPU'larda bu 6 veya 4'tür. Yenilerde ise 25 kadardır. işlem basitçe şu şekilde tanımlanabilir. Bir şekilde PIQ ile Bellekteki bilgi farklılaştırılır. Kod bu şekilde yazılır. Eğer debugger içerisinde ise adım adım program çalıştırıldığından PIQ her defasında temizlenir. Dolayısıyla her zaman güncel kalır. Oysa normal çalışma esnasında orjinal kalan ve değişmeyen PIQ'dan dolayı eski kod işleme sokulur. Ve program bir sonraki satırı işler geçer. Oysa farklılaşmanın olmadığında program döner durur.
Örnek:
Adres
Hex
Instruction
CS:0100
B9 75 02
MOV CX,0275
CS:0103
BE 90 01
MOV SI,0190
CS:0106
89 F7
MOV DI,SI
CS:0108
AC
LODSB
CS:0109
C7 06 0F 01 24 06
MOV Word Ptr [010F],0624
CS:010F
34 73
XOR AL,73
CS:0111
AA
STOSB
CS:0112
C7 06 0F 01 24 06
MOV Word Ptr [010F],0624
CS:0118
E2 EE
LOOP 0108
Şuna Dikkat edin.
Adres
Hex
Instruction
CS:010F
24 06
AND AL,06
=============================================
Açıklamalar:
Program örneklerinde CLI/STI çifti kullanılmamıştır. Interrupt kontrolü veya üzerine alma durumlarında bu komutların başta ve sonra yer alması gereklidir. Bunun sebebi eğer siz interrupt vektörünü değiştirirken interrupt çağrılırsa sistem çökecektir

xxxxxx