Η προσπάθειά του PhotoPaul για τον 4ο διαγωνισμό του anticrack
by PhotoPaul
ΕΚΘΕΣΗ ΓΙΑ ΤΟ 2ο PROJECT
Πραγματικά θεωρώ πως είναι ΕΞΑΙΡΕΤΙΚΑ χρήσιμο για ΚΑΘΕ cracker να γνωρίζει καλά το Portable Executable File.Οφείλω να επισημάνω ότι αυτά που θα λεχθούν σε αυτήν την έκθεση δεν είναι εύκολα στην κατανόηση.Για κανένα λόγο όμως μην τα παρατήσετε.Σας διαβεβαιώνω πως προσωπικά, όπως και οι περισσότεροι crackers,χρειάστηκα πολλές ώρες και καλή εξάσκηση για να καταλάβω το pe file format,το επίσημο format των binary files των Windows.Οι γνώσεις αυτές έχουν σημαντικότατη εφαρμογή στον κλάδο του packing/unpacking,στο Import Table Rebuilding,σχεδόν σε ότι μπορείτε να φανταστείτε.Ας ξεκινήσουμε λοιπόν...
Δυσκολία: Μέτριο - Προχωρημένο Συνοδευτικά αρχεία: ΕΔΩ
|
Πραγματικά λυπάμαι που δε θα προσφέρω ένα εύκολο βοήθημα για το 2ο project της M.A.S.K. team, καθώς πιστεύω πως τα σχετικά tutorials του Iczelion στο θέμα "PE File Format" είναι ιδανικά για τα πρώτα σας βήματα. Αυτό που κάνω στην συνέχεια είναι να βρίσκω τον kernel των Windows (WindowsXP κατά προτίμηση καθώς επιμένω ότι είναι το καλύτερο λειτουργικό alive ;-) στην μνήμη, να τον scanάρω σαν PE αρχείο (άλλωστε δεν είναι και τίποτα παραπάνω), και να διαβάζω το exports-table του για να πάρω τις διευθύνσεις ορισμένων απαραίτητων APIs (βλέπε LoadLibrary και GetProcAddress). Ακολουθεί............ |
| Η προσπάθειά του PhotoPaul για τον 4ο διαγωνισμό του anticrack. |
| Μηδένισα το "Executable As Code" flag του .text section, έτσι ο win32dasm δεν το κάνει πλέον dissasemble. |
| Έκανα inject το ακόλουθο Win32 resource ενός πολύ απλού διαλόγου (dialog) για να μπορεί να γίνει ο έλεγχος. |
|
1000 DIALOG 0, 0, 186, 55 STYLE DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Contest #4 - Protect-Me" { CONTROL "Register",1,BUTTON,BS_PUSHBUTTON | BS_FLAT | WS_CHILD | WS_VISIBLE | WS_TABSTOP,67,35,50,14 CONTROL "User Name :",2,STATIC,SS_RIGHT | WS_CHILD | WS_VISIBLE | WS_GROUP,5,5,50,10 CONTROL "Serial Number :",3,STATIC,SS_RIGHT | WS_CHILD | WS_VISIBLE | WS_GROUP,5,20,50,10 CONTROL "PhotoPaul",4,EDIT,ES_LEFT | ES_READONLY | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP,60,5,120,10 CONTROL "",5,EDIT,ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP,60,20,120,10 } |
| Άλλαξα το Entry Point έτσι ώστε η εκτέλεση να ξεκινάει από τον δικό μου κώδικα. Χρησιμοποίησα έναν πολύ απλό SEH (Structured Exception Handler) με την προοπτική να μπορώ αργότερα να αποφασίσω αν το serial είναι σωστό. |
|
Ο πραγματικός κώδικας ακολουθεί: NOTICE(1): Μεγάλο μέρος του κώδικα υπάρχει για να μου επιτρεπει να χρησιμοποιώ non-imported APIs. NOTICE(2): Αν το serial είναι λάθος θα λάβει χώρα ένα Exception. Ο SEH μου θα αναλάβει δράση και θα τερματίσει την εφαρμογή φυσιολογικά. |
|
.586p .MMX .model flat,stdcall option casemap :none ;diff equ 0 ;I use constant diff because the code will be injected diff equ 88h .code KernelAddress dd 0 Kernel32ApisList db 11,"LoadLibrary" LoadLibrary dd 0 db 14,"GetProcAddress" GetProcAddress dd 0 szExitProcess db "ExitProcess",0 ExitProcess dd 0 szCreateThread db "CreateThread",0 CreateThread dd 0 szSuspendThread db "SuspendThread",0 SuspendThread dd 0 szResumeThread db "ResumeThread",0 ResumeThread dd 0 szUser32 db "User32.dll",0 User32 dd 0 szDialogBoxParam db "DialogBoxParamA",0 DialogBoxParam dd 0 szEndDialog db "EndDialog",0 EndDialog dd 0 szGetDlgItem db "GetDlgItem",0 GetDlgItem dd 0 szGetWindowText db "GetWindowTextA",0 GetWindowText dd 0 szPostQuitMessage db "PostQuitMessage",0 PostQuitMessage dd 0 hWin dd 1 start: call startup startup proc pop ecx @@: xor edx,edx dec ecx mov dx,[ecx+3Ch] test dx,0F800h jnz @B cmp ecx,[ecx+edx+34h] jnz @B mov diff+KernelAddress,ecx mov ecx,2 mov esi,diff+Offset Kernel32ApisList xor ebx,ebx ApisLoop: inc esi push ecx movzx ecx,byte ptr [esi-1] push ecx mov edx,diff+KernelAddress add edx,[edx+3Ch] mov edx,[edx+78h] add edx,diff+KernelAddress mov edi,[edx+20h] add edi,diff+KernelAddress mov edi,[edi] add edi,diff+KernelAddress mov eax,[edx+18] xor ebx,ebx FindNext: push ecx inc ebx push esi push edi repz cmpsb pop edi pop esi jnz WrongApi pop ecx mov ecx,[edx+36] add ecx,diff+KernelAddress dec ebx movzx eax,word ptr [ecx+ebx*2] mov ebx,[edx+28] add ebx,diff+KernelAddress mov eax,[ebx+eax*4] add eax,diff+KernelAddress jmp exit+1 WrongApi: dec edi @@: inc edi cmp byte ptr [edi],0 jnz @B inc edi dec eax jz exit pop ecx jmp FindNext exit: retn pop ebx pop ecx add esi,ebx mov [esi],eax add esi,4 loop ApisLoop mov esi,[diff+GetProcAddress] mov edi,diff+KernelAddress push diff+offset szExitProcess push edi call esi mov diff+ExitProcess,eax push diff+offset szCreateThread push edi call esi mov diff+CreateThread,eax push diff+offset szSuspendThread push edi call esi mov diff+SuspendThread,eax push diff+offset szResumeThread push edi call esi mov diff+ResumeThread,eax push diff+offset szUser32 call [diff+LoadLibrary] mov diff+User32,eax mov edi,diff+User32 push diff+offset szDialogBoxParam push edi call esi mov diff+DialogBoxParam,eax push diff+offset szEndDialog push edi call esi mov diff+EndDialog,eax push diff+offset szGetDlgItem push edi call esi mov diff+GetDlgItem,eax push diff+offset szGetWindowText push edi call esi mov diff+GetWindowText,eax push diff+offset szPostQuitMessage push edi call esi mov diff+PostQuitMessage,eax jmp mystart startup endp mystart proc ASSUME FS:NOTHING call @F push 0 call [diff+ExitProcess] @@: push fs:[0] mov fs:[0],esp db 64h,0A1h,18h,00h,00h,00h,8Bh,40h,30h,8Bh,40h,08h push 0 call next1 .if dword ptr [esp+8]==110h push dword ptr [esp+4] pop hWin .elseif dword ptr [esp+8]==111h mov eax,dword ptr [esp+0Ch] and eax,0ffffh .if eax==1 call @F dd 0 @@: push 0 push 4 push hWin call [diff+GetDlgItem] push 0Ah call @F a1 db 1,1,1,1,1,1,1,1,1,1 @@: push eax call [diff+GetWindowText] push 5 push hWin call [diff+GetDlgItem] push 0Ah call @F a2 db 1,1,1,1,1,1,1,1,1,1 @@: push eax call [diff+GetWindowText] mov esi,offset a1+diff mov edi,offset a2+diff xor ecx,ecx xor edx,edx .while ecx<eax xor dl,byte ptr [esi+ecx] xor dl,byte ptr [edi+ecx] inc ecx .endw movzx eax,dl imul ecx push eax call Next mov eax,dword ptr [esp+4] xor eax,91C0h call @F @@: pop ebx add ebx,14h mov word ptr [ebx],ax ret 4 Next: push 0 push 0 call [diff+CreateThread] aa:: jmp $ int 97h push 0 push hWin call [diff+EndDialog] .endif .endif mov eax,0 ret 10h next1: push 0 push 3E8h push eax call [diff+DialogBoxParam] jmp myend mystart endp myend proc mov eax,2A80F0h xor eax,dword ptr [aa+diff] mov esi,eax pop fs:[0] jmp eax myend endp end start |
| Ένα serial που δουλεύει είναι το: "Lockless" |
| Το protection scheme είναι ένα βλακώδες XORing, αλλά επειδή δούλεψα περισσότερο στο injection μέρος της πρόκλησης. |
| Δεν χρησιμοποίησα καθόλου anti-debugging/anti-tracing tricks, πολύ απλά γιατί δε θέλω να τα μάθει κανένας καραγκιόζης ο οποίος θα τα χρησιμοποιήσει για σατανικούς σκοπούς (i.e. protecting sharewares) ;-) |
|
Lockless World Headquarters PhotoPaul@lockless.com Greetings go out to: aCoder M.A.S.K STC Especially to Lord Anshar And all the other members of the legendary Lockless ...we fly high... |
ΠΡΟΣΟΧΗ Φυσικά δεν χρειάζεται καν να σας θυμίσω πως το βοήθημα αυτό είναι αυστηρά για εκπαιδευτικούς σκοπούς και για την οποιαδήποτε λάθος χρήση τους ο δημιουργός του δεν φέρει καμμία ευθύνη.Αν θέλετε έτοιμα cracks υπάρχουν πολλά άλλα μέρη στο internet,εδώ παρέχουμε μόνο γνώση.