From: martin.holst@gmail.com <martin.holst@gmail.com@ef4ab9da-24cd-11de-8aaa-f3a34680c41f> Date: Sun, 26 May 2013 20:05:13 +0000 (+0000) Subject: Added binlib, to handle binary data from lua, based on lpack http://www.tecgraf.puc... X-Git-Tag: v1.0.0~80^2~28 X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/f057bddb70733c45eb6110b48df944d01a4be864 Added binlib, to handle binary data from lua, based on lpack http://www.tecgraf.puc-rio.br/~lhf/ftp/lua/#lpack --- diff --git a/client/Makefile b/client/Makefile index 5b6f4e83..71da64fd 100644 --- a/client/Makefile +++ b/client/Makefile @@ -73,6 +73,7 @@ CMDSRCS = nonce2key/crapto1.c\ cmdmain.c \ cmdlft55xx.c \ cmdlfpcf7931.c\ + pm3_binlib.c\ scripting.c\ cmdscript.c\ diff --git a/client/cmdscript.c b/client/cmdscript.c index bd4a3006..86cb91b4 100644 --- a/client/cmdscript.c +++ b/client/cmdscript.c @@ -24,6 +24,7 @@ #include "cmdmain.h" #include "cmdscript.h" #include "cmdhfmf.h" +#include "pm3_binlib.h" #include <lua.h> #include <lualib.h> @@ -210,6 +211,10 @@ int CmdRun(const char *Cmd) //Sets the 'command line' libraries, basically just the commandline stuff set_cmdlibraries(lua_state); + + //Add the 'bin' library + set_bin_library(lua_state); + char cmd_name[32]; int len = 0; memset(cmd_name, 0, 32); diff --git a/client/pm3_binlib.c b/client/pm3_binlib.c new file mode 100644 index 00000000..e3af7b47 --- /dev/null +++ b/client/pm3_binlib.c @@ -0,0 +1,349 @@ +/* +* lpack.c +* a Lua library for packing and unpacking binary data +* Luiz Henrique de Figueiredo <lhf@tecgraf.puc-rio.br> +* 29 Jun 2007 19:27:20 +* This code is hereby placed in the public domain. +* with contributions from Ignacio Castao <castanyo@yahoo.es> and +* Roberto Ierusalimschy <roberto@inf.puc-rio.br>. +*/ + +#define OP_ZSTRING 'z' /* zero-terminated string */ +#define OP_BSTRING 'p' /* string preceded by length byte */ +#define OP_WSTRING 'P' /* string preceded by length word */ +#define OP_SSTRING 'a' /* string preceded by length size_t */ +#define OP_STRING 'A' /* string */ +#define OP_FLOAT 'f' /* float */ +#define OP_DOUBLE 'd' /* double */ +#define OP_NUMBER 'n' /* Lua number */ +#define OP_CHAR 'c' /* char (1-byte int) */ +#define OP_BYTE 'C' /* byte = unsigned char (1-byte unsigned int) */ +#define OP_SHORT 's' /* short (2-byte int) */ +#define OP_USHORT 'S' /* unsigned short (2-byte unsigned int) */ +#define OP_INT 'i' /* int (4-byte int) */ +#define OP_UINT 'I' /* unsigned int (4-byte unsigned int) */ +#define OP_LONG 'l' /* long (8-byte int) */ +#define OP_ULONG 'L' /* unsigned long (8-byte unsigned int) */ +#define OP_LITTLEENDIAN '<' /* little endian */ +#define OP_BIGENDIAN '>' /* big endian */ +#define OP_NATIVE '=' /* native endian */ + +#define OP_HEX 'H' + +#include <ctype.h> +#include <string.h> +#include <lua.h> +#include <lualib.h> +#include <lauxlib.h> + +#include "pm3_binlib.h" + + +static void badcode(lua_State *L, int c) +{ + char s[]="bad code `?'"; + s[sizeof(s)-3]=c; + luaL_argerror(L,1,s); +} + +static int doendian(int c) +{ + int x=1; + int e=*(char*)&x; + if (c==OP_LITTLEENDIAN) return !e; + if (c==OP_BIGENDIAN) return e; + if (c==OP_NATIVE) return 0; + return 0; +} + +static void doswap(int swap, void *p, size_t n) +{ + if (swap) + { + char *a=(char*)p; + int i,j; + for (i=0, j=n-1, n=n/2; n--; i++, j--) + { + char t=a[i]; a[i]=a[j]; a[j]=t; + } + } +} + +#define UNPACKNUMBER(OP,T) \ + case OP: \ + { \ + T a; \ + int m=sizeof(a); \ + if (i+m>len) { done = 1; break;} \ + memcpy(&a,s+i,m); \ + i+=m; \ + doswap(swap,&a,m); \ + lua_pushnumber(L,(lua_Number)a); \ + ++n; \ + break; \ + } + +#define UNPACKSTRING(OP,T) \ + case OP: \ + { \ + T l; \ + int m=sizeof(l); \ + if (i+m>len) { done = 1; break; } \ + memcpy(&l,s+i,m); \ + doswap(swap,&l,m); \ + if (i+m+l>len) { done = 1; break;} \ + i+=m; \ + lua_pushlstring(L,s+i,l); \ + i+=l; \ + ++n; \ + break; \ + } + +#define HEXDIGITS(DIG) \ + "0123456789ABCDEF"[DIG] + +static int l_unpack(lua_State *L) /** unpack(f,s, [init]) */ +{ + size_t len; + const char *s=luaL_checklstring(L,2,&len); /* switched s and f */ + const char *f=luaL_checkstring(L,1); + int i_read = luaL_optint(L,3,1)-1; + unsigned int i; + if (i_read >= 0) { + i = i_read; + } else { + i = 0; + } + int n=0; + int swap=0; + int done=0; + lua_pushnil(L); + while (*f && done == 0) + { + int c=*f++; + int N=1; + if (isdigit((int) (unsigned char) *f)) + { + N=0; + while (isdigit((int) (unsigned char) *f)) N=10*N+(*f++)-'0'; + if (N==0 && c==OP_STRING) { lua_pushliteral(L,""); ++n; } + } + while (N-- && done == 0) switch (c) + { + case OP_LITTLEENDIAN: + case OP_BIGENDIAN: + case OP_NATIVE: + { + swap=doendian(c); + N=0; + break; + } + case OP_STRING: + { + ++N; + if (i+N>len) {done = 1; break; } + lua_pushlstring(L,s+i,N); + i+=N; + ++n; + N=0; + break; + } + case OP_ZSTRING: + { + size_t l; + if (i>=len) {done = 1; break; } + l=strlen(s+i); + lua_pushlstring(L,s+i,l); + i+=l+1; + ++n; + break; + } + UNPACKSTRING(OP_BSTRING, unsigned char) + UNPACKSTRING(OP_WSTRING, unsigned short) + UNPACKSTRING(OP_SSTRING, size_t) + UNPACKNUMBER(OP_NUMBER, lua_Number) + UNPACKNUMBER(OP_DOUBLE, double) + UNPACKNUMBER(OP_FLOAT, float) + UNPACKNUMBER(OP_CHAR, char) + UNPACKNUMBER(OP_BYTE, unsigned char) + UNPACKNUMBER(OP_SHORT, short) + UNPACKNUMBER(OP_USHORT, unsigned short) + UNPACKNUMBER(OP_INT, int) + UNPACKNUMBER(OP_UINT, unsigned int) + UNPACKNUMBER(OP_LONG, long) + UNPACKNUMBER(OP_ULONG, unsigned long) + case OP_HEX: + { + luaL_Buffer buf; + char hdigit = '0'; + int val = 0; + luaL_buffinit(L,&buf); + N++; + if (i+N > len) {done = 1; break;} + for (unsigned int ii = i; ii < i+N; ii++) { + val = s[ii] & 0xF0; + val = val >> 4; + hdigit = HEXDIGITS(val); + luaL_addlstring(&buf, &hdigit, 1); + + val = s[ii] & 0x0F; + hdigit = HEXDIGITS(val); + luaL_addlstring(&buf, &hdigit, 1); + } + luaL_pushresult(&buf); + n++; + i += N; + N = 0; + break; + } + + case ' ': case ',': + break; + default: + badcode(L,c); + break; + } + } + lua_pushnumber(L,i+1); + lua_replace(L,-n-2); + return n+1; +} + +#define PACKNUMBER(OP,T) \ + case OP: \ + { \ + T a=(T)luaL_checknumber(L,i++); \ + doswap(swap,&a,sizeof(a)); \ + luaL_addlstring(&b,(char*)&a,sizeof(a)); \ + break; \ + } + +#define PACKSTRING(OP,T) \ + case OP: \ + { \ + size_t l; \ + const char *a=luaL_checklstring(L,i++,&l); \ + T ll=(T)l; \ + doswap(swap,&ll,sizeof(ll)); \ + luaL_addlstring(&b,(char*)&ll,sizeof(ll)); \ + luaL_addlstring(&b,a,l); \ + break; \ + } + +static int l_pack(lua_State *L) /** pack(f,...) */ +{ + int i=2; + const char *f=luaL_checkstring(L,1); + int swap=0; + luaL_Buffer b; + luaL_buffinit(L,&b); + while (*f) + { + int c=*f++; + int N=1; + if (isdigit((int) (unsigned char) *f)) + { + N=0; + while (isdigit((int) (unsigned char) *f)) N=10*N+(*f++)-'0'; + } + while (N--) switch (c) + { + case OP_LITTLEENDIAN: + case OP_BIGENDIAN: + case OP_NATIVE: + { + swap=doendian(c); + N=0; + break; + } + case OP_STRING: + case OP_ZSTRING: + { + size_t l; + const char *a=luaL_checklstring(L,i++,&l); + luaL_addlstring(&b,a,l+(c==OP_ZSTRING)); + break; + } + PACKSTRING(OP_BSTRING, unsigned char) + PACKSTRING(OP_WSTRING, unsigned short) + PACKSTRING(OP_SSTRING, size_t) + PACKNUMBER(OP_NUMBER, lua_Number) + PACKNUMBER(OP_DOUBLE, double) + PACKNUMBER(OP_FLOAT, float) + PACKNUMBER(OP_CHAR, char) + PACKNUMBER(OP_BYTE, unsigned char) + PACKNUMBER(OP_SHORT, short) + PACKNUMBER(OP_USHORT, unsigned short) + PACKNUMBER(OP_INT, int) + PACKNUMBER(OP_UINT, unsigned int) + PACKNUMBER(OP_LONG, long) + PACKNUMBER(OP_ULONG, unsigned long) + case OP_HEX: + { // doing digit parsing the lpack way + unsigned char sbyte = 0; + size_t l; + unsigned int ii = 0; + int odd = 0; + const char *a = luaL_checklstring(L, i++, &l); + for (ii = 0; ii < l; ii++) { + if (isxdigit((int) (unsigned char) a[ii])) { + if (isdigit((int) (unsigned char) a[ii])) { + sbyte += a[ii] - '0'; + odd++; + } else if (a[ii] >= 'A' && a[ii] <= 'F') { + sbyte += a[ii] - 'A' + 10; + odd++; + } else if (a[ii] >= 'a' && a[ii] <= 'f') { + sbyte += a[ii] - 'a' + 10; + odd++; + } + if (odd == 1) { + sbyte = sbyte << 4; + } else if (odd == 2) { + luaL_addlstring(&b, (char *) &sbyte, 1); + sbyte = 0; + odd = 0; + } + } else if (isspace(a[ii])) { + /* ignore */ + } else { + /* err ... ignore too*/ + } + } + if (odd == 1) { + luaL_addlstring(&b, (char *) &sbyte, 1); + } + break; + } + case ' ': case ',': + break; + default: + badcode(L,c); + break; + } + } + luaL_pushresult(&b); + return 1; +} + +static const luaL_Reg binlib[] = +{ + {"pack", l_pack}, + {"unpack", l_unpack}, + {NULL, NULL} +}; + +LUALIB_API int luaopen_binlib (lua_State *L) { + luaL_newlib(L, binlib); + return 1; +} +/* +** Open bin library +*/ +int set_bin_library (lua_State *L) { + + luaL_requiref(L, "bin", luaopen_binlib, 1); + lua_pop(L, 1); + return 1; +} + diff --git a/client/pm3_binlib.h b/client/pm3_binlib.h new file mode 100644 index 00000000..e45b0233 --- /dev/null +++ b/client/pm3_binlib.h @@ -0,0 +1,7 @@ +#ifndef PM3_BINLIB +#define PM3_BINLIB + +#include <lua.h> +int set_bin_library (lua_State *L); + +#endif /* PM3_BINLIB */ diff --git a/client/scripting.c b/client/scripting.c index 6db27dc7..331a8877 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -44,7 +44,7 @@ static int l_SendCommand(lua_State *L){ const char *data = luaL_checklstring(L, 1, &size); if(size != sizeof(UsbCommand)) { - printf("Got data size %d, expected %d" , size,sizeof(UsbCommand)); + printf("Got data size %d, expected %d" , (int) size,(int) sizeof(UsbCommand)); lua_pushstring(L,"Wrong data size"); return 1; } @@ -106,7 +106,7 @@ static int l_WaitForResponseTimeout(lua_State *L){ static int l_nonce2key(lua_State *L){ return CmdHF14AMfRdSc(luaL_checkstring(L, 1));} static int l_PrintAndLog(lua_State *L){ return CmdHF14AMfDump(luaL_checkstring(L, 1));} -void set_pm3_libraries(lua_State *L) +int set_pm3_libraries(lua_State *L) { static const luaL_Reg libs[] = { {"SendCommand", l_SendCommand}, diff --git a/client/scripting.h b/client/scripting.h index 58e5359e..89a866bc 100644 --- a/client/scripting.h +++ b/client/scripting.h @@ -18,6 +18,6 @@ * @param L */ -void set_pm3_libraries(lua_State *L); +int set_pm3_libraries(lua_State *L); #endif diff --git a/client/scripts/mifare.lua b/client/scripts/mifare.lua index 174c760e..93837d03 100644 --- a/client/scripts/mifare.lua +++ b/client/scripts/mifare.lua @@ -8,7 +8,30 @@ print("core.SendCommand", core.SendCommand) print("core.WaitForResponseTimeout", core.WaitForResponseTimeout) print("core.nonce2key", core.nonce2key) -- To actually send something meaningful, we need to include the 'Binlib' or 'lpack' library. -local x = core.SendCommand("aaaabbbb2222111100000ggggaaaabbbb2222111100000ggggaaaabbbb2222111100000ggggaaaabbbb2222111100000ggggaaaabbbb2222111100000ggggaaaabbbb2222111100000ggggaaaabbbb2222111100000ggggaaaabbbb2222111100000ggggaaaabbbb2222111100000ggggaaaabbbb2222111100000ggggaaaabbbb2222111100000ggggaaaabbbb2222111100000ggggaaaabbbb2222111100000ggggaaaabbbb2222111100000ggggaaaabbbb2222111100000ggggaaaabbbb2222111100000ggggaaaabbbb2222111100000ggggaaaabbbb2222111100000ggggaaaabbbb2222111100000ggggaaaabbbb2222111100000gggg12345678901234567890123456789012345678901234") -local result = core.WaitForResponseTimeout(0x0611,1000) +local cmd = 0x0611 -- CMD_READER_MIFARE - uint_64 +local arg1, arg2, arg3 = "0","0","0" -- 3 x uint_64 +local d = string.rep("00",512)-- 512 bytes +local usbcommand = bin.pack("LLLLH",cmd, arg1, arg2, arg3,d); +print("len(usbcommand): ", string.len(usbcommand)); +local x = core.SendCommand(usbcommand); +local result +repeat + result = core.WaitForResponseTimeout(cmd,1000) + print(".") +until result + +local r_cmd, r_arg1, r_arg2, r_arg3,r_data; +--[[ +response = bin.unpack() +isOK = resp.arg[0] & 0xff; + +uid = (uint32_t)bytes_to_num(resp.d.asBytes + 0, 4); +nt = (uint32_t)bytes_to_num(resp.d.asBytes + 4, 4); +par_list = bytes_to_num(resp.d.asBytes + 8, 8); +ks_list = bytes_to_num(resp.d.asBytes + 16, 8); + + +end +--]] --- Oh, and nonce2Key is not 'glued' yet. print("err", result) \ No newline at end of file