"IdeStatik v3.04"

Mr_Stop
Program Url: http://www.ideyapi.com.tr
Program Tipi: Statik programı
       Araçlar:
 SoftICE, Revirgin, Peditor v1.7, Icedump
Basit ()  Orta ( )  Zor ( )  Pro (x ) 

Başlangıç

Bu program beni epeyce uğraştırdı.Toplam 3 aydır uğraşıyordum.Sonunda oldu sizin de birşey öğrenmeniz amacıyla bulduklarımı paylaşmak istedim.Bu yazı biraz profesyonelce olduğundan ilk başta hasp ile ilgili ceviri yazısını okumanızı tavsiye ederim.Bazı basamakları atlayarak geçtim anlamadığınız yerler için eski yazılara bakın.

Yazı

Idestatik hasp3-envelope ile korunmuş birşey.Hasp envelope şu şekilde çalışıyor.Program hasp envelope ile paketleniyor ve ancak dongle takılı olduğu zaman dongle dan gelen cevaba göre açılıyor ve işlemi yapıyor.Yani dongle ileçalışan bir paketleme mekanizması diyebiliriz.

Programı kırrarken bazı avantajlarımız var

buna karşılık bazı dezavantajlarımız da var.

Yine programı kırmayı kısımlara ayırıcaz,hasp servislerini bulmak ve emule etmek,envelope dan kurtarmak ve programı kırmak.

KISIM I HASP Servisleri ve Emulasyon.

İlk olarak tabii ki icedumpı indirip çalıştırıyoruz.Hasp için klasik breakpointimiz olan bpx freeenvrionmentstringsa yı koyup programı çalıştırıyoruz.Idestids ye gelinceye kadar F5 e basıp F12 ve F10ile izliyoruz.

0167:007ADAC8  E8B21F0000          CALL      007AFA7F   ;hasp servisi
0167:007ADACD  5D                  POP       EBP
0167:007ADACE  8B7D1C              MOV       EDI,[EBP+1C] ;dongle dan geriye dönenler..
0167:007ADAD1  8907                MOV       [EDI],EAX
0167:007ADAD3  8B7D20              MOV       EDI,[EBP+20]
0167:007ADAD6  891F                MOV       [EDI],EBX
0167:007ADAD8  8B7D24              MOV       EDI,[EBP+24]
0167:007ADADB  890F                MOV       [EDI],ECX
0167:007ADADD  8B7D28              MOV       EDI,[EBP+28]
0167:007ADAE0  8917                MOV       [EDI],EDX 
0167:007ADAE2  5E                  POP       ESI
0167:007ADAE3  5F                  POP       EDI
0167:007ADAE4  5A                  POP       EDX
0167:007ADAE5  59                  POP       ECX
0167:007ADAE6  5B                  POP       EBX
0167:007ADAE7  58                  POP       EAX
0167:007ADAE8  5D                  POP       EBP
0167:007ADAE9  C3                  RET 

Bizim amacımız bundan sonra pop ebp satırından sonra gerçek dongle cevabını programa vermek.Bu yüzden dongle servislerini çokiyibilmemiz gerekiyor. Ayrıcaçok da dikkatli olmamız gerekiyor bazı servisler değişik parametre ile çağrılabilir.Bunları iyi bir şekiled not etmemiz gerekiyor.

İlk servisimiz IsHasp() fonksiyonu yani hasp bağlı mı? Bu fonksiyon eğer eax ta 1 dönerse dongle var 0 dönerse yok demek oluyor.Biz o zaman pop ebp satırında iken r eax 1 ile eax ı 1 yapıyoruz.Bundan böyle artık çağrılan bütün hasp fonksiyonlarını ve parametrelerini not etmemiz gerekiyor.Bu şekilde emulasyonumuzu yazıp programı unpack edicez. bpm 7adac8 x ile breakpoint koyuyoruz.Dikkat ederseniz bpx ile breakpoint kopymadım çünkü bpx ile koyarsak program çökebiliyor.İlk durduğunda şunu göreceksiniz.

EAX=00000FC0   EBX=00000200   ECX=0000771D   EDX=00007729

Ceviri yazısında da belirttiğim gibi hasp a gönderilen parametreler registerlar vasıtasıyla dongle a gönderiliyor.bh servis numarası cx password1 dx password2 ve ax da seed oluyor.Bu demek oluyor ki program servis 2 iyi 771D 7729 paswordları ve FC0 seed i ile çağırmış.Bizim programa gerçek değerlerini yollamamız gerekiyor.Yine pop ebp satırında icedumpın güzel bir özelliği olan haspcode eklentisini kullanıcaz.-haspcode 771D 7729 FC0 bunu yazdığımız anda gerçek değerlerin registerlara gönderildiğini göreceksiniz.Şimdi bir daha F5 e basıyoruz.

EAX=00000FC0 EBX=00000200 ECX=0000771D EDX=00007729

Bu da yine aynı servis ve yine aynı password ve seed ileçağrılmış.Yine pop ebp satırında iken -haspcode 771D 7729 FC0 yazıp gerçek return değerlerini giriyoruz.Bir kez daha F5 e basıyoruz.

EAX=00005FF5 EBX=00000200 ECX=0000771D EDX=00007729

Bu sefer passwordlar aynı olmasına rağmen farklı bir seed ile haspcode çağrılmış.Yine aynı yerde bu sefer -haspcode 771D 7729 5FF5 yazıp gerçek retun kodlarını programa gönderiyoruz.Bir kez daha F5 e bastığımızda bu sefer freeenvironmentstringsa breakpointi yüzünden durduğumuz görüyoruz.Kodu izlediğimizde şunları görüyoruz.

0167:00664534  55                  PUSH      EBP
0167:00664535  E809FEFFFF          CALL      00664343
0167:0066453A  5D                  POP       EBP
0167:0066453B  8B7D1C              MOV       EDI,[EBP+1C]
0167:0066453E  8907                MOV       [EDI],EAX
0167:00664540  8B7D20              MOV       EDI,[EBP+20]
0167:00664543  891F                MOV       [EDI],EBX
0167:00664545  8B7D24              MOV       EDI,[EBP+24]
0167:00664548  890F                MOV       [EDI],ECX
0167:0066454A  8B7D28              MOV       EDI,[EBP+28]
0167:0066454D  8917                MOV       [EDI],EDX

Bu bize envelope un açıldığını ve programın artık kendi içinden haspı çağırdığını görüyoruz.Biz servisleri yine takip edebilmek için 00664535 satırına yine breakpoint koyuyoruz.Programı takip edip calldan geri döndüğümüzde şunu göreceğiz.

0167:00556BC4  899EB42F0000        MOV       [ESI+00002FB4],EBX
0167:00556BCA 899EC82F0000 MOV [ESI+00002FC8],EBX
0167:00556BD0 899EC02F0000 MOV [ESI+00002FC0],EBX
0167:00556BD6 899EBC2F0000 MOV [ESI+00002FBC],EBX
0167:00556BDC 899EC42F0000 MOV [ESI+00002FC4],EBX
0167:00556BE2 89442444 MOV [ESP+44],EAX
0167:00556BE6 E814D91000 CALL 006644FF ;hasp callı
0167:00556BEB 8D44243C LEA EAX,[ESP+3C]
0167:00556BEF 8D4C2438 LEA ECX,[ESP+38]
0167:00556BF3 50 PUSH EAX
0167:00556BF4 8D542438 LEA EDX,[ESP+38]
0167:00556BF8 51 PUSH ECX
0167:00556BF9 8D442448 LEA EAX,[ESP+48]
0167:00556BFD 52 PUSH EDX
0167:00556BFE 81C538760000 ADD EBP,00007638
0167:00556C04 50 PUSH EAX
0167:00556C05 57 PUSH EDI
0167:00556C06 55 PUSH EBP
0167:00556C07 53 PUSH EBX
0167:00556C08 6A0C PUSH 0C
0167:00556C0A 6A05 PUSH 05 ;servis 5
0167:00556C0C E8EED81000 CALL 006644FF ;hasp call

Program servis 5 i yani HaspStatus u çağırıyor.Burda yapmamız gereken eax ebx ve ecx e 1 yazmak.Servis 5 3 kez çağrılıyor sanırım.Daha sonra program açılıyor ve 00664535 satırına koyduğumuz breakpointte duruyoruz.

EAX=006B53B0   EBX=00003301   ECX=0000771D   EDX=00007729

Bu sefer çağrılan servis 33 yani writeblock.Bunun sonucunda da ecx te 0 yani successful dönmesi gerekiyor.Program bundan sonra bir kaç kez daha servis 5 i çağırıyor ve sonunda açılıyor.Programı deniyoruz.Yeni bir dosya açmaya çalıştığımızda yine koyduğumuz breakpointte duruyoruz.

EAX=006B53B0   EBX=00003201   ECX=0000771D   EDX=00007729   ESI=00000002  EDI=00000032

Bu işte emule etmesi en zor servis.Çünkü orjinal dongle olmadan dongle dan ne okuduğunu bulmamız aslında zor birşey.İlk olarak bu servisin parametrelerini öğrenip ne döndürmemiz gerektiğini bulalım.Hasp'ın manualinde aynen şöyle yazıyor.

Service 50 (32h): ReadBlock
hasp (Service(ebx), SeedCode(eax), LptNum, Password1(ecx), Password2(edx),Par1, Par2(esi), Par3, Par4)
Parameters Used
Service 50
LptNum:Printer Portu
Password1 İlk HASP password
Password2 İkinci HASP password
Par1 Start Address – Bloğu okumak içinki başlangıç adresi
Par2 Block Length – Word cisinden bloğun uzunluğu
Par3 Buffer Segment – Program bufferının segment adresi(değişken)

Buffer segemnt adresini 32 bit programlarda tanımlamanıza gerek yoktur.
Par4 Buffer Offset – Program bufferının offset adresi (değişken).

Dönen değerler
Par3 Status – Memeorynin durumu bildiren kod

Sonuç
Hasp memory de bulunan program bufferına okunur.

Gördüğünüz gibi burda Par1 Par2 ve Par3 de öenmli olduğundan bunların değerlerini de bilmemiz gerekiyor.Bunları şu şekilde bulabiliriz.hasp call'ı çağrılmadan önce ne push edilmiş ona bakarız ve bu değerleri buluruz.dd ebp+14 bize dongle memoryi verecektir.Ama asıl mesele memory den ne okutacağımız.Bu şekilde çalıştırdığımızda program yeni bir dosya açtığımızda göçüyor.Onunla sonra ilgilenicez.Şimdi buraya kadar bulduklarımız ile emulasyonumuzu yazalım.

cmp bh,1            ;IsHasp ?
jnz @nextservice
xor eax,eax
inc eax          ;HaspConnected
ret
@nextservice:
cmp bh,2          ;HaspCode()  
jnz @service5
cmp eax,0FC0h     ;Service2 3 kez çağrılıyor iki kez seed FC0h ile bir kez de 5FF5h
jnz  @itsanother  ;seed FC0 değilse diğer seed e bak
mov eax,0C1BBh    ;gerçek değerleri yolla
mov ebx,0D69Fh
mov ecx,0EA59h
mov edx,05FF5h
ret
@itsanother:
mov eax,03FE9h ;başka bir seed ile çağrıldı.
mov ebx,0DA77h
mov ecx,07BA8h
mov edx,031A7h
ret
@service5:
cmp bh, 5    ;HaspStatus() ?
jnz @service33
mov eax,1   ;MemoHasp
mov ebx,eax ;MemoHasp
mov ecx,eax ;Port #
ret 
@service33:   ;Write Block
cmp bh,32h ;
jz @service32
;xor ebx,ebx ;buna gerek yok zaten ebx sıfırlanıyor.
xor ecx,ecx  ;success
ret
@service32:    ;ReadBlock Ben bunu CrakZ'ın sitesinde gördüm.Manasını anlatıcam
push ebp ; save the value of ebp
call delta ; call delta
delta:
pop ebp ; put current address (IP) in ebp
lea ebx, [ebp+14] ; get the start of our dongle memory
pop ebp ; get original value of ebp back
mov ecx, esi ; set up counter
shl edi, 1 ; multiply by 2
lea esi, [ebx][edi] ; so we get the correct address to read from
shr edi, 1 ; divide by 2
xchg edi, eax ; buffer pointer into edi
repe movsw ; copy with the length of ecx
xchg edi, eax ; restore eax
ret
DB 112 dup(0)

Burada anlaşılmıycak varsa bir servis32 için yazdığım emulasyon rutini.Burda bizim yaptığımız o andaki EIP ı bulup DB 112 dup(0) ile tanımladığımız bufferdan istediğimiz okutmak.call delta ile o andaki EIP i buluyoruz.Bunu virüs kodlarını incelerseniz çok fazla görürsünüz.

Biz bu sayede gerçek değerleri db 112 dup ile tanımladığımız yere koyucaz.Tek sorun orda ne olduğunu bulmak.Şimdi bunu assemble edin.Ben size tasm ı ve Code Snippet Creator u öneririm Assemble ettiğimiz bu dosyayı (80FF01 ile başlayıp IczelionMarker ile bitiyo) 3CA317h offsetine pastliycez.Dikkat edin ama seçtiğiniz kadar yerin aynısını dosyadan da seçip paste edin.Şimdi artık işimiz çok daha kolaylaştı.

bpx freeenvironmentstringsa ile breakpoint koyuyoruz.7ADAC8 satırına geldiğimizde r eax 1 ile yine eax 1 bir yapıyoruz.Daha sonra

a 7ADAC8

bu sayede o bölgeyi kendi rutinimize yolluycaz.

call 7CB317

Bu call bizim için enveleopu halledicek.Yine freeenvironmentstringsa yüzünden duruyoruz.Call dan geri döndükten sonra bu sefer

a 664535

bu sayede o bölgeyi kendi rutinimize yolluycaz.

call 7CB317

Şimdi artık programı servis 32h ı çağırdığı zaman durdurup ne istediği öğrenmemiz lazım. bpm 7cb317 x if bh==32 ile breakpoint koyup yolumuza devam ediyoruz.Durduğu zaman servis 32h çağrılmış olucak.

Artık kodu dikkatlice incelememiz gerekiyor.F10 ile kendi yazdığımız emulasyon kodunu takip ediyoruz.xchg edi, eax satırında iken edi nin 6B53B0 olduğunu görüyoruz.Edi buffer adresimiz yani dongledan gelen cevaplar buraya okunuyor.Muhtemelen bizim şu anda edi de gördüğümüz değer(dd edi) yanlış bir değer çünkü biz servis 32 yi emule etmediğimizde oraya hiç birşey yazılmıyordu ama yine çalışmadı.Demek ki bizim oraya gerçek değeri yazmamız gerekiyor.Peki dongle olmadan bunu nasıl yapıcaz.Bu sefer bu mümkün.

Herşeye yeniden başlıyoruz.Envelope açıldıktan (7ADAC8 i geçtikten sonra) 664535 daki freeenvrionmentstringa breakpointinde bu sefer sonra not ettiğimiz edi ye bpm 6b53B0 x ile breakpoint koyuyoruz.Şu kodu göreceksiniz.

0167:005639A7  E8C42EFFFF          CALL      00556870
0167:005639AC EB02 JMP 005639B0
0167:005639AE 33C0 XOR EAX,EAX
0167:005639B0 6A00 PUSH 00
0167:005639B2 898378010000 MOV [EBX+00000178],EAX ;burda eax bizim bölgeye yazılıyor.
0167:005639B8 898348040000 MOV [EBX+00000448],EAX
0167:005639BE 8B10 MOV EDX,[EAX]

eax ın değerine bakarsak 00B8E8EC sayısını görüyoruz.Demekki orda olan değer buymuş.Bizde ona göre kendi emulasyon kodumuzda db 112 dup(0) ile tanımladığımız bölgeye o sayıyı girmemiz lazım.Ben ilk başta böyle yapmıştım ama sonra bir sorunla karşılaştım.Bu sayı windows98 WinMe ve win2k da değişik yani tek bir sayı yazamayız.O yüzden direkt olarak bu call dan çıkarken bizim emulasyon koduna eax ı yazmamız gerekiyor.Bu yüzden 556870 satırındaki call a giriyoruz ve sonuna şunu ekliyoruz. mov [0007CB3E5],eax bu şekilde eax ın değeri bizim buffera yollanmış oldu.Emulasyonu ve değişkliği bu şekilde yaptığımız zaman programın çok güzel bir şekilde çalıştığını göreceksiniz.İşlem tamam!

KISIM II Unpack

Programı unpacklemek için OEP i bulmamız gerekiyor.OEP i bulmakiçin şunu yapıcaz.Bu program Visual C ile yazıldığından start ı sabit dir ve kullanılan apiler de belli.Yine yukarda anlattığım gibi freeenvironmentstringsa ya breakpoint koyup emulasyon kodumuza yönlendiriyoruz.Daha sonra bpx Getstartupinfo ile breakpoint koyuyoruz.Program durduğunda pageup tuşu ile yukarı çıkıyoruz.push ebp satırının olduğu yer bizim OEP yani 665632.

Yeniden programı çalıştırıyoruz.ilk freeenvironmentstringsa dan sonra emulasyon koduna yönlendiriyoruz.Daha sonra bpm 665632ile breakpoint koyuyoruz.Bir kaç saniye sonra program duracaktır.O zaman şunu yazıyoruz.

a eip
jmp eip

Bu şekilde memoryde loopa sokmuş oluyoruz.Peditor ile task listten bizim programı seçip dump ediyoruz.Daha sonra 00265632h satırına gidip oraya eski değeri olan 55 8B yazıyoruz.OEP e de 00265632 yazıyoruz.Programı çalıştırdığınızda yine çalışacaktır.Düzeltilecek tek kısım, orjinal programdaki hasp callı da yine bizim emulasyon koduna yönlendirmek olucaktır.Bu şekilde program tamamen haspdan arınacaktır.Fakat;

Eğer bu dosyayı windows2k da çalıştırırsanız programın göçtüğünü görürsünüz.Neden çünkü import tablosu o andaki sizin bilgisayarınıza göre oluşturulmuştur.Bu yüzden importu da yeniden oluşturup düzeltmeniz gerekecek.Bunu da imprec ile kolayca yapabilirsiniz.Görev tamamlandı.Artık idestatik donglesız ve çok daha hızlı çalışıyor.

Bu anlattığım yöntem Hasp4 de çalışmıycaktır.Çünkü Hasp4'ün HaspCode() algoritması şu an için çözülmedi.Bu yüzden orjinal dongle olmadan return kodları bulamazsınız.Her ne kadar çoğu arkadaş bana inanmayıp bana zilyon tane döküman yollayıp, tembel,azimsiz vs dese de gerçek bu.Bana Hasp4 yüzünden ukalalık yapanların, Md5 ile uğraşmamdan sonraki(Hasp4 Md5 hashi ile korunuyor) mailleri de ayrı bir araştırma konusu :)

Günün Alınıtısı:

One night a man had a dream. He dreamed he was walking along
the beach with the Lord. Across the sky flashed scenes from
his life. For each scene, he noticed two sets of footprints in the
sand: one belonging to him, and the other the Lord.

When the last scene of his life flashed before him, he looked
back at the footprints in the sand. He noticed that many times
along the path of his life there was only one set of footprints. He
also noticed that it happened at the very lowest and saddest times
in his life.

This really bothered him and he questioned the Lord about it.
"Lord, You said that once I decide to follow You, You'd walk
with me all the way. But I have noticed that during the most
troublesome times in my life, there is only one set of footprints.
I don't understand why when I needed you most You would
leave me".

The Lord replied, "My precious, precious child. I love you and
I would never leave you. During your times of trial and
suffering, when you see only one set of footprints, it was then
that I carried you."


Bu 3 ay kumsalda sadece bir ayak izi vardı....

Son Notlar

Bu yazıda yazım yanlışları hatta bilgi hatası olabilir.Eğer bir yanlış bulursanız bana email atın düzeltmeye çalışırım.Bir programı eğer gerçekten kullanıyorsanız, programı satın almayı düşünün.Micro$oft programlarını - bırakın satın almayı - kullanmayı bile düşünmeyin.