Skip to content

Instantly share code, notes, and snippets.

@jacopo-j
Last active April 8, 2024 13:44
Show Gist options
  • Star 28 You must be signed in to star a gist
  • Fork 15 You must be signed in to fork a gist
  • Save jacopo-j/6a6a0e3c4e2fe974955ce41878f6df5b to your computer and use it in GitHub Desktop.
Save jacopo-j/6a6a0e3c4e2fe974955ce41878f6df5b to your computer and use it in GitHub Desktop.
Frida script to spoof and hide several Android identifiers
/* Utilities */
var RANDOM = function() {};
function _randomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function _randomHex(len) {
var hex = '0123456789abcdef';
var output = '';
for (var i = 0; i < len; ++i) {
output += hex.charAt(Math.floor(Math.random() * hex.length));
}
return output;
}
function _pad(n, width) {
n = n + "";
return n.length >= width ? n : new Array(width - n.length + 1).join("0") + n;
}
function _randomPaddedInt(length) {
return _pad(_randomInt(0, Math.pow(10, length)), length);
}
function _luhn_getcheck(code) {
code = String(code).concat("0");
var len = code.length;
var parity = len % 2;
var sum = 0;
for (var i = len - 1; i >= 0; i--) {
var d = parseInt(code.charAt(i))
if (i % 2 == parity) {
d *= 2;
}
if (d > 9) {
d -= 9;
}
sum += d;
}
var checksum = sum % 10;
return checksum == 0 ? 0 : 10 - checksum;
}
function _luhn_verify(code) {
code = String(code);
var len = code.length;
var parity = len % 2;
var sum = 0;
for (var i = len - 1; i >= 0; i--) {
var d = parseInt(code.charAt(i))
if (i % 2 == parity) {
d *= 2;
}
if (d > 9) {
d -= 9;
}
sum += d;
}
return sum % 10 == 0;
}
/* Spoofing functions */
function spoofAndroidID(android_id) {
if (android_id == RANDOM) {
android_id = _randomHex(16);
} else if (android_id !== null) {
android_id = String(android_id).toLowerCase();
if (! android_id.match(/^[0-9a-f]{16}$/)) {
throw new Error("Invalid Android ID value");
}
}
var ss = Java.use("android.provider.Settings$Secure");
ss.getString.overload("android.content.ContentResolver", "java.lang.String").implementation = function(context, param) {
if (param == ss.ANDROID_ID.value) {
return android_id;
} else {
return this.getString(context, param);
}
}
}
function spoofPhone(phone) {
if (phone === RANDOM) {
phone = _randomPaddedInt(10);
} else if (phone !== null) {
phone = String(phone);
if (! phone.match(/^[0-9]{1,15}$/)) {
throw new Error("Invalid phone number");
}
}
var tm = Java.use("android.telephony.TelephonyManager");
tm.getLine1Number.overload().implementation = function() {
return phone;
}
}
function spoofIMEI(imei) {
if (imei === RANDOM) {
imei = _randomPaddedInt(14);
imei = imei.concat(_luhn_getcheck(imei));
} else if (imei !== null) {
imei = String(imei);
if (! imei.match(/^[0-9]{15}$/)) {
throw new Error("Invalid IMEI value");
}
if (! _luhn_verify(imei)) {
console.warn("IMEI has an invalid check digit");
}
}
var tm = Java.use("android.telephony.TelephonyManager");
tm.getDeviceId.overload().implementation = function() {
return imei;
}
tm.getDeviceId.overload("int").implementation = function(slotIndex) {
return imei;
}
tm.getImei.overload().implementation = function() {
return imei;
}
tm.getImei.overload("int").implementation = function(slotIndex) {
return imei;
}
}
function spoofIMSI(imsi) {
if (imsi == RANDOM) {
imsi = _randomPaddedInt(15);
} else if (imsi !== null) {
imsi = String(imsi);
if (! imsi.match(/^[0-9]{14,15}$/)) {
throw new Error("Invalid IMSI value");
}
}
var tm = Java.use("android.telephony.TelephonyManager");
tm.getSubscriberId.overload().implementation = function() {
return imsi;
}
}
function spoofICCID(iccid) {
if (iccid == RANDOM) {
iccid = "89".concat(_randomPaddedInt(16));
iccid = iccid.concat(_luhn_getcheck(iccid));
} else if (iccid !== null) {
iccid = String(iccid);
if (! iccid.match(/^[0-9]{19,20}$/)) {
throw new Error("Invalid ICCID value");
}
if (! _luhn_verify(iccid)) {
console.warn("ICCID has an invalid check digit");
}
}
var tm = Java.use("android.telephony.TelephonyManager");
tm.getSimSerialNumber.overload().implementation = function() {
return iccid;
}
}
function spoofMAC(mac) {
if (mac == RANDOM) {
mac = [];
for (var i = 0; i < 6; i++) {
mac.push(_randomInt(0, 255));
}
mac = Java.array("byte", mac);
} else if (mac !== null) {
var mac_str = String(mac).toUpperCase();
if (! mac_str.match(/^([0-9A-F]{2}:){5}[0-9A-F]{2}$/)) {
throw new Error("Invalid MAC address value");
}
mac = [];
var mac_arr = mac_str.split(":");
for (var i = 0; i < 6; i++) {
mac.push(parseInt(mac_arr[i], 16));
}
mac = Java.array("byte", mac);
}
var ni = Java.use("java.net.NetworkInterface");
ni.getHardwareAddress.overload().implementation = function() {
return mac;
}
}
function hideGSFID(gsf_id) {
var cr = Java.use("android.content.ContentResolver");
cr.query.overload("android.net.Uri", "[Ljava.lang.String;", "android.os.Bundle", "android.os.CancellationSignal").implementation = function(uri, projection, queryArgs, cancellationSignal) {
var qres = this.query(uri, projection, queryArgs, cancellationSignal);
if (uri.toString() == "content://com.google.android.gsf.gservices") {
qres = null;
}
return qres;
}
cr.query.overload("android.net.Uri", "[Ljava.lang.String;", "java.lang.String", "[Ljava.lang.String;", "java.lang.String", "android.os.CancellationSignal").implementation = function(uri, projection, selection, selectionArgs, sortOrder, cancellationSignal) {
var qres = this.query(uri, projection, selection, selectionArgs, sortOrder, cancellationSignal);
if (uri.toString() == "content://com.google.android.gsf.gservices") {
qres = null;
}
return qres;
}
cr.query.overload("android.net.Uri", "[Ljava.lang.String;", "java.lang.String", "[Ljava.lang.String;", "java.lang.String").implementation = function(uri, projection, selection, selectionArgs, sortOrder) {
var qres = this.query(uri, projection, selection, selectionArgs, sortOrder);
if (uri.toString() == "content://com.google.android.gsf.gservices") {
qres = null;
}
return qres;
}
}
Java.perform(function () {
spoofMAC(RANDOM);
spoofICCID(RANDOM);
spoofIMSI(RANDOM);
spoofAndroidID(RANDOM);
spoofIMEI(RANDOM);
spoofPhone(RANDOM);
hideGSFID();
});
@WeslenPy
Copy link

very cool

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment