1 /*
2  * zipcrack.c - where the 'crack' routine is located
3  */
4 
5 /*
6  * guiding comments for gencrack.pl
7  *
8  * MTH cpmask init_cpmask crack_cpmask load_img
9  *
10  * LCL init_crack_pw crack_pw
11  * LOD load_zip
12  *
13  * ARC ARCH_i386
14  * DEF USE_MULT_TAB
15  * DEF TARGET_CPU 0 $ 5 $ 6
16  * DFT TARGET_CPU==COMPILE_CPU && USE_MULT_TAB
17  * DEP defined(__i386__) || defined(__i386) || defined(i386)
18  *
19  * DEF USE_MULT_TAB
20  * DFT USE_MULT_TAB
21  * DEP 1
22  *
23  * END
24  */
25 
26 #include "crc32.h"
27 
28 #undef USE_GCC_X86_ASM
29 #define USE_GCC_X86_ASM (ARCH_i386 && USE_GCC_ASM && USE_MULT_TAB)
30 
init_crack_pw(void)31 static void init_crack_pw (void)
32 {
33 #if USE_MULT_TAB
34   u16 t;
35   for (t = 0; t < 16384; t++)
36     mult_tab[t] = ((t*4+3) * (t*4+2) >> 8) & 0xff;
37 #endif
38 }
39 
crack_pw(gen_func genfunc,callback_func cbfunc)40 static int crack_pw (gen_func genfunc, callback_func cbfunc)
41 {
42   int changed = -1;
43   int crack_count = 0;
44   u32 key_stack[(MAX_PW+1) * 3] = { 0x12345678UL, 0x23456789UL, 0x34567890UL };
45   u32 *sp;
46 #if USE_GCC_X86_ASM
47   int dummy; /* dummy output.  */
48 #endif
49 
50   sp = 0; /* to calm down dumb compilers */
51 
52   do
53     {
54       int count = file_count;
55       int count2 = 0;
56       u32 key0, key1, key2;
57       u8 *p;
58       u8 *b = files;
59 
60       if (changed < 0)
61         {
62           changed = strlen (pw);
63           pw_end = pw + changed;
64           sp = key_stack + changed * 3;
65         }
66 
67       sp -= changed * 3;
68       p = (u8 *)pw_end - changed;
69 
70       if (++crack_count >= 1000000 && verbosity)
71         {
72           printf ("checking pw %-40.40s\r", pw), fflush (stdout);
73           crack_count = 0;
74         }
75 
76 #  if USE_GCC_X86_ASM && TARGET_CPU
77       asm(
78 "        movl (%7),%0\n"
79 "        movl 4(%7),%1\n"
80 "        movl 8(%7),%2\n"
81 "        xorl %3,%3\n"
82 "        movb (%5),%b3\n"
83 "1:      xorb %b0,%b3\n"
84 "        shrl $8,%0\n"
85 "        incl %5\n"
86 "        xorl %c6(,%3,4),%0\n"
87 "        movb %b0,%b3\n"
88 "        addl $12,%7\n"
89 "        movl %0,(%7)\n"
90 "        addl %1,%3\n"
91 "        imul $134775813,%3\n"
92 "        leal 1(%3),%1\n"
93 "        shrl $24,%3\n"
94 "        movl %1,4(%7)\n"
95 "        xorb %b2,%b3\n"
96 "        shrl $8,%2\n"
97 "        xorl %c6(,%3,4),%2\n"
98 "        movb (%5),%b3\n"
99 "        orb  %b3,%b3\n"
100 "        movl %2,8(%7)\n"
101 "        jnz  1b\n"
102          : "=c" (key0), "=a" (key1), "=b" (key2), "=&d" (dummy), "=D" (sp)
103          : "S" (p), "i" (crc_32_tab), "D" (sp)
104       );
105 #  else
106       key0 = *sp++;
107       key1 = *sp++;
108       key2 = *sp++;
109       do {
110         *sp++ = key0 = crc32 (key0, *p++);
111         *sp++ = key1 = (key1 + (u8)key0) * 134775813 + 1;
112         *sp++ = key2 = crc32 (key2, key1 >> 24);
113       } while (*p);
114 
115       sp -= 3;
116 #  endif
117 
118       do
119         {
120           u8 target, pre_target;
121 
122 #         if USE_GCC_X86_ASM && TARGET_CPU
123             asm(
124 "              movl $-12,%%edi\n"
125 "              pushl %%ebx\n"
126 "              addl $12,%3\n"
127 "              pushl %%ecx\n"
128 "              xorl %%edx,%%edx\n"
129 "              pushl %%ebp\n"
130 "              jmp  2f\n"
131 "1:            shrl $2,%%edx\n"
132 "              movb %c8(%%edx),%%dl\n"
133 "              xorb -1(%3,%%edi),%%dl\n"
134 #if TARGET_CPU == 6
135 "              movzbl %%dl,%%ebp\n"
136 #else
137 "              movl %%edx,%%ebp\n"
138 #endif
139 "              xorb %b4,%%dl\n"
140 "              shrl $8,%4\n"
141 #if TARGET_CPU == 6
142 "              movzbl %%dl,%%edx\n"
143 #else
144 "              andl $0xff,%%edx\n"
145 #endif
146 "              xorl %c7(,%%edx,4),%4\n"
147 #if TARGET_CPU == 6
148 "              movzbl %b4,%%edx\n"
149 #else
150 "              movb %b4,%%dl\n"
151 #endif
152 "              addl %5,%%edx\n"
153 "              imul $134775813,%%edx\n"
154 "              leal 1(%%edx),%5\n"
155 "              shrl $24,%%edx\n"
156 #if TARGET_CPU == 6
157 "              xorl %6,%%edx\n"
158 "              shrl $8,%6\n"
159 "              movzbl %%dl,%%edx\n"
160 #else
161 "              xorb %b6,%%dl\n"
162 "              shrl $8,%6\n"
163 #endif
164 "              xorl %c7(,%%edx,4),%6\n"
165 "2:            \n"
166 #if TARGET_CPU == 6
167 "              movzwl %w6,%%edx\n"
168 #else
169 "              movw %w6,%%dx\n"
170 #endif
171 "              shrl $2,%%edx\n"
172 "              movb %c8(%%edx),%%dl\n"
173 "              xorb (%3,%%edi),%%dl\n"
174 #if TARGET_CPU == 6
175 "              movzbl %%dl,%%ebp\n"
176 #else
177 "              movl %%edx,%%ebp\n"
178 #endif
179 "              xorb %b4,%%dl\n"
180 "              shrl $8,%4\n"
181 #if TARGET_CPU == 6
182 "              movzbl %%dl,%%edx\n"
183 #else
184 "              andl $0xff,%%edx\n"
185 #endif
186 "              xorl %c7(,%%edx,4),%4\n"
187 #if TARGET_CPU == 6
188 "              movzbl %b4,%%edx\n"
189 #else
190 "              movb %b4,%%dl\n"
191 #endif
192 "              addl %5,%%edx\n"
193 "              imul $134775813,%%edx\n"
194 "              leal 1(%%edx),%5\n"
195 "              shrl $24,%%edx\n"
196 #if TARGET_CPU == 6
197 "              xorl %6,%%edx\n"
198 "              shrl $8,%6\n"
199 "              movzbl %%dl,%%edx\n"
200 #else
201 "              xorb %b6,%%dl\n"
202 "              shrl $8,%6\n"
203 #endif
204 "              xorl %c7(,%%edx,4),%6\n"
205 "              addl $2,%%edi\n"
206 #if TARGET_CPU == 6
207 "              movzwl %w6,%%edx\n"
208 #else
209 "              movw %w6,%%dx\n"
210 #endif
211 "              jne  1b\n"
212 #if TARGET_CPU == 6
213 "              movzwl %w6,%6\n"
214 #else
215 "              andl $0xffff,%6\n"
216 #endif
217 "              movb -1(%3),%1\n"
218 "              shrl $2,%6\n"
219 "              movl %%ebp,%k2\n"
220 "              popl %%ebp\n"
221 "              popl %%ecx\n"
222 "              xorb %c8(%6),%1\n"
223 "              popl %%ebx\n"
224                : "=S" (b), "=a" (target), "=d" (pre_target)
225                : "S" (b), "c" (key0), "a" (key1), "b" (key2),
226                  "i" (crc_32_tab), "i" (mult_tab)
227                : "edi"
228             );
229 #         else
230 #           if !USE_MULT_TAB
231               u16 t;
232 #           endif
233             u32 kez0, kez1, kez2;
234             u8 *e = b + FILE_SIZE - 1;
235 
236             kez0 = key0, kez1 = key1, kez2 = key2;
237             do
238               {
239 #               if USE_MULT_TAB
240                   pre_target = *b++ ^ mult_tab [(u16)(kez2) >> 2];
241 #               else
242                   t = kez2 | 2;
243                   pre_target = *b++ ^ (u8)(((u16) (t * (t^1)) >> 8));
244 #               endif
245                 kez0 = crc32 (kez0, pre_target);
246                 kez1 = (kez1 + (u8)kez0) * 134775813 + 1;
247                 kez2 = crc32 (kez2, kez1 >> 24);
248               }
249             while (b < e);
250 
251 #           if USE_MULT_TAB
252               target = *b++ ^ mult_tab [(u16)(kez2) >> 2];
253 #           else
254               t = kez2 | 2;
255               target = *b++ ^ (u8)(((u16) (t * (t^1)) >> 8));
256 #           endif
257 #         endif
258 
259           /*printf ("pw=%s, t1=%02x, t2=%02x (%02x, %02x)\n", pw, target, pre_target, b[0], b[1]);*/
260 
261           if (target != *b++)
262             goto out;
263 
264           if (pre_target == *b++)
265             count2++;
266         }
267       while(--count);
268 
269       if ((changed = cbfunc (pw, 0)))
270          return changed;
271 
272       out: ;
273     }
274   while ((changed = genfunc ()));
275 
276   return 0;
277 }
278 
279