proxmark3/client/src/cmdmain.c

353 lines
11 KiB
C
Raw Normal View History

//-----------------------------------------------------------------------------
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
//
2018-07-29 13:37:23 +08:00
// Modified 2018 iceman <iceman at iuse.se>
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Main command parser entry point
//-----------------------------------------------------------------------------
2019-04-13 08:41:46 +08:00
2019-04-13 09:01:31 +08:00
// ensure gmtime_r is available even with -std=c99; must be included before
2019-04-13 08:41:46 +08:00
#if !defined(_WIN32)
#define _POSIX_C_SOURCE 200112L
#endif
#include "cmdmain.h"
2013-06-27 05:13:02 +08:00
#include <string.h>
#include <ctype.h>
#include <time.h> // MingW
#include <stdlib.h> // calloc
#include "comms.h"
#include "cmdhf.h"
#include "cmddata.h"
#include "cmdhw.h"
#include "cmdlf.h"
#include "cmdtrace.h"
#include "cmdscript.h"
#include "cmdcrc.h"
#include "cmdanalyse.h"
#include "emv/cmdemv.h" // EMV
#include "cmdflashmem.h" // rdv40 flashmem commands
#include "cmdsmartcard.h" // rdv40 smart card ISO7816 commands
#include "cmdusart.h" // rdv40 FPC USART commands
#include "cmdwiegand.h" // wiegand commands
#include "ui.h"
#include "util_posix.h"
#include "commonutil.h" // ARRAYLEN
#include "preferences.h"
#include "cliparser.h"
Client cleanup and restructuring. Stage 1... Next Step is refactoring some of the giant functions which are just copy/paste of some other ones with just a few line changes, removing unnecessary 'goto' etc. The MS Windows version is broken with this commit but will be fixed soon. Everything can't be done all at once :P The commands are now hierarchical, for example: "hf 14a read" vs. "hf 14b read". You can also request help: "hf help", "data help", "hf 15 help" etc. Indents are now space-based, not tab-based anymore. Hopefully no one will be trolling about it, considering the suicide-prone work being done here ;) client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h, client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h, client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c, client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h, client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h, client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h, client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h, client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h, client/cmdhflegic.c, client/cmdhflegic.c: New files. client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c, client/proxmark3.h, client/Makefile: Update accordingly. client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes. client/translate.h, client/command.c, client/gui.c, client/usb.c, client/prox.h: Remove. include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd. common/crc16.h: New file. common/crc16.c: Modify accordingly. common/iso14443crc.h: New file. common/iso14443_crc.c: Rename to common/iso14443crc.c: and modify accordingly. armsrc/lfops.c, armsrc/iso14443.c, armsrc/iso14443a.c: include .h files from the common directory instead of including the c files. common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
static int CmdHelp(const char *Cmd);
2020-05-03 07:13:28 +08:00
static void AppendDate(char *s, size_t slen, const char *fmt) {
struct tm *ct, tm_buf;
time_t now = time(NULL);
#if defined(_WIN32)
ct = gmtime_s(&tm_buf, &now) == 0 ? &tm_buf : NULL;
#else
ct = gmtime_r(&now, &tm_buf);
#endif
if (fmt == NULL)
strftime(s, slen, "%Y-%m-%dT%H:%M:%SZ", ct); // ISO8601
else
strftime(s, slen, fmt, ct);
}
static int lf_search_plus(const char *Cmd) {
sample_config oldconfig;
memset(&oldconfig, 0, sizeof(sample_config));
int retval = lf_getconfig(&oldconfig);
if (retval != PM3_SUCCESS) {
PrintAndLogEx(ERR, "failed to get current device config");
return retval;
}
// Divisor : frequency(khz)
// 95 88 47 31 23
// 125.00 134.83 250.00 375.00 500.00
int16_t default_divisor[] = {95, 88, 47, 31, 23};
/*
default LF config is set to:
decimation = 1
bits_per_sample = 8
averaging = YES
divisor = 95 (125kHz)
trigger_threshold = 0
samples_to_skip = 0
verbose = YES
*/
sample_config config = {
.decimation = 1,
.bits_per_sample = 8,
.averaging = 1,
.trigger_threshold = 0,
.samples_to_skip = 0,
.verbose = false
};
// Iteration defaults
for (int i = 0; i < ARRAYLEN(default_divisor); ++i) {
if (kbd_enter_pressed()) {
PrintAndLogEx(INFO, "Keyboard pressed. Done.");
break;
}
// Try to change config!
uint32_t d;
d = config.divisor = default_divisor[i];
PrintAndLogEx(INFO, "--> trying (" _GREEN_("%d.%02d kHz")")", 12000 / (d + 1), ((1200000 + (d + 1) / 2) / (d + 1)) - ((12000 / (d + 1)) * 100));
retval = lf_config(&config);
if (retval != PM3_SUCCESS)
break;
// The config for pm3 is changed, we can trying search!
retval = CmdLFfind(Cmd);
if (retval == PM3_SUCCESS)
break;
}
lf_config(&oldconfig);
return retval;
}
2020-11-23 08:39:54 +08:00
static int CmdAuto(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "auto",
"Run LF SEARCH / HF SEARCH / DATA PLOT / DATA SAVE",
"auto"
);
void *argtable[] = {
arg_param_begin,
2021-04-20 05:00:02 +08:00
arg_lit0("c", NULL, "Continue searching even after a first hit"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
bool exit_first = (arg_get_lit(ctx, 1) == false);
CLIParserFree(ctx);
PrintAndLogEx(INFO, "lf search");
int ret = CmdLFfind("");
if (ret == PM3_SUCCESS && exit_first)
return ret;
PrintAndLogEx(INFO, "hf search");
ret = CmdHFSearch("");
if (ret == PM3_SUCCESS && exit_first)
return ret;
PrintAndLogEx(INFO, "lf search - unknown");
ret = lf_search_plus("");
if (ret == PM3_SUCCESS && exit_first)
return ret;
if (ret != PM3_SUCCESS)
PrintAndLogEx(INFO, "Failed both LF / HF SEARCH,");
PrintAndLogEx(INFO, "Trying " _YELLOW_("`lf read`") " and save a trace for you");
CmdPlot("");
2020-01-10 03:02:01 +08:00
lf_read(false, 40000);
char *fname = calloc(100, sizeof(uint8_t));
2020-12-01 22:13:30 +08:00
AppendDate(fname, 100, "-f lf_unknown_%Y-%m-%d_%H:%M");
CmdSave(fname);
free(fname);
return PM3_SUCCESS;
}
int CmdRem(const char *Cmd) {
2020-12-01 22:16:23 +08:00
CLIParserContext *ctx;
CLIParserInit(&ctx, "rem",
"Add a text line in log file",
"rem my message -> adds a timestamp with `my message`"
2020-12-01 22:16:23 +08:00
);
void *argtable[] = {
arg_param_begin,
arg_strx1(NULL, NULL, NULL, "message line you want inserted"),
2020-12-01 22:16:23 +08:00
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
2020-12-24 02:51:10 +08:00
struct arg_str *foo = arg_get_str(ctx, 1);
size_t count = 0;
size_t len = 0;
do {
count += strlen(foo->sval[len]);
} while (len++ < (foo->count - 1));
2020-12-01 22:16:23 +08:00
char s[count + foo->count];
memset(s, 0, sizeof(s));
len = 0;
do {
snprintf(s + strlen(s), sizeof(s) - strlen(s), "%s ", foo->sval[len]);
} while (len++ < (foo->count - 1));
CLIParserFree(ctx);
char buf[22] = {0};
AppendDate(buf, sizeof(buf), NULL);
PrintAndLogEx(SUCCESS, "%s remark: %s", buf, s);
return PM3_SUCCESS;
}
static int CmdHints(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hints",
"Turn on/off hints",
"hints --on\n"
"hints -1\n"
);
void *argtable[] = {
arg_param_begin,
arg_lit0("1", "on", "turn on hints"),
arg_lit0("0", "off", "turn off hints"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
bool turn_on = arg_get_lit(ctx, 1);
bool turn_off = arg_get_lit(ctx, 2);
CLIParserFree(ctx);
if (turn_on && turn_off) {
PrintAndLogEx(ERR, "you can't turn off and on at the same time");
return PM3_EINVARG;
}
2020-11-23 08:39:54 +08:00
if (turn_off) {
session.show_hints = false;
} else if (turn_on) {
session.show_hints = true;
}
2020-04-16 15:01:14 +08:00
PrintAndLogEx(INFO, "Hints are %s", (session.show_hints) ? "ON" : "OFF");
return PM3_SUCCESS;
}
2019-07-15 06:31:38 +08:00
static int CmdMsleep(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "msleep",
"Sleep for given amount of milliseconds",
"msleep 100"
);
void *argtable[] = {
arg_param_begin,
arg_int0("t", "ms", "<ms>", "time in milliseconds"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
uint32_t ms = arg_get_u32_def(ctx, 1, 0);
CLIParserFree(ctx);
if (ms == 0) {
PrintAndLogEx(ERR, "Specified invalid input. Can't be zero");
return PM3_EINVARG;
2019-07-15 06:31:38 +08:00
}
2019-07-15 06:31:38 +08:00
msleep(ms);
return PM3_SUCCESS;
}
static int CmdQuit(const char *Cmd) {
2021-04-19 07:43:26 +08:00
CLIParserContext *ctx;
CLIParserInit(&ctx, "quit",
"Quit the Proxmark3 client terminal",
"quit"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
2019-04-19 06:42:25 +08:00
return PM3_EFATAL;
}
static int CmdRev(const char *Cmd) {
CmdCrc(Cmd);
2019-04-19 06:42:25 +08:00
return PM3_SUCCESS;
}
Client cleanup and restructuring. Stage 1... Next Step is refactoring some of the giant functions which are just copy/paste of some other ones with just a few line changes, removing unnecessary 'goto' etc. The MS Windows version is broken with this commit but will be fixed soon. Everything can't be done all at once :P The commands are now hierarchical, for example: "hf 14a read" vs. "hf 14b read". You can also request help: "hf help", "data help", "hf 15 help" etc. Indents are now space-based, not tab-based anymore. Hopefully no one will be trolling about it, considering the suicide-prone work being done here ;) client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h, client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h, client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c, client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h, client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h, client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h, client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h, client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h, client/cmdhflegic.c, client/cmdhflegic.c: New files. client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c, client/proxmark3.h, client/Makefile: Update accordingly. client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes. client/translate.h, client/command.c, client/gui.c, client/usb.c, client/prox.h: Remove. include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd. common/crc16.h: New file. common/crc16.c: Modify accordingly. common/iso14443crc.h: New file. common/iso14443_crc.c: Rename to common/iso14443crc.c: and modify accordingly. armsrc/lfops.c, armsrc/iso14443.c, armsrc/iso14443a.c: include .h files from the common directory instead of including the c files. common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
static int CmdPref(const char *Cmd) {
CmdPreferences(Cmd);
return PM3_SUCCESS;
}
static int CmdClear(const char *Cmd) {
2021-03-24 00:06:53 +08:00
CLIParserContext *ctx;
CLIParserInit(&ctx, "clear",
2021-04-08 17:08:39 +08:00
"Clear the Proxmark3 client terminal screen",
"clear"
);
2021-03-24 00:06:53 +08:00
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
PrintAndLogEx(NORMAL, _CLEAR_ _TOP_ "");
return PM3_SUCCESS;
}
static command_t CommandTable[] = {
2020-06-21 22:36:12 +08:00
2021-03-29 16:49:19 +08:00
{"help", CmdHelp, AlwaysAvailable, "Use `" _YELLOW_("<command> help") "` for details of a command"},
2021-04-10 18:28:39 +08:00
{"prefs", CmdPref, AlwaysAvailable, "{ Edit client/device preferences... }"},
2021-03-29 16:49:19 +08:00
{"--------", CmdHelp, AlwaysAvailable, "----------------------- " _CYAN_("Technology") " -----------------------"},
{"analyse", CmdAnalyse, AlwaysAvailable, "{ Analyse utils... }"},
{"data", CmdData, AlwaysAvailable, "{ Plot window / data buffer manipulation... }"},
{"emv", CmdEMV, AlwaysAvailable, "{ EMV ISO-14443 / ISO-7816... }"},
{"hf", CmdHF, AlwaysAvailable, "{ High frequency commands... }"},
{"hw", CmdHW, AlwaysAvailable, "{ Hardware commands... }"},
{"lf", CmdLF, AlwaysAvailable, "{ Low frequency commands... }"},
{"mem", CmdFlashMem, IfPm3Flash, "{ Flash memory manipulation... }"},
{"reveng", CmdRev, AlwaysAvailable, "{ CRC calculations from RevEng software... }"},
{"smart", CmdSmartcard, AlwaysAvailable, "{ Smart card ISO-7816 commands... }"},
{"script", CmdScript, AlwaysAvailable, "{ Scripting commands... }"},
{"trace", CmdTrace, AlwaysAvailable, "{ Trace manipulation... }"},
{"usart", CmdUsart, IfPm3FpcUsartFromUsb, "{ USART commands... }"},
{"wiegand", CmdWiegand, AlwaysAvailable, "{ Wiegand format manipulation... }"},
{"--------", CmdHelp, AlwaysAvailable, "----------------------- " _CYAN_("General") " -----------------------"},
{"auto", CmdAuto, IfPm3Present, "Automated detection process for unknown tags"},
{"clear", CmdClear, AlwaysAvailable, "Clear screen"},
{"hints", CmdHints, AlwaysAvailable, "Turn hints on / off"},
{"msleep", CmdMsleep, AlwaysAvailable, "Add a pause in milliseconds"},
{"rem", CmdRem, AlwaysAvailable, "Add a text line in log file"},
{"quit", CmdQuit, AlwaysAvailable, ""},
{"exit", CmdQuit, AlwaysAvailable, "Exit program"},
{NULL, NULL, NULL, NULL}
Client cleanup and restructuring. Stage 1... Next Step is refactoring some of the giant functions which are just copy/paste of some other ones with just a few line changes, removing unnecessary 'goto' etc. The MS Windows version is broken with this commit but will be fixed soon. Everything can't be done all at once :P The commands are now hierarchical, for example: "hf 14a read" vs. "hf 14b read". You can also request help: "hf help", "data help", "hf 15 help" etc. Indents are now space-based, not tab-based anymore. Hopefully no one will be trolling about it, considering the suicide-prone work being done here ;) client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h, client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h, client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c, client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h, client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h, client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h, client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h, client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h, client/cmdhflegic.c, client/cmdhflegic.c: New files. client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c, client/proxmark3.h, client/Makefile: Update accordingly. client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes. client/translate.h, client/command.c, client/gui.c, client/usb.c, client/prox.h: Remove. include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd. common/crc16.h: New file. common/crc16.c: Modify accordingly. common/iso14443crc.h: New file. common/iso14443_crc.c: Rename to common/iso14443crc.c: and modify accordingly. armsrc/lfops.c, armsrc/iso14443.c, armsrc/iso14443a.c: include .h files from the common directory instead of including the c files. common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
};
static int CmdHelp(const char *Cmd) {
2019-04-10 18:23:40 +08:00
(void)Cmd; // Cmd is not used so far
2019-03-10 06:35:06 +08:00
CmdsHelp(CommandTable);
2019-04-19 06:42:25 +08:00
return PM3_SUCCESS;
Client cleanup and restructuring. Stage 1... Next Step is refactoring some of the giant functions which are just copy/paste of some other ones with just a few line changes, removing unnecessary 'goto' etc. The MS Windows version is broken with this commit but will be fixed soon. Everything can't be done all at once :P The commands are now hierarchical, for example: "hf 14a read" vs. "hf 14b read". You can also request help: "hf help", "data help", "hf 15 help" etc. Indents are now space-based, not tab-based anymore. Hopefully no one will be trolling about it, considering the suicide-prone work being done here ;) client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h, client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h, client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c, client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h, client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h, client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h, client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h, client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h, client/cmdhflegic.c, client/cmdhflegic.c: New files. client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c, client/proxmark3.h, client/Makefile: Update accordingly. client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes. client/translate.h, client/command.c, client/gui.c, client/usb.c, client/prox.h: Remove. include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd. common/crc16.h: New file. common/crc16.c: Modify accordingly. common/iso14443crc.h: New file. common/iso14443_crc.c: Rename to common/iso14443crc.c: and modify accordingly. armsrc/lfops.c, armsrc/iso14443.c, armsrc/iso14443a.c: include .h files from the common directory instead of including the c files. common/Makefile.common, armsrc/Makefile: Modify accordingly.
2010-02-04 09:27:07 +08:00
}
//-----------------------------------------------------------------------------
// Entry point into our code: called whenever the user types a command and
// then presses Enter, which the full command line that they typed.
//-----------------------------------------------------------------------------
int CommandReceived(char *Cmd) {
2019-03-10 06:35:06 +08:00
return CmdsParse(CommandTable, Cmd);
2019-03-12 07:12:26 +08:00
}
2020-05-03 07:13:28 +08:00
command_t *getTopLevelCommandTable(void) {
return CommandTable;
}