MASM32單詞跑馬燈免輸ID序號產生器:超級簡單 (6千字)

看雪資料發表於2001-11-12

;軟體註冊演算法:
;1.(硬碟ID(Hex)+806H) xor 1E3733H,轉為10進位制=註冊ID;
;2.(111A7BH-(註冊ID mod 3E8H)) xor 註冊ID,轉為10進位制=序列號
;以下是MASM32序號產生器
;kg-pmd.asm==============================================
.386                  ;程式碼型別?
.model flat,stdcall  ;編譯模式?
option casemap:none  ;大小寫敏感
include hd.h          ;標頭檔案
  _WinMain Proto  :DWORD,:DWORD,:DWORD,:DWORD
  Calculation Proto

.const
  DLG_MAIN  equ    1000 ;與資原始檔中的ID值定義要相符
  IDC_UN    equ    1001
  IDC_SN    equ    1002
  ID_GEN    equ    1003
  ID_EXIT  equ    1004

.data                  ;資料段定義,靜態變數
MsgCap        db "單詞跑馬燈 Ver 1.0 序號產生器  by 5,555",0
MsgName      db "請輸入您的機器碼!",0
hInstance    dd 0
ID_Hex        dd 0
UserLen      dd 0
  VName    db 256 dup (0)
  FSName    db 256 dup (0)
  Drive    db "C:\",0
  VID      dd 0
.data?                ;資料段定義,動態變數
UserID      db 80 dup (?)
SN          db 80 dup (?)

.code
start:
invoke GetModuleHandle,NULL            ;取得應用程式的控制程式碼
mov hInstance,eax
invoke DialogBoxParam,hInstance,DLG_MAIN,NULL,offset _WinMain,NULL ;呼叫API函式顯示對話方塊,進入訊息迴圈(_WinMain函式處理這個迴圈),引數含義自己查
invoke ExitProcess,NULL      ;退出訊息迴圈後,結束程式(返回NULL值?)

_WinMain  proc    uses ebx edi esi, \ ;過程用到的暫存器,編譯時自動PUSH&POP。
          hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD ;幾個系統引數
         
          mov    eax,wMsg                              ;取訊息
          .if    eax == WM_CLOSE                        ;處理關閉視窗、初始化視窗及視窗按鈕按下的動作,這裡只列了三類
                invoke    EndDialog,hWnd,NULL
          .elseif eax == WM_INITDIALOG
                  call GetID                            ;預先取得跑馬燈的使用者ID
                  invoke SetDlgItemText, hWnd, IDC_UN, addr UserID ;顯示在對話方塊中的“機器碼”後
                  invoke SetWindowText,hWnd,ADDR MsgCap            ;將MsgCap字串寫到對話方塊標題欄上(原來MsgCap字串我是加密過的,用UEDIT不能改。這樣即使用exescope修改了資源中的標題欄,標題資訊也不會變:)
                  invoke SendDlgItemMessage,hWnd,IDC_SN,EM_SETREADONLY,TRUE,NULL ;傳送訊息使註冊碼框只讀
          .elseif eax == WM_COMMAND                    ;處理命令
                  mov eax,wParam
                  .IF lParam!=0                        ;???
                      .if eax==ID_GEN
                          invoke GetDlgItemText, hWnd, IDC_UN, addr UserID, 80  ;從ID為IDC_UN(機器碼)的文字框中取得字串並放入UserID中
                          .if  eax!=NULL                                        ;如果並非沒有輸入,計算
                              mov UserLen,eax
                              invoke Calculation
                              invoke SetDlgItemText, hWnd, IDC_SN, addr SN      ;顯示SN的內容到ID號IDC_SN的框中
                          .else
                              invoke MessageBox,NULL,addr MsgName,addr MsgCap,MB_OK or MB_ICONEXCLAMATION
                          .endif
                      .elseif eax==ID_EXIT
                          invoke SendMessage,hWnd,WM_CLOSE,NULL,NULL
                      .endif
                  .ENDIF
          .else
                  mov eax,FALSE        ;如果沒有處理過訊息,返回False值(放入任務佇列,下次迴圈繼續處理?)
                  ret
          .endif
          mov eax,TRUE                ;否則返回True
          ret
_WinMain  ENDP       


Calculation Proc
            pushad                      ;儲存所有的暫存器值,懶人的方法:)。以下就不用解釋了吧。
            mov ecx,UserLen
            lea ebp,UserID
            call Dec2Hex
            mov ID_Hex,eax
            mov ebp,3e8h
            cdq
            div ebp
            mov eax,111a7bh
            sub eax,edx
            xor eax,ID_Hex
            lea ebp,SN
            call Num2Dec
            popad
            ret
Calculation Endp

GetID      Proc
            pushad
            invoke  GetVolumeInformation, addr Drive, addr VName, 255, addr VID, 0, 0, addr FSName, 255
            mov eax,VID
            add eax,806h
            xor eax,1e3733h
            mov ID_Hex,eax
            lea ebp,UserID
            call Num2Dec
            popad
            ret
GetID      Endp

;===數字轉換成10進位制字串,對0也同樣適用
Num2Dec Proc  uses ebx edx edi  ;入口:eax:Num to convert, ebp-->buffer 出口:ecx:返回轉換後的ASC長度
        xor edi,edi
        mov ebx,10
@Num2Dec_Lop1:
        cdq
        div ebx
        push edx
        inc edi
        test eax,eax
        jnz @Num2Dec_Lop1
        mov ecx,edi
@Num2Dec_Lop2:
        pop eax
        add al,'0'
        mov byte ptr [ebp],al
        inc ebp
        dec edi
        jnz @Num2Dec_Lop2
        mov byte ptr [ebp],0      ;加上結尾的0
        ret
Num2Dec Endp

;===10進位制字串轉換成16進位制數字,對0也同樣適用
Dec2Hex Proc  uses ebx edx ecx edi    ;入口:ecx:字串長度 ebp-->0結尾的10進位制字串 出口:eax:返回值
        xor ebx,ebx
        mov edi,1
@Dec2Hex_Lop_1:
        xor eax,eax
        mov al,[ebp+ecw-1]
        sub al,'0'
        imul edi
        add ebx,eax
        imul edi,10
        loop @Dec2Hex_Lop_1
        mov eax,ebx
        ret
Dec2Hex Endp
        End start
       
;kg-pmd.rc       
#include <e:\masm32\include\resource.h>
#define DLG_MAIN  1000
#define IDC_UN    1001
#define IDC_SN    1002
#define ID_GEN    1003
#define ID_EXIT  1004
DLG_MAIN DIALOG 64,53,240,52
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "單詞跑馬燈 Ver 1.0 序號產生器  by 5,555"
FONT 9, "宋體"
{
DEFPUSHBUTTON "註冊", ID_GEN, 180, 8, 50, 14
PUSHBUTTON "退出", ID_EXIT, 180, 26, 50, 14
EDITTEXT IDC_UN, 52, 10, 100, 12, WS_BORDER | WS_TABSTOP
EDITTEXT IDC_SN, 52, 29, 100, 13, WS_BORDER | WS_TABSTOP
LTEXT "機器碼:", -1, 8, 12, 40, 10
LTEXT "註冊碼:", -1, 8, 30, 41, 9
}

;hd.h****************************************
      include \masm32\include\windows.inc
      include \masm32\include\user32.inc
      include \masm32\include\kernel32.inc
      include \masm32\include\gdi32.inc
      include \masm32\include\comctl32.inc
      include \masm32\include\comdlg32.inc
      include \masm32\include\shell32.inc
      include \masm32\include\advapi32.inc

      includelib \masm32\lib\user32.lib
      includelib \masm32\lib\kernel32.lib
      includelib \masm32\lib\gdi32.lib
      includelib \masm32\lib\comctl32.lib
      includelib \masm32\lib\comdlg32.lib
      includelib \masm32\lib\shell32.lib
      includelib \masm32\lib\advapi32.lib

相關文章