그래서 오늘 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를 사과한다!
미리 감사드립니다. 툰 투니.