LAB
研究室
その他プログラムTIPS
ドングル
少し前に自宅での3DCGのアニメーション用に
messiah studio(http://www.projectmessiah.com/)というソフトを超キャンペーン価格で購入したのですが、
このソフトのライセンス認証が少し面白い仕組みになっていました。
市販のUSBメモリをハードウェアキーとして動作させるのです。
昔はライセンス認証の為だけに専用のドングルと呼ばれるハードウェアを使っていたのですが、
果たして市販のUSBメモリがその役目を果たせるのか気になったので少し調べてみました。
するとWindowsではWMIという機能でディスクドライブのユニークなIDを取得できるようです。
ソースコードも沢山見つける事が出来たのですが、
C#やVBのコードばかりでしたので、C++ではどう書いたら良いのか試しに書いてみました。
今回はUSBのディスクドライブを列挙してその固有IDを表示するものです。
(ソースコードはVisualStudio2010のコンソールアプリケーションで動作確認しています。)
#include
#include
// ただの加算関数
int funcAdd(int a, int b)
{
return a + b;
}
// 上の関数のx86バイナリコード
unsigned char codeAdd[] =
{
// _a$ = 8
// _b$ = 12
0x55, // push ebp
0x8b, 0xec, // mov ebp, esp
0x81, 0xec, 0xc0,0x00, 0x00, 0x00, // sub esp, 192
0x53, // push ebx
0x56, // push esi
0x57, // push edi
0x8d, 0xbd, 0x40, 0xff, 0xff, 0xff, // lea edi, [ebp - 192]
0xb9, 0x30, 0x00, 0x00, 0x00, // mov ecx, 48
0xb8, 0xcc, 0xcc, 0xcc, 0xcc, // mov eax, -858993460
0xf3, 0xab, // rep stosd
0x8b, 0x45, 0x08, // mov eax, _a$[ebp]
0x03, 0x45, 0x0c, // add eax, _b$[ebp]
0x5f, // pop edi
0x5e, // pop esi
0x5b, // pop ebx
0x8b, 0xe5, // mov esp, edp
0x5d, // pop edp
0xc3 // ret 0
};
typedef int(*funcType)(int a, int b);
int main()
{
// 通常関数のコール結果
printf("func %d\n", funcAdd(5, 10));
// 少し前のwindowsから実行属性の無い領域を実行させられないプロテクトが入っている為
// 実行属性付の領域を確保する
void* code = VirtualAlloc( NULL, sizeof(codeAdd), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if(code != NULL){
memcpy(code, codeAdd, sizeof(codeAdd));
DWORD oldProteted;
VirtualProtect( code, sizeof(codeAdd), PAGE_EXECUTE, &oldProteted );
// このような感じでデータ領域のコードを実行属性の領域に移してきて実行させる事が出来る
funcType func = (funcType)code;
printf("code %d\n", func(5, 10));
}
return 0;
}
COMの初期化関係で行数が多いですが、
実質はインスタンス作成部分から固有ID取得までが目的の処理になります。
この固有IDを基にしたライセンスファイルを作成して、
アプリケーション起動時に二つの整合性を確認出来れば確かにハードウェアキーとして使えそうです。
面白くなってきたのでもしかしたら次回に続くかもしれないです。
CATEGORY
- 製品事例 (7)
- デモプログラム (18)
- プログラムTIPS (41)
- C言語 (5)
- C++ (6)
- C++cording (4)
- Ruby (8)
- VisualStudioの使い方 (3)
- 最適化Tips (5)
- ゲーム開発テクニック (2)
- その他 (7)


