MTPhreak-6572: sKai-specific MP0B_001 file modifier
-- MTPhreak IMEI changer and randomizer for MediaTek NVRAM | |
-- This version is adapted specifically for the Sigma sKai and other MT6572 based phones | |
-- Usage: lua mtphreak-6572.lua NVRAMfile [imei1 [imei2]] | |
-- If no IMEIs are passed, they are randomized (with respect to Luhn checksum) | |
function parseImei(imeistr) -- imei string to 12-byte table | |
local imeiTbl = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} | |
for i = 1, 15 do | |
local digit = tonumber(imeistr:sub(i,i)) | |
local x = ((i - 1) >> 1) + 1 | |
if i&1 == 1 then | |
imeiTbl[x] = imeiTbl[x] | digit | |
else | |
imeiTbl[x] = imeiTbl[x] | (digit << 4) | |
end | |
end | |
return imeiTbl | |
end | |
function tblToBytestring(tbl) | |
local s = "" | |
for i=1, #tbl do | |
s = s .. string.char(tbl[i]) | |
end | |
return s | |
end | |
function encodeImei(imeistr, mk) | |
local opBlk = parseImei(imeistr) | |
for index, value in ipairs(opBlk) do | |
opBlk[index] = value ~ mk[index] | |
end | |
for i = 1, 10 do | |
local targetIndex = (i&1 == 0) and 12 or 11 | |
opBlk[targetIndex] = (opBlk[targetIndex] + opBlk[i]) % 256 | |
end | |
return tblToBytestring(opBlk) | |
end | |
function getRandomImei() | |
local imeiRndStr = string.format("%014d", math.random(0,10000000) .. math.random(0,10000000)) | |
local imei = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} | |
local revmap = {0, 2, 4, 6, 8, 1, 3, 5, 7, 9} | |
for i = 1, 14 do | |
imei[i] = tonumber(imeiRndStr:sub(i,i)) | |
end | |
local oddsum = imei[1] + imei[3] + imei[5] + imei[7] + imei[9] + imei[11] + imei[13] | |
local evensum = revmap[imei[2] + 1] + revmap[imei[4] + 1] + revmap[imei[6] + 1] | |
+ revmap[imei[8] + 1] + revmap[imei[10] + 1] + revmap[imei[12] + 1] + revmap[imei[14] + 1] | |
local luhn = 10 - (oddsum + evensum) % 10 | |
return imeiRndStr .. ((luhn > 9) and 0 or luhn) | |
end | |
-- main command part | |
local imeiFileName = arg[1] | |
local imeiFile = assert(io.open(imeiFileName, "rb")) | |
local imei1 = arg[2] | |
local imei2 = arg[3] | |
local imeiFull = imeiFile:read("*all") | |
imeiFile:seek("end", -12) | |
local masterKey = { string.byte(imeiFile:read("*all"), 1, -1) } | |
-- for MT6572, we don't need the bitwise inversion of master key! | |
-- However, we need another mask transformation | |
local masterMask = {0x68, 3, 0x41, 0x20, 0, 0, 0x50, 0xf2, 0x87, 1, 0, 0} | |
for index, value in ipairs(masterKey) do | |
masterKey[index] = value ~ masterMask[index] | |
end | |
masterKey[11] = 0 | |
masterKey[12] = 0 | |
-- now we have the master key table ready | |
assert(imeiFile:close()) | |
if imei1 == nil and imei2 == nil then -- randomize | |
math.randomseed(os.clock()*100000000000) | |
imei1 = getRandomImei() | |
imei2 = getRandomImei() | |
end | |
imeiFile = assert(io.open(imeiFileName, "wb")) | |
imeiFile:write(imeiFull) | |
if imei1 ~= nil then -- write the first IMEI | |
print('Writing IMEI 1: ' .. imei1) | |
local encodedImei1 = encodeImei(imei1, masterKey) | |
imeiFile:seek("set") | |
imeiFile:write(encodedImei1) | |
end | |
if imei2 ~= nil then -- write the second IMEI | |
print('Writing IMEI 2: ' .. imei2) | |
local encodedImei2 = encodeImei(imei2, masterKey) | |
imeiFile:seek("set", 12) | |
imeiFile:write(encodedImei2) | |
end | |
assert(imeiFile:close()) | |
print('IMEIs written to ' .. imeiFileName) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment