Develop and Download Open Source Software

Browse Subversion Repository

Diff of /branches/mty-makai/mty.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 25 by chapuni, Sat Mar 17 12:20:48 2007 UTC revision 26 by chapuni, Sun Mar 18 07:40:49 2007 UTC
# Line 1  Line 1 
1  /***********************************************************************  /***********************************************************************
2   *   *
3   *      file: mty.cpp   *      file: mty.c
4   *   *
5   *      まあ、待て屋。   *      まあ、待て屋。
6   *   *
# Line 8  Line 8 
8   *   *
9   */   */
10    
 #define DEBUG 0  
 #define USE_DT 1  
   
 #ifndef DEBUG  
 #define NDEBUG  
 #endif  
   
11  #include <assert.h>  #include <assert.h>
12  #include <ctype.h>  #include <ctype.h>
13  #include <errno.h>  #include <errno.h>
# Line 27  Line 20 
20  #include <string.h>  #include <string.h>
21  #include <time.h>  #include <time.h>
22    
 #ifdef __GNUC__  
   
 #include <stdint.h>  
 #define ALIGN_PREFIX(n)  
 #define ALIGN_SUFFIX(n) __attribute__ ((aligned(n)))  
 #ifdef __SSE__  
 typedef unsigned DQWORD_T __attribute__ ((mode(V4SI)));  
 #endif  
   
 #else  
   
 #include <xmmintrin.h>  
 #define ALIGN_PREFIX(n) __declspec(align(16))  
 #define ALIGN_SUFFIX(n)  
   
 /* inttypes.h */  
 typedef __int8 int8_t;  
 typedef __int32 int32_t;  
 typedef unsigned __int32 uint32_t;  
 typedef unsigned __int64 uint64_t;  
   
 typedef __m128 DQWORD_T;  
   
 #endif  
   
23  #if defined(WIN32)  #if defined(WIN32)
24    
25  #include <windows.h>  #include <windows.h>
# Line 64  typedef __m128 DQWORD_T; Line 32  typedef __m128 DQWORD_T;
32    
33  #endif  #endif
34    
35    #include "config.h"
36  #include "crypt64.h"  #include "crypt64.h"
37  #include "dt4.h"  #include "dt4.h"
38    #include "expr.h"
39  #if defined(USE_MMX)  #include "translate.h"
   
 #define N_STRIDE 6  
 typedef uint64_t        WS_T;  
 typedef uint32_t        ALU_T;  
   
 #define CRYPT64_CLOBBER /* "%ecx", "%edx", */  
   
 #elif defined(USE_64)   /* 64-bit ALU */  
   
 #define N_STRIDE 6  
 typedef uint64_t        WS_T;  
 typedef uint64_t        ALU_T;  
   
 #define CRYPT64_CLOBBER /* "%rcx", "%rdx",*/ "%r8", "%r9",  
   
 #elif defined(USE_64_XMM)  
   
 #define N_STRIDE 7  
 typedef DQWORD_T        WS_T;  
 typedef uint64_t        ALU_T;  
   
 #define CRYPT64_CLOBBER /* "%rcx", "%rdx",*/  
                                     
 #else   /* XMM */  
   
 #define N_STRIDE 7  
 typedef DQWORD_T        WS_T;  
 typedef uint32_t        ALU_T;  
   
 #define CRYPT64_CLOBBER /* "%ecx", "%edx", */  
   
 #endif  
40    
41  #define N_I             (sizeof(WS_T) / sizeof(uint32_t))  #define N_I             (sizeof(WS_T) / sizeof(uint32_t))
42  #define N_ALU (sizeof(WS_T) / sizeof(ALU_T))  #define N_ALU (sizeof(WS_T) / sizeof(ALU_T))
# Line 172  struct KEY Line 109  struct KEY
109    SLICE ks[28];    SLICE ks[28];
110  };  };
111    
 /* 漢字クラス表 */  
 unsigned char cp932[0x10000] = {  
 #include "cp932.inc"  
 };  
   
112  /* 鍵文字列 */  /* 鍵文字列 */
113  unsigned char key[8 + 8];  unsigned char key[8 + 8];
114  unsigned char okey[8 + 8];  unsigned char okey[8 + 8];
# Line 188  struct Line 120  struct
120    unsigned map[256];    unsigned map[256];
121  } kcls[8 + 8];  } kcls[8 + 8];
122    
123  #define KCLS_AN 1  
124  #define KCLS_KA 2  /* 拡張鍵クラス */
 #define KCLS_K1 4  
125  #define KCLS_DT0 64  #define KCLS_DT0 64
126  #define KCLS_DT1 128  #define KCLS_DT1 128
127  #define KCLS_K2 256  #define KCLS_K2 256
# Line 750  key_init() Line 681  key_init()
681    
682  /***************************************************************  /***************************************************************
683   *   *
  *      可視文字列に変換  
  *      n = 0, flag !=0 で呼ぶこと  
  *  
  *      ptr で指される文字列は、変換に成功したら書き換えられる  
  *  
  *      成功したら flg, 失敗したら 0 を返す。  
  *  
  */  
   
 unsigned  
 translate(unsigned char *ptr,  
                   int n,  
                   unsigned flag)  
 {  
   int r;  
   unsigned char buf[32];  
   unsigned s0 = (n == 1 || n == 2 ? 0x00 : 0x80);  
   unsigned s1 = (n == 0 || n == 1 ? 0x00 : 0x80);  
   unsigned c0 = ptr[n] << 8;  
   unsigned c1 = ptr[n + 1];  
   unsigned cs0 = c0 ^ (s0 << 8);  
   unsigned cs1 = c1 ^ s1;  
   
   if (n >= 8)  
         return flag;  
   
   if (n == 7)  
         {  
           int i;  
           /* 最後の1文字 */  
           if (!(ptr[7] & 0x7F))  
                 return flag;  
             
           for (i = 0x00; i <= 0x7E; i++)  
                 {  
                   if (cp932[c0 | i] & KCLS_K1)  
                         {  
                           ptr[8] = i;  
                           return flag;  
                         }  
                   if (cp932[c0 | (0x80 + i)] & KCLS_K1)  
                         {  
                           ptr[8] = 0x80 + i;  
                           return flag;  
                         }  
                 }  
   
           ptr[7] ^= 0x80; c0 = ptr[7] << 8;  
           for (i = 0x00; i <= 0x7E; i++)  
                 {  
                   if (cp932[c0 | i] & KCLS_K1)  
                         {  
                           ptr[8] = i;  
                           return flag;  
                         }  
                   if (cp932[c0 | (0x80 + i)] & KCLS_K1)  
                         {  
                           ptr[8] = 0x80 + i;  
                           return flag;  
                         }  
                 }  
           ptr[7] ^= 0x80; c0 = ptr[7] << 8;  
         }  
   
   /* K1 */  
   if (cp932[c0 | c1] & KCLS_K1)  
         {  
           r = translate(ptr, n + 2, flag);  
           if (r)  
                 return r;  
         }  
   if (s0  
           && cp932[cs0 | c1] & KCLS_K1)  
         {  
           memcpy(buf, ptr, sizeof(buf));  
           buf[n] ^= s0;  
           r = translate(buf, n + 2, flag);  
           if (r)  
                 {  
                   memcpy(ptr, buf, sizeof(buf));  
                   return r;  
                 }  
         }  
   if (s1  
           && cp932[c0 | cs1] & KCLS_K1)  
         {  
           memcpy(buf, ptr, sizeof(buf));  
           buf[n + 1] ^= s1;  
           r = translate(buf, n + 2, flag);  
           if (r)  
                 {  
                   memcpy(ptr, buf, sizeof(buf));  
                   return r;  
                 }  
         }  
   if (s0 && s1  
           && cp932[cs0 | cs1] & KCLS_K1)  
         {  
           memcpy(buf, ptr, sizeof(buf));  
           buf[n] ^= s0;  
           buf[n + 1] ^= s1;  
           r = translate(buf, n + 2, flag);  
           if (r)  
                 {  
                   memcpy(ptr, buf, sizeof(buf));  
                   return r;  
                 }  
         }  
   
   /* AN */  
   if (cp932[c0] & (KCLS_AN | KCLS_KA))  
         {  
           r = translate(ptr, n + 1, flag);  
           if (r)  
                 return r;  
         }  
   if (s0 && cp932[cs0] & (KCLS_AN | KCLS_KA))  
         {  
           memcpy(buf, ptr, sizeof(buf));  
           buf[n] ^= s0;  
           r = translate(buf, n + 1, flag);  
           if (r)  
                 {  
                   memcpy(ptr, buf, sizeof(buf));  
                   return r;  
                 }  
         }  
   
   /* KA */  
   /* KG */  
   /* KD */  
   /* AD */  
   
   return 0;  
 }  
   
 /***************************************************************  
  *  
684   *      Salt のセット   *      Salt のセット
685   *      オペランドのオフセットを書き換えて回ってるので注意   *      オペランドのオフセットを書き換えて回ってるので注意
686   *   *
# Line 953  set_salt(signed char *code, Line 746  set_salt(signed char *code,
746          }          }
747  }  }
748    
 /***************************************************************  
  *  
  *      オペコードを展開  
  *  
  *      r       EAX, ECX, EDX, EBX  
  *              SIB, EBP, ESI, EDI  
  *  
  */  
   
 /* ofs8(i) もしくは ofs32(i) を生成 */  
 static  
 signed char *  
 disp_rm(signed char *pc,  
                 unsigned d,  
                 unsigned i,  
                 long ofs)  
 {  
   assert(i != 4);       /* SP ではなく SIB になる */  
   if (-128 <= ofs && ofs <= 127)  
         {  
           /* short ofs  
                  01 ddd sss [ofs.b] */  
           pc[0] = (0100  
                            | ((d << 3) & 0070)  
                            | (i & 0007));  
           pc[1] = ofs;  
           return pc + 2;  
         }  
   else  
         {  
           /* long ofs  
                  10 ddd sss [ofs.l] */  
           pc[0] = (0200  
                            | ((d << 3) & 0070)  
                            | (i & 0007));  
           *(long *)&pc[1] = ofs;        /* XXX unaligned */  
           return pc + 5;  
         }  
 }  
   
 #define PTR_T   7       /* DI(LR+16) */  
 #define OFS_T   (64 + 32 - 16)  
   
 #ifdef USE_64   /* ALU 64 */  
   
 /*  
  *      0x49 0xF7 11-010-ddd    not  
  *      0x49 op   11-sss-ddd  
  *  
  *      0x4C op   rm  
  *      0x4C 0x8B rm    load  
  *      0x4C 0x89 rm    store  
  *  
  */  
   
 #define OP_MOV  0x8B  
 #define OP_STOR 0x89  
 #define OP_AND  0x23  
 #define OP_OR   0x0B  
 #define OP_XOR  0x33  
   
 static  
 signed char *  
 reg_op(signed char *pc,  
            unsigned op,  
            unsigned d,  
            unsigned s)  
 {  
   pc[0] = 0x4D; /* 49 */  
   pc[1] = op & 0xFD;  
   /* 11 ddd sss */  
   pc[2] = (0300  
                    | ((s << 3) & 0070)  
                    | (d & 0007));  
   return pc + 3;  
 }  
   
 static  
 signed char *  
 reg_mem(signed char *pc,  
                 unsigned op,  
                 unsigned d,  
                 unsigned i,  
                 long ofs)  
 {  
   pc[0] = 0x4C;  
   pc[1] = op;  
   return disp_rm(pc + 2, d, i, ofs);  
 }  
   
 #else   /* MMX or XMM */  
   
 #define OP_MOV  0x6F  
 #define OP_STOR 0x7F      
 #define OP_AND  0xDB  
 #define OP_ANDN 0xDF  
 #define OP_OR   0xEB  
 #define OP_XOR  0xEF  
   
 static  
 signed char *  
 reg_op(signed char *pc,  
            unsigned op,  
            unsigned d,  
            unsigned s)  
 {  
 #ifndef USE_MMX  
   *pc++ = 0x66;  
 #endif  
   pc[0] = 0x0F;  
   pc[1] = op;  
   /* 11 ddd sss */  
   pc[2] = (0300  
                    | ((d << 3) & 0070)  
                    | (s & 0007));  
   return pc + 3;  
 }  
   
 static  
 signed char *  
 reg_mem(signed char *pc,  
                 unsigned op,  
                 unsigned d,  
                 unsigned i,  
                 int ofs)  
 {  
 #ifndef USE_MMX  
   *pc++ = 0x66;  
 #endif  
   pc[0] = 0x0F;  
   pc[1] = op;  
   return disp_rm(pc + 2, d, i, ofs);  
 }  
   
 #endif  
   
 /***************************************************************  
  *  
  *      与えられた式を解析・命令生成  
  *  
  *      ^               先頭固定  
  *      $               末尾固定  
  *      ?               任意の1文字  
  *      *               任意の0文字以上  
  *      &               大小区別ナシ、グループに使われた場合、capitalize  
  *      ()              グループ化  
  *      \s              or  
  *      \1              一致したグループ(実体)  
  *      $(fn)   テキストを展開(グループはクラスとして扱われる)  
  *  
  *                      以下、クラス展開のメタキャラ  
  *      [A-Z]   文字クラス定義 ^ は排他  
  *      {}              0文字以上  
  *      {n}             n文字  
  *      {n,}    n文字以上  
  *      {,n}    n文字以下  
  *      {m,n}   m-n文字  
  *  
  */  
   
 static  
 int  
 cv64(int c)  
 {  
   if ('.' <= c && c <= '/')  
         return c - '.';  
   else if ('0' <= c && c <= '9')  
         return c - '0' + 2;  
   else if ('A' <= c && c <= 'Z')  
         return c - 'A' + 2 + 10;  
   else if ('a' <= c && c <= 'z')  
         return c - 'a' + 2 + 10 + 26;  
   else  
         return -1;  
 }  
   
 static  
 int  
 expr_make(signed char *iptr,  
                   int ofs,  
                   char const *expr,  
                   int len)  
 {  
   /* 先頭制約 */  
   signed char *o_iptr = iptr;  
   unsigned op = OP_MOV;  
   int i;  
   
   if (expr[0] == '^')  
         {  
           if (len == 0 || ofs > 0)  
                 return -1;  
           expr++;  
           len--;  
         }  
   
   /* 一文字づつ展開 */  
   for (i = 0; i < len; i++)  
         {  
           int c = expr[i];  
   
           if (c == '$')  
                 {  
                   assert(op != OP_MOV);  
                   if (ofs < 10)  
                         return 0;  
                   else if (ofs > 10)  
                         return -1;  
                   return iptr - o_iptr;  
                 }  
   
           if (ofs >= 10)  
                 return -1;  
   
           if (c == '[')  
                 {  
                   /* クラスをまとめる */  
                   unsigned oop; /* MOVQ */  
                   int j;  
                   int cs[64];  
                   memset(cs, 0, 64 * sizeof(int));  
                   for (i++; c = expr[i], c != ']'; i++)  
                         {  
                           c = cv64(c);  
                           if (c < 0)  
                                 return -1;  
                           if (expr[i + 1] == '-')  
                                 {  
                                   int ce = cv64(expr[i + 2]);  
                                   if (ce < 0)  
                                         return -1;  
                                   while (c <= ce)  
                                         cs[c++]++;  
                                   i += 2;  
                                 }  
                           else  
                                 cs[c]++;  
                         }  
                   assert(c == ']');  
   
                   /* マップされたモノから命令を生成する */  
                   oop = OP_MOV;  
                   for (j = 0; j < 64; j++)  
                         if (cs[j])  
                           {  
                                 if (ofs == 9 && (j & 3))  
                                   continue;  
                                 iptr = reg_mem(iptr,  
                                                            oop,  
                                                            1,           /* MM1/R9 */  
                                                            PTR_T,  
                                                            sizeof(WS_T) * (OFS_T + (64 * ofs + j)));  
                                 oop = OP_OR;  
                           }  
                   if (oop != OP_OR)  
                         {  
                           if (ofs == 9)  
                                 return -1;  
                         }  
                   else  
                         {  
                           iptr = reg_op(iptr,  
                                                         op,  
                                                         0,              /* MM0/R8 */  
                                                         1);             /* MM1/R9 */  
                           op = OP_AND;  
                         }  
                   ofs++;  
                 }  
           else if (c == '?')  
                 {  
                   ofs++;  
                 }  
           else if ((c = cv64(c)) >= 0)  
                 {  
                   if (ofs == 9 && (c & 3))  
                         return -1;  
                   iptr = reg_mem(iptr,  
                                                  op,  
                                                  0,             /* MM0/R8 */  
                                                  PTR_T,  
                                                  sizeof(WS_T) * (OFS_T + (64 * ofs + c)));  
                   op = OP_AND;  
                   ofs++;  
                 }  
           else  
                 return -1;  
         }  
   
   return iptr - o_iptr;  
 }  
 /*  
 Fighters ^FIGHTERS ^BayStars ^Red[Ss]tar/ ^REDSTAR/ ^Parsifal ^VALKYRIE ^Valkyrie  
 ^Dr.Death ^IamCHONO ^RAGNAROK ^MARAOH.. ^MARAOH// ......... God[Ff]ather GODFATHER  
 ^maraGULO[./] BLACKJACK ^[Bb]lackjack ^BlackJack [Pp]atagonia PATAGONIA ^JC.PENNEY  
 ^JC.Penney ^syombolic ROCKNROLL stammerB4U Ms.Erie.W. MARA.w/w/w R3[0-4]SKYLINE  
 100000[Gg]et. 100000GET.  
 */  
 signed char *  
 expr_parse(signed char *iptr,  
                    int codesiz_limit,  
                    char const *expr)  
 {  
   /* ファイルを読み込む  
          この版では手抜きで 64K 制限 */  
 #define TARGET_SIZ 65536  
   char expr_buf[TARGET_SIZ + 1];  
   FILE *fp;  
   size_t sz;  
   
   fp = fopen("target.txt", "rb");  
   assert(fp != NULL);  
   memset(expr_buf, 0, TARGET_SIZ + 1);  
   sz = fread(expr_buf, sizeof(char), TARGET_SIZ, fp);  
   fclose(fp);  
   
   /* XXX ターゲットのサイズをチェック */  
   if (sz == TARGET_SIZ)  
         {  
           /* トークンのトラバース */  
           char *ds, *pe, *ps;  
           for (ds = &expr_buf[TARGET_SIZ - 1];  
                    !isspace(*ds);  
                    ds--)  
                 assert(ds >= expr_buf);  
           for (pe = ds++; isspace(*pe); pe--)  
                 assert(pe >= expr_buf);  
           for (ps = pe++; !isspace(*ps); ps--)  
                 assert(ps >= expr_buf);  
           fprintf(stderr, "WARNING: <");  
           ps++;  
           while (ps < pe)  
                 fputc(*ps++, stderr);  
           fprintf(stderr, ">より後ろのターゲット<%s(ry>はオ?ル\n",  
                           ds);  
           *pe = 0;  
         }  
   
   /* MM7 にターゲット毎に比較結果を OR していくため  
          まずはゼロクリア */  
   iptr = reg_op(iptr, OP_XOR, 7, 7);    /* MM7/R15 := 0 */  
   
   /* 順繰りに parse */  
   expr = expr_buf;  
   while (expr[0])  
         {  
           char const *p;  
           int i;  
   
           /* 頭の Whitespace を読み飛ばす */  
           while (isspace(expr[0]))  
                 expr++;  
   
           if (!expr[0])  
                 break;  
   
           /* トークンを切り出す */  
           for (p = expr; expr[0] && !isspace(expr[0]); expr++)  
                 ;  
   
           /* 展開する */  
           for (i = 0; i < 10; i++)  
                 {  
                   int n = expr_make(iptr, i, p, expr - p);  
                   if (n < 0)  
                         break;  
 #if DEBUG>=1  
                   if (n > 0)  
                         {  
                           int j;  
                           for (j = 0; &p[j] < expr; j++)  
                                 putchar(p[j]);  
                           printf(": of=%d len=%d\n", i, expr - p);  
                         }  
 #endif  
                   /* 1ターゲット分の比較結果を MM7 に追加 */  
                   if (n > 0)  
                         iptr = reg_op(iptr + n,  
                                                   OP_OR,  
                                                   7,    /* MM7/R15 */  
                                                   0);   /* MM0/R8  */  
                 }  
         }  
   
   /* MM7 に生成された結果を t[31] に格納 */  
   return reg_mem(iptr,  
                                  OP_STOR,  
                                  7,     /* MM7/R15 */  
                                  PTR_T,  
                                  sizeof(WS_T) * (64 + 31 - 16));  
 }  
   
749  static  static
750  unsigned  unsigned
751  usec()  usec()

Legend:
Removed from v.25  
changed lines
  Added in v.26

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26