實作經過:
首先用 "VB應用程式精靈" 生成一個密碼輸入範本
接著編譯成 check.exe
放到 [C++]keymaker 專案中輸入Name生成序號
放到 [C++]check 專案中生成 check.dll
http://d.turboupload.com/d/327208/Key.zip.html
內容包含三個專案及一個 sn.jpg + check.dll、check.exe、keymaker.exe
這裡引用了上一篇 "序號產生器的實作 教學 "的程式
將其包裝成 .dll 給
VB 呼叫
(因為 VB的亂數特性比較特別,為了省去開發時間所以這麼做...)
除了修改了
no=no*10+lpNameString[i];
(目的是當Name輸入 ABC、CBA 與 ACB... 會得到不同值)
及
handle= open("check.exe", O_BINARY);
兩段
(至於 dll 寫法請各位自行看範例)
原理:
VB software:
.裡藉由呼叫 CheckLoginString 後得到的返回值來判斷 (0是未通過; 1是通過)
[C++]check專案:
.限制此軟體只有一百組序號(應該是不會有重複...?),也就是只發行一百套,
如果軟體透過WWW傳序號回發行公司,就可製作黑名單序號表...
.使用 Name值+check.exe檔案大小 來作亂數表參數,如此得到三重保證
(當有人竄改check.exe時造成檔案大小改變的話 序號即無效、Name有分大小寫、亂數)
將srand及open寫在 try{} 裡配合 catch{} 是為了當 keymaker.exe 不是與check.exe放在一起運行時
亦可運行無誤,只是會得到不同的序號...
原本是想將 keymaker 也用VB + [C++].dll 方式寫成
不過碰到 Dev-C++ 對 SysAllocString 函式提出 [linker error] SysAllocString@4 錯誤
可能要改用 VC++來編譯,或 改寫.def定義檔 (沒裝VC++ & 不會...)
所以目前作罷中~
不過還是貼出原始檔 (有裝VC++或非 Dev-C++的版友可以編譯看看)
以上希望大家會喜歡
(以後看看情形來寫一篇自我破解的應用 ^o^, 等瀏覽人數超過 60人次再寫~)
也歡迎就本篇所討論範圍及內容作交流討論~thx~
KeyMaker.frm 內容
PHP 語法:
VERSION 5.00
Begin VB.Form Form1
BorderStyle = 1 '單線固定
Caption = "Form1"
ClientHeight = 1080
ClientLeft = 45
ClientTop = 435
ClientWidth = 3000
LinkTopic = "Form1"
MaxButton = 0 'False
MinButton = 0 'False
ScaleHeight = 1080
ScaleWidth = 3000
StartUpPosition = 3 '系統預設值
Begin VB.TextBox Text2
Alignment = 2 '置中對齊
Height = 375
Left = 120
TabIndex = 3
Text = "請填寫名稱"
Top = 120
Width = 1935
End
Begin VB.CommandButton Command2
Caption = "複製"
Height = 375
Left = 2160
TabIndex = 2
Top = 600
Width = 735
End
Begin VB.CommandButton Command1
Caption = "生成"
Height = 375
Left = 2160
TabIndex = 1
Top = 120
Width = 735
End
Begin VB.TextBox Text1
Alignment = 2 '置中對齊
Height = 375
Left = 120
MaxLength = 10
TabIndex = 0
Text = "ABC-123456"
Top = 600
Width = 1935
End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Private Declare Function CheckLoginStringExport Lib "keymake.dll" (ByVal Name As String, ByVal LoopNum As Integer) As String
Dim NO As Long
Private Sub Command1_Click()
Dim sn As String
sn = Text2.Text
sn = CheckLoginStringExport(sn, NO)
Text1.Text = sn
NO = NO + 1
If NO >= 100 Then NO = 0
End Sub
Private Sub Text2_Click()
Text2.Text = ""
End Sub
dll.h 內容
PHP 語法:
#include <windows.h>
#ifndef _DLL_H_
#define _DLL_H_
#if BUILDING_DLL
# define DLLIMPORT __declspec (dllexport)
#else /* Not BUILDING_DLL */
# define DLLIMPORT __declspec (dllimport)
# define API
#endif /* Not BUILDING_DLL */
#ifdef __cplusplus
extern "C" {
#endif
DLLIMPORT BSTR _stdcall CheckLoginStringExport(TCHAR* lpNameString, int intLoopNum);
#ifdef __cplusplus
}
#endif
#endif /* _DLL_H_ */
dllmain.cpp 內容
PHP 語法:
/* Replace "dll.h" with the name of your header */
#include "dll.h"
#include <TCHAR.H>
#include <oleauto.h>
#include <fcntl.h>
#include <exception>
#define ASCII_NUM 3
#define MULTIPLY_VALUE 2
//using namespace std;
DLLIMPORT BSTR _stdcall CheckLoginStringExport(TCHAR* lpNameString, int intLoopNum)
{
//計: 3個英文 + "-" + 6個阿拉伯數字 + '\0'
char key[ASCII_NUM+ASCII_NUM*MULTIPLY_VALUE+2]="\0";
long no=0;
int handle, i, j, rndreset;
for(i=0; i<strlen(lpNameString) ;i++)
no=no*10+lpNameString[i];
try{
handle= open("check.exe", O_BINARY);
rndreset=filelength(handle)+no;
srand( (unsigned int)rndreset);
close(handle);
}
catch(std::exception & exc){} //如果檔案不在之例外處理
for(j=0; j<intLoopNum; j++){
no=0;
for(i=0; i<ASCII_NUM ;i++){
key[no++]= (char)(rand()%26 +65); //轉成英文字母
}
key[no++]= '-';
for(i=0; i<(ASCII_NUM*MULTIPLY_VALUE) ;i++){
key[no++]= (char)(rand()%10 +48); //轉成阿拉伯數字
}
}
return SysAllocString((BSTR)key);
}