zacharee / SamloaderKotlin

MIT License
949 stars 107 forks source link

I have obtained the TAC of 80% of Samsung mobile phones on the market. I hope it will be helpful to project development. #130

Closed xlzhen-940218 closed 9 months ago

xlzhen-940218 commented 10 months ago

tacs.csv

The data is a bit messy because I also caught it with a crawler. One mobile phone model corresponds to multiple models. And it also corresponds to multiple TACs. I can't determine which regions correspond to TACs. It takes some trial and error.

change code

`package tk.zwander.common.data.imei

import korlibs.io.serialization.csv.CSV import java.io.InputStream

data object IMEIGenerator {

fun makeImeiForModel(model: String): List<String> {
    val adjustedModel = if (model.endsWith("U1")) {
        model.replace("U1", "U")
    } else {
        model
    }
    val tac = IMEIDatabase.imeis[adjustedModel] ?: return getImeiClean(adjustedModel)
    val baseImei = "${tac}${IMEIDatabase.DUMMY_SERIAL}"
    println("bastImei = $baseImei")
    val imeiList: ArrayList<String> = ArrayList()
    imeiList.add(calculateCheckDigitForPartialImei(baseImei))
    return imeiList
}

private fun getImeiClean(adjustedModel: String): List<String> {
    println("get other imei : $adjustedModel")
    val tacs: ArrayList<String> = ArrayList()
    IMEIDatabase.csvClean.lines.forEach { line ->
        line.forEach { li ->
            run {
                if (li.trim().uppercase() == adjustedModel.trim().uppercase()) {
                    println("find imei = ${line[0]}")
                    tacs.add(line[0])

                }
            }

        }

    }
    val imeiList: ArrayList<String> = ArrayList()
    for (tac in tacs) {
        val baseImei = "${tac}${IMEIDatabase.DUMMY_SERIAL}"
        println("bastImei = $baseImei")
        imeiList.add(calculateCheckDigitForPartialImei(baseImei))
    }
    return imeiList
}

private fun calculateCheckDigitForFullImei(imei: String): Int {
    val length = imei.length
    val parity = length % 2

    var sum = 0

    for (i in length - 1 downTo 0) {
        var d = imei[i].digitToInt()

        if (i % 2 == parity) {
            d *= 2
        }

        if (d > 9) {
            d -= 9
        }

        sum += d
    }

    return sum % 10
}

private fun calculateCheckDigitForPartialImei(baseImei: String): String {
    val check = calculateCheckDigitForFullImei("${baseImei}0")

    val adjustedCheck = if (check == 0) 0 else 10 - check
    println("imei = ${baseImei}${adjustedCheck}")
    return "${baseImei}${adjustedCheck}"
}

}

data object IMEIDatabase { const val DUMMY_SERIAL = "123456"

val imeis = mutableMapOf<String, String>()
var inputStream: InputStream? = javaClass.classLoader.getResourceAsStream("tacs.csv")
var inputStreamClean: InputStream? = javaClass.classLoader.getResourceAsStream("tacs_2.csv")
val csvStrClean: String = inputStreamClean?.readAllBytes()?.let { java.lang.String(it, "utf-8") }.toString()
val csvClean = CSV.parse(csvStrClean)

init {
    val csvStr: String = inputStream?.readAllBytes()?.let { java.lang.String(it, "utf-8") }.toString()
    val csv = CSV.parse(csvStr)
    csv.lines.forEach { line ->
        if (line.size >= 2) {
            val tac = line[0]
            val model = line[1].cleanUpModel()
            val model2 = line.getOrNull(2)?.cleanUpModel()

            imeis[model] = tac
            model2?.let { imeis[it] = tac }
        }
    }

}

private fun String.cleanUpModel(): String {
    val trimmed = trim()

    if (!trimmed.contains("-")) {
        return trimmed
    }

    val firstSpace = trimmed.indexOfFirst { it == ' ' }.takeIf { it != -1 } ?: trimmed.length
    val beforeSpaces = trimmed.slice(0 until firstSpace)

    val firstSlash = beforeSpaces.indexOfFirst { it == '/' }.takeIf { it != -1 } ?: beforeSpaces.length

    return beforeSpaces.slice(0 until firstSlash)
}

} `

xlzhen-940218 commented 10 months ago

javascript code to F12 Control Panel from website: https://swappa.com/imei/tac

js attack tac.txt

zacharee commented 10 months ago

I'm seeing some matches that don't really make sense. The X700 and X800 are supposed to be WiFi-only tablets, but are listed next to TACs. Does that mean any cellular variant of those will work with that TAC?

xlzhen-940218 commented 10 months ago

I'm seeing some matches that don't really make sense. The X700 and X800 are supposed to be WiFi-only tablets, but are listed next to TACs. Does that mean any cellular variant of those will work with that TAC?

I tried the popular models on the samfw website and the success rate was 80%. And the data I captured is not very accurate. It would be worse if it is not a popular model. In fact, the same model sold in different regions may require different imei numbers. But I couldn't find a more accurate source of data.