mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-20 05:13:46 -07:00
add support for (nested) cmd scripts in script list/run
This commit is contained in:
parent
e10085bfe8
commit
d08f03058b
4 changed files with 111 additions and 57 deletions
|
@ -33,7 +33,10 @@ static int CmdHelp(const char *Cmd);
|
||||||
*/
|
*/
|
||||||
static int CmdScriptList(const char *Cmd) {
|
static int CmdScriptList(const char *Cmd) {
|
||||||
(void)Cmd; // Cmd is not used so far
|
(void)Cmd; // Cmd is not used so far
|
||||||
return searchAndList(LUA_SCRIPTS_SUBDIR, ".lua");
|
int ret = searchAndList(LUA_SCRIPTS_SUBDIR, ".lua");
|
||||||
|
if (ret != PM3_SUCCESS)
|
||||||
|
return ret;
|
||||||
|
return searchAndList(CMD_SCRIPTS_SUBDIR, ".cmd");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,21 +46,6 @@ static int CmdScriptList(const char *Cmd) {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static int CmdScriptRun(const char *Cmd) {
|
static int CmdScriptRun(const char *Cmd) {
|
||||||
// create new Lua state
|
|
||||||
lua_State *lua_state;
|
|
||||||
lua_state = luaL_newstate();
|
|
||||||
|
|
||||||
// load Lua libraries
|
|
||||||
luaL_openlibs(lua_state);
|
|
||||||
|
|
||||||
//Sets the pm3 core libraries, that go a bit 'under the hood'
|
|
||||||
set_pm3_libraries(lua_state);
|
|
||||||
|
|
||||||
//Add the 'bin' library
|
|
||||||
set_bin_library(lua_state);
|
|
||||||
|
|
||||||
//Add the 'bit' library
|
|
||||||
set_bit_library(lua_state);
|
|
||||||
|
|
||||||
char preferredName[128] = {0};
|
char preferredName[128] = {0};
|
||||||
char arguments[256] = {0};
|
char arguments[256] = {0};
|
||||||
|
@ -67,37 +55,65 @@ static int CmdScriptRun(const char *Cmd) {
|
||||||
sscanf(Cmd, "%127s%n %255[^\n\r]%n", preferredName, &name_len, arguments, &arg_len);
|
sscanf(Cmd, "%127s%n %255[^\n\r]%n", preferredName, &name_len, arguments, &arg_len);
|
||||||
|
|
||||||
char *script_path;
|
char *script_path;
|
||||||
int res = searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", false);
|
if ((!str_endswith(preferredName, ".cmd")) && (searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", true) == PM3_SUCCESS)) {
|
||||||
if (res != PM3_SUCCESS)
|
int error;
|
||||||
return res;
|
PrintAndLogEx(SUCCESS, "Executing Lua script: %s, args '%s'\n", script_path, arguments);
|
||||||
|
|
||||||
int error;
|
// create new Lua state
|
||||||
PrintAndLogEx(SUCCESS, "Executing: %s, args '%s'\n", script_path, arguments);
|
lua_State *lua_state;
|
||||||
error = luaL_loadfile(lua_state, script_path);
|
lua_state = luaL_newstate();
|
||||||
free(script_path);
|
|
||||||
if (!error) {
|
|
||||||
lua_pushstring(lua_state, arguments);
|
|
||||||
lua_setglobal(lua_state, "args");
|
|
||||||
|
|
||||||
//Call it with 0 arguments
|
// load Lua libraries
|
||||||
error = lua_pcall(lua_state, 0, LUA_MULTRET, 0); // once again, returns non-0 on error,
|
luaL_openlibs(lua_state);
|
||||||
|
|
||||||
|
//Sets the pm3 core libraries, that go a bit 'under the hood'
|
||||||
|
set_pm3_libraries(lua_state);
|
||||||
|
|
||||||
|
//Add the 'bin' library
|
||||||
|
set_bin_library(lua_state);
|
||||||
|
|
||||||
|
//Add the 'bit' library
|
||||||
|
set_bit_library(lua_state);
|
||||||
|
|
||||||
|
error = luaL_loadfile(lua_state, script_path);
|
||||||
|
free(script_path);
|
||||||
|
if (!error) {
|
||||||
|
lua_pushstring(lua_state, arguments);
|
||||||
|
lua_setglobal(lua_state, "args");
|
||||||
|
|
||||||
|
//Call it with 0 arguments
|
||||||
|
error = lua_pcall(lua_state, 0, LUA_MULTRET, 0); // once again, returns non-0 on error,
|
||||||
|
}
|
||||||
|
if (error) { // if non-0, then an error
|
||||||
|
// the top of the stack should be the error string
|
||||||
|
if (!lua_isstring(lua_state, lua_gettop(lua_state)))
|
||||||
|
PrintAndLogEx(FAILED, "Error - but no error (?!)");
|
||||||
|
|
||||||
|
// get the top of the stack as the error and pop it off
|
||||||
|
const char *str = lua_tostring(lua_state, lua_gettop(lua_state));
|
||||||
|
lua_pop(lua_state, 1);
|
||||||
|
puts(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
//luaL_dofile(lua_state, buf);
|
||||||
|
// close the Lua state
|
||||||
|
lua_close(lua_state);
|
||||||
|
PrintAndLogEx(SUCCESS, "\nFinished\n");
|
||||||
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
if (error) { // if non-0, then an error
|
if ((!str_endswith(preferredName, ".lua")) && (searchFile(&script_path, CMD_SCRIPTS_SUBDIR, preferredName, ".cmd", true) == PM3_SUCCESS)) {
|
||||||
// the top of the stack should be the error string
|
PrintAndLogEx(SUCCESS, "Executing Cmd script: %s, args '%s'\n", script_path, arguments);
|
||||||
if (!lua_isstring(lua_state, lua_gettop(lua_state)))
|
int ret = push_cmdscriptfile(script_path, true);
|
||||||
PrintAndLogEx(FAILED, "Error - but no error (?!)");
|
if (ret != PM3_SUCCESS)
|
||||||
|
PrintAndLogEx(ERR, "could not open " _YELLOW_("%s") "...", script_path);
|
||||||
// get the top of the stack as the error and pop it off
|
free(script_path);
|
||||||
const char *str = lua_tostring(lua_state, lua_gettop(lua_state));
|
return ret;
|
||||||
lua_pop(lua_state, 1);
|
|
||||||
puts(str);
|
|
||||||
}
|
}
|
||||||
|
// file not found, let's search again to display the error messages
|
||||||
//luaL_dofile(lua_state, buf);
|
int ret = PM3_EUNDEF;
|
||||||
// close the Lua state
|
if (!str_endswith(preferredName, ".cmd")) ret = searchFile(&script_path, LUA_SCRIPTS_SUBDIR, preferredName, ".lua", false);
|
||||||
lua_close(lua_state);
|
if (!str_endswith(preferredName, ".lua")) ret = searchFile(&script_path, CMD_SCRIPTS_SUBDIR, preferredName, ".cmd", false);
|
||||||
PrintAndLogEx(SUCCESS, "\nFinished\n");
|
return ret;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
|
|
|
@ -933,6 +933,7 @@ static int searchFinalFile(char **foundpath, const char *pm3dir, const char *sea
|
||||||
((strcmp(DICTIONARIES_SUBDIR, pm3dir) == 0) ||
|
((strcmp(DICTIONARIES_SUBDIR, pm3dir) == 0) ||
|
||||||
(strcmp(LUA_LIBRARIES_SUBDIR, pm3dir) == 0) ||
|
(strcmp(LUA_LIBRARIES_SUBDIR, pm3dir) == 0) ||
|
||||||
(strcmp(LUA_SCRIPTS_SUBDIR, pm3dir) == 0) ||
|
(strcmp(LUA_SCRIPTS_SUBDIR, pm3dir) == 0) ||
|
||||||
|
(strcmp(CMD_SCRIPTS_SUBDIR, pm3dir) == 0) ||
|
||||||
(strcmp(RESOURCES_SUBDIR, pm3dir) == 0))) {
|
(strcmp(RESOURCES_SUBDIR, pm3dir) == 0))) {
|
||||||
char *path = calloc(strlen(exec_path) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char));
|
char *path = calloc(strlen(exec_path) + strlen(pm3dir) + strlen(filename) + 1, sizeof(char));
|
||||||
if (path == NULL)
|
if (path == NULL)
|
||||||
|
|
|
@ -63,6 +63,38 @@ int check_comm(void) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// first slot is always NULL, indicating absence of script when idx=0
|
||||||
|
FILE *cmdscriptfile[MAX_NESTED_CMDSCRIPT + 1] = {0};
|
||||||
|
uint8_t cmdscriptfile_idx = 0;
|
||||||
|
bool cmdscriptfile_stayafter = false;
|
||||||
|
|
||||||
|
int push_cmdscriptfile(char *path, bool stayafter) {
|
||||||
|
if (cmdscriptfile_idx == MAX_NESTED_CMDSCRIPT) {
|
||||||
|
PrintAndLogEx(ERR, "Too many nested scripts, skipping %s\n", path);
|
||||||
|
return PM3_EMALLOC;
|
||||||
|
}
|
||||||
|
FILE *tmp = fopen(path, "r");
|
||||||
|
if (tmp == NULL)
|
||||||
|
return PM3_EFILE;
|
||||||
|
if (cmdscriptfile_idx == 0)
|
||||||
|
cmdscriptfile_stayafter = stayafter;
|
||||||
|
cmdscriptfile[++cmdscriptfile_idx] = tmp;
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *current_cmdscriptfile() {
|
||||||
|
return cmdscriptfile[cmdscriptfile_idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool pop_cmdscriptfile() {
|
||||||
|
fclose(cmdscriptfile[cmdscriptfile_idx]);
|
||||||
|
cmdscriptfile[cmdscriptfile_idx--] = NULL;
|
||||||
|
if (cmdscriptfile_idx == 0)
|
||||||
|
return cmdscriptfile_stayafter;
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Main thread of PM3 Client
|
// Main thread of PM3 Client
|
||||||
void
|
void
|
||||||
#ifdef __has_attribute
|
#ifdef __has_attribute
|
||||||
|
@ -80,7 +112,6 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) {
|
||||||
strcreplace(script_cmd, script_cmd_len, ';', '\0');
|
strcreplace(script_cmd, script_cmd_len, ';', '\0');
|
||||||
}
|
}
|
||||||
bool stdinOnPipe = !isatty(STDIN_FILENO);
|
bool stdinOnPipe = !isatty(STDIN_FILENO);
|
||||||
FILE *sf = NULL;
|
|
||||||
char script_cmd_buf[256] = {0x00}; // iceman, needs lua script the same file_path_buffer as the rest
|
char script_cmd_buf[256] = {0x00}; // iceman, needs lua script the same file_path_buffer as the rest
|
||||||
|
|
||||||
PrintAndLogEx(DEBUG, "ISATTY/STDIN_FILENO == %s\n", (stdinOnPipe) ? "true" : "false");
|
PrintAndLogEx(DEBUG, "ISATTY/STDIN_FILENO == %s\n", (stdinOnPipe) ? "true" : "false");
|
||||||
|
@ -98,8 +129,7 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) {
|
||||||
char *path;
|
char *path;
|
||||||
int res = searchFile(&path, CMD_SCRIPTS_SUBDIR, script_cmds_file, ".cmd", false);
|
int res = searchFile(&path, CMD_SCRIPTS_SUBDIR, script_cmds_file, ".cmd", false);
|
||||||
if (res == PM3_SUCCESS) {
|
if (res == PM3_SUCCESS) {
|
||||||
sf = fopen(path, "r");
|
if (push_cmdscriptfile(path, stayInCommandLoop) == PM3_SUCCESS)
|
||||||
if (sf)
|
|
||||||
PrintAndLogEx(SUCCESS, "executing commands from file: %s\n", path);
|
PrintAndLogEx(SUCCESS, "executing commands from file: %s\n", path);
|
||||||
else
|
else
|
||||||
PrintAndLogEx(ERR, "could not open " _YELLOW_("%s") "...", path);
|
PrintAndLogEx(ERR, "could not open " _YELLOW_("%s") "...", path);
|
||||||
|
@ -119,16 +149,18 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) {
|
||||||
bool printprompt = false;
|
bool printprompt = false;
|
||||||
char *prompt = PROXPROMPT;
|
char *prompt = PROXPROMPT;
|
||||||
|
|
||||||
|
check_script:
|
||||||
// If there is a script file
|
// If there is a script file
|
||||||
if (sf) {
|
if (current_cmdscriptfile()) {
|
||||||
|
|
||||||
// clear array
|
// clear array
|
||||||
memset(script_cmd_buf, 0, sizeof(script_cmd_buf));
|
memset(script_cmd_buf, 0, sizeof(script_cmd_buf));
|
||||||
|
|
||||||
// read script file
|
// read script file
|
||||||
if (!fgets(script_cmd_buf, sizeof(script_cmd_buf), sf)) {
|
if (!fgets(script_cmd_buf, sizeof(script_cmd_buf), current_cmdscriptfile())) {
|
||||||
fclose(sf);
|
if (!pop_cmdscriptfile())
|
||||||
sf = NULL;
|
break;
|
||||||
|
goto check_script;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// remove linebreaks
|
// remove linebreaks
|
||||||
|
@ -205,12 +237,15 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) {
|
||||||
PrintAndLogEx(NORMAL, "%s%s", prompt, cmd);
|
PrintAndLogEx(NORMAL, "%s%s", prompt, cmd);
|
||||||
g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG;
|
g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG;
|
||||||
|
|
||||||
|
// add to history if not from a script
|
||||||
|
if (!current_cmdscriptfile()) {
|
||||||
|
HIST_ENTRY *entry = history_get(history_length);
|
||||||
|
// add if not identical to latest recorded cmd
|
||||||
|
if ((!entry) || (strcmp(entry->line, cmd) != 0))
|
||||||
|
add_history(cmd);
|
||||||
|
}
|
||||||
|
// process cmd
|
||||||
int ret = CommandReceived(cmd);
|
int ret = CommandReceived(cmd);
|
||||||
|
|
||||||
HIST_ENTRY *entry = history_get(history_length);
|
|
||||||
if ((!entry) || (strcmp(entry->line, cmd) != 0))
|
|
||||||
add_history(cmd);
|
|
||||||
|
|
||||||
// exit or quit
|
// exit or quit
|
||||||
if (ret == PM3_EFATAL)
|
if (ret == PM3_EFATAL)
|
||||||
break;
|
break;
|
||||||
|
@ -230,8 +265,8 @@ main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop) {
|
||||||
SendCommandNG(CMD_QUIT_SESSION, NULL, 0);
|
SendCommandNG(CMD_QUIT_SESSION, NULL, 0);
|
||||||
msleep(100); // Make sure command is sent before killing client
|
msleep(100); // Make sure command is sent before killing client
|
||||||
|
|
||||||
if (sf)
|
while (current_cmdscriptfile())
|
||||||
fclose(sf);
|
pop_cmdscriptfile();
|
||||||
|
|
||||||
if (my_history_path) {
|
if (my_history_path) {
|
||||||
write_history(my_history_path);
|
write_history(my_history_path);
|
||||||
|
|
|
@ -20,11 +20,13 @@
|
||||||
#define PROXPROMPT_OFFLINE "[offline] pm3 --> "
|
#define PROXPROMPT_OFFLINE "[offline] pm3 --> "
|
||||||
#define PROXHISTORY "history.txt"
|
#define PROXHISTORY "history.txt"
|
||||||
#define PROXLOG "log_%Y%m%d.txt"
|
#define PROXLOG "log_%Y%m%d.txt"
|
||||||
|
#define MAX_NESTED_CMDSCRIPT 10
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int push_cmdscriptfile(char *path, bool stayafter);
|
||||||
const char *get_my_executable_path(void);
|
const char *get_my_executable_path(void);
|
||||||
const char *get_my_executable_directory(void);
|
const char *get_my_executable_directory(void);
|
||||||
void main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop);
|
void main_loop(char *script_cmds_file, char *script_cmd, bool stayInCommandLoop);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue