├── .gitignore ├── jni ├── Application.mk ├── Android.mk └── changemac.c ├── install-msm8916.sh ├── init └── changemac.rc ├── addon.d └── 52-changemac.sh ├── install.sh ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | libs/ 2 | obj/ 3 | -------------------------------------------------------------------------------- /jni/Application.mk: -------------------------------------------------------------------------------- 1 | APP_ABI := armeabi-v7a 2 | APP_PLATFORM := android-24 3 | -------------------------------------------------------------------------------- /install-msm8916.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | WCNSS_DEVICE_ADDRESS=a000000 exec ./install.sh "$@" 3 | -------------------------------------------------------------------------------- /init/changemac.rc: -------------------------------------------------------------------------------- 1 | on init 2 | exec -- /system/xbin/changemac 3 | 4 | on property:wlan.driver.status=* 5 | setprop net.hostname "" 6 | exec -- /system/xbin/changemac 7 | -------------------------------------------------------------------------------- /jni/Android.mk: -------------------------------------------------------------------------------- 1 | LOCAL_PATH := $(call my-dir) 2 | 3 | include $(CLEAR_VARS) 4 | 5 | LOCAL_CFLAGS += -Wall -Wextra -Werror 6 | 7 | LOCAL_MODULE := changemac 8 | LOCAL_LDLIBS := -llog 9 | 10 | ifneq ($(WCNSS_DEVICE_ADDRESS),) 11 | LOCAL_CFLAGS += -DWCNSS_DEVICE_ADDRESS="\"$(WCNSS_DEVICE_ADDRESS)\"" 12 | endif 13 | 14 | LOCAL_SRC_FILES := changemac.c 15 | 16 | include $(BUILD_EXECUTABLE) 17 | -------------------------------------------------------------------------------- /addon.d/52-changemac.sh: -------------------------------------------------------------------------------- 1 | #!/sbin/sh 2 | 3 | . /tmp/backuptool.functions 4 | 5 | list_files() { 6 | cat < 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #define LOG_TAG "changemac" 11 | 12 | #define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__) 13 | #define ALOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__) 14 | 15 | /* https://android.googlesource.com/kernel/msm/+/android-8.0.0_r0.4/Documentation/devicetree/bindings/wcnss/wcnss-wlan.txt#65 */ 16 | #ifndef WCNSS_DEVICE_ADDRESS 17 | #define WCNSS_DEVICE_ADDRESS "fb000000" 18 | #endif 19 | #ifndef WCNSS_DEVICE_COMPATIBLE 20 | #define WCNSS_DEVICE_COMPATIBLE "qcom,wcnss-wlan" 21 | #endif 22 | 23 | #ifndef WCNSS_SYSFS_PATH 24 | #define WCNSS_SYSFS_PATH "/sys/bus/platform/devices/" WCNSS_DEVICE_ADDRESS "." WCNSS_DEVICE_COMPATIBLE 25 | #endif 26 | 27 | #ifndef WCNSS_MAC_ADDRESS_FILE 28 | #define WCNSS_MAC_ADDRESS_FILE WCNSS_SYSFS_PATH "/wcnss_mac_addr" 29 | #endif 30 | 31 | #define MAC_OUI_LENGTH 3 32 | #define MAC_CUSTOM_LENGTH 3 33 | 34 | static const uint8_t VENDORS[][MAC_OUI_LENGTH] = { 35 | { 0x00, 0x26, 0x37 }, /* SAMSUNG ELECTRO MECHANICS CO., LTD. */ 36 | { 0x08, 0x00, 0x28 }, /* Texas Instruments */ 37 | { 0x44, 0x74, 0x6c }, /* Sony Mobile Communications AB */ 38 | { 0x64, 0x16, 0xf0 }, /* HUAWEI TECHNOLOGIES CO.,LTD */ 39 | { 0x80, 0x19, 0x34 }, /* Intel Corporate */ 40 | { 0x84, 0x10, 0x0d }, /* Motorola Mobility LLC, a Lenovo Company */ 41 | { 0x84, 0x3a, 0x4b }, /* Intel Corporate */ 42 | { 0xb0, 0xc0, 0x90 }, /* Chicony Electronics Co., Ltd. */ 43 | { 0xe4, 0xb3, 0x18 }, /* Intel Corporate */ 44 | { 0xf0, 0x25, 0xb7 }, /* SAMSUNG ELECTRO-MECHANICS(THAILAND) */ 45 | { 0xf8, 0xa9, 0xd0 }, /* LG Electronics (Mobile Communications) */ 46 | }; 47 | 48 | #define VENDORS_COUNT (sizeof(VENDORS) / sizeof(*VENDORS)) 49 | 50 | static bool random_buffer(void *buffer, size_t size); 51 | static uint32_t random_uniform(uint32_t n); 52 | static const uint8_t *random_vendor(void); 53 | 54 | int main(int argc, char **argv) { 55 | (void) argc; 56 | (void) argv; 57 | 58 | const uint8_t *vendor = random_vendor(); 59 | 60 | uint8_t custom[MAC_CUSTOM_LENGTH]; 61 | random_buffer(custom, sizeof(custom)); 62 | 63 | char mac_address[3 * (MAC_OUI_LENGTH + MAC_CUSTOM_LENGTH)]; 64 | snprintf(mac_address, sizeof(mac_address), "%02x:%02x:%02x:%02x:%02x:%02x", 65 | vendor[0], vendor[1], vendor[2], 66 | custom[0], custom[1], custom[2]); 67 | 68 | ALOGI("Generated MAC address: %s", mac_address); 69 | 70 | FILE *output = fopen(WCNSS_MAC_ADDRESS_FILE, "w"); 71 | if (output == NULL) { 72 | /* There's nothing we can do about it, the MAC address will probably be leaked */ 73 | ALOGE("Could not open output file: %d", errno); 74 | return 1; 75 | } 76 | 77 | if (fputs(mac_address, output) < 0) { 78 | ALOGE("Could not write to output file: %d", errno); 79 | 80 | if (fclose(output) != 0) { 81 | ALOGE("Could not close output file: %d", errno); 82 | } 83 | 84 | return 1; 85 | } 86 | 87 | if (fclose(output) != 0) { 88 | ALOGE("Could not close output file: %d", errno); 89 | return 1; 90 | } 91 | 92 | return 0; 93 | } 94 | 95 | bool random_buffer(void *buffer, size_t size) { 96 | static FILE *urandom = NULL; 97 | if (urandom == NULL) { 98 | urandom = fopen("/dev/urandom", "r"); 99 | 100 | if (urandom == NULL) { 101 | /* This should never happen, probably due to SELinux */ 102 | ALOGE("Could not open /dev/urandom: %d", errno); 103 | return false; 104 | } 105 | } 106 | 107 | return (fread(buffer, size, 1, urandom) == 1); 108 | } 109 | 110 | uint32_t random_uniform(uint32_t n) { 111 | uint32_t max = UINT32_MAX - (UINT32_MAX % n); 112 | 113 | uint32_t x; 114 | do { 115 | if (!random_buffer(&x, sizeof(x))) { 116 | ALOGE("Could not read random bytes from stream: %d", errno); 117 | 118 | /* Ignore the error to avoid leaking the MAC address */ 119 | srand(time(NULL)); 120 | return rand() % n; 121 | } 122 | } while (x >= max); 123 | 124 | return (x / (max / n)); 125 | } 126 | 127 | const uint8_t *random_vendor(void) { 128 | uint32_t x = random_uniform(VENDORS_COUNT); 129 | 130 | ALOGI("Selected vendor index: %" PRIu32 "\n", x); 131 | return VENDORS[x]; 132 | } 133 | --------------------------------------------------------------------------------