mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-07-08 06:00:53 -07:00
fix reveng memory bug + @iceman1001 s scripting
This commit is contained in:
parent
7a23fca13a
commit
2e16354693
5 changed files with 255 additions and 141 deletions
|
@ -90,16 +90,11 @@ int GetModels(char *Models[], int *count, uint32_t *width){
|
||||||
PZERO, /* check value unused */
|
PZERO, /* check value unused */
|
||||||
NULL /* no model name */
|
NULL /* no model name */
|
||||||
};
|
};
|
||||||
|
|
||||||
int ibperhx = 8;//, obperhx = 8;
|
int ibperhx = 8;//, obperhx = 8;
|
||||||
int rflags = 0, uflags = 0; /* search and UI flags */
|
int rflags = 0, uflags = 0; /* search and UI flags */
|
||||||
|
|
||||||
//unsigned long width = 0UL;
|
|
||||||
//int c, mode = 0, args, psets, pass;
|
|
||||||
poly_t apoly, crc, qpoly = PZERO, *apolys = NULL, *pptr = NULL, *qptr = NULL;
|
poly_t apoly, crc, qpoly = PZERO, *apolys = NULL, *pptr = NULL, *qptr = NULL;
|
||||||
model_t pset = model, *candmods, *mptr;
|
model_t pset = model, *candmods, *mptr;
|
||||||
//char *string;
|
|
||||||
|
|
||||||
//myname = argv[0];
|
|
||||||
|
|
||||||
/* stdin must be binary */
|
/* stdin must be binary */
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -108,14 +103,10 @@ int GetModels(char *Models[], int *count, uint32_t *width){
|
||||||
|
|
||||||
SETBMP();
|
SETBMP();
|
||||||
|
|
||||||
//pos=0;
|
|
||||||
//optind=1;
|
|
||||||
|
|
||||||
int args = 0, psets, pass;
|
int args = 0, psets, pass;
|
||||||
int Cnt = 0;
|
int Cnt = 0;
|
||||||
if (*width == 0) { //reveng -D
|
if (*width == 0) { //reveng -D
|
||||||
*count = mcount();
|
*count = mcount();
|
||||||
//PrintAndLog("Count: %d",*count);
|
|
||||||
if(!*count)
|
if(!*count)
|
||||||
return uerr("no preset models available");
|
return uerr("no preset models available");
|
||||||
|
|
||||||
|
@ -123,15 +114,14 @@ int GetModels(char *Models[], int *count, uint32_t *width){
|
||||||
mbynum(&model, mode);
|
mbynum(&model, mode);
|
||||||
mcanon(&model);
|
mcanon(&model);
|
||||||
size_t size = (model.name && *model.name) ? strlen(model.name) : 6;
|
size_t size = (model.name && *model.name) ? strlen(model.name) : 6;
|
||||||
//PrintAndLog("Size: %d, %s",size,model.name);
|
|
||||||
char *tmp = calloc(size+1, sizeof(char));
|
char *tmp = calloc(size+1, sizeof(char));
|
||||||
if (tmp==NULL)
|
if (tmp==NULL)
|
||||||
return uerr("out of memory?");
|
return uerr("out of memory?");
|
||||||
|
|
||||||
memcpy(tmp, model.name, size);
|
memcpy(tmp, model.name, size);
|
||||||
Models[mode] = tmp;
|
Models[mode] = tmp;
|
||||||
//ufound(&model);
|
|
||||||
}
|
}
|
||||||
|
mfree(&model);
|
||||||
} else { //reveng -s
|
} else { //reveng -s
|
||||||
|
|
||||||
if(~model.flags & P_MULXN)
|
if(~model.flags & P_MULXN)
|
||||||
|
@ -150,7 +140,7 @@ int GetModels(char *Models[], int *count, uint32_t *width){
|
||||||
rflags &= ~R_HAVEQ;
|
rflags &= ~R_HAVEQ;
|
||||||
|
|
||||||
|
|
||||||
/* not going to be sending additional args
|
/* not going to be sending additional args at this time (maybe future?)
|
||||||
|
|
||||||
// allocate argument array
|
// allocate argument array
|
||||||
args = argc - optind;
|
args = argc - optind;
|
||||||
|
@ -193,9 +183,11 @@ int GetModels(char *Models[], int *count, uint32_t *width){
|
||||||
if(rflags & R_HAVEX && psncmp(&model.xorout, &pset.xorout))
|
if(rflags & R_HAVEX && psncmp(&model.xorout, &pset.xorout))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
//for additional args (not used yet, maybe future?)
|
||||||
apoly = pclone(pset.xorout);
|
apoly = pclone(pset.xorout);
|
||||||
if(pset.flags & P_REFOUT)
|
if(pset.flags & P_REFOUT)
|
||||||
prev(&apoly);
|
prev(&apoly);
|
||||||
|
|
||||||
for(qptr = apolys; qptr < pptr; ++qptr) {
|
for(qptr = apolys; qptr < pptr; ++qptr) {
|
||||||
crc = pcrc(*qptr, pset.spoly, pset.init, apoly, 0);
|
crc = pcrc(*qptr, pset.spoly, pset.init, apoly, 0);
|
||||||
if(ptst(crc)) {
|
if(ptst(crc)) {
|
||||||
|
@ -206,7 +198,9 @@ int GetModels(char *Models[], int *count, uint32_t *width){
|
||||||
}
|
}
|
||||||
pfree(&apoly);
|
pfree(&apoly);
|
||||||
if(qptr == pptr) {
|
if(qptr == pptr) {
|
||||||
|
|
||||||
/* the selected model solved all arguments */
|
/* the selected model solved all arguments */
|
||||||
|
|
||||||
mcanon(&pset);
|
mcanon(&pset);
|
||||||
|
|
||||||
size_t size = (pset.name && *pset.name) ? strlen(pset.name) : 6;
|
size_t size = (pset.name && *pset.name) ? strlen(pset.name) : 6;
|
||||||
|
@ -219,7 +213,6 @@ int GetModels(char *Models[], int *count, uint32_t *width){
|
||||||
memcpy(tmp, pset.name, size);
|
memcpy(tmp, pset.name, size);
|
||||||
Models[Cnt++] = tmp;
|
Models[Cnt++] = tmp;
|
||||||
*count = Cnt;
|
*count = Cnt;
|
||||||
//ufound(&pset);
|
|
||||||
uflags |= C_RESULT;
|
uflags |= C_RESULT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -233,25 +226,21 @@ int GetModels(char *Models[], int *count, uint32_t *width){
|
||||||
}
|
}
|
||||||
} while(~rflags & R_HAVERI && ++pass < 2);
|
} while(~rflags & R_HAVERI && ++pass < 2);
|
||||||
}
|
}
|
||||||
|
//got everything now free the memory...
|
||||||
|
|
||||||
if(uflags & C_RESULT) {
|
if(uflags & C_RESULT) {
|
||||||
for(qptr = apolys; qptr < pptr; ++qptr)
|
for(qptr = apolys; qptr < pptr; ++qptr)
|
||||||
pfree(qptr);
|
pfree(qptr);
|
||||||
return 1;
|
|
||||||
//exit(EXIT_SUCCESS);
|
|
||||||
}
|
}
|
||||||
if(!(model.flags & P_REFIN) != !(model.flags & P_REFOUT))
|
if(!(model.flags & P_REFIN) != !(model.flags & P_REFOUT))
|
||||||
return uerr("cannot search for crossed-endian models");
|
return uerr("cannot search for crossed-endian models");
|
||||||
|
|
||||||
pass = 0;
|
pass = 0;
|
||||||
do {
|
do {
|
||||||
mptr = candmods = reveng(&model, qpoly, rflags, args, apolys);
|
mptr = candmods = reveng(&model, qpoly, rflags, args, apolys);
|
||||||
if(mptr && plen(mptr->spoly))
|
if(mptr && plen(mptr->spoly))
|
||||||
uflags |= C_RESULT;
|
uflags |= C_RESULT;
|
||||||
while(mptr && plen(mptr->spoly)) {
|
while(mptr && plen(mptr->spoly)) {
|
||||||
/* results were printed by the callback
|
|
||||||
* string = mtostr(mptr);
|
|
||||||
* puts(string);
|
|
||||||
* free(string);
|
|
||||||
*/
|
|
||||||
mfree(mptr++);
|
mfree(mptr++);
|
||||||
}
|
}
|
||||||
free(candmods);
|
free(candmods);
|
||||||
|
@ -266,10 +255,8 @@ int GetModels(char *Models[], int *count, uint32_t *width){
|
||||||
free(apolys);
|
free(apolys);
|
||||||
if(~uflags & C_RESULT)
|
if(~uflags & C_RESULT)
|
||||||
return uerr("no models found");
|
return uerr("no models found");
|
||||||
|
mfree(&model);
|
||||||
|
|
||||||
}
|
}
|
||||||
//PrintAndLog("DONE");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,10 +33,10 @@ unsigned int current_command = CMD_UNKNOWN;
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
static int CmdQuit(const char *Cmd);
|
static int CmdQuit(const char *Cmd);
|
||||||
static int CmdRev(const char *Cmd);
|
static int CmdRev(const char *Cmd);
|
||||||
/* // for testing reveng api - cmdcrc.c
|
// for testing reveng api - cmdcrc.c
|
||||||
static int CmdrevengT(const char *Cmd);
|
static int CmdrevengT(const char *Cmd);
|
||||||
static int CmdrevengC(const char *Cmd);
|
static int CmdrevengC(const char *Cmd);
|
||||||
*/
|
|
||||||
|
|
||||||
//For storing command that are received from the device
|
//For storing command that are received from the device
|
||||||
static UsbCommand cmdBuffer[CMD_BUFFER_SIZE];
|
static UsbCommand cmdBuffer[CMD_BUFFER_SIZE];
|
||||||
|
@ -53,10 +53,10 @@ static command_t CommandTable[] =
|
||||||
{"hw", CmdHW, 1, "{ Hardware commands... }"},
|
{"hw", CmdHW, 1, "{ Hardware commands... }"},
|
||||||
{"lf", CmdLF, 1, "{ Low Frequency commands... }"},
|
{"lf", CmdLF, 1, "{ Low Frequency commands... }"},
|
||||||
{"reveng",CmdRev, 1, "Crc calculations from the software reveng1-30"},
|
{"reveng",CmdRev, 1, "Crc calculations from the software reveng1-30"},
|
||||||
/* // for testing reveng api - cmdcrc.c
|
// for testing reveng api - cmdcrc.c
|
||||||
{"revengt",CmdrevengT,1, "TEST Crc calculations from the software reveng1-30"},
|
//{"revengt",CmdrevengT,1, "TEST Crc calculations from the software reveng1-30"},
|
||||||
{"revengc",CmdrevengC,1, "TEST Crc calculations from the software reveng1-30"},
|
//{"revengc",CmdrevengC,1, "TEST Crc calculations from the software reveng1-30"},
|
||||||
*/
|
|
||||||
{"script",CmdScript,1, "{ Scripting commands }"},
|
{"script",CmdScript,1, "{ Scripting commands }"},
|
||||||
{"quit", CmdQuit, 1, "Exit program"},
|
{"quit", CmdQuit, 1, "Exit program"},
|
||||||
{"exit", CmdQuit, 1, "Exit program"},
|
{"exit", CmdQuit, 1, "Exit program"},
|
||||||
|
@ -84,7 +84,7 @@ int CmdRev(const char *Cmd)
|
||||||
CmdCrc(Cmd);
|
CmdCrc(Cmd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/* // for testing reveng api - cmdcrc.c
|
// for testing reveng api - cmdcrc.c
|
||||||
int CmdrevengT(const char *Cmd)
|
int CmdrevengT(const char *Cmd)
|
||||||
{
|
{
|
||||||
return CmdrevengTest(Cmd);
|
return CmdrevengTest(Cmd);
|
||||||
|
@ -93,7 +93,7 @@ int CmdrevengC(const char *Cmd)
|
||||||
{
|
{
|
||||||
return CmdrevengTestC(Cmd);
|
return CmdrevengTestC(Cmd);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
/**
|
/**
|
||||||
* @brief This method should be called when sending a new command to the pm3. In case any old
|
* @brief This method should be called when sending a new command to the pm3. In case any old
|
||||||
* responses from previous commands are stored in the buffer, a call to this method should clear them.
|
* responses from previous commands are stored in the buffer, a call to this method should clear them.
|
||||||
|
|
|
@ -444,7 +444,7 @@ ippx:
|
||||||
if(uflags & C_RESULT) {
|
if(uflags & C_RESULT) {
|
||||||
for(qptr = apolys; qptr < pptr; ++qptr)
|
for(qptr = apolys; qptr < pptr; ++qptr)
|
||||||
pfree(qptr);
|
pfree(qptr);
|
||||||
return 1;
|
//return 1;
|
||||||
//exit(EXIT_SUCCESS);
|
//exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
if(!(model.flags & P_REFIN) != !(model.flags & P_REFOUT)){
|
if(!(model.flags & P_REFIN) != !(model.flags & P_REFOUT)){
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "../common/crc64.h"
|
#include "../common/crc64.h"
|
||||||
#include "../common/sha1.h"
|
#include "../common/sha1.h"
|
||||||
#include "aes.h"
|
#include "aes.h"
|
||||||
|
#include "cmdcrc.h"
|
||||||
/**
|
/**
|
||||||
* The following params expected:
|
* The following params expected:
|
||||||
* UsbCommand c
|
* UsbCommand c
|
||||||
|
@ -388,6 +389,60 @@ static int l_sha1(lua_State *L)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int l_reveng_models(lua_State *L){
|
||||||
|
|
||||||
|
char *models[80];
|
||||||
|
int count = 0;
|
||||||
|
lua_Integer in_width = luaL_checkinteger(L, 1);
|
||||||
|
|
||||||
|
if( in_width > 89 ) return returnToLuaWithError(L,"Width cannot exceed 89, got %d", in_width);
|
||||||
|
|
||||||
|
uint32_t width = (uint32_t)in_width;
|
||||||
|
int ans = GetModels(models, &count, &width);
|
||||||
|
if (!ans) return 0;
|
||||||
|
|
||||||
|
lua_newtable(L);
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++){
|
||||||
|
lua_pushstring(L, (const char*)models[i]);
|
||||||
|
lua_rawseti(L,-2,i+1);
|
||||||
|
free(models[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int l_reveng_RunModel(lua_State *L){
|
||||||
|
//-c || -v
|
||||||
|
//inModel = valid model name string - CRC-8
|
||||||
|
//inHexStr = input hex string to calculate crc on
|
||||||
|
//reverse = reverse calc option if true
|
||||||
|
//endian = {0 = calc default endian input and output, b = big endian input and output, B = big endian output, r = right justified
|
||||||
|
// l = little endian input and output, L = little endian output only, t = left justified}
|
||||||
|
//result = calculated crc hex string
|
||||||
|
char result[50];
|
||||||
|
|
||||||
|
size_t dataLen;
|
||||||
|
const char *inModel = luaL_checklstring(L, 1, &dataLen);
|
||||||
|
if ( dataLen < 4 ) return returnToLuaWithError(L,"Can't find model, got %s", inModel);
|
||||||
|
|
||||||
|
const char *inHexStr = luaL_checklstring(L, 2, &dataLen);
|
||||||
|
if ( dataLen < 4 ) return returnToLuaWithError(L,"Hex string too short, got %d", dataLen);
|
||||||
|
|
||||||
|
int reverse = luaL_checkinteger(L, 3);
|
||||||
|
const char endian = luaL_checklstring(L, 4, &dataLen)[0];
|
||||||
|
|
||||||
|
//PrintAndLog("mod: %s, hex: %s, rev %d", inModel, inHexStr, reverse);
|
||||||
|
//int RunModel(char *inModel, char *inHexStr, bool reverse, char endian, char *result)
|
||||||
|
int ans = RunModel( (char *)inModel, (char *)inHexStr, (bool)reverse, endian, result);
|
||||||
|
if (!ans)
|
||||||
|
return returnToLuaWithError(L,"Reveng failed");
|
||||||
|
|
||||||
|
lua_pushstring(L, (const char*)result);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be
|
* @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be
|
||||||
* able to do "require('foobar')" if foobar.lua is within lualibs folder.
|
* able to do "require('foobar')" if foobar.lua is within lualibs folder.
|
||||||
|
@ -433,6 +488,9 @@ int set_pm3_libraries(lua_State *L)
|
||||||
{"crc16", l_crc16},
|
{"crc16", l_crc16},
|
||||||
{"crc64", l_crc64},
|
{"crc64", l_crc64},
|
||||||
{"sha1", l_sha1},
|
{"sha1", l_sha1},
|
||||||
|
{"reveng_models", l_reveng_models},
|
||||||
|
{"reveng_runmodel", l_reveng_RunModel},
|
||||||
|
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
69
client/scripts/e.lua
Normal file
69
client/scripts/e.lua
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
local getopt = require('getopt')
|
||||||
|
local utils = require('utils')
|
||||||
|
|
||||||
|
example = "script calculates many checksums (CRC) over the provided hex input"
|
||||||
|
author = "Iceman"
|
||||||
|
desc =
|
||||||
|
[[
|
||||||
|
This script calculates many checksums (CRS) over the provided hex input.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
-b data in hex
|
||||||
|
-w width of the CRC algorithm. <optional> defaults to all known CRC presets.
|
||||||
|
Examples :
|
||||||
|
script run e -b 010203040506070809
|
||||||
|
script run e -b 010203040506070809 -w 16
|
||||||
|
]]
|
||||||
|
|
||||||
|
---
|
||||||
|
-- A debug printout-function
|
||||||
|
function dbg(args)
|
||||||
|
if DEBUG then
|
||||||
|
print("###", args)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
---
|
||||||
|
-- This is only meant to be used when errors occur
|
||||||
|
function oops(err)
|
||||||
|
print("ERROR: ",err)
|
||||||
|
return nil,err
|
||||||
|
end
|
||||||
|
---
|
||||||
|
-- Usage help
|
||||||
|
function help()
|
||||||
|
print(desc)
|
||||||
|
print("Example usage")
|
||||||
|
print(example)
|
||||||
|
end
|
||||||
|
---
|
||||||
|
-- The main entry point
|
||||||
|
function main(args)
|
||||||
|
|
||||||
|
local data = '01020304'
|
||||||
|
local width = 0
|
||||||
|
|
||||||
|
-- Read the parameters
|
||||||
|
for o, a in getopt.getopt(args, 'hb:w:') do
|
||||||
|
if o == "h" then return help() end
|
||||||
|
if o == "b" then data = utils.ConvertHexToa end
|
||||||
|
if o == "w" then width = a end
|
||||||
|
end
|
||||||
|
|
||||||
|
print('Width of CRC: '..width..' bytes: '..data)
|
||||||
|
print('')
|
||||||
|
print('Model','CRC', 'CRC_Reverse')
|
||||||
|
|
||||||
|
local lists = core.reveng_models(width)
|
||||||
|
for _,i in pairs(lists) do
|
||||||
|
local one = core.reveng_runmodel(i, data, 0,0)
|
||||||
|
local two = core.reveng_runmodel(i, data, 1,0)
|
||||||
|
|
||||||
|
print(i, one, two)
|
||||||
|
end
|
||||||
|
|
||||||
|
if 1 == 1 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
main(args)
|
Loading…
Add table
Add a link
Reference in a new issue