diff --git a/armsrc/mifarecmd.c b/armsrc/mifarecmd.c index 0e21a9736..db421954c 100644 --- a/armsrc/mifarecmd.c +++ b/armsrc/mifarecmd.c @@ -1529,13 +1529,22 @@ void MifareChkKeys(uint16_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain, b uint64_t key = 0; uint32_t cuid = 0; int i, res; - uint8_t blockNo = arg0 & 0xFF; - uint8_t keyType = (arg0 >> 8) & 0xFF; - uint8_t keyCount = arg2; - uint8_t cascade_levels = 0; - uint8_t isOK = 0; - bool have_uid = false; - bool clearTrace = arg1 & 0xFF; + uint8_t cascade_levels = 0, isOK = 0; + uint8_t blockNo, keyType, keyCount; + bool clearTrace, have_uid = false; + + if (ng) { + keyType = datain[0]; + blockNo = datain[1]; + clearTrace = datain[2]; + keyCount = datain[3]; + datain += 4; + } else { + blockNo = arg0 & 0xFF; + keyType = (arg0 >> 8) & 0xFF; + clearTrace = arg1; + keyCount = arg2; + } LEDsoff(); LED_A_ON(); diff --git a/client/lualibs/commands.lua b/client/lualibs/commands.lua index 244f3e6a1..a9a2a95e9 100644 --- a/client/lualibs/commands.lua +++ b/client/lualibs/commands.lua @@ -33,7 +33,7 @@ Command = { if (type(data) == 'string') then -- We need to check if it is correct length, otherwise pad it - local len = string.len(data) + local len = #data if (len < 1024) then --Should be 1024 hex characters to represent 512 bytes of data data = data .. string.rep("0",1024 - len ) @@ -42,7 +42,7 @@ Command = { -- OOps, a bit too much data here print( ( "WARNING: data size too large, was %s chars, will be truncated "):format(len) ) -- - data = data:sub(1,1024) + data = data:sub(1, 1024) end else print(("WARNING; data was NOT a (hex-) string, but was %s"):format(type(data))) @@ -67,7 +67,7 @@ Command = { -- OOps, a bit too much data here print( ( "WARNING: data size too large, was %s chars, will be truncated "):format( #data) ) -- - data = data:sub(1,1024) + data = data:sub(1, 1024) end end o.data = data @@ -87,7 +87,7 @@ Command = { -- OOps, a bit too much data here print( ( "WARNING: data size too large, was %s chars, will be truncated "):format( #data) ) -- - data = data:sub(1,1024) + data = data:sub(1, 1024) end end o.data = data @@ -129,7 +129,7 @@ function Command:__responsetostring() tostring(self.resp_arg2), tostring(self.resp_arg3))) print('NG ::', self.resp_ng) - print('package ::', self.resp_response) + print('Data ::', self.resp_data) end @@ -194,12 +194,13 @@ function Command:sendNG( ignore_response, timeout ) return nil, 'Error, waiting for response timed out :: '..msg end - -- lets digest +--[[ uncomment if you want to debug + + -- lets digest response NG package. local data local count, cmd, length, magic, status, crc, arg1, arg2, arg3 = bin.unpack('SSIsSLLL', response) count, data, ng = bin.unpack('H'..length..'C', response, count) ---[[ uncomment if you want to debug self.resp_cmd = cmd self.resp_length = length self.resp_magic = magic @@ -213,8 +214,7 @@ function Command:sendNG( ignore_response, timeout ) self:__responsetostring() --]] - local packed = bin.pack("LLLLH", cmd, arg1, arg2, arg3, data) - return packed, nil; + return response end return _commands diff --git a/client/scripting.c b/client/scripting.c index 5aa76d33c..fe1fe1def 100644 --- a/client/scripting.c +++ b/client/scripting.c @@ -162,7 +162,7 @@ static int l_SendCommandNG(lua_State *L) { return returnToLuaWithError(L, "You need to supply two parameters"); // parse input - uint64_t cmd = luaL_checknumber(L, 1); + uint16_t cmd = luaL_checknumber(L, 1); // data const char *p_data = luaL_checklstring(L, 2, &size); diff --git a/client/scripts/mfkeys.lua b/client/scripts/mfkeys.lua index 7d39db5a5..a8426fda5 100644 --- a/client/scripts/mfkeys.lua +++ b/client/scripts/mfkeys.lua @@ -29,6 +29,8 @@ Arguments: -p : print keys ]] +local PM3_SUCCESS = 0 -- needs to be refactored into own like usb_cmd + local TIMEOUT = 10000 -- 10 seconds --- -- This is only meant to be used when errors occur @@ -56,8 +58,11 @@ local function checkCommand(response) return nil, "Timeout while waiting for device to respond" end - local count, cmd, arg0, arg1, arg2, data = bin.unpack('LLLLH40',result) - if arg0 == 1 then + local data + local count, cmd, length, magic, status, crc, arg1, arg2, arg3 = bin.unpack('SSIsSLLL', response) + count, data, ng = bin.unpack('H'..length..'C', response, count) + + if status == PM3_SUCCESS then key = data:sub(1, 12) return key end @@ -67,34 +72,37 @@ end local function checkBlock(blockno, testkeys, keytype) - -- The command data is only 512 bytes, each key is 6 bytes, meaning that we can send max 85 keys in one go. + -- The command data is only 512 bytes, + -- each key is 6 bytes, + -- NG args inside dataarray is 4 bytes. That give us (512-4)/6 or max 84 keys in one go. -- If there's more, we need to split it up local arg1 = bit32.bor(bit32.lshift(keytype, 8), blockno) - + local arg2 = '00' -- don't clear trace local start, remaining = 1, #testkeys + local maxchunk = math.floor((512-4)/6) local chunksize = remaining - if remaining > 85 then chunksize = 85 end + if remaining > maxchunk then chunksize = maxchunk end local n = chunksize - + while remaining > 0 do - --print('start', start, 'chunksize', chunksize, 'testkeys kvar', remaining, 'N-index=', n) +-- print('start', start, 'chunksize', chunksize, 'testkeys kvar', remaining, 'N-index=', n) + local d0 = ('%04X%02X%02X'):format(arg1, arg2, chunksize) local d1 = table.concat(testkeys, "", start, n) + + core.clearCommandBuffer() - core.clearCommandBuffer() - print(("Testing block %d, keytype %d, with %d keys"):format(blockno, keytype, chunksize)) - local c = Command:newNG{cmd = cmds.CMD_MIFARE_CHKKEYS, - arg1 = arg1, - arg3 = chunksize, - data = d1} - status, err = checkCommand(c:sendNG(false, TIMEOUT)) - if status then return status, blockno end + local c = Command:newNG{cmd = cmds.CMD_MIFARE_CHKKEYS, data = d0..d1} + key, err = checkCommand(c:sendNG(false, TIMEOUT)) + + if key then return key, blockno end + start = start + chunksize remaining = remaining - chunksize - if remaining < 85 then chunksize = remaining end + if remaining < maxchunk then chunksize = remaining end n = n + chunksize end return nil