1 /*
2 ** opt.c
3 **
4 ** Started on  Fri Nov  2 15:17:02 2001 mayhem
5 ** Last update Thu May 22 17:25:54 2003 mayhem
6 */
7 #include "elfsh.h"
8 
9 
10 /* Precise a general weak bounded regex for all options */
vm_getglregx(u_int index,u_int argc,char ** argv)11 int		vm_getglregx(u_int index, u_int argc, char **argv)
12 {
13   if (index + 1 < argc && argv[index + 1][0] != ELFSH_MINUS)
14     {
15       if (regcomp(&world.state.vm_regx, argv[index + 1], REG_EXTENDED) < 0)
16 	return (-1);
17       world.state.vm_use_regx = 1;
18       world.state.vm_sregx = argv[index + 1];
19       if (!world.state.vm_quiet)
20 	printf("\n [*] Changed global regex to %s \n", argv[index + 1]);
21       return (1);
22     }
23   return (-1);
24 }
25 
26 /* Read the input file parameter */
vm_getoption(u_int index,u_int argc,char ** argv)27 int		vm_getoption(u_int index, u_int argc, char **argv)
28 {
29   if (index + 1 >= argc)
30     return (-1);
31   world.args.param[0] = argv[index + 1];
32   return (1);
33 }
34 
35 /* Read the input file parameter */
vm_getinput(u_int index,u_int argc,char ** argv)36 int		vm_getinput(u_int index, u_int argc, char **argv)
37 {
38   if (index + 1 >= argc)
39     return (-1);
40   world.state.input = argv[index + 1];
41   return (1);
42 }
43 
44 /* Read the output file parameter */
vm_getoutput(u_int index,u_int argc,char ** argv)45 int		vm_getoutput(u_int index, u_int argc, char **argv)
46 {
47   if (index + 1 >= argc)
48     return (-1);
49   world.state.output = argv[index + 1];
50   return (1);
51 }
52 
53 /* Read the sorting parameter */
vm_getsort(u_int index,u_int argc,char ** argv)54 int		vm_getsort(u_int index, u_int argc, char **argv)
55 {
56   char		*str;
57 
58   if (index + 1 >= argc)
59     return (-1);
60   if (argv[index + 1][0] != ELFSH_SORT_BY_ADDR &&
61       argv[index + 1][0] != ELFSH_SORT_BY_SIZE)
62     return (-1);
63   str = (argv[index + 1][0] == ELFSH_SORT_BY_ADDR ? "ADDR" : "SIZE");
64   if (!world.state.vm_quiet)
65     printf(" [*] Switched to %s sorting\n\n", str);
66   world.state.sort = argv[index + 1];
67   return (1);
68 }
69 
70 /* Activate a 2-non-regx-mandatory-parameters option */
vm_getoption2(u_int index,u_int argc,char ** argv)71 int		vm_getoption2(u_int index, u_int argc, char **argv)
72 {
73   if (index + 2 >= argc)
74     return (-1);
75   world.args.param[0] = argv[index + 1];
76   world.args.param[1] = argv[index + 2];
77   return (2);
78 }
79 
80 /* Activate a 2-non-regx-mandatory-parameters option */
vm_getoption3(u_int index,u_int argc,char ** argv)81 int		vm_getoption3(u_int index, u_int argc, char **argv)
82 {
83   if (index + 3 >= argc)
84     return (-1);
85   world.args.param[0] = argv[index + 1];
86   world.args.param[1] = argv[index + 2];
87   world.args.param[2] = argv[index + 3];
88   return (3);
89 }
90 
91 /* Activate a non-mandatory-regex-parameter option */
vm_getregxoption(u_int index,u_int argc,char ** argv)92 int		vm_getregxoption(u_int index, u_int argc, char **argv)
93 {
94   if (index + 1 < argc && argv[index + 1][0] != ELFSH_MINUS)
95     {
96       if (regcomp(&world.args.regx, argv[index + 1], REG_EXTENDED) < 0)
97 	return (-1);
98       world.args.use_regx = 1;
99       return (1);
100     }
101   return (0);
102 }
103 
104 /* Fetch parameters until we find NULL or something starting by '-' */
vm_getvarparams(u_int index,u_int argc,char ** argv)105 int		vm_getvarparams(u_int index, u_int argc, char **argv)
106 {
107   u_int		idx;
108 
109   for (idx = 0;
110        idx < 254 && index + idx + 1 < argc;
111        idx++)
112     world.args.param[idx] = argv[index + idx + 1];
113   return (idx ? idx : -1);
114 }
115 
116 /* Add an entry to the requested dump list */
vm_add2list(char outtype,u_int index,int argc,char ** argv)117 static int      vm_add2list(char outtype, u_int index, int argc, char **argv)
118 {
119   char		*off;
120 
121   if (argv[index + 1] == NULL)
122     return (-1);
123   world.args.disasm.rname = argv[index + 1];
124   world.args.disasm.otype = outtype;
125   off = strchr(argv[index + 1], '%');
126   if (off)
127     {
128       world.args.disasm.size = atoi(off + 1);
129       *off = 0;
130     }
131   off = strchr(argv[index + 1], ':');
132   if (off)
133     {
134       world.args.disasm.off = atoi(off + 1);
135       *off = 0;
136     }
137   if (regcomp(&world.args.disasm.name, argv[index + 1], REG_EXTENDED) < 0)
138     return (-1);
139   return (1);
140 }
141 
142 /* Add an DISASM typed entry */
vm_getdisasm(u_int index,u_int argc,char ** argv)143 int		vm_getdisasm(u_int index, u_int argc, char **argv)
144 {
145   return (vm_add2list(ELFSH_DISASM_VIEW, index, argc, argv));
146 }
147 
148 /* Add an HEXA typed entry */
vm_gethexa(u_int index,u_int argc,char ** argv)149 int		vm_gethexa(u_int index, u_int argc, char **argv)
150 {
151   return (vm_add2list(ELFSH_HEXA_VIEW, index, argc, argv));
152 }
153 
154 /* Parse the command line options and interactive mode commands */
vm_parseopt(int argc,char ** argv)155 int		vm_parseopt(int argc, char **argv)
156 {
157   u_int		index;
158   int		ret;
159   elfshcmd_t	*actual;
160 
161   /* Main option reading loop : using the command hash table */
162   bzero(&world.args, sizeof (elfshargv_t));
163   for (index = 1; index < argc; index++)
164     {
165       actual = hash_get(&cmd_hash, argv[index] +
166 			(world.state.vm_mode == ELFSH_VMSTATE_CMDLINE));
167 
168       /* We matched a command : call the reg() and exec() handlers */
169       if (actual != NULL)
170 	{
171 	  if (actual->reg != NULL)
172 	    {
173 	      ret = actual->reg(index, argc, argv);
174 	      if (ret < 0)
175 		return (vm_doerror(vm_badparam, argv[index]));
176 	      else
177 		index += ret;
178 	    }
179 	  if (actual->exec != NULL)
180 	    {
181 	      if (!vm_implicit(actual, argv) && actual->exec() < 0)
182 		elfsh_error();
183 	    }
184 	}
185 
186       /* We did -NOT- matched a command, do error */
187       else
188 	vm_doerror(vm_unknown, argv[index]);
189     }
190   return (0);
191 }
192 
193 
194 
195 
196 
197