2001/3/19

「コードの自己展開と暗号化」

  私はシェアウェアは作らないので別に必要がないのですが、 シェアの作者達はシリアル破りの対策とかが大変みたいですね。 普通にダイアログを出してパスワードを入力させる、というタイプの物は 逆アセンブラをかけられて一瞬でパスワードを盗まれてしまいます。

というわけで、最も単純なクラック対策はプログラムの最初の部分や パスワードのチェック部分などを自己展開方式 & 暗号化 することだと思うのですが、簡単な暗号化の方法を考えてみました。下のコードは eax + ebx を計算して printf で表示するという関数を暗号化したものです。

実際にはもっと複雑な暗号化を行って、かつ自己展開したコードの中で 更にコードの展開を行って…という風にすれば、それだけでも 大分堅牢なクラック対策になるのではないのでしょうか。

と言っても、本気で逆アセンブラをかけられたら何をしても無駄なような気もしますが。


//コードの暗号化サンプル
// (c) tokai@fides.dti.ne.jp 2001/3/19

#include < stdio.h >
#include < stdlib.h >

// 暗号化したコード
unsigned char dat[]={
  0x54,// push ebx
  0x51,// push eax
  0x04, 0xc4,// add eax,ebx
  0x51, // push eax
  0x53,               // push edx
  0x00, 0xd2,         // call ecx
  0x84, 0xc5, 0x11,   // add   esp,16
  0xc4// ret
};
char *formc="結果 %d = %d + %d\n";


int main(){

  unsigned long printf_add;
  unsigned char *func_add;
  int i;

  printf_add = (unsigned long)printf;

  printf("コードの暗号化サンプル\n");

  // ここから
  func_add = malloc(12);
  for(i=0;i < 12;i++) func_add[i] = dat[i]-1;  // データ展開 兼 解読(ただ 1 引いてるだけ)
  _asm{ 
  mov eax,10
  mov ebx,22
  mov ecx,printf_add
  mov edx,dword ptr [formc]
  call dword ptr [func_add] // 実行
  }
  free(func_add);
  // ここまで

  printf("以上。\n");

  return 0;
}