"IdeStatik v3.04" |
|
|
|
|
|
Araçlar:
|
|
|
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.
|
|
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ı....
|
|
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.