RfidResearchGroup / proxmark3

Iceman Fork - Proxmark3
http://www.icedev.se
GNU General Public License v3.0
3.72k stars 998 forks source link

SWIG revolución #897

Open doegox opened 4 years ago

doegox commented 4 years ago

Issue to track ideas, progress and tasks to

First PoC tests on https://github.com/RfidResearchGroup/proxmark3/tree/libpm3_experiments Current compilation paths to keep an eye on:

Next steps:

doegox commented 4 years ago

unified API is maintained in client/include/ SWIG will not be required for ppl to compile the repo. We'll take care that when updating API, we generate the SWIG artefacts and push them on the repo (currently: client/src/libpm3_luawrap.c , client/src/libpm3_pywrap.c and client/src/libpm3.py)

iceman1001 commented 4 years ago

Yes,

We will be able to use "printandlog" fcts to catch most of pm3 output and return to the external API calls. I suppose setting a flag, we enable the "copy output" while running. Or the py / lua needs to redirect stdout,stderror to catch it.

I think we start with three simple ftcs to expose from our API to start with. No need to over do it. Lua wrap doesn't have more than a dozen api fcts hooked up. Some crc/mac/crypto. The next fourth fcts would be "sending usbcommand / receive". That should be many happy for a long time. The rest can come later if community makes an effort.

The exposed API fcts should be in a mature state. ie, not prone to change.
Even if SWIG makes it easy, I don't want to change the API all the time.

doegox commented 4 years ago

yes good point on API stability.

doegox commented 4 years ago

Thinking a bit ahead, we should have also:

iceman1001 commented 4 years ago

Indeed, the openproxmark, could take a string with "/dev/acm01" etc, which would give the possibility to connect to several proxmarks. Nevertheless, I think this is too far off yet. I tend to take bites of a problem and make that work.

slurdge commented 4 years ago

proxmark3+jupyter=💖💖💖

iceman1001 commented 4 years ago

...looks like we got someones attention.... Where is that lz4 ;)

doegox commented 4 years ago

Indeed, the openproxmark, could take a string with "/dev/acm01" etc, which would give the possibility to connect to several proxmarks. Nevertheless, I think this is too far off yet. I tend to take bites of a problem and make that work.

I was not thinking of the client itself, rather the lib and API. Such that from a script you could do

import pm3
a=pm3.open("/dev/ttyACM0")
b=pm3.open("/dev/ttyACM1")
a.cmd("hw status")
b.cmd("hw status")

etc

iceman1001 commented 4 years ago

yes, that is what I ment.

doegox commented 4 years ago

Here is what we have in the current experimental branch:

Embedded Lua:

local pm3 = require("pm3")
p=pm3.get_current_dev()
pm3.console(p, "hw status")

Embedded Python:

import pm3
p=pm3.get_current_dev()
pm3.console(p, "hw status")

External Lua using libpm3:

local pm3 = require("pm3")
p=pm3.open("/dev/ttyACM0")
pm3.console(p, "hw status")
pm3.close(p)

External Python using libpm3:

import pm3
p=pm3.open("/dev/ttyACM0")
pm3.console(p, "hw status")
pm3.close(p)

External C using libpm3:

#include "pm3.h"

int main(int argc, char *argv[]) {
    pm3_device *p;
    p = pm3_open("/dev/ttyACM0");
    pm3_console(p, "hw status");
    pm3_close(p);
}

Proxmark3 client and libpm3 are still two separated entities that will need to converge into a lightweight client using libpm3.

Note: it doesn't support several devices for real yet but at least the API is ready for it.

iceman1001 commented 4 years ago

ok, after context everywhere, I give in, session -> context.

slurdge commented 4 years ago

For Python & LUA, shouldn't the API give an "object" that is a proxmark instance? Like this:

import pm3
with pm3.open("/dev/ttyACM0") as p:
    p.console("hw status")

I guess this is what @doegox has in mind. Also, do you want each lib (python, lua etc.) create the higher level wrappers themselves? I would think of something along the lines:

with pm3.open("/dev/ttyACM0") as p:
   p.hw.status() #gives you a string
   p.hf.search()

But it would mean SWIG is able to create objects across scripting languages... not sure about it. Its easy to create the overall wrapper but it would mean having it in sync with underlying API.

doegox commented 4 years ago

yes the Python wrapper would be more pythonesque the way you propose. For me the questions are:

Note that the console("hw status") is just the start, to have quick access to the existing fcts, in the future we should get more real functions APIs, e.g. int hw_status(void); called by CLI parser and by swig API.

iceman1001 commented 4 years ago

Lets keep things simple. We take what SWIG offers out of the box. That keeps it easy to maintain. If pattern is the same across engine api, ppl feel acustomed. Looks the same, behavies the same.

As @doegox mentions, in later stages, exposing more and more fcts. Right now thats not the purpose of this exercise.

doegox commented 4 years ago

After some rework thanks to @slurdge here is what we have in the current experimental branch:

Embedded Lua:

local pm3 = require("pm3")
p=pm3.pm3()
p:console("hw status")
print(p.name)

Embedded Python:

import pm3
p=pm3.pm3()
p.console("hw status")
print("Device:", p.name)

External Lua using libpm3:

local pm3 = require("pm3")
p=pm3.pm3("/dev/ttyACM0")
p:console("hw status")
print(p.name)

External Python using libpm3:

import pm3
p=pm3.pm3("/dev/ttyACM0")
p.console("hw status")
print("Device:", p.name)

External C using libpm3:

#include "pm3.h"

int main(int argc, char *argv[]) {
    pm3 *p;
    p = pm3_open("/dev/ttyACM0");
    pm3_console(p, "hw status");
    pm3_close(p);
}
iceman1001 commented 4 years ago

Its some nice progress.

snowsign commented 1 year ago

Any updates on this? It's been a few years and there still isn't a consistent Python/Lua API. Python scripts run through the client currently need to rely on the serial port, which isn't possible when running through the client due to locking.

iceman1001 commented 1 year ago

No active work is going on. Feel free to pick up and complete it!