ANTICHAT.XYZ    VIDEO.ANTICHAT.XYZ    НОВЫЕ СООБЩЕНИЯ    ФОРУМ  
Баннер 1   Баннер 2

ANTICHAT — форум по информационной безопасности, OSINT и технологиям

ANTICHAT — русскоязычное сообщество по безопасности, OSINT и программированию. Форум ранее работал на доменах antichat.ru, antichat.com и antichat.club, и теперь снова доступен на новом адресе — forum.antichat.xyz.
Форум восстановлен и продолжает развитие: доступны архивные темы, добавляются новые обсуждения и материалы.
⚠️ Старые аккаунты восстановить невозможно — необходимо зарегистрироваться заново.
Вернуться   Форум АНТИЧАТ > Программирование_OLD > Реверсинг
   
 
 
Опции темы Поиск в этой теме Опции просмотра

CrackMe[7] или что я хотел увидеть
  #11  
Старый 02.01.2007, 17:32
taha
Постоянный
Регистрация: 20.08.2006
Сообщений: 327
Провел на форуме:
2472378

Репутация: 1077
Post CrackMe[7] или что я хотел увидеть

Вообще то я хотел увидеть не сухой ответ типа: "Переход тут". А собственно последовательность действий после которых вы пришли к этому выводу.
Поскольку следующий пост не специально прочитать нельзя, могу смело выложить пример подобающего ответа)) Конечно исходников у вас быть не могло. Но еслиб вы видели номер, как я перегонял свои функции из MASM в FASM =). Я не знаю кгде в фасм лежат некоторые неообходимые структуры тк дело чаще имею с масм. Я просто брал функции компилил на масм, потом рипал необходимые структуры. Конечно далёкий от совершенства способ но... Вобщем я понял, что каждый ассемблер хорош для своих целей))
Ну начнём... Грузим прогу в Olly. Мдя много непонятных функций. F9, прога запустилась. Оля проставила в комментах используемые апи (От меня: Это пережиток воровства функций. Я хотел это сделать и ещё коечего, но потом понял, что мне к премутациям приступать пока рано))!! Но поиск кернел32 и апи решил оставить. ИМХО должно затруднить реверс тем кто юзает дезассемблеры).
Вводим чтонить, enter. Прога немного повисла.. Что это? Спросит читатель! Терпение, - скажу я!! Перезапустим прогу и поставим бряк на USER32.GetDlgItemTextA. Опять что-нибудь вводим! И брякаемся на этой функции. F8, прога считала введёное слово.Трассерим дальше, программа начинает что то расшифровывать и пушить, точнее наоборот)), пушить и расшифровывать.

Код:
00401101   > FFB6 2F124000  PUSH DWORD PTR DS:[ESI+40122F]
00401107   . BF 04000000    MOV EDI,4
0040110C   > 80343C 25      XOR BYTE PTR SS:[ESP+EDI],25
00401110   . 4F             DEC EDI
00401111   .^75 F9          JNZ SHORT CrackMe[.0040110C
00401113   . 83EE 04        SUB ESI,4
00401116   . 83FE FC        CMP ESI,-4
00401119   .^75 E6          JNZ SHORT CrackMe[.00401101


От меня: ______________________________________

В исходном варианте это выглядело так:

Код:
@@:   push dword [CMPProc+esi]
          mov edi,4h
@@2: xor byte [esp+edi],25h
          dec edi
          jne @@2
          sub esi,4h
          cmp esi,-4h
          jne @B

_______________________________________________

Дальше в edi идёт адрес введённого слова.

mov edi,caption

А в стек адрес после джампа. Этот прыжок должен был показаться вам странным, так как он идёт сам на себя.

Код:
 0040112A   >-EB FE          JMP SHORT CrackMe[.0040112A
Вот почему программа подвисала. Тогда как автор(тобишь я) проверяю пасс? По идее после:

Код:
 mov esi,esp
 add esi,4h
Должен идти прыжок на esi. Так как вышеперечислиные действия должны были напомнить вам элементы стекового полиморфизма)).
Но почему там jmp $. Вот тут вы должны были вспомнить мой предыдущий крякмис. Там была применина такая вещь, как tls.callback. Способы обхода этой функции я описывал в своей статье "Общие концепции борьбы с протектерами". Я предпочитаю пользоваться плагином Olly Advanced. Где его скачать я постил в треде посвящённом тулзам. Так вот в опциях к плагину ставим "Break on TLS Callback". Перезапускаем программу. Мы попали в колбечную функцию.

Код:
00401257  /. 55             PUSH EBP
00401258  |. 89E5           MOV EBP,ESP
0040125A  |. 837D 0C 01     CMP DWORD PTR SS:[EBP+C],1
0040125E  |. 75 0E          JNZ SHORT CrackMe[.0040126E
00401260  |. FF15 5C304000  CALL DWORD PTR DS:[<&KERNEL32.IsDebugger>; [IsDebuggerPresent
00401266  |. 85C0           TEST EAX,EAX
00401268  |. 74 04          JE SHORT CrackMe[.0040126E
0040126A  |> C9             LEAVE
0040126B  |. C2 0C00        RETN 0C
0040126E  |> 803D 00104000 >CMP BYTE PTR DS:[<ModuleEntryPoint>],0CC
00401275  |.^74 F3          JE SHORT CrackMe[.0040126A
00401277  |. 66:C705 2A1140>MOV WORD PTR DS:[40112A],0E6FF
00401280  |. C9             LEAVE
00401281  \. C2 0C00        RETN 0C


Если дебугер включен или/и на ep стоит int3; ничего не происходит. А если нет jmp $ меняется на jmp esi))). Обходим всё это и добираемся до нашего jmp. Он изменился, как мы и предполагали, на jmp esi. Переходим по нему.

Код:
0006FCA8   33F6             XOR ESI,ESI
0006FCAA   4E               DEC ESI
0006FCAB   8B0D 71214000    MOV ECX,DWORD PTR DS:[402171]
0006FCB1   83E9 02          SUB ECX,2
0006FCB4   46               INC ESI
0006FCB5   49               DEC ECX
0006FCB6   8A86 67214000    MOV AL,BYTE PTR DS:[ESI+402167]
0006FCBC   66:31F0          XOR AX,SI
0006FCBF   3A0437           CMP AL,BYTE PTR DS:[EDI+ESI]
0006FCC2   75 09            JNZ SHORT 0006FCCD
0006FCC4   85C9             TEST ECX,ECX
0006FCC6  ^75 EC            JNZ SHORT 0006FCB4
0006FCC8   31C0             XOR EAX,EAX
0006FCCA   40               INC EAX
0006FCCB   EB 02            JMP SHORT 0006FCCF
0006FCCD   31C0             XOR EAX,EAX
0006FCCF   C3               RETN


Функция сравнения пароля. Кста в оригинале она выглядит почти также =))). Идём до ret'а. и выходим на

Код:
0040112C   . 83C4 28        ADD ESP,28


Вот зачем перед этим шло push CrackMe[.0040112C. Знаменитый push + ret)). Add же чистит стек от функции проверки.
А дальше идёт та самая проверка на валидность пасса:

Код:
00401131   . 85C0           TEST EAX,EAX
00401133   . 74 44          JE SHORT CrackMe[.00401179


Перебиваем je на jne. И f9. Брякаемся на исключении:

Код:
004011C9   > 31C0           XOR EAX,EAX
004011CB   . C700 01000000  MOV DWORD PTR DS:[EAX],1


Жмём шифт-f9 пока не вылитит нужная мессага. Happy end.

Кому интересна функция CryptStr.
Смотрим в окне стека адрес SEH-функции. И ставим на неё бряк. Шифт-f9. И мы в функции.

Код:
004011F0  |. FF05 97214000  INC DWORD PTR DS:[402197]                ;  CrackMe[.0040218A
004011F6  |. 8B1D 97214000  MOV EBX,DWORD PTR DS:[402197]            ;  CrackMe[.0040218A
004011FC  |. 8A0B           MOV CL,BYTE PTR DS:[EBX]
004011FE  |. 84C9           TEST CL,CL
00401200  |. 74 09          JE SHORT CrackMe[.0040120B


Украденный код проверки на конец строки. Если строка не закончилась, то к eip исключительной ситуации добавляем 6(размер mov dword ptr [eax],1). Выходим к расшифровке байта. А если строка закончилась, переходим на восстановлние регистров в функции CryptStr. Вот такой вот замысловатый SEH =)).

Сорц пробной программы: __________________________________________________ __________
Код:
format PE GUI 4.0
        include 'include\win32a.inc'
        entry $
 start:
        push   15h
        push   szmsgBody
        call   Crypt

        invoke MessageBox,0,szmsgBody,szmsgBody,0

        invoke ExitProcess,0

proc Crypt kstr:dword,kk:byte
        push edi
        push eax
        mov  edi,[ebp+8]
        mov  [cstr],edi
        mov  ah,byte [ebp+0Ch]
        mov  byte [key],ah

        push ebp               ; \ Устанавливаем SEH
        push esp               ; |
        push Next              ; |
        push SEHHandler        ; |
        push dword [fs:0]      ; |
        mov  [fs:0],ESP        ; /

        dec  dword [cstr]
@@:
        xor  eax,eax           ;\   Исключение
        mov  dword [eax],1     ;/

        sub  esp,10h           ;<--- Всстанавливем seh, тк он удаляется после выполнения SEHHandler

        mov  al, byte [key]
        mov  ebx,dword [cstr]
        xor  byte [ebx],al
        jmp  @B
Next:
        pop  eax
        pop  edi
        ret
        endp

proc SEHHandler
        PUSH EDX
        MOV  EDX,DWORD [EBP+0Ch]
        MOV  EAX,DWORD [EBP+10h]

        inc  dword [cstr]       ; \ Украденные байты))
        mov  ebx,dword [cstr]   ; |
        mov  cl,byte [ebx]      ; |
        test cl,cl              ; | Если 0, то возврат на Next(SafeOffset)
        je   @F                 ; /

        add  dword [EAX+0B8h],6h ;   Если нет, то на eip+6 (это размер mov dword [eax],1)
        jmp  ne0                 ;   Для продолжения расшифровки!
@@:
        PUSH DWORD [EDX+8h]           ;[edx].SafeOffset
        POP  DWORD [EAX+0B8h]         ;[eax].regEip
ne0:
        PUSH DWORD [EDX+0Ch]          ;[edx].PrevEsp
        POP  DWORD [EAX+0C4h]         ;[eax].regEsp
        PUSH DWORD [EDX+10h]          ;[edx].PrevEbp
        POP  DWORD [EAX+0B4h]         ;[eax].regEbp

        MOV  EAX,0h
        POP  EDX
        ret
        endp

section '.data' data readable writeable
        key        dd        ?
        cstr       dd        ?
        szmsgBody  db 5Dh,74h,65h,65h,6Ch,35h,70h,7Bh,71h,34h,35h,28h,3Ch,00h ; "Happy end! =)", 0

section '.idata' import data readable writeable
  library kernel,'KERNEL32.DLL',\
           user,'USER32.DLL'
  import  kernel,\
           ExitProcess,'ExitProcess'
  import  user,\
           MessageBox,'MessageBoxA'
__________________________________________________ __________________________________
 
 





Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 


Быстрый переход




ANTICHAT.XYZ