Replace ukbhit by kbd_enter_pressed, not requiring tcgetattr:

Note that it behaves differently now
* it looks for Enter key only, not any key
* it "eats" the input, no need for (void)getchar() after it
* it works the same no matter the value of ICANON
* the mingw version has been adapted to act the similarly

This should fix its usage on Android where tcgetattr always returns -1
This commit is contained in:
Philippe Teuwen 2019-07-11 13:01:34 +02:00
commit 844d732297
27 changed files with 90 additions and 126 deletions

View file

@ -623,8 +623,7 @@ static int CmdAnalyseA(const char *Cmd) {
for (uint8_t k=0; k<4; k = (k+1) % 4 ) {
PrintAndLogEx(NORMAL, "\e[s%c\e[u", star[k]);
fflush(stdout);
if (ukbhit()) {
int gc = getchar(); (void)gc;
if (kbd_enter_pressed()) {
break;
}
}

View file

@ -40,7 +40,7 @@ static int usage_hf_sniff() {
static int usage_hf_tune() {
PrintAndLogEx(NORMAL, "Usage: hf tune [<iter>]");
PrintAndLogEx(NORMAL, "Continuously measure HF antenna tuning.");
PrintAndLogEx(NORMAL, "Press button or keyboard to interrupt.");
PrintAndLogEx(NORMAL, "Press button or Enter to interrupt.");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " <iter> - number of iterations (default: infinite)");
PrintAndLogEx(NORMAL, "");
@ -98,7 +98,7 @@ int CmdHFTune(const char *Cmd) {
int iter = param_get32ex(Cmd, 0, 0, 10);
PacketResponseNG resp;
PrintAndLogEx(SUCCESS, "Measuring HF antenna, click button or press a key to exit");
PrintAndLogEx(SUCCESS, "Measuring HF antenna, click button or press Enter to exit");
clearCommandBuffer();
uint8_t mode[] = {1};
SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_HF, mode, sizeof(mode));
@ -109,9 +109,7 @@ int CmdHFTune(const char *Cmd) {
mode[0] = 2;
// loop forever (till button pressed) if iter = 0 (default)
for (uint8_t i = 0; iter == 0 || i < iter; i++) {
if (ukbhit()) { // abort by keyboard press
int gc = getchar();
(void)gc;
if (kbd_enter_pressed()) { // abort by keyboard press
break;
}
SendCommandNG(CMD_MEASURE_ANTENNA_TUNING_HF, mode, sizeof(mode));

View file

@ -375,9 +375,7 @@ static int CmdHF14ACUIDs(const char *Cmd) {
// repeat n times
for (int i = 0; i < n; i++) {
if (ukbhit()) {
int gc = getchar();
(void)gc;
if (kbd_enter_pressed()) {
PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n");
break;
}
@ -489,7 +487,7 @@ int CmdHF14ASim(const char *Cmd) {
PrintAndLogEx(SUCCESS, "press pm3-button to abort simulation");
while (!ukbhit()) {
while (!kbd_enter_pressed()) {
if (WaitForResponseTimeout(CMD_SIMULATE_MIFARE_CARD, &resp, 1500) == 0) continue;
if (resp.status != PM3_SUCCESS) break;

View file

@ -135,7 +135,7 @@ static int CmdHFFelicaSim(const char *Cmd) {
if (verbose)
PrintAndLogEx(NORMAL, "Press pm3-button to abort simulation");
while (!ukbhit()) {
while (!kbd_enter_pressed()) {
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) continue;
}
return 0;
@ -357,9 +357,7 @@ static int CmdHFFelicaDumpLite(const char *Cmd) {
timeout++;
printf(".");
fflush(stdout);
if (ukbhit()) {
int gc = getchar();
(void)gc;
if (kbd_enter_pressed()) {
PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n");
DropField();
return 1;

View file

@ -176,7 +176,7 @@ static int usage_hf_iclass_managekeys(void) {
return 0;
}
static int usage_hf_iclass_reader(void) {
PrintAndLogEx(NORMAL, "Act as a Iclass reader. Look for iClass tags until a key or the pm3 button is pressed\n");
PrintAndLogEx(NORMAL, "Act as a Iclass reader. Look for iClass tags until Enter or the pm3 button is pressed\n");
PrintAndLogEx(NORMAL, "Usage: hf iclass reader [h] [1]\n");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h This help text");
@ -376,16 +376,14 @@ static int CmdHFiClassSim(const char *Cmd) {
case 2: {
PrintAndLogEx(INFO, "Starting iCLASS sim 2 attack (elite mode)");
PrintAndLogEx(INFO, "press keyboard to cancel");
PrintAndLogEx(INFO, "press Enter to cancel");
PacketResponseNG resp;
clearCommandBuffer();
SendCommandOLD(CMD_SIMULATE_TAG_ICLASS, simType, NUM_CSNS, 0, csns, 8 * NUM_CSNS);
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
tries++;
if (ukbhit()) {
int gc = getchar();
(void)gc;
if (kbd_enter_pressed()) {
PrintAndLogEx(WARNING, "\naborted via keyboard.");
return 0;
}
@ -427,16 +425,14 @@ static int CmdHFiClassSim(const char *Cmd) {
case 4: {
// reader in key roll mode, when it has two keys it alternates when trying to verify.
PrintAndLogEx(INFO, "Starting iCLASS sim 4 attack (elite mode, reader in key roll mode)");
PrintAndLogEx(INFO, "press keyboard to cancel");
PrintAndLogEx(INFO, "press Enter to cancel");
PacketResponseNG resp;
clearCommandBuffer();
SendCommandOLD(CMD_SIMULATE_TAG_ICLASS, simType, NUM_CSNS, 0, csns, 8 * NUM_CSNS);
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
tries++;
if (ukbhit()) {
int gc = getchar();
(void)gc;
if (kbd_enter_pressed()) {
PrintAndLogEx(WARNING, "\naborted via keyboard.");
return 0;
}
@ -969,9 +965,7 @@ static int CmdHFiClassReader_Dump(const char *Cmd) {
while (true) {
printf(".");
fflush(stdout);
if (ukbhit()) {
int gc = getchar();
(void)gc;
if (kbd_enter_pressed()) {
PrintAndLogEx(WARNING, "\n[!] aborted via keyboard!\n");
DropField();
return 0;
@ -1945,9 +1939,7 @@ static int CmdHFiClassCheckKeys(const char *Cmd) {
uint64_t t2 = msclock();
uint8_t timeout = 0;
if (ukbhit()) {
int gc = getchar();
(void)gc;
if (kbd_enter_pressed()) {
PrintAndLogEx(WARNING, "\n[!] Aborted via keyboard!\n");
goto out;
}
@ -2446,7 +2438,7 @@ int readIclass(bool loop, bool verbose) {
// loop in client not device - else on windows have a communication error
PacketResponseNG resp;
while (!ukbhit()) {
while (!kbd_enter_pressed()) {
clearCommandBuffer();
SendCommandMIX(CMD_READER_ICLASS, flags, 0, 0, NULL, 0);

View file

@ -1692,9 +1692,7 @@ static int CmdHF14AMfChk_fast(const char *Cmd) {
// main keychunk loop
for (i = 0; i < keycnt; i += chunksize) {
if (ukbhit()) {
int gc = getchar();
(void)gc;
if (kbd_enter_pressed()) {
PrintAndLogEx(WARNING, "\naborted via keyboard!\n");
goto out;
}
@ -1974,9 +1972,7 @@ static int CmdHF14AMfChk(const char *Cmd) {
printf(".");
fflush(stdout);
if (ukbhit()) {
int gc = getchar();
(void)gc;
if (kbd_enter_pressed()) {
PrintAndLogEx(INFO, "\naborted via keyboard!\n");
goto out;
}
@ -2281,7 +2277,7 @@ static int CmdHF14AMfSim(const char *Cmd) {
if (flags & FLAG_INTERACTIVE) {
PrintAndLogEx(INFO, "Press pm3-button or send another cmd to abort simulation");
while (!ukbhit()) {
while (!kbd_enter_pressed()) {
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500)) continue;
if (!(flags & FLAG_NR_AR_ATTACK)) break;
if ((resp.oldarg[0] & 0xffff) != CMD_SIMULATE_MIFARE_CARD) break;
@ -2328,8 +2324,8 @@ static int CmdHF14AMfSniff(const char *Cmd) {
PrintAndLogEx(NORMAL, "-------------------------------------------------------------------------\n");
PrintAndLogEx(NORMAL, "Executing mifare sniffing command. \n");
PrintAndLogEx(NORMAL, "Press the key on the Proxmark3 device to abort both Proxmark3 and client.\n");
PrintAndLogEx(NORMAL, "Press the key on pc keyboard to abort the client.\n");
PrintAndLogEx(NORMAL, "Press the button on the Proxmark3 device to abort both Proxmark3 and client.\n");
PrintAndLogEx(NORMAL, "Press Enter to abort the client.\n");
PrintAndLogEx(NORMAL, "-------------------------------------------------------------------------\n");
clearCommandBuffer();
@ -2341,9 +2337,7 @@ static int CmdHF14AMfSniff(const char *Cmd) {
while (true) {
printf(".");
fflush(stdout);
if (ukbhit()) {
int gc = getchar();
(void)gc;
if (kbd_enter_pressed()) {
PrintAndLogEx(INFO, "\naborted via keyboard!\n");
break;
}
@ -3242,7 +3236,7 @@ static int CmdHf14AMfNack(const char *Cmd) {
bool verbose = (ctmp == 'v');
if (verbose)
PrintAndLogEx(INFO, "Started testing card for NACK bug. Press key to abort");
PrintAndLogEx(INFO, "Started testing card for NACK bug. Press Enter to abort");
detect_classic_nackbug(verbose);
return PM3_SUCCESS;
@ -3307,9 +3301,7 @@ static int CmdHF14AMfice(const char *Cmd) {
uint64_t t1 = msclock();
do {
if (ukbhit()) {
int gc = getchar();
(void)gc;
if (kbd_enter_pressed()) {
PrintAndLogEx(INFO, "\naborted via keyboard!\n");
break;
}

View file

@ -491,7 +491,7 @@ static int CmdAWIDBrute(const char *Cmd) {
}
PrintAndLogEx(SUCCESS, "Bruteforceing AWID %d Reader", fmtlen);
PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or press key");
PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or press Enter");
uint16_t up = cn;
uint16_t down = cn;
@ -503,9 +503,7 @@ static int CmdAWIDBrute(const char *Cmd) {
PrintAndLogEx(WARNING, "Device offline\n");
return PM3_ENODATA;
}
if (ukbhit()) {
int gc = getchar();
(void)gc;
if (kbd_enter_pressed()) {
PrintAndLogEx(INFO, "aborted via keyboard!");
return sendPing();
}

View file

@ -544,9 +544,7 @@ static int CmdEM410xBrute(const char *Cmd) {
char testuid[11];
testuid[10] = 0;
if (ukbhit()) {
int gc = getchar();
(void)gc;
if (kbd_enter_pressed()) {
PrintAndLogEx(WARNING, "\nAborted via keyboard!\n");
free(uidBlock);
return PM3_EOPABORTED;
@ -580,9 +578,7 @@ static int CmdEM410xBrute(const char *Cmd) {
static int CmdEM410xWatch(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
do {
if (ukbhit()) {
int gc = getchar();
(void)gc;
if (kbd_enter_pressed()) {
PrintAndLogEx(WARNING, "\naborted via keyboard!\n");
break;
}

View file

@ -580,9 +580,7 @@ static int CmdHIDBrute(const char *Cmd) {
return PM3_ENODATA;
}
if (ukbhit()) {
int gc = getchar();
(void)gc;
if (kbd_enter_pressed()) {
PrintAndLogEx(INFO, "aborted via keyboard!");
return sendPing();
}

View file

@ -1843,9 +1843,7 @@ static int CmdT55xxWipe(const char *Cmd) {
}
static bool IsCancelled(void) {
if (ukbhit()) {
int gc = getchar();
(void)gc;
if (kbd_enter_pressed()) {
PrintAndLogEx(WARNING, "\naborted via keyboard!\n");
return true;
}

View file

@ -914,9 +914,7 @@ static int smart_brute_sfi(bool decodeTLV) {
for (uint16_t rec = 1; rec <= 255; rec++) {
if (ukbhit()) {
int gc = getchar();
(void)gc;
if (kbd_enter_pressed()) {
PrintAndLogEx(WARNING, "\naborted via keyboard!\n");
free(buf);
return 1;

View file

@ -312,11 +312,9 @@ static int CmdUsartBtFactory(const char *Cmd) {
PrintAndLogEx(WARNING, _RED_("WARNING: process only if strictly needed!"));
PrintAndLogEx(WARNING, "This requires BT turned ON and NOT connected!");
PrintAndLogEx(WARNING, "Is the add-on blue light blinking? (Say 'n' if you want to abort) [y/n]");
while (!ukbhit()) {
msleep(200);
}
if (tolower(getchar()) != 'y') {
char input[3];
if ((fgets(input,sizeof(input),stdin) == NULL) || (strncmp(input, "y\n", sizeof(input)) != 0)) {
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(FAILED, "Aborting.");
return PM3_EOPABORTED;
@ -448,11 +446,10 @@ static int CmdUsartBtFactory(const char *Cmd) {
}
if ((baudrate != USART_BAUD_RATE) || (parity != USART_PARITY)) {
PrintAndLogEx(WARNING, "Add-on uart settings changed, please turn BT add-on OFF and ON again, then press any key.");
while (!ukbhit()) {
PrintAndLogEx(WARNING, "Add-on uart settings changed, please turn BT add-on OFF and ON again, then press Enter.");
while (!kbd_enter_pressed()) {
msleep(200);
}
getchar();
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "Trying to connect add-on with the new settings.");
found = usart_bt_testcomm(USART_BAUD_RATE, USART_PARITY) == PM3_SUCCESS;

View file

@ -15,10 +15,10 @@ local reader15693 = require('read15')
-- @return if successfull: an table containing card info
-- @return if unsuccessfull : nil, error
local function waitForTag()
print("Waiting for card... press any key to quit")
print("Waiting for card... press Enter to quit")
local readers = {reader14443A, reader14443B, reader15693}
local i = 0;
while not core.ukbhit() do
while not core.kbd_enter_pressed() do
i = (i % 3) +1
r = readers[i]
print("Reading with ",i)

View file

@ -121,8 +121,8 @@ end
-- @return if successfull: an table containing card info
-- @return if unsuccessfull : nil, error
local function waitFor14443a()
print('Waiting for card... press any key to quit')
while not core.ukbhit() do
print('Waiting for card... press Enter to quit')
while not core.kbd_enter_pressed() do
res, err = read14443a()
if res then return res end
-- err means that there was no response from card

View file

@ -99,8 +99,8 @@ end
-- @return if successfull: an table containing card info
-- @return if unsuccessfull : nil, error
local function waitFor14443b()
print('Waiting for card... press any key to quit')
while not core.ukbhit() do
print('Waiting for card... press Enter to quit')
while not core.kbd_enter_pressed() do
res, err = read14443b(false)
if res then return res end
-- err means that there was no response from card

View file

@ -133,8 +133,8 @@ end
-- @return if successfull: an table containing card info
-- @return if unsuccessfull : nil, error
local function waitFor15693()
print('Waiting for card... press any key to quit')
while not core.ukbhit() do
print('Waiting for card... press Enter to quit')
while not core.kbd_enter_pressed() do
res, err = read15693()
if res then return res end
-- err means that there was no response from card

View file

@ -28,9 +28,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
SendCommandMIX(CMD_READER_MIFARE, arg0, blockno, key_type, NULL, 0);
//flush queue
while (ukbhit()) {
int gc = getchar();
(void)gc;
while (kbd_enter_pressed()) {
return PM3_EOPABORTED;
}
@ -38,9 +36,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key) {
while (true) {
printf(".");
fflush(stdout);
if (ukbhit()) {
int gc = getchar();
(void)gc;
if (kbd_enter_pressed()) {
return PM3_EOPABORTED;
}
@ -955,9 +951,7 @@ int detect_classic_nackbug(bool verbose) {
while (true) {
printf(".");
fflush(stdout);
if (ukbhit()) {
int gc = getchar();
(void)gc;
if (kbd_enter_pressed()) {
return PM3_EOPABORTED;
}

View file

@ -411,8 +411,8 @@ static int l_foobar(lua_State *L) {
* @param L
* @return boolean, true if kbhit, false otherwise.
*/
static int l_ukbhit(lua_State *L) {
lua_pushboolean(L, ukbhit() ? true : false);
static int l_kbd_enter_pressed(lua_State *L) {
lua_pushboolean(L, kbd_enter_pressed() ? true : false);
return 1;
}
@ -1064,7 +1064,7 @@ int set_pm3_libraries(lua_State *L) {
{"WaitForResponseTimeout", l_WaitForResponseTimeout},
{"mfDarkside", l_mfDarkside},
{"foobar", l_foobar},
{"ukbhit", l_ukbhit},
{"kbd_enter_pressed", l_kbd_enter_pressed},
{"clearCommandBuffer", l_clearCommandBuffer},
{"console", l_CmdConsole},
{"iso15693_crc", l_iso15693_crc},

View file

@ -488,7 +488,7 @@ local function readtag(mfkey, aeskey )
for blockNo = 0, numBlocks-1 do
if core.ukbhit() then
if core.kbd_enter_pressed() then
print("[fail] aborted by user")
return nil
end

View file

@ -206,7 +206,7 @@ local function main(args)
if x then core.console(cmd) end
end
if core.ukbhit() then
if core.kbd_enter_pressed() then
print('aborted by user')
break
end

View file

@ -186,7 +186,7 @@ local function main(args)
for cardnum = baseid, endid do
local card = cardHex(cardnum, facility)
print('Press enter to program card '..cardnum..':'..facility..' (hex: '..card..')')
--This would be better with 'press any key', but we'll take what we can get.
--This would be better with 'press Enter', but we'll take what we can get.
io.read()
core.console( ('lf hid clone %s'):format(card) )
end

View file

@ -208,7 +208,7 @@ local function perform_check(numsectors)
for sector = 0, #keys do
-- Check if user aborted
if core.ukbhit() then
if core.kbd_enter_pressed() then
print('Aborted by user')
break
end

View file

@ -70,7 +70,7 @@ end
-- @return if successfull: an table containing card info
-- @return if unsuccessfull : nil, error
local function wait_for_mifare()
while not core.ukbhit() do
while not core.kbd_enter_pressed() do
res, err = lib14a.read()
if res then return res end
-- err means that there was no response from card
@ -161,7 +161,7 @@ local function main(args)
while not _exit do
if print_message then
print('Waiting for card or press any key to stop')
print('Waiting for card or press Enter to stop')
print_message = false
end
res, err = wait_for_mifare()

View file

@ -198,7 +198,7 @@ local function main(args)
io.flush()
if core.ukbhit() then
if core.kbd_enter_pressed() then
print("aborted by user")
break
end

View file

@ -118,7 +118,7 @@ local function main(args)
core.clearCommandBuffer()
if core.ukbhit() then
if core.kbd_enter_pressed() then
print('aborted by user')
break
end

View file

@ -26,38 +26,46 @@ uint8_t g_debugMode = 0;
#define MAX_BIN_BREAK_LENGTH (3072+384+1)
#ifndef _WIN32
#include <termios.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <stdarg.h>
#include <fcntl.h>
int ukbhit(void) {
int cnt = 0;
int error;
static struct termios Otty, Ntty;
if (tcgetattr(STDIN_FILENO, &Otty) == -1) return -1;
Ntty = Otty;
Ntty.c_iflag = 0x0000; // input mode
Ntty.c_oflag = 0x0000; // output mode
Ntty.c_lflag &= ~ICANON; // control mode = raw
Ntty.c_cc[VMIN] = 1; // return if at least 1 character is in the queue
Ntty.c_cc[VTIME] = 0; // no timeout. Wait forever
if (0 == (error = tcsetattr(STDIN_FILENO, TCSANOW, &Ntty))) { // set new attributes
error += ioctl(STDIN_FILENO, FIONREAD, &cnt); // get number of characters available
error += tcsetattr(STDIN_FILENO, TCSANOW, &Otty); // reset attributes
int kbd_enter_pressed(void) {
int flags;
if ((flags = fcntl(STDIN_FILENO, F_GETFL, 0)) < 0) {
PrintAndLogEx(ERR, "fcntl failed in kbd_enter_pressed");
return -1;
}
return (error == 0 ? cnt : -1);
//non-blocking
flags |= O_NONBLOCK;
if (fcntl(STDIN_FILENO, F_SETFL, flags) < 0) {
PrintAndLogEx(ERR, "fcntl failed in kbd_enter_pressed");
return -1;
}
int c;
int ret = 0;
do { //get all available chars
c = getchar();
ret |= c == '\n';
} while (c != EOF);
//blocking
flags &= ~O_NONBLOCK;
if (fcntl(STDIN_FILENO, F_SETFL, flags) < 0) {
PrintAndLogEx(ERR, "fcntl failed in kbd_enter_pressed");
return -1;
}
return ret;
}
#else
#include <conio.h>
int ukbhit(void) {
return kbhit();
int kbd_enter_pressed(void) {
int ret = 0;
while(kbhit())
{
ret |= getch() == '\r';
}
return ret;
}
#endif

View file

@ -129,7 +129,7 @@
uint8_t g_debugMode;
int ukbhit(void);
int kbd_enter_pressed(void);
void AddLogLine(const char *fn, const char *data, const char *c);
void AddLogHex(const char *fn, const char *extData, const uint8_t *data, const size_t len);
void AddLogUint64(const char *fn, const char *data, const uint64_t value);