2012-07-09 3 views
1

그래서 오늘 this crackme을 해결했습니다. 필자는 몇 가지 마지막 지침을 제외하고는 직렬 생성 루틴을 찾아서 이해했습니다. 나는 처음으로 어셈블리에 keygen 을 쓰려고 결심했다. 시리얼 루틴의 마지막 몇 가지 지침이 나올 때까지 모든 것이 잘 진행되고있었습니다. 내가 MASM 인텔 어셈블리를 사용하고 있습니다 (? 인텔은 & T, 당신이 전화를 어떻게)이 내 현재 코드입니다 :FILD, FSTP 및 FST 조립 지침

.386 
.model flat,stdcall 
option casemap:none 

include  \masm32\include\windows.inc 
include  \masm32\include\kernel32.inc 
include  \masm32\include\user32.inc 
includelib \masm32\lib\kernel32.lib 
includelib \masm32\lib\user32.lib 

DlgProc  proto :DWORD,:DWORD,:DWORD,:DWORD 
SerialCalc proto :DWORD 

.data 
EnterText db  "...enter a name...",0 
temp  db  "temp",0 
Format  db  "%i-x019871",0 

.data? 
NameBuffer  db   100 dup(?) 
SerialBuffer db   150 dup(?) 
SerialLength dd   ? 
hInstance  HINSTANCE ? 

.const 
IDC_NAME   equ  1002 
IDC_SERIAL   equ  1003 
IDC_GENERATE  equ  1004 
IDC_NAMELABEL  equ  1005 
IDC_SERIALLABEL  equ  1006 
IDD_MAIN   equ  1001 

.code 
start: 

    invoke GetModuleHandle, NULL 
    mov hInstance,eax 
    invoke DialogBoxParam, hInstance, IDD_MAIN, NULL, addr DlgProc, NULL 
    invoke ExitProcess, 0 

DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM 
    .if uMsg == WM_INITDIALOG 
     invoke GetDlgItem,hWnd,IDC_NAME ;get IDC_NAME 
     invoke SetFocus,eax    ;focus on it 
    .elseif uMsg == WM_COMMAND 
     mov eax, wParam ;wParam = control that issued the WM_COMMAND message 
     .if ax == IDC_NAME ;if it was the name box 
      shr eax, 16 ;shift right and get more info? 
      .if ax == EN_CHANGE ;if the text was changed 
       invoke GetDlgItemText, hWnd, IDC_NAME, addr NameBuffer, 100 ;get text 
       invoke lstrlen, addr NameBuffer ;get length 
       mov SerialLength, eax ;move length into var 
       .if eax == 0 ;if length is 0 
        invoke SetDlgItemTextA, hWnd, IDC_SERIAL, addr EnterText ;"...enter a name..." 
       .elseif eax > 0 ;if length is bigger than 0 
        invoke SerialCalc, hWnd ;calc 
        invoke SetDlgItemTextA, hWnd, IDC_SERIAL, addr SerialBuffer ;"serial" 
       .endif 
      .endif 
     .endif 
    .elseif uMsg == WM_CLOSE 
     invoke EndDialog, hWnd, 0 
    .endif 

    xor eax,eax 
    ret 
DlgProc endp 

SerialCalc proc hWnd:HWND 
    ;push ecx allocate space for 1 local variable; i was trying to do something with local variables, but I failed 
    mov edx, SerialLength 
    imul edx, edx, 875CDh 
    mov eax, 51EB851Fh 
    mul edx 
    mov eax, edx 
    shr eax, 5h 
    imul eax, eax, -370h 
    xor edx, edx ;mov edx, 0 
    ;problems start here; I took this code from a solution i found 
    ;push edx 
    ;push eax 
    ;fild qword ptr [esp] 
    ;add esp, 8 
    ;fstp real8 ptr [SerialBuffer] 
      ;more stuff should come here sprintf etc.. but since I haven't solved my main problem yet I decided not to rush 
SerialCalc endp 

end start 

그리고이 프로그램 자체의 실제 시리얼 루틴 :

MOV EDX,EAX 
IMUL EDX,EDX,875CD 
MOV EAX,51EB851F 
MUL EDX 
MOV EAX,EDX 
SHR EAX,5 
IMUL EAX,EAX,-370 
MOV EDX,0 
PUSH EDX               ; ||format = NULL 
PUSH EAX               ; ||s = FE8BC1A0 
FILD QWORD PTR SS:[ESP]            ; || 
LEA ESP,DWORD PTR SS:[ESP+8]          ; || 
FSTP QWORD PTR SS:[EBP-410]           ; || 
FLD QWORD PTR SS:[EBP-410]           ; || 
FSTP QWORD PTR SS:[ESP+8]           ; || 
MOV DWORD PTR SS:[ESP+4],Crackme_.00401469       ; ||ASCII "%i-x019871" 
LEA EAX,[LOCAL.194]             ; || 
MOV DWORD PTR SS:[ESP],EAX           ; || 
CALL <JMP.&msvcrt.sprintf>           ; |\sprintf 
LEA EAX,[LOCAL.194]             ; | 
MOV DWORD PTR SS:[ESP+4],EAX          ; | 
LEA EAX,[LOCAL.130]             ; | 
MOV DWORD PTR SS:[ESP],EAX           ; | 
CALL <JMP.&msvcrt.strcmp>           ; \strcmp 

루틴은 EAX에서 완료된 시리얼을 계산하여 스택으로 밀어 넣고, 내가 이해할 수있는 한 FILD를 사용하여 FPU 스택으로 밀어 넣고 FSPT를 사용하여 FPU에서 꺼내어 넣습니다 EBP-410, FLD를 사용하여 EBP-410을 다시 FPU로 밀어 넣고 마지막으로 FSTP를 사용하여 sprintf의 매개 변수로 ESP + 8에 저장합니다. 스프린트와 strcmp는 여기서 중요하지 않지만 어쨌든 나는 그들을 포함시켰다. 그래서 당신은 무슨 일이 일어나고 있는지 더 잘 이해할 수있다.

그런데이 LOCAL 194는 형식이 지정된 문자열이 놓일 장소입니다.

인터넷을 검색하여 설명을 찾았지만 실제로이 문제를 내 keygen으로 전송하는 데 도움이되는 실제 사례 나 자료를 찾지 못했습니다.

마지막 질문은 다음과 같습니다. 이것을 어떻게 keygen으로 전송합니까? 나는 항상 "프로그램이 작동을 멈췄다"는 메시지를 받거나 시리얼 박스에 아무것도 나타나지 않는다. SerialCalc 루틴에서 주석 처리 된 부분은 다른 사람의 솔루션에서 작동 할 경우 해독 한 부분이지만 안타깝게도 그렇지 않습니다.

문제 나 추가 정보가 필요한 경우 알려주십시오.

나는 나의 noobiness를 사과한다!

미리 감사드립니다. 툰 투니.

답변

1

나는 마침내 그것을 얻었다! 그것은 지시 또는 무언가 후에 정확하게 스택을 균형을 조정하지 않은 것 같습니다. 어쨌든 Visual Studio를 사용하여 인라인 어셈블리를 작성하고 마침내 작동하게했습니다. 읽어 주셔서 감사합니다.