【问题标题】:FILD, FSTP and FST assembly instructionsFILD、FSTP 和 FST 组装说明
【发布时间】:2012-07-09 07:26:45
【问题描述】:

所以我今天一直在解决thiscrackme。除了最后几条指令外,我设法找到并理解了串行生成例程。我决定第一次在汇编中编写一个keygen。一切都很顺利,直到我来到串行例程的最后几条指令。我正在使用 MASM 和 Intel 程序集(Intel、AT&T,你怎么称呼这些?)这是我当前的代码:

.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 将其存储到 ESP+8 作为 sprintf 的参数。 sprint 和 strcmp 在这里并不重要,但我还是将它们包括在内,以便您更好地了解发生了什么。

顺便说一下,这个 LOCAL 194. 是放置格式化字符串的地方。

我在互联网上搜索并找到了这些说明的描述,但没有找到任何可以帮助我将其转移到我的密钥生成器的实际示例或材料。

所以最后一个问题是:如何将其转移到我的注册机?我总是收到“程序已停止工作”消息,或者串行框中没有显示任何内容。我的 SerialCalc 例程中的注释内容是我从另一个人的解决方案中抄袭的部分,只是为了尝试它是否可以工作,但不幸的是,它没有。

如果您需要有关问题的更多详细信息或任何额外信息,请告诉我。

我为我的菜鸟道歉!

提前致谢, 屯图尼。

【问题讨论】:

    标签: assembly floating-point x86 reverse-engineering fpu


    【解决方案1】:

    我终于明白了!似乎我在指令或其他东西之后没有正确平衡堆栈。无论如何,我用 Visual Studio 编写了内联汇编,终于让它工作了。感谢阅读。

    【讨论】:

      猜你喜欢
      • 2013-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多