-
Notifications
You must be signed in to change notification settings - Fork 0
/
help.c
314 lines (307 loc) · 16.9 KB
/
help.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
int verbose_options(u8 *arg) {
u8 *p;
if(!arg || (strlen(arg) < 2)) return -1;
if(((arg[0] != '-') && (arg[0] != '/')) || (strlen(arg) != 2)) {
for(p = arg; (*p == '-') || (*p == '/'); p++);
if(!stricmp(p, "help")) strcpy(arg, "-h");
else if(!stricmp(p, "commands")) strcpy(arg, "-c");
else if(!stricmp(p, "filter")) strcpy(arg, "-f");
else if(!stricmp(p, "list")) strcpy(arg, "-l");
else if(!stricmp(p, "verbose")) strcpy(arg, "-v");
else if(!stricmp(p, "debug")) strcpy(arg, "-V");
else if(!stricmp(p, "listfile")) strcpy(arg, "-L");
else if(!stricmp(p, "hex")) strcpy(arg, "-x");
else if(!stricmp(p, "write")) strcpy(arg, "-w");
else if(!stricmp(p, "endian")) strcpy(arg, "-E");
else if(!stricmp(p, "void")) strcpy(arg, "-0");
else if(!stricmp(p, "reimport")) strcpy(arg, "-r");
else if(!stricmp(p, "reinject")) strcpy(arg, "-r");
else if(!stricmp(p, "sockets")) strcpy(arg, "-n");
else if(!stricmp(p, "network")) strcpy(arg, "-n");
else if(!stricmp(p, "process")) strcpy(arg, "-p");
else if(!stricmp(p, "audio")) strcpy(arg, "-A");
else if(!stricmp(p, "video")) strcpy(arg, "-g");
else if(!stricmp(p, "winmsg")) strcpy(arg, "-m");
else if(!stricmp(p, "calldll")) strcpy(arg, "-C");
else if(!stricmp(p, "hex_html")) strcpy(arg, "-H");
else if(!stricmp(p, "hex_console")) strcpy(arg, "-X");
else if(!stricmp(p, "update")) strcpy(arg, "-u");
else if(!stricmp(p, "continue")) strcpy(arg, "-.");
else if(!stricmp(p, "continue_anyway")) strcpy(arg, "-.");
else if(!stricmp(p, "XDBG_ALLOC_ACTIVE")) strcpy(arg, "-9");
else if(!stricmp(p, "XDBG_ALLOC_INDEX")) strcpy(arg, "-8");
else if(!stricmp(p, "XDBG_ALLOC_VERBOSE")) strcpy(arg, "-7");
else if(!stricmp(p, "XDBG_HEAPVALIDATE")) strcpy(arg, "-6");
else if(!stricmp(p, "gui")) strcpy(arg, "-G");
else if(!stricmp(p, "quiet")) strcpy(arg, "-q");
else return -1;
}
return 0;
}
void myhelp(u8 *argv0) {
printf("\n"
"Usage: %s\n"
" [options]\n"
" <script.BMS>\n"
" <input_archive/folder>\n"
" [output_folder]\n"
"\n"
"Options:\n"
"-l list the files without extracting them\n"
"-f W filter the files to extract using the W wildcards separated by comma or\n"
" semicolon, example -f \"*.mp3,*.txt;*myname*\"\n"
" if the filter starts with ! it's considered an ignore filter\n"
" the filter can be also a text file containing filters\n"
" example: quickbms -f \"*.mp3;!*.ogg\" script.bms archive.dat output\n"
" example: quickbms -f myfilters_list.txt script.bms archive.dat\n"
" please use {} instead of * to avoid problems on Windows, you can also\n"
" use multiple -f if you feel more comfortable\n"
"-F W as above but works only with the files in the input folder (if used)\n"
" example: quickbms -F \"*.dat\" script.bms input_folder output_folder\n"
"-o if the output files already exist this option will overwrite them\n"
" automatically without asking the user confirmation\n"
"-k keep the current files if already exist without asking (skip all)\n"
"-K automatically rename the files if duplicates already exist\n"
"-r experimental reimport option that should work with many archives:\n"
" quickbms script.bms archive.pak output_folder\n"
" modify the needed files in output_folder and maybe remove the others\n"
" quickbms -w -r script.bms archive.pak output_folder\n"
" you must read section 3 of quickbms.txt before using this feature\n"
"-u check if there is a new version of QuickBMS available\n"
"-i generate an ISO9660 file instead of extracting every file, the name of\n"
" the ISO image will be the name of the input file or folder\n"
"-z exactly as above but generate a ZIP file\n"
"\n"
"Advanced options:\n"
"-d automatically create an additional output folder with the name of the\n"
" input folder and file processed, eg. models/mychar/mychar.arc/FILES,\n"
" -d works also if input and output folders are the same (rename folder)\n"
"-D similar to -d but will not create the folder with the filename\n"
"-E experimental option for automatically reversing the endianess of any\n"
" file simply reading it field by field (so each get will produce a put)\n"
"-c quick list of the basic BMS commands and some notes about this tool\n"
"-S CMD execute the command CMD on each file extracted, you must specify the\n"
" #INPUT# placeholder which will be replaced by the name of the file\n"
" example: -S \"lame -b 192 -t --quiet #INPUT#\"\n"
"-Y automatically answer yes to any question\n"
"-O F redirect the output of all the extracted files to the file F\n"
"-s SF add a script file or command before the execution of the input script,\n"
" useful if an archive uses a different endianess or encryption and so on\n"
" SF can be a script or directly the bms instruction you want to execute\n"
"-. don't terminate QuickBMS if there is an error while parsing multiple\n"
" files (like wrong compression or small file), just continue with the\n"
" other files in the folder\n"
"\n"
"Debug and experimental options:\n"
"-v verbose debug information, useful for verifying possible errors\n"
"-V alternative verbose output, useful for programmers\n"
"-q quiet, no *log output\n"
"-Q very quiet, no output except the Print command\n"
"-L F dump the offset/size/name of the files inside the file F\n"
"-x use the hexadecimal notation in myitoa (debug)\n"
"-0 no extraction of files, useful for testing a script without using space\n"
"-R needed for the programs that act as interface for QuickBMS\n"
"-a S pass arguments to the input script that will take the names\n"
" quickbms_arg1, quickbms_arg2, quickbms_arg3 and so on, note that they\n"
" handled as arguments so pay attentions to spaces and commas, eg:\n"
" -a \"arg1 \\\"arg 2\\\", arg3\"\n"
" -a arg1 -a \"\\\"arg 2\\\"\" -a arg3\n"
"-H cool HTML hex viewer output, use it only with very small files!\n"
//" T can be -1, 1, 2 or 3 and is a different type of output\n"
"-X cool hex viewer output on the console (support Less-like keys)\n"
"-9 toggle XDBG_ALLOC_ACTIVE (%s)\n"
"-8 toggle XDBG_ALLOC_INDEX (%s)\n"
"-7 toggle XDBG_ALLOC_VERBOSE (%s)\n"
"-6 toggle XDBG_HEAPVALIDATE (%s)\n"
"-3 execute an INT3 before each CallDll, compression and encryption\n"
"-I toggle variable names case sensitivity (case %s)\n"
"-M F experimental compare and merge feature that allows to compare the\n"
" extracted files with those located in the folder F, currently this\n"
" experimental option will create files of 0 bytes if they are not\n"
" different, so it's not simple to identify what files were written\n"
"-Z in reimport mode it will replace all the archived files with zeroes\n"
"-P CP set the default codepage to use, it can be a number or string\n"
"-T do not delete the TEMPORARY_FILE at the end of the process\n"
"\n"
"Features and security activation options:\n"
"-w enable the write mode required to write physical input files with Put*\n"
"-C enable the usage of CallDll without asking permission\n"
"-n enable the usage of network sockets\n"
"-p enable the usage of processes\n"
"-A enable the usage of audio device\n"
"-g enable the usage of video graphic device\n"
"-m enable the usage of Windows messages\n"
"-G force the GUI mode on Windows, it's automatically enabled if you\n"
" double-click on the QuickBMS executable\n"
"\n"
"Examples:\n"
" quickbms c:\\zip.bms c:\\myfile.zip \"c:\\new folder\"\n"
" quickbms -l -f \"*.txt;*.dds\" zip.bms myfile.zip\n"
" quickbms -F \"{}.bff\" c:\\nfsshift.bms c:\\Shift\\Pakfiles c:\\output\n"
"\n"
"Check quickbms.txt for the manual and the list of additional credits.\n"
"\n", argv0,
XDBG_ALLOC_ACTIVE ? "enabled" : "disabled",
XDBG_ALLOC_INDEX ? "enabled" : "disabled",
XDBG_ALLOC_VERBOSE ? "enabled" : "disabled",
XDBG_HEAPVALIDATE ? "enabled" : "disabled",
g_insensitive ? "insensitive" : "sensitive");
}
void quick_bms_list(void) {
fputs("\n"
"quick reference list of the BMS commands:\n"
"\n"
" CLog <filename> <offset> <compressed_size> <uncompressed_size> [file]\n"
" extract the file at give offset decompressing its content\n"
"\n"
" Do\n"
" ...\n"
" While <variable> <condition> <variable>\n"
" perform a loop which ends when the condition is no longer valid\n"
"\n"
" FindLoc <variable> <type> <string> [file] [ret_if_err]\n"
" if the string is found put its offset in the variable\n"
" by default if FindLoc doesn't find the string it terminates the script\n"
" while if ret_if_err is specified (for example -1 or \"\") it will be put in\n"
" variable instead of terminating\n"
"\n"
" For [variable] = [value] [To] [variable]\n"
" ...\n"
" Next [variable]\n"
" classical for(;;) loop, Next simply increments the value of the variable\n"
" the arguments are optionals for using this For like an endless loop and\n"
" To can be substituited with any condition like != == < <= > >= and so on\n"
"\n"
" Break\n"
" quit a loop (experimental)\n"
"\n"
" Get <variable> <type> [file]\n"
" read a number (8, 16, 32 bits) or a string\n"
"\n"
" GetDString <variable> <length> [file]\n"
" read a string of the specified length\n"
"\n"
" GoTo <offset> [file]\n"
" reach the specified offset, if it's negative it goes from the end\n"
"\n"
" IDString [file] <string>\n"
" check if the data in the file matches the given string\n"
"\n"
" Log <filename> <offset> <size> [file]\n"
" extract the file at the given offset with that size\n"
"\n"
" Math <variable> <operator> <variable>\n"
" perform a mathematical operation on the first variable, available op:\n"
" + * / - ^ & | % ! ~ << >> r (rot right) l (rot left) s (bit s) w (byte s)\n"
"\n"
" Open <folder> <filename> <file>\n"
" open a new file and assign the given file number\n"
"\n"
" SavePos <variable> [file]\n"
" save the current offset in the variable\n"
"\n"
" Set <variable> [type] <variable>\n"
" assign the content of the second variable to the first one, type ignored\n"
"\n"
" String <variable> <operator> <variable>\n"
" perform an append/removing/xor operation on the first variable\n"
"\n"
" CleanExit\n"
" terminate the extraction\n"
"\n"
" If <variable> <criterium> <variable>\n"
" ...\n"
" Else / Elif / Else If\n"
" ...\n"
" EndIf\n"
" classical if(...) { ... } else if { ... } else { ... }\n"
"\n"
" GetCT <variable> <type> <character> [file]\n"
" read a string (type is useless) delimited by the given character\n"
"\n"
" ComType <type> [dictionary]\n"
" specify the type of compression to use in CLog: quickbms.txt for the list\n"
"\n"
" ReverseLong <variable>\n"
" invert the order/endianess of the variable\n"
"\n"
" Endian <type>\n"
" choose between little and big endian order of the read numbers\n"
"\n"
" FileXOR <string_of_numbers> [offset]\n"
" xor the read data with the sequence of numbers in the given string\n"
"\n"
" FileRot13 <string_of_numbers> [offset]\n"
" add/substract the read data with the sequence of numbers in the string\n"
"\n"
" Strlen <variable> <variable>\n"
" put the length of the second variable in the first one\n"
"\n"
" GetVarChr <variable> <variable> <offset> [type]\n"
" put the byte at the given offset of the second variable in the first one\n"
"\n"
" PutVarChr <variable> <offset> <variable> [type]\n"
" put the byte in the second variable in the first one at the given offset\n"
"\n"
" Padding <number> [file]\n"
" adjust the current offset of the file using the specified number (size of\n"
" padding), note that at the moment the padding is performed only when\n"
" this command is called and not automatically after each file reading\n"
"\n"
" Append\n"
" enable/disable the writing of the data at the end of the files with *Log\n"
"\n"
" Encryption <algorithm> <key> [ivec] [mode] [keylen]\n"
" enable that type of decryption: quickbms.txt for the list\n"
"\n"
" Print \"message\"\n"
" display a message, you can display the content of the variables simply\n"
" specifying their name between '%' like: Print \"my offset is %OFFSET%\"\n"
"\n"
" GetArray <variable> <array_num> <index>\n"
" get the value stored at the index position of array_num\n"
"\n"
" PutArray <array_num> <index> <variable>\n"
" store the variable at the index position of array_num\n"
"\n"
" StartFunction NAME\n"
" ...\n"
" EndFunction\n"
" CallFunction NAME\n"
" experimental functions for recursive archives\n"
"\n"
"Refer to quickbms.txt for the rest of the commands and their details!\n"
"\n"
"NOTES:\n"
"- a variable and a fixed number are the same thing internally in the tool\n"
" because all the data is handled as strings with the consequent pros\n"
" (incredibly versatile) and cons (slowness with some types of scripts)\n"
"- everything is case insensitive (ABC is like abc) except the content of\n"
" strings and variables (excluded some operations like in String)\n"
"- the [file] field is optional, if not specified it's 0 so the main file\n"
"- also the final ';' char of the original BMS language is optional\n"
"- example of <string_of_numbers>: \"0x123 123 456 -12 -0x7f\" or 0xff or \"\"\n"
"- both hexadecimal (0x) and decimal numbers are supported, negatives included\n"
"- all the mathematical operations are performed using signed 32 bit numbers\n"
"- available types of data: long (32 bits), short (16), byte (8), string\n"
"- all the fixed strings are handled in C syntax like \"\\x12\\x34\\\\hello\\\"bye\\0\"\n"
"- do not use variable names which start with a number like 123MYVAR or -MYVAR\n"
"- if you use the file MEMORY_FILE will be used a special memory buffer, create\n"
" it with CLog or Log and use it normally like any other file\n"
"- is possible to use multiple memory files: MEMORY_FILE, MEMORY_FILE2,\n"
" MEMORY_FILE3, MEMORY_FILE4 and so on\n"
"- use TEMPORARY_FILE for creating a file with this exact name also in -l mode\n"
"\n"
"information about the original BMS scripting language and original examples:\n"
" http://wiki.xentax.com/index.php/BMS\n"
" http://multiex.xentax.com/complete_scripts.txt\n"
"\n"
"check the source code of this tool for the additional enhancements implemented\n"
"by me (like support for xor, rot13, lzo, lzss, zlib/deflate and so on) or send\n"
"me a mail because various features are not documented yet or just watch the\n"
"examples provided on the project's homepage which cover ALL the enhancements:\n"
" http://quickbms.aluigi.org\n"
"\n"
"the tool supports also the \"multiex inifile\" commands in case of need.\n"
"\n", stdout);
}