Created
June 16, 2020 22:16
-
-
Save plugnburn/afdef1d10f17f1e744bf3a36592e6a02 to your computer and use it in GitHub Desktop.
MTPhreak-6572: sKai-specific MP0B_001 file modifier
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 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