mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-09-20 07:16:14 +08:00
Added native output grabbing for Python and Lua: less hacky than output_grabber.py, should work on ProxSpace as well
This commit is contained in:
parent
83f6e2b56b
commit
369c5bb5db
|
@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file.
|
|||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||
|
||||
## [unreleased][unreleased]
|
||||
- Added native output grabbing for Python and Lua: less hacky than `output_grabber.py`, should work on ProxSpace as well (@doegox)
|
||||
- Changed `hf mf chk/fchk`: added option `--no-default` to skip loading the usual ~61 hardcoded keys (@doegox)
|
||||
- Fixed `hf mf wipe` to detect properly write errors (@doegox)
|
||||
- Fixed `hf mf fchk` which was leaving the RF field on when interrupted by keyboard (@doegox)
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
../../pm3 -c "script run testembedded_grab.py" -i
|
|
@ -1,4 +1,13 @@
|
|||
local pm3 = require("pm3")
|
||||
p=pm3.pm3()
|
||||
|
||||
p:console("hw status")
|
||||
print(p.name)
|
||||
p:console("hw version")
|
||||
for line in p.grabbed_output:gmatch("[^\r\n]+") do
|
||||
if line:find("Unique ID") or line:find("uC:") then
|
||||
print(line)
|
||||
end
|
||||
end
|
||||
|
||||
print("Device:", p.name)
|
||||
p:console("Rem passthru remark! :coffee:", true)
|
||||
|
|
|
@ -2,5 +2,13 @@
|
|||
|
||||
import pm3
|
||||
p=pm3.pm3()
|
||||
|
||||
p.console("hw status")
|
||||
p.console("hw version")
|
||||
for line in p.grabbed_output.split('\n'):
|
||||
if "Unique ID" in line:
|
||||
print(line)
|
||||
if "uC:" in line:
|
||||
print(line)
|
||||
print("Device:", p.name)
|
||||
p.console("Rem passthru remark! :coffee:", True)
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import pm3
|
||||
from output_grabber import OutputGrabber
|
||||
|
||||
out = OutputGrabber()
|
||||
p=pm3.pm3()
|
||||
print("Device:", p.name)
|
||||
with out:
|
||||
p.console("hw status")
|
||||
for line in out.captured_output.split('\n'):
|
||||
if "Unique ID" in line:
|
||||
print(line)
|
|
@ -2,5 +2,14 @@
|
|||
|
||||
local pm3 = require("pm3")
|
||||
p=pm3.pm3("/dev/ttyACM0")
|
||||
|
||||
p:console("hw status")
|
||||
print(p.name)
|
||||
p:console("hw version")
|
||||
for line in p.grabbed_output:gmatch("[^\r\n]+") do
|
||||
if line:find("Unique ID") or line:find("uC:") then
|
||||
print(line)
|
||||
end
|
||||
end
|
||||
|
||||
print("Device:", p.name)
|
||||
p:console("Rem passthru remark! :coffee:", true)
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
PYTHONPATH=../../pyscripts ipython3 -i ./test_grab.py
|
|
@ -2,5 +2,13 @@
|
|||
|
||||
import pm3
|
||||
p=pm3.pm3("/dev/ttyACM0")
|
||||
|
||||
p.console("hw status")
|
||||
p.console("hw version")
|
||||
for line in p.grabbed_output.split('\n'):
|
||||
if "Unique ID" in line:
|
||||
print(line)
|
||||
if "uC:" in line:
|
||||
print(line)
|
||||
print("Device:", p.name)
|
||||
p.console("Rem passthru remark! :coffee:", True)
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import pm3
|
||||
from output_grabber import OutputGrabber
|
||||
|
||||
out = OutputGrabber()
|
||||
p=pm3.pm3("/dev/ttyACM0")
|
||||
print("Device:", p.name)
|
||||
with out:
|
||||
p.console("hw status")
|
||||
for line in out.captured_output.split('\n'):
|
||||
if "Unique ID" in line:
|
||||
print(line)
|
|
@ -16,10 +16,13 @@
|
|||
#ifndef LIBPM3_H
|
||||
#define LIBPM3_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct pm3_device pm3;
|
||||
|
||||
pm3 *pm3_open(const char *port);
|
||||
int pm3_console(pm3 *dev, const char *cmd);
|
||||
int pm3_console(pm3 *dev, const char *cmd, bool passthru);
|
||||
const char *pm3_grabbed_output_get(pm3 *dev);
|
||||
const char *pm3_name_get(pm3 *dev);
|
||||
void pm3_close(pm3 *dev);
|
||||
pm3 *pm3_get_current_dev(void);
|
||||
|
|
|
@ -19,7 +19,6 @@ import time
|
|||
import subprocess
|
||||
import argparse
|
||||
import pm3
|
||||
from output_grabber import OutputGrabber
|
||||
# optional color support
|
||||
try:
|
||||
# pip install ansicolors
|
||||
|
@ -49,14 +48,6 @@ for tool, bin in tools.items():
|
|||
if not os.path.isfile(bin):
|
||||
if os.path.isfile(bin + ".exe"):
|
||||
tools[tool] = bin + ".exe"
|
||||
|
||||
print(f"Native Windows/ProxSpace detected.")
|
||||
print(f"Currently, our Python output grabbing does not work properly on this environment.")
|
||||
print(f"Use WSL or Linux.")
|
||||
# cf https://stackoverflow.com/questions/52373180/python-on-windows-handle-invalid-when-redirecting-stdout-writing-to-file
|
||||
# for ref : https://docs.python.org/3/c-api/init_config.html#c.PyConfig.legacy_windows_stdio
|
||||
exit()
|
||||
|
||||
else:
|
||||
print(f"Cannot find {bin}, abort!")
|
||||
exit()
|
||||
|
@ -69,27 +60,24 @@ parser.add_argument('-d', '--debug', action='store_true', help='Enable debug mod
|
|||
args = parser.parse_args()
|
||||
|
||||
start_time = time.time()
|
||||
out = OutputGrabber()
|
||||
p = pm3.pm3()
|
||||
|
||||
restore_color = False
|
||||
with out:
|
||||
p.console("prefs get color")
|
||||
p.console("prefs set color --off")
|
||||
for line in out.captured_output.split('\n'):
|
||||
p.console("prefs get color")
|
||||
p.console("prefs set color --off")
|
||||
for line in p.grabbed_output.split('\n'):
|
||||
if "ansi" in line:
|
||||
restore_color = True
|
||||
with out:
|
||||
p.console("hf 14a read")
|
||||
p.console("hf 14a read")
|
||||
uid = None
|
||||
for line in out.captured_output.split('\n'):
|
||||
for line in p.grabbed_output.split('\n'):
|
||||
if "UID:" in line:
|
||||
uid = int(line[10:].replace(' ', ''), 16)
|
||||
if uid is None:
|
||||
print("Card not found")
|
||||
if restore_color:
|
||||
with out:
|
||||
p.console("prefs set color --ansi")
|
||||
p.console("prefs set color --ansi")
|
||||
_ = p.grabbed_output
|
||||
exit()
|
||||
print("UID: " + color(f"{uid:08X}", fg="green"))
|
||||
|
||||
|
@ -102,9 +90,8 @@ def print_key(sec, key_type, key):
|
|||
found_keys = [["", ""] for _ in range(NUM_SECTORS)]
|
||||
if not args.no_init_check:
|
||||
print("Checking default keys...")
|
||||
with out:
|
||||
p.console("hf mf fchk")
|
||||
for line in out.captured_output.split('\n'):
|
||||
p.console("hf mf fchk")
|
||||
for line in p.grabbed_output.split('\n'):
|
||||
if "[+] 0" in line:
|
||||
res = [x.strip() for x in line.split('|')]
|
||||
sec = int(res[0][4:])
|
||||
|
@ -119,18 +106,17 @@ nt = [["", ""] for _ in range(NUM_SECTORS)]
|
|||
nt_enc = [["", ""] for _ in range(NUM_SECTORS)]
|
||||
par_err = [["", ""] for _ in range(NUM_SECTORS)]
|
||||
print("Getting nonces...")
|
||||
with out:
|
||||
for sec in range(NUM_SECTORS):
|
||||
blk = sec * 4
|
||||
if found_keys[sec][0] == "" or found_keys[sec][1] == "":
|
||||
# Even if one key already found, we'll need both nt
|
||||
for key_type in [0, 1]:
|
||||
cmd = f"hf mf isen -n1 --blk {blk} -c {key_type+4} --key {BACKDOOR_RF08S}"
|
||||
p.console(cmd)
|
||||
cmd += f" --c2 {key_type}"
|
||||
p.console(cmd)
|
||||
for sec in range(NUM_SECTORS):
|
||||
blk = sec * 4
|
||||
if found_keys[sec][0] == "" or found_keys[sec][1] == "":
|
||||
# Even if one key already found, we'll need both nt
|
||||
for key_type in [0, 1]:
|
||||
cmd = f"hf mf isen -n1 --blk {blk} -c {key_type+4} --key {BACKDOOR_RF08S}"
|
||||
p.console(cmd)
|
||||
cmd += f" --c2 {key_type}"
|
||||
p.console(cmd)
|
||||
print("Processing traces...")
|
||||
for line in out.captured_output.split('\n'):
|
||||
for line in p.grabbed_output.split('\n'):
|
||||
if "nested cmd: 64" in line or "nested cmd: 65" in line:
|
||||
sec = int(line[24:26], 16)//4
|
||||
key_type = int(line[21:23], 16) - 0x64
|
||||
|
@ -232,9 +218,8 @@ for sec in range(NUM_SECTORS):
|
|||
cmd = f"hf mf fchk --blk {sec * 4} -{kt} -f {dic} --no-default"
|
||||
if args.debug:
|
||||
print(cmd)
|
||||
with out:
|
||||
p.console(cmd)
|
||||
for line in out.captured_output.split('\n'):
|
||||
p.console(cmd)
|
||||
for line in p.grabbed_output.split('\n'):
|
||||
if "aborted via keyboard" in line:
|
||||
abort = True
|
||||
if "found:" in line:
|
||||
|
@ -259,9 +244,8 @@ for sec in range(NUM_SECTORS):
|
|||
cmd = f"hf mf fchk --blk {sec * 4} -{kt} -f {dic} --no-default"
|
||||
if args.debug:
|
||||
print(cmd)
|
||||
with out:
|
||||
p.console(cmd)
|
||||
for line in out.captured_output.split('\n'):
|
||||
p.console(cmd)
|
||||
for line in p.grabbed_output.split('\n'):
|
||||
if "aborted via keyboard" in line:
|
||||
abort = True
|
||||
if "found:" in line:
|
||||
|
@ -281,9 +265,8 @@ for sec in range(NUM_SECTORS):
|
|||
cmd = f"hf mf fchk --blk {sec * 4} -{kt} -f {dic} --no-default"
|
||||
if args.debug:
|
||||
print(cmd)
|
||||
with out:
|
||||
p.console(cmd)
|
||||
for line in out.captured_output.split('\n'):
|
||||
p.console(cmd)
|
||||
for line in p.grabbed_output.split('\n'):
|
||||
if "aborted via keyboard" in line:
|
||||
abort = True
|
||||
if "found:" in line:
|
||||
|
@ -324,9 +307,8 @@ for sec in range(NUM_SECTORS):
|
|||
cmd += f" -k {k}"
|
||||
if args.debug:
|
||||
print(cmd)
|
||||
with out:
|
||||
p.console(cmd)
|
||||
for line in out.captured_output.split('\n'):
|
||||
p.console(cmd)
|
||||
for line in p.grabbed_output.split('\n'):
|
||||
if "aborted via keyboard" in line:
|
||||
abort = True
|
||||
if "found:" in line:
|
||||
|
@ -338,8 +320,8 @@ for sec in range(NUM_SECTORS):
|
|||
if abort:
|
||||
break
|
||||
if restore_color:
|
||||
with out:
|
||||
p.console("prefs set color --ansi")
|
||||
p.console("prefs set color --ansi")
|
||||
_ = p.grabbed_output
|
||||
|
||||
if abort:
|
||||
print("Brute-forcing phase aborted via keyboard!")
|
||||
|
@ -389,10 +371,7 @@ else:
|
|||
cmd = f"hf mf fchk -f keys_{uid:08x}.dic --no-default --dump"
|
||||
if args.debug:
|
||||
print(cmd)
|
||||
with out:
|
||||
p.console(cmd)
|
||||
for line in out.captured_output.split('\n'):
|
||||
print(line)
|
||||
p.console(cmd, passthru = True)
|
||||
|
||||
elapsed_time = time.time() - start_time
|
||||
minutes = int(elapsed_time // 60)
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
import os
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
|
||||
# From https://stackoverflow.com/a/29834357
|
||||
class OutputGrabber(object):
|
||||
"""
|
||||
Class used to grab standard output or another stream.
|
||||
"""
|
||||
escape_char = "\b"
|
||||
|
||||
def __init__(self, stream=None, threaded=False):
|
||||
self.origstream = stream
|
||||
self.threaded = threaded
|
||||
if self.origstream is None:
|
||||
self.origstream = sys.stdout
|
||||
self.origstreamfd = self.origstream.fileno()
|
||||
self.captured_output = ""
|
||||
|
||||
def __enter__(self):
|
||||
self.start()
|
||||
return self
|
||||
|
||||
def __exit__(self, type, value, traceback):
|
||||
self.stop()
|
||||
|
||||
def start(self):
|
||||
"""
|
||||
Start capturing the stream data.
|
||||
"""
|
||||
self.captured_output = ""
|
||||
# Create a pipe so the stream can be captured:
|
||||
self.pipe_out, self.pipe_in = os.pipe()
|
||||
# Save a copy of the stream:
|
||||
self.streamfd = os.dup(self.origstreamfd)
|
||||
# Replace the original stream with our write pipe:
|
||||
os.dup2(self.pipe_in, self.origstreamfd)
|
||||
if self.threaded:
|
||||
# Start thread that will read the stream:
|
||||
self.workerThread = threading.Thread(target=self.readOutput)
|
||||
self.workerThread.start()
|
||||
# Make sure that the thread is running and os.read() has executed:
|
||||
time.sleep(0.01)
|
||||
|
||||
def stop(self):
|
||||
"""
|
||||
Stop capturing the stream data and save the text in `captured_output`.
|
||||
"""
|
||||
# Print the escape character to make the readOutput method stop:
|
||||
self.origstream.write(self.escape_char)
|
||||
# Flush the stream to make sure all our data goes in before
|
||||
# the escape character:
|
||||
self.origstream.flush()
|
||||
if self.threaded:
|
||||
# wait until the thread finishes so we are sure that
|
||||
# we have until the last character:
|
||||
self.workerThread.join()
|
||||
else:
|
||||
self.readOutput()
|
||||
# Close the pipe:
|
||||
os.close(self.pipe_in)
|
||||
os.close(self.pipe_out)
|
||||
# Restore the original stream:
|
||||
os.dup2(self.streamfd, self.origstreamfd)
|
||||
# Close the duplicate stream:
|
||||
os.close(self.streamfd)
|
||||
|
||||
def readOutput(self):
|
||||
"""
|
||||
Read the stream data (one byte at a time)
|
||||
and save the text in `captured_output`.
|
||||
"""
|
||||
while True:
|
||||
char = os.read(self.pipe_out,1).decode(self.origstream.encoding, errors='replace')
|
||||
if not char or self.escape_char in char:
|
||||
break
|
||||
self.captured_output += char
|
||||
|
||||
if __name__ == "__main__":
|
||||
print("This is a library, don't use it as a script")
|
|
@ -1,13 +1,10 @@
|
|||
# This file was automatically generated by SWIG (http://www.swig.org).
|
||||
# Version 4.0.2
|
||||
# This file was automatically generated by SWIG (https://www.swig.org).
|
||||
# Version 4.2.1
|
||||
#
|
||||
# Do not make changes to this file unless you know what you are doing--modify
|
||||
# Do not make changes to this file unless you know what you are doing - modify
|
||||
# the SWIG interface file instead.
|
||||
|
||||
from sys import version_info as _swig_python_version_info
|
||||
if _swig_python_version_info < (2, 7, 0):
|
||||
raise RuntimeError("Python 2.7 or later required")
|
||||
|
||||
# Import the low-level C/C++ module
|
||||
if __package__ or "." in __name__:
|
||||
from . import _pm3
|
||||
|
@ -29,10 +26,10 @@ def _swig_repr(self):
|
|||
|
||||
def _swig_setattr_nondynamic_instance_variable(set):
|
||||
def set_instance_attr(self, name, value):
|
||||
if name == "thisown":
|
||||
self.this.own(value)
|
||||
elif name == "this":
|
||||
if name == "this":
|
||||
set(self, name, value)
|
||||
elif name == "thisown":
|
||||
self.this.own(value)
|
||||
elif hasattr(self, name) and isinstance(getattr(type(self), name), property):
|
||||
set(self, name, value)
|
||||
else:
|
||||
|
@ -69,9 +66,10 @@ class pm3(object):
|
|||
_pm3.pm3_swiginit(self, _pm3.new_pm3(*args))
|
||||
__swig_destroy__ = _pm3.delete_pm3
|
||||
|
||||
def console(self, cmd):
|
||||
return _pm3.pm3_console(self, cmd)
|
||||
def console(self, cmd, passthru=False):
|
||||
return _pm3.pm3_console(self, cmd, passthru)
|
||||
name = property(_pm3.pm3_name_get)
|
||||
grabbed_output = property(_pm3.pm3_grabbed_output_get)
|
||||
|
||||
# Register pm3 in _pm3:
|
||||
_pm3.pm3_swigregister(pm3)
|
||||
|
|
|
@ -53,18 +53,32 @@ void pm3_close(pm3_device_t *dev) {
|
|||
msleep(100); // Make sure command is sent before killing client
|
||||
CloseProxmark(dev);
|
||||
}
|
||||
free_grabber();
|
||||
}
|
||||
|
||||
int pm3_console(pm3_device_t *dev, const char *cmd) {
|
||||
int pm3_console(pm3_device_t *dev, const char *cmd, bool passthru) {
|
||||
// For now, there is no real device context:
|
||||
(void) dev;
|
||||
return CommandReceived(cmd);
|
||||
uint8_t prev_printAndLog = g_printAndLog;
|
||||
if (! passthru) {
|
||||
g_printAndLog |= PRINTANDLOG_GRAB;
|
||||
g_printAndLog &= ~PRINTANDLOG_PRINT;
|
||||
}
|
||||
int ret = CommandReceived(cmd);
|
||||
g_printAndLog = prev_printAndLog;
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char *pm3_name_get(pm3_device_t *dev) {
|
||||
return dev->g_conn->serial_port_name;
|
||||
}
|
||||
|
||||
const char *pm3_grabbed_output_get(pm3_device_t *dev) {
|
||||
char *tmp = g_grabbed_output.ptr;
|
||||
g_grabbed_output.idx = 0;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
pm3_device_t *pm3_get_current_dev(void) {
|
||||
return g_session.current_device;
|
||||
}
|
||||
|
|
|
@ -8,6 +8,13 @@
|
|||
/* Strip "pm3_" from API functions for SWIG */
|
||||
%rename("%(strip:[pm3_])s") "";
|
||||
%feature("immutable","1") pm3_current_dev;
|
||||
|
||||
#ifdef PYWRAP
|
||||
#include <Python.h>
|
||||
%typemap(default) bool passthru {
|
||||
$1 = Py_False;
|
||||
}
|
||||
#endif
|
||||
typedef struct {
|
||||
%extend {
|
||||
pm3() {
|
||||
|
@ -30,8 +37,9 @@ typedef struct {
|
|||
pm3_close($self);
|
||||
}
|
||||
}
|
||||
int console(char *cmd);
|
||||
int console(char *cmd, bool passthru = false);
|
||||
char const * const name;
|
||||
char const * const grabbed_output;
|
||||
}
|
||||
} pm3;
|
||||
//%nodefaultctor device;
|
||||
|
|
|
@ -2768,18 +2768,23 @@ static int _wrap_pm3_console(lua_State *L) {
|
|||
int SWIG_arg = 0;
|
||||
pm3 *arg1 = (pm3 *) 0 ;
|
||||
char *arg2 = (char *) 0 ;
|
||||
bool arg3 = (bool) false ;
|
||||
int result;
|
||||
|
||||
SWIG_check_num_args("pm3::console", 2, 2)
|
||||
SWIG_check_num_args("pm3::console", 2, 3)
|
||||
if (!SWIG_isptrtype(L, 1)) SWIG_fail_arg("pm3::console", 1, "pm3 *");
|
||||
if (!SWIG_lua_isnilstring(L, 2)) SWIG_fail_arg("pm3::console", 2, "char *");
|
||||
if (lua_gettop(L) >= 3 && !lua_isboolean(L, 3)) SWIG_fail_arg("pm3::console", 3, "bool");
|
||||
|
||||
if (!SWIG_IsOK(SWIG_ConvertPtr(L, 1, (void **)&arg1, SWIGTYPE_p_pm3, 0))) {
|
||||
SWIG_fail_ptr("pm3_console", 1, SWIGTYPE_p_pm3);
|
||||
}
|
||||
|
||||
arg2 = (char *)lua_tostring(L, 2);
|
||||
result = (int)pm3_console(arg1, arg2);
|
||||
if (lua_gettop(L) >= 3) {
|
||||
arg3 = (lua_toboolean(L, 3) != 0);
|
||||
}
|
||||
result = (int)pm3_console(arg1, arg2, arg3);
|
||||
lua_pushnumber(L, (lua_Number) result);
|
||||
SWIG_arg++;
|
||||
return SWIG_arg;
|
||||
|
@ -2815,6 +2820,30 @@ fail:
|
|||
}
|
||||
|
||||
|
||||
static int _wrap_pm3_grabbed_output_get(lua_State *L) {
|
||||
int SWIG_arg = 0;
|
||||
pm3 *arg1 = (pm3 *) 0 ;
|
||||
char *result = 0 ;
|
||||
|
||||
SWIG_check_num_args("pm3::grabbed_output", 1, 1)
|
||||
if (!SWIG_isptrtype(L, 1)) SWIG_fail_arg("pm3::grabbed_output", 1, "pm3 *");
|
||||
|
||||
if (!SWIG_IsOK(SWIG_ConvertPtr(L, 1, (void **)&arg1, SWIGTYPE_p_pm3, 0))) {
|
||||
SWIG_fail_ptr("pm3_grabbed_output_get", 1, SWIGTYPE_p_pm3);
|
||||
}
|
||||
|
||||
result = (char *)pm3_grabbed_output_get(arg1);
|
||||
lua_pushstring(L, (const char *)result);
|
||||
SWIG_arg++;
|
||||
return SWIG_arg;
|
||||
|
||||
fail:
|
||||
SWIGUNUSED;
|
||||
lua_error(L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void swig_delete_pm3(void *obj) {
|
||||
pm3 *arg1 = (pm3 *) obj;
|
||||
delete_pm3(arg1);
|
||||
|
@ -2829,6 +2858,7 @@ static int _proxy__wrap_new_pm3(lua_State *L) {
|
|||
}
|
||||
static swig_lua_attribute swig_pm3_attributes[] = {
|
||||
{ "name", _wrap_pm3_name_get, SWIG_Lua_set_immutable },
|
||||
{ "grabbed_output", _wrap_pm3_grabbed_output_get, SWIG_Lua_set_immutable },
|
||||
{0, 0, 0}
|
||||
};
|
||||
static swig_lua_method swig_pm3_methods[] = {
|
||||
|
|
|
@ -3270,6 +3270,149 @@ SWIGINTERN void delete_pm3(pm3 *self) {
|
|||
}
|
||||
}
|
||||
|
||||
SWIGINTERN int
|
||||
SWIG_AsVal_double(PyObject *obj, double *val) {
|
||||
int res = SWIG_TypeError;
|
||||
if (PyFloat_Check(obj)) {
|
||||
if (val) *val = PyFloat_AsDouble(obj);
|
||||
return SWIG_OK;
|
||||
#if PY_VERSION_HEX < 0x03000000
|
||||
} else if (PyInt_Check(obj)) {
|
||||
if (val) *val = (double) PyInt_AsLong(obj);
|
||||
return SWIG_OK;
|
||||
#endif
|
||||
} else if (PyLong_Check(obj)) {
|
||||
double v = PyLong_AsDouble(obj);
|
||||
if (!PyErr_Occurred()) {
|
||||
if (val) *val = v;
|
||||
return SWIG_OK;
|
||||
} else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
#ifdef SWIG_PYTHON_CAST_MODE
|
||||
{
|
||||
int dispatch = 0;
|
||||
double d = PyFloat_AsDouble(obj);
|
||||
if (!PyErr_Occurred()) {
|
||||
if (val) *val = d;
|
||||
return SWIG_AddCast(SWIG_OK);
|
||||
} else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
if (!dispatch) {
|
||||
long v = PyLong_AsLong(obj);
|
||||
if (!PyErr_Occurred()) {
|
||||
if (val) *val = v;
|
||||
return SWIG_AddCast(SWIG_AddCast(SWIG_OK));
|
||||
} else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
#include <float.h>
|
||||
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
||||
SWIGINTERNINLINE int
|
||||
SWIG_CanCastAsInteger(double *d, double min, double max) {
|
||||
double x = *d;
|
||||
if ((min <= x && x <= max)) {
|
||||
double fx, cx, rd;
|
||||
errno = 0;
|
||||
fx = floor(x);
|
||||
cx = ceil(x);
|
||||
rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */
|
||||
if ((errno == EDOM) || (errno == ERANGE)) {
|
||||
errno = 0;
|
||||
} else {
|
||||
double summ, reps, diff;
|
||||
if (rd < x) {
|
||||
diff = x - rd;
|
||||
} else if (rd > x) {
|
||||
diff = rd - x;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
summ = rd + x;
|
||||
reps = diff / summ;
|
||||
if (reps < 8 * DBL_EPSILON) {
|
||||
*d = rd;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
SWIGINTERN int
|
||||
SWIG_AsVal_long(PyObject *obj, long *val) {
|
||||
#if PY_VERSION_HEX < 0x03000000
|
||||
if (PyInt_Check(obj)) {
|
||||
if (val) *val = PyInt_AsLong(obj);
|
||||
return SWIG_OK;
|
||||
} else
|
||||
#endif
|
||||
if (PyLong_Check(obj)) {
|
||||
long v = PyLong_AsLong(obj);
|
||||
if (!PyErr_Occurred()) {
|
||||
if (val) *val = v;
|
||||
return SWIG_OK;
|
||||
} else {
|
||||
PyErr_Clear();
|
||||
return SWIG_OverflowError;
|
||||
}
|
||||
}
|
||||
#ifdef SWIG_PYTHON_CAST_MODE
|
||||
{
|
||||
int dispatch = 0;
|
||||
long v = PyInt_AsLong(obj);
|
||||
if (!PyErr_Occurred()) {
|
||||
if (val) *val = v;
|
||||
return SWIG_AddCast(SWIG_OK);
|
||||
} else {
|
||||
PyErr_Clear();
|
||||
}
|
||||
if (!dispatch) {
|
||||
double d;
|
||||
int res = SWIG_AddCast(SWIG_AsVal_double(obj, &d));
|
||||
// Largest double not larger than LONG_MAX (not portably calculated easily)
|
||||
// Note that double(LONG_MAX) is stored in a double rounded up by one (for 64-bit long)
|
||||
// 0x7ffffffffffffc00LL == (int64_t)std::nextafter(double(__uint128_t(LONG_MAX)+1), double(0))
|
||||
const double long_max = sizeof(long) == 8 ? 0x7ffffffffffffc00LL : LONG_MAX;
|
||||
// No equivalent needed for 64-bit double(LONG_MIN) is exactly LONG_MIN
|
||||
if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, long_max)) {
|
||||
if (val) *val = (long)(d);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return SWIG_TypeError;
|
||||
}
|
||||
|
||||
|
||||
SWIGINTERN int
|
||||
SWIG_AsVal_bool(PyObject *obj, bool *val) {
|
||||
int r;
|
||||
if (!PyBool_Check(obj))
|
||||
return SWIG_ERROR;
|
||||
r = PyObject_IsTrue(obj);
|
||||
if (r == -1)
|
||||
return SWIG_ERROR;
|
||||
if (val) *val = r ? true : false;
|
||||
return SWIG_OK;
|
||||
}
|
||||
|
||||
|
||||
SWIGINTERNINLINE PyObject *
|
||||
SWIG_From_int(int value) {
|
||||
return PyInt_FromLong((long) value);
|
||||
|
@ -3403,16 +3546,19 @@ SWIGINTERN PyObject *_wrap_pm3_console(PyObject *self, PyObject *args) {
|
|||
PyObject *resultobj = 0;
|
||||
pm3 *arg1 = (pm3 *) 0 ;
|
||||
char *arg2 = (char *) 0 ;
|
||||
bool arg3 = (bool) false ;
|
||||
void *argp1 = 0 ;
|
||||
int res1 = 0 ;
|
||||
int res2 ;
|
||||
char *buf2 = 0 ;
|
||||
int alloc2 = 0 ;
|
||||
PyObject *swig_obj[2] ;
|
||||
bool val3 ;
|
||||
int ecode3 = 0 ;
|
||||
PyObject *swig_obj[3] ;
|
||||
int result;
|
||||
|
||||
(void)self;
|
||||
if (!SWIG_Python_UnpackTuple(args, "pm3_console", 2, 2, swig_obj)) SWIG_fail;
|
||||
if (!SWIG_Python_UnpackTuple(args, "pm3_console", 2, 3, swig_obj)) SWIG_fail;
|
||||
res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_pm3, 0 | 0);
|
||||
if (!SWIG_IsOK(res1)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pm3_console" "', argument " "1"" of type '" "pm3 *""'");
|
||||
|
@ -3423,7 +3569,14 @@ SWIGINTERN PyObject *_wrap_pm3_console(PyObject *self, PyObject *args) {
|
|||
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "pm3_console" "', argument " "2"" of type '" "char *""'");
|
||||
}
|
||||
arg2 = (char *)(buf2);
|
||||
result = (int)pm3_console(arg1, arg2);
|
||||
if (swig_obj[2]) {
|
||||
ecode3 = SWIG_AsVal_bool(swig_obj[2], &val3);
|
||||
if (!SWIG_IsOK(ecode3)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(ecode3), "in method '" "pm3_console" "', argument " "3"" of type '" "bool""'");
|
||||
}
|
||||
arg3 = (bool)(val3);
|
||||
}
|
||||
result = (int)pm3_console(arg1, arg2, arg3);
|
||||
resultobj = SWIG_From_int((int)(result));
|
||||
if (alloc2 == SWIG_NEWOBJ) free((char *)buf2);
|
||||
return resultobj;
|
||||
|
@ -3457,6 +3610,30 @@ fail:
|
|||
}
|
||||
|
||||
|
||||
SWIGINTERN PyObject *_wrap_pm3_grabbed_output_get(PyObject *self, PyObject *args) {
|
||||
PyObject *resultobj = 0;
|
||||
pm3 *arg1 = (pm3 *) 0 ;
|
||||
void *argp1 = 0 ;
|
||||
int res1 = 0 ;
|
||||
PyObject *swig_obj[1] ;
|
||||
char *result = 0 ;
|
||||
|
||||
(void)self;
|
||||
if (!args) SWIG_fail;
|
||||
swig_obj[0] = args;
|
||||
res1 = SWIG_ConvertPtr(swig_obj[0], &argp1, SWIGTYPE_p_pm3, 0 | 0);
|
||||
if (!SWIG_IsOK(res1)) {
|
||||
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "pm3_grabbed_output_get" "', argument " "1"" of type '" "pm3 *""'");
|
||||
}
|
||||
arg1 = (pm3 *)(argp1);
|
||||
result = (char *)pm3_grabbed_output_get(arg1);
|
||||
resultobj = SWIG_FromCharPtr((const char *)result);
|
||||
return resultobj;
|
||||
fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
SWIGINTERN PyObject *pm3_swigregister(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
|
||||
PyObject *obj;
|
||||
if (!SWIG_Python_UnpackTuple(args, "swigregister", 1, 1, &obj)) return NULL;
|
||||
|
@ -3473,6 +3650,7 @@ static PyMethodDef SwigMethods[] = {
|
|||
{ "delete_pm3", _wrap_delete_pm3, METH_O, NULL},
|
||||
{ "pm3_console", _wrap_pm3_console, METH_VARARGS, NULL},
|
||||
{ "pm3_name_get", _wrap_pm3_name_get, METH_O, NULL},
|
||||
{ "pm3_grabbed_output_get", _wrap_pm3_grabbed_output_get, METH_O, NULL},
|
||||
{ "pm3_swigregister", pm3_swigregister, METH_O, NULL},
|
||||
{ "pm3_swiginit", pm3_swiginit, METH_VARARGS, NULL},
|
||||
{ NULL, NULL, 0, NULL }
|
||||
|
|
|
@ -553,7 +553,7 @@ check_script:
|
|||
if (cmd[0] != '\0') {
|
||||
uint8_t old_printAndLog = g_printAndLog;
|
||||
if (!printprompt) {
|
||||
g_printAndLog &= PRINTANDLOG_LOG;
|
||||
g_printAndLog &= ~PRINTANDLOG_PRINT;
|
||||
}
|
||||
char prompt[PROXPROMPT_MAX_SIZE] = {0};
|
||||
prompt_compose(prompt, sizeof(prompt), prompt_ctx, prompt_dev, prompt_net, true);
|
||||
|
@ -1462,6 +1462,8 @@ int main(int argc, char *argv[]) {
|
|||
preferences_save();
|
||||
}
|
||||
|
||||
free_grabber();
|
||||
|
||||
return mainret;
|
||||
}
|
||||
#endif //LIBPM3
|
||||
|
|
|
@ -168,6 +168,33 @@ int searchHomeFilePath(char **foundpath, const char *subdir, const char *filenam
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
void free_grabber(void) {
|
||||
free(g_grabbed_output.ptr);
|
||||
g_grabbed_output.ptr = NULL;
|
||||
g_grabbed_output.size = 0;
|
||||
g_grabbed_output.idx = 0;
|
||||
}
|
||||
|
||||
static void fill_grabber(const char *string) {
|
||||
if (g_grabbed_output.ptr == NULL || g_grabbed_output.size - g_grabbed_output.idx < MAX_PRINT_BUFFER) {
|
||||
char *tmp = realloc(g_grabbed_output.ptr, g_grabbed_output.size + MAX_PRINT_BUFFER);
|
||||
if (tmp == NULL) {
|
||||
// We leave current g_grabbed_output untouched
|
||||
PrintAndLogEx(ERR, "Out of memory error in fill_grabber()");
|
||||
return;
|
||||
}
|
||||
g_grabbed_output.ptr = tmp;
|
||||
g_grabbed_output.size += MAX_PRINT_BUFFER;
|
||||
}
|
||||
int len = snprintf(g_grabbed_output.ptr + g_grabbed_output.idx, MAX_PRINT_BUFFER, "%s", string);
|
||||
if (len < 0 || len > MAX_PRINT_BUFFER) {
|
||||
// We leave current g_grabbed_output_len untouched
|
||||
PrintAndLogEx(ERR, "snprintf error in fill_grabber()");
|
||||
return;
|
||||
}
|
||||
g_grabbed_output.idx += len;
|
||||
}
|
||||
|
||||
void PrintAndLogOptions(const char *str[][2], size_t size, size_t space) {
|
||||
char buff[2000] = "Options:\n";
|
||||
char format[2000] = "";
|
||||
|
@ -299,12 +326,15 @@ void PrintAndLogEx(logLevel_t level, const char *fmt, ...) {
|
|||
} else {
|
||||
snprintf(buffer2, sizeof(buffer2), "%s%s", prefix, buffer);
|
||||
if (level == INPLACE) {
|
||||
char buffer3[sizeof(buffer2)] = {0};
|
||||
char buffer4[sizeof(buffer2)] = {0};
|
||||
memcpy_filter_ansi(buffer3, buffer2, sizeof(buffer2), !g_session.supports_colors);
|
||||
memcpy_filter_emoji(buffer4, buffer3, sizeof(buffer3), g_session.emoji_mode);
|
||||
fprintf(stream, "\r%s", buffer4);
|
||||
fflush(stream);
|
||||
// ignore INPLACE if rest of output is grabbed
|
||||
if (!(g_printAndLog & PRINTANDLOG_GRAB)) {
|
||||
char buffer3[sizeof(buffer2)] = {0};
|
||||
char buffer4[sizeof(buffer2)] = {0};
|
||||
memcpy_filter_ansi(buffer3, buffer2, sizeof(buffer2), !g_session.supports_colors);
|
||||
memcpy_filter_emoji(buffer4, buffer3, sizeof(buffer3), g_session.emoji_mode);
|
||||
fprintf(stream, "\r%s", buffer4);
|
||||
fflush(stream);
|
||||
}
|
||||
} else {
|
||||
fPrintAndLog(stream, "%s", buffer2);
|
||||
}
|
||||
|
@ -401,18 +431,32 @@ static void fPrintAndLog(FILE *stream, const char *fmt, ...) {
|
|||
}
|
||||
#endif
|
||||
|
||||
if ((g_printAndLog & PRINTANDLOG_LOG) && logging && logfile) {
|
||||
if (((g_printAndLog & PRINTANDLOG_LOG) && logging && logfile) ||
|
||||
(g_printAndLog & PRINTANDLOG_GRAB)) {
|
||||
memcpy_filter_emoji(buffer3, buffer2, sizeof(buffer2), EMO_ALTTEXT);
|
||||
if (filter_ansi) { // already done
|
||||
if (!filter_ansi) {
|
||||
memcpy_filter_ansi(buffer, buffer3, sizeof(buffer3), true);
|
||||
}
|
||||
}
|
||||
if ((g_printAndLog & PRINTANDLOG_LOG) && logging && logfile) {
|
||||
if (filter_ansi) {
|
||||
fprintf(logfile, "%s", buffer3);
|
||||
} else {
|
||||
memcpy_filter_ansi(buffer, buffer3, sizeof(buffer3), true);
|
||||
fprintf(logfile, "%s", buffer);
|
||||
}
|
||||
if (linefeed)
|
||||
fprintf(logfile, "\n");
|
||||
fflush(logfile);
|
||||
}
|
||||
if (g_printAndLog & PRINTANDLOG_GRAB) {
|
||||
if (filter_ansi) {
|
||||
fill_grabber(buffer3);
|
||||
} else {
|
||||
fill_grabber(buffer);
|
||||
}
|
||||
if (linefeed)
|
||||
fill_grabber("\n");
|
||||
}
|
||||
|
||||
if (flushAfterWrite)
|
||||
fflush(stdout);
|
||||
|
|
|
@ -80,6 +80,7 @@ bool GetFlushAfterWrite(void);
|
|||
void memcpy_filter_ansi(void *dest, const void *src, size_t n, bool filter);
|
||||
void memcpy_filter_rlmarkers(void *dest, const void *src, size_t n);
|
||||
void memcpy_filter_emoji(void *dest, const void *src, size_t n, emojiMode_t mode);
|
||||
void free_grabber(void);
|
||||
|
||||
int searchHomeFilePath(char **foundpath, const char *subdir, const char *filename, bool create_home);
|
||||
|
||||
|
|
|
@ -36,8 +36,10 @@
|
|||
#define UTIL_BUFFER_SIZE_SPRINT 8196
|
||||
// global client debug variable
|
||||
uint8_t g_debugMode = 0;
|
||||
// global client disable logging variable
|
||||
// global client enable/disable printing/logging/grabbing variable
|
||||
uint8_t g_printAndLog = PRINTANDLOG_PRINT | PRINTANDLOG_LOG;
|
||||
// global pointer to grabbed output
|
||||
grabbed_output g_grabbed_output = {NULL, 0, 0};
|
||||
// global client tell if a pending prompt is present
|
||||
bool g_pendingPrompt = false;
|
||||
// global CPU core count override
|
||||
|
|
|
@ -34,8 +34,16 @@ extern uint8_t g_printAndLog;
|
|||
extern bool g_pendingPrompt;
|
||||
extern int g_numCPUs;
|
||||
|
||||
typedef struct {
|
||||
char *ptr;
|
||||
size_t size;
|
||||
size_t idx;
|
||||
} grabbed_output;
|
||||
extern grabbed_output g_grabbed_output;
|
||||
|
||||
#define PRINTANDLOG_PRINT 1
|
||||
#define PRINTANDLOG_LOG 2
|
||||
#define PRINTANDLOG_GRAB 4
|
||||
|
||||
// Return error
|
||||
#define PM3_RET_ERR(err, ...) { \
|
||||
|
|
|
@ -12813,6 +12813,6 @@
|
|||
"metadata": {
|
||||
"commands_extracted": 740,
|
||||
"extracted_by": "PM3Help2JSON v1.00",
|
||||
"extracted_on": "2024-08-14T08:56:40"
|
||||
"extracted_on": "2024-08-14T11:49:06"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue