mirror of
https://github.com/Proxmark/proxmark3.git
synced 2024-09-21 07:16:24 +08:00
fix reveng memory bug + @iceman1001 s scripting
This commit is contained in:
parent
7a23fca13a
commit
2e16354693
251
client/cmdcrc.c
251
client/cmdcrc.c
|
@ -90,16 +90,11 @@ int GetModels(char *Models[], int *count, uint32_t *width){
|
|||
PZERO, /* check value unused */
|
||||
NULL /* no model name */
|
||||
};
|
||||
|
||||
int ibperhx = 8;//, obperhx = 8;
|
||||
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;
|
||||
model_t pset = model, *candmods, *mptr;
|
||||
//char *string;
|
||||
|
||||
//myname = argv[0];
|
||||
|
||||
/* stdin must be binary */
|
||||
#ifdef _WIN32
|
||||
|
@ -108,14 +103,10 @@ int GetModels(char *Models[], int *count, uint32_t *width){
|
|||
|
||||
SETBMP();
|
||||
|
||||
//pos=0;
|
||||
//optind=1;
|
||||
|
||||
int args = 0, psets, pass;
|
||||
int Cnt = 0;
|
||||
if (*width == 0) { //reveng -D
|
||||
*count = mcount();
|
||||
//PrintAndLog("Count: %d",*count);
|
||||
if(!*count)
|
||||
return uerr("no preset models available");
|
||||
|
||||
|
@ -123,153 +114,149 @@ int GetModels(char *Models[], int *count, uint32_t *width){
|
|||
mbynum(&model, mode);
|
||||
mcanon(&model);
|
||||
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));
|
||||
if (tmp==NULL)
|
||||
return uerr("out of memory?");
|
||||
|
||||
memcpy(tmp, model.name, size);
|
||||
Models[mode] = tmp;
|
||||
//ufound(&model);
|
||||
}
|
||||
mfree(&model);
|
||||
} else { //reveng -s
|
||||
|
||||
if(~model.flags & P_MULXN)
|
||||
return uerr("cannot search for non-Williams compliant models");
|
||||
if(~model.flags & P_MULXN)
|
||||
return uerr("cannot search for non-Williams compliant models");
|
||||
|
||||
praloc(&model.spoly, *width);
|
||||
praloc(&model.init, *width);
|
||||
praloc(&model.xorout, *width);
|
||||
if(!plen(model.spoly))
|
||||
palloc(&model.spoly, *width);
|
||||
praloc(&model.spoly, *width);
|
||||
praloc(&model.init, *width);
|
||||
praloc(&model.xorout, *width);
|
||||
if(!plen(model.spoly))
|
||||
palloc(&model.spoly, *width);
|
||||
else
|
||||
*width = plen(model.spoly);
|
||||
|
||||
/* special case if qpoly is zero, search to end of range */
|
||||
if(!ptst(qpoly))
|
||||
rflags &= ~R_HAVEQ;
|
||||
|
||||
|
||||
/* not going to be sending additional args at this time (maybe future?)
|
||||
|
||||
// allocate argument array
|
||||
args = argc - optind;
|
||||
if(!(apolys = malloc(args * sizeof(poly_t))))
|
||||
return uerr("cannot allocate memory for argument list");
|
||||
|
||||
for(pptr = apolys; optind < argc; ++optind) {
|
||||
if(uflags & C_INFILE)
|
||||
*pptr++ = rdpoly(argv[optind], model.flags, ibperhx);
|
||||
else
|
||||
*width = plen(model.spoly);
|
||||
*pptr++ = strtop(argv[optind], model.flags, ibperhx);
|
||||
}
|
||||
// exit value of pptr is used hereafter!
|
||||
|
||||
*/
|
||||
|
||||
/* special case if qpoly is zero, search to end of range */
|
||||
if(!ptst(qpoly))
|
||||
rflags &= ~R_HAVEQ;
|
||||
|
||||
|
||||
/* not going to be sending additional args
|
||||
|
||||
// allocate argument array
|
||||
args = argc - optind;
|
||||
if(!(apolys = malloc(args * sizeof(poly_t))))
|
||||
return uerr("cannot allocate memory for argument list");
|
||||
|
||||
for(pptr = apolys; optind < argc; ++optind) {
|
||||
if(uflags & C_INFILE)
|
||||
*pptr++ = rdpoly(argv[optind], model.flags, ibperhx);
|
||||
else
|
||||
*pptr++ = strtop(argv[optind], model.flags, ibperhx);
|
||||
}
|
||||
// exit value of pptr is used hereafter!
|
||||
|
||||
*/
|
||||
|
||||
/* if endianness not specified, try
|
||||
* little-endian then big-endian.
|
||||
* NB: crossed-endian algorithms will not be
|
||||
* searched.
|
||||
*/
|
||||
/* scan against preset models */
|
||||
if(~uflags & C_FORCE) {
|
||||
pass = 0;
|
||||
Cnt = 0;
|
||||
do {
|
||||
psets = mcount();
|
||||
//PrintAndLog("psets: %d",psets);
|
||||
while(psets) {
|
||||
mbynum(&pset, --psets);
|
||||
|
||||
/* skip if different width, or refin or refout don't match */
|
||||
if(plen(pset.spoly) != *width || (model.flags ^ pset.flags) & (P_REFIN | P_REFOUT))
|
||||
continue;
|
||||
/* skip if the preset doesn't match specified parameters */
|
||||
if(rflags & R_HAVEP && pcmp(&model.spoly, &pset.spoly))
|
||||
continue;
|
||||
if(rflags & R_HAVEI && psncmp(&model.init, &pset.init))
|
||||
continue;
|
||||
if(rflags & R_HAVEX && psncmp(&model.xorout, &pset.xorout))
|
||||
continue;
|
||||
|
||||
apoly = pclone(pset.xorout);
|
||||
if(pset.flags & P_REFOUT)
|
||||
prev(&apoly);
|
||||
for(qptr = apolys; qptr < pptr; ++qptr) {
|
||||
crc = pcrc(*qptr, pset.spoly, pset.init, apoly, 0);
|
||||
if(ptst(crc)) {
|
||||
pfree(&crc);
|
||||
break;
|
||||
} else
|
||||
pfree(&crc);
|
||||
}
|
||||
pfree(&apoly);
|
||||
if(qptr == pptr) {
|
||||
/* the selected model solved all arguments */
|
||||
mcanon(&pset);
|
||||
|
||||
size_t size = (pset.name && *pset.name) ? strlen(pset.name) : 6;
|
||||
//PrintAndLog("Size: %d, %s, count: %d",size,pset.name, Cnt);
|
||||
char *tmp = calloc(size+1, sizeof(char));
|
||||
if (tmp==NULL){
|
||||
PrintAndLog("out of memory?");
|
||||
return 0;
|
||||
}
|
||||
memcpy(tmp, pset.name, size);
|
||||
Models[Cnt++] = tmp;
|
||||
*count = Cnt;
|
||||
//ufound(&pset);
|
||||
uflags |= C_RESULT;
|
||||
}
|
||||
}
|
||||
mfree(&pset);
|
||||
|
||||
/* toggle refIn/refOut and reflect arguments */
|
||||
if(~rflags & R_HAVERI) {
|
||||
model.flags ^= P_REFIN | P_REFOUT;
|
||||
for(qptr = apolys; qptr < pptr; ++qptr)
|
||||
prevch(qptr, ibperhx);
|
||||
}
|
||||
} while(~rflags & R_HAVERI && ++pass < 2);
|
||||
}
|
||||
if(uflags & C_RESULT) {
|
||||
for(qptr = apolys; qptr < pptr; ++qptr)
|
||||
pfree(qptr);
|
||||
return 1;
|
||||
//exit(EXIT_SUCCESS);
|
||||
}
|
||||
if(!(model.flags & P_REFIN) != !(model.flags & P_REFOUT))
|
||||
return uerr("cannot search for crossed-endian models");
|
||||
/* if endianness not specified, try
|
||||
* little-endian then big-endian.
|
||||
* NB: crossed-endian algorithms will not be
|
||||
* searched.
|
||||
*/
|
||||
/* scan against preset models */
|
||||
if(~uflags & C_FORCE) {
|
||||
pass = 0;
|
||||
Cnt = 0;
|
||||
do {
|
||||
mptr = candmods = reveng(&model, qpoly, rflags, args, apolys);
|
||||
if(mptr && plen(mptr->spoly))
|
||||
uflags |= C_RESULT;
|
||||
while(mptr && plen(mptr->spoly)) {
|
||||
/* results were printed by the callback
|
||||
* string = mtostr(mptr);
|
||||
* puts(string);
|
||||
* free(string);
|
||||
*/
|
||||
mfree(mptr++);
|
||||
psets = mcount();
|
||||
//PrintAndLog("psets: %d",psets);
|
||||
while(psets) {
|
||||
mbynum(&pset, --psets);
|
||||
|
||||
/* skip if different width, or refin or refout don't match */
|
||||
if(plen(pset.spoly) != *width || (model.flags ^ pset.flags) & (P_REFIN | P_REFOUT))
|
||||
continue;
|
||||
/* skip if the preset doesn't match specified parameters */
|
||||
if(rflags & R_HAVEP && pcmp(&model.spoly, &pset.spoly))
|
||||
continue;
|
||||
if(rflags & R_HAVEI && psncmp(&model.init, &pset.init))
|
||||
continue;
|
||||
if(rflags & R_HAVEX && psncmp(&model.xorout, &pset.xorout))
|
||||
continue;
|
||||
|
||||
//for additional args (not used yet, maybe future?)
|
||||
apoly = pclone(pset.xorout);
|
||||
if(pset.flags & P_REFOUT)
|
||||
prev(&apoly);
|
||||
|
||||
for(qptr = apolys; qptr < pptr; ++qptr) {
|
||||
crc = pcrc(*qptr, pset.spoly, pset.init, apoly, 0);
|
||||
if(ptst(crc)) {
|
||||
pfree(&crc);
|
||||
break;
|
||||
} else
|
||||
pfree(&crc);
|
||||
}
|
||||
pfree(&apoly);
|
||||
if(qptr == pptr) {
|
||||
|
||||
/* the selected model solved all arguments */
|
||||
|
||||
mcanon(&pset);
|
||||
|
||||
size_t size = (pset.name && *pset.name) ? strlen(pset.name) : 6;
|
||||
//PrintAndLog("Size: %d, %s, count: %d",size,pset.name, Cnt);
|
||||
char *tmp = calloc(size+1, sizeof(char));
|
||||
if (tmp==NULL){
|
||||
PrintAndLog("out of memory?");
|
||||
return 0;
|
||||
}
|
||||
memcpy(tmp, pset.name, size);
|
||||
Models[Cnt++] = tmp;
|
||||
*count = Cnt;
|
||||
uflags |= C_RESULT;
|
||||
}
|
||||
}
|
||||
free(candmods);
|
||||
mfree(&pset);
|
||||
|
||||
/* toggle refIn/refOut and reflect arguments */
|
||||
if(~rflags & R_HAVERI) {
|
||||
model.flags ^= P_REFIN | P_REFOUT;
|
||||
for(qptr = apolys; qptr < pptr; ++qptr)
|
||||
prevch(qptr, ibperhx);
|
||||
}
|
||||
} while(~rflags & R_HAVERI && ++pass < 2);
|
||||
}
|
||||
//got everything now free the memory...
|
||||
|
||||
if(uflags & C_RESULT) {
|
||||
for(qptr = apolys; qptr < pptr; ++qptr)
|
||||
pfree(qptr);
|
||||
free(apolys);
|
||||
if(~uflags & C_RESULT)
|
||||
return uerr("no models found");
|
||||
|
||||
}
|
||||
if(!(model.flags & P_REFIN) != !(model.flags & P_REFOUT))
|
||||
return uerr("cannot search for crossed-endian models");
|
||||
|
||||
pass = 0;
|
||||
do {
|
||||
mptr = candmods = reveng(&model, qpoly, rflags, args, apolys);
|
||||
if(mptr && plen(mptr->spoly))
|
||||
uflags |= C_RESULT;
|
||||
while(mptr && plen(mptr->spoly)) {
|
||||
mfree(mptr++);
|
||||
}
|
||||
free(candmods);
|
||||
if(~rflags & R_HAVERI) {
|
||||
model.flags ^= P_REFIN | P_REFOUT;
|
||||
for(qptr = apolys; qptr < pptr; ++qptr)
|
||||
prevch(qptr, ibperhx);
|
||||
}
|
||||
} while(~rflags & R_HAVERI && ++pass < 2);
|
||||
for(qptr = apolys; qptr < pptr; ++qptr)
|
||||
pfree(qptr);
|
||||
free(apolys);
|
||||
if(~uflags & C_RESULT)
|
||||
return uerr("no models found");
|
||||
mfree(&model);
|
||||
}
|
||||
//PrintAndLog("DONE");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,10 +33,10 @@ unsigned int current_command = CMD_UNKNOWN;
|
|||
static int CmdHelp(const char *Cmd);
|
||||
static int CmdQuit(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 CmdrevengC(const char *Cmd);
|
||||
*/
|
||||
|
||||
|
||||
//For storing command that are received from the device
|
||||
static UsbCommand cmdBuffer[CMD_BUFFER_SIZE];
|
||||
|
@ -53,10 +53,10 @@ static command_t CommandTable[] =
|
|||
{"hw", CmdHW, 1, "{ Hardware commands... }"},
|
||||
{"lf", CmdLF, 1, "{ Low Frequency commands... }"},
|
||||
{"reveng",CmdRev, 1, "Crc calculations from the software reveng1-30"},
|
||||
/* // for testing reveng api - cmdcrc.c
|
||||
{"revengt",CmdrevengT,1, "TEST Crc calculations from the software reveng1-30"},
|
||||
{"revengc",CmdrevengC,1, "TEST Crc calculations from the software reveng1-30"},
|
||||
*/
|
||||
// for testing reveng api - cmdcrc.c
|
||||
//{"revengt",CmdrevengT,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 }"},
|
||||
{"quit", CmdQuit, 1, "Exit program"},
|
||||
{"exit", CmdQuit, 1, "Exit program"},
|
||||
|
@ -84,7 +84,7 @@ int CmdRev(const char *Cmd)
|
|||
CmdCrc(Cmd);
|
||||
return 0;
|
||||
}
|
||||
/* // for testing reveng api - cmdcrc.c
|
||||
// for testing reveng api - cmdcrc.c
|
||||
int CmdrevengT(const char *Cmd)
|
||||
{
|
||||
return CmdrevengTest(Cmd);
|
||||
|
@ -93,7 +93,7 @@ int CmdrevengC(const char *Cmd)
|
|||
{
|
||||
return CmdrevengTestC(Cmd);
|
||||
}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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.
|
||||
|
|
|
@ -444,7 +444,7 @@ ippx:
|
|||
if(uflags & C_RESULT) {
|
||||
for(qptr = apolys; qptr < pptr; ++qptr)
|
||||
pfree(qptr);
|
||||
return 1;
|
||||
//return 1;
|
||||
//exit(EXIT_SUCCESS);
|
||||
}
|
||||
if(!(model.flags & P_REFIN) != !(model.flags & P_REFOUT)){
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "../common/crc64.h"
|
||||
#include "../common/sha1.h"
|
||||
#include "aes.h"
|
||||
#include "cmdcrc.h"
|
||||
/**
|
||||
* The following params expected:
|
||||
* UsbCommand c
|
||||
|
@ -388,6 +389,60 @@ static int l_sha1(lua_State *L)
|
|||
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
|
||||
* 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},
|
||||
{"crc64", l_crc64},
|
||||
{"sha1", l_sha1},
|
||||
{"reveng_models", l_reveng_models},
|
||||
{"reveng_runmodel", l_reveng_RunModel},
|
||||
|
||||
{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…
Reference in a new issue