1 /*
2  *	Copyright (c) 2000,2001,2002 Guido Draheim <guidod@gmx.de>
3  *      Use freely under the restrictions of the ZLIB license.
4  *
5  *      show zip-reading with xor-obfuscation.
6  *      Note that the difference to the standard zzdir.c is quite small.
7  */
8 
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <ctype.h>
13 
14 #include <zzip/zzip.h>
15 #include <zzip/plugin.h>
16 
17 #if defined ZZIP_HAVE_UNISTD_H
18 #include <unistd.h>
19 #elif defined ZZIP_HAVE_IO_H
20 #include <io.h>
21 #else
22 #error need posix io for this example
23 #endif
24 
25 static const char usage[] =
26 {
27     "zzdir <dir>.. \n"
28     "  - prints a content table to stdout, but the dir can also be a zip-arch."
29     "\n"
30     " the file is part of an inflated zip-archive obfuscated with xor value,\n"
31     " given by the numeric option (default is 0x55). \n"
32     "\n"
33     " To show the contents of a zip-archive named 'test.zip', you may write \n"
34     "     zzdir test \n"
35 };
36 
37 static int xor_value;
38 
xor_read(int f,void * p,zzip_size_t l)39 static zzip_ssize_t xor_read (int f, void* p, zzip_size_t l)
40 {
41     zzip_ssize_t r = read(f, p, l);
42     zzip_ssize_t x; char* q; for (x=0, q=p; x < r; x++) q[x] ^= xor_value;
43     return r;
44 }
45 
46 static zzip_plugin_io_handlers xor_handlers = { };
47 static zzip_strings_t xor_fileext[] = { ".dat", "", 0 };
48 
49 int
main(int argc,char ** argv)50 main (int argc, char ** argv)
51 {
52     int argn;
53     int exitcode = 0;
54     xor_value = 0x55;
55 
56     if (argc <= 1 || ! strcmp (argv[1], "--help"))
57     {
58         printf (usage);
59         return 0;
60     }
61     if (! strcmp (argv[1], "--version"))
62     {
63 	printf (__FILE__ " version " ZZIP_PACKAGE_NAME " " ZZIP_PACKAGE_VERSION "\n");
64 	return 0;
65     }
66 
67     zzip_init_io (&xor_handlers, 0); xor_handlers.fd.read = &xor_read;
68 
69     for (argn=1; argn < argc; argn++)
70     {
71         ZZIP_DIR * dir;
72         ZZIP_DIRENT * d;
73 
74 	if (argv[argn][0] == '-')
75 	{
76 	    if (isdigit(argv[argn][1]))	xor_value = atoi (argv[argn]+1);
77 	    continue;
78 	}
79 
80         dir = zzip_opendir_ext_io(argv[argn],
81 				  ZZIP_ONLYZIP, xor_fileext, &xor_handlers);
82         if (! dir)
83         {
84             fprintf (stderr, "did not open %s: ", argv[argn]);
85             perror(argv[argn]);
86 	    exitcode++;
87             continue;
88         }
89 
90         if (argc > 2) printf ("%s: \n", argv[argn]);
91 
92 	/* read each dir entry and show one line of info per file */
93         while ((d = zzip_readdir (dir)))
94         {
95 	    /* orignalsize / compression-type / compression-ratio / filename */
96             if (d->st_size > 999999)
97             {
98                 printf ("%5dK %-9s %2d%% %s\n",
99 			d->st_size>>10,
100 			zzip_compr_str(d->d_compr),
101 			100 - (d->d_csize|1)/((d->st_size/100)|1),
102 			d->d_name);
103             }else{
104                 printf ("%6d %-9s %2d%% %s\n",
105 			d->st_size,
106 			zzip_compr_str(d->d_compr),
107 			100 - (d->d_csize|1)*100/(d->st_size|1),
108 			d->d_name);
109             }
110         }
111 
112         zzip_closedir(dir);
113     }
114 
115     return exitcode;
116 }
117 
118 /*
119  * Local variables:
120  * c-file-style: "stroustrup"
121  * End:
122  */
123