APP逆向——某站device-id參數

免責聲明

  1. 本博客所涉及的 爬蟲技術、逆向分析方法 僅用于 學習、研究和技術交流
  2. 文中所有示例代碼、工具和方法,均不得用于以下行為:
    • 未經授權的數據采集
    • 侵犯他人知識產權
    • 干擾或破壞正常業務系統
    • 任何違反國家法律法規的行為
  1. 因讀者將本教程內容用于 非法用途 而產生的一切后果,由讀者本人承擔,本博客作者不承擔任何法律及連帶責任。
  2. 請在學習和實踐過程中 遵守相關法律法規、網站/平臺的服務協議及 robots 協議,合理合規地使用所學技術。

device-id

這其實就是設備id,可以直接隨機生成就行,這里還是帶著看一下

String a4 = com.bilibili.api.e.a();
if (!TextUtils.isEmpty(a4)) {aVar.h("Device-ID", a4);
}

直接看com.bilibili.api.e.a吧:

public class e {private static String a;public static String a() {return a;}public static void b(String str) {a = str;}
}

一樣的也是b函數調用,可以用hook也可以直接查找用例,這里就不帶大家找了:

public void run() {if (!j.a) {com.bilibili.api.d.b(j.c(this.a));}// 這是加密值com.bilibili.api.e.b(com.bilibili.lib.biliid.utils.f.a.c(this.a));
}

先找this.a:

a(Context context) {this.a = context;
}

context 上下文環境 —— 管理資源

Context 就是應用在 Android 系統中的運行環境,提供了操作資源、啟動組件、獲取系統服務的能力。

那么這里就不用管,直接看com.bilibili.lib.biliid.utils.f.a.c

public static String c(@Nullable Context context) {// 如果之前已經有緩存的 f13193c,就直接返回,避免重復計算if (!TextUtils.isEmpty(f13193c)) {return f13193c;}// 如果 context 是 null,啥也沒法干,直接返回空字符串if (context == null) {return "";}// 從 e.k().f(context) 獲取一個值(可能是存儲的 ID)String f = c2.f.b0.c.a.e.k().f(context);f13193c = f;// 如果獲取到的值非空,就直接返回if (!TextUtils.isEmpty(f)) {return f13193c;}// 如果還是沒拿到,就調用 g(context) 生成一個新的 IDf13193c = g(context);// 把新生成的 ID 存起來(持久化到本地,比如 SharedPreferences)c2.f.b0.c.a.e.k().x(f13193c, context);// 返回最終的 IDreturn f13193c;
}// 前面很多都是從之前所說的存儲中拿,重點看g函數
static String g(Context context) {// 1. 先調用 f(context) 獲取一個基礎值(可能是之前存儲的 ID 或默認值)String f = f(context);// 2. 如果 f 太短(小于 4 個字符),說明無效,需要生成一個新的if (f.length() < 4) {// a. 獲取 Android 系統 ID(每臺設備唯一)String androidId = Settings.Secure.getString(context.getContentResolver(), "android_id");// b. 獲取設備型號并進行處理(g.g(Build.MODEL))String modelHash = g.g(Build.MODEL);// c. 拼接 Android ID 和設備型號,形成一個新的字符串f = androidId + "@" + modelHash;}// 3. 對最終的字符串做進一步處理(b(f)return b(f);
}// 主要
String androidId = Settings.Secure.getString(context.getContentResolver(), "android_id"); // 之前獲取過
// b. 獲取設備型號并進行處理(g.g(Build.MODEL) 清除空格)
String modelHash = g.g(Build.MODEL);  // Build.MODEL:設備型號// c. 拼接 Android ID 和設備型號,形成一個新的字符串
f = androidId + "@" + modelHash;// b(f) : 自定義算法
public static String b(String str) {// 1. 將字符串轉換成字節數組byte[] bytes = str.getBytes();// 2. 對第一個字節做異或運算,增加混淆性// bytes[0] = bytes[0] ^ (bytes.length & 255)bytes[0] = (byte) (bytes[0] ^ ((byte) (bytes.length & 255)));// 3. 從第二個字節開始,每個字節都和前一個字節異或for (int i = 1; i < bytes.length; i++) {bytes[i] = (byte) ((bytes[i - 1] ^ bytes[i]) & 255);}try {// 4. 將處理后的字節數組進行 Base64 編碼(flags = 11)return new String(Base64.encode(bytes, 11));} catch (Exception unused) {// 5. 編碼失敗時,返回原始字符串return str;}
}

梳理好之后,就可以直接模擬出python代碼(經過校驗,是一致的):

def obfuscate_string(s: str) -> str:"""型號加密,不補 Base64 '='"""# 1. 將字符串轉換成字節數組bytes_arr = bytearray(s.encode('utf-8'))if not bytes_arr:return s# 2. 對第一個字節做異或運算bytes_arr[0] = bytes_arr[0] ^ (len(bytes_arr) & 0xFF)# 3. 從第二個字節開始,每個字節都和前一個字節異或for i in range(1, len(bytes_arr)):bytes_arr[i] = (bytes_arr[i - 1] ^ bytes_arr[i]) & 0xFFtry:# 4. Base64 編碼,URL-safe,并去掉結尾 '='encoded = base64.urlsafe_b64encode(bytes_arr)return encoded.decode('utf-8').rstrip('=')except Exception:# 5. 編碼失敗時返回原始字符串return sdef get_device_id():"""獲取device_id"""androidId = '5d01aa95f9aca38c'models = ["Pixel 7", "Redmi K50", "ONEPLUS 9 Pro", "Vivo V23", "MI 12X","SM-G998B", "Xiaomi 11T", "OPPO Reno8", "Pixel 7 Pro", "Lenovo Legion Y90","Realme GT Neo3", "MI 11 Ultra", "Redmi Note 11", "ONEPLUS A6013", "VOG-L29","P50 Pro", "OPPO Find X5", "Vivo X80", "Pixel 6a", "Redmi K40","SM-G991U", "Xiaomi 12S", "Realme GT", "ONEPLUS 8T", "Vivo Y76","OPPO Reno7", "MI 10 Pro", "Pixel 5", "Lenovo K12 Pro", "Redmi Note 10","SM-G990F"]model = random.choice(models)modelHash = model.replace(' ', '').strip()return obfuscate_string(androidId + "@" + modelHash)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/96676.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/96676.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/96676.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

C/C++數據結構之循環鏈表

概述循環鏈表本質上也是一個單向或雙向鏈表&#xff0c;但其最后一個節點的指針并不指向NULL&#xff0c;而是指向鏈表的第一個節點&#xff0c;從而形成一個閉合的環。這種結構使得在遍歷鏈表時&#xff0c;可以從任意一個節點開始&#xff0c;并最終回到起始點。音樂播放軟件…

Mongodb的教程

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 前言 一、mongodb是什么&#xff1f; 二、mongodb的下載與安裝教程 三、mongodb的常見操作 總結 前言 在當今數據驅動的世界中&#xff0c;數據庫技術是構建高效…

MySQL視圖有什么用?一文讀懂虛擬表的六大核心價值

引言 在數據庫開發中&#xff0c;你是否遇到過這樣的困境&#xff1a;業務人員需要查看復雜關聯數據卻難以理解多表JOIN&#xff0c;或需要限制某些用戶只能訪問特定字段&#xff1f;MySQL視圖正是為此設計的"數據透視鏡"。本文將通過官方定義、典型場景和最佳實踐&a…

ubuntu24.04 frps服務器端自動啟動設置【2025-08-20】

Ubuntu 24.04采用systemd作為默認的init系統&#xff0c;我們可以通過創建systemd服務單元文件來實現開機自啟動。以下是具體實施步驟&#xff1a;創建服務文件使用文本編輯器創建服務配置文件&#xff1a;sudo nano /etc/systemd/system/frps.service編寫服務配置內容在文件中…

數據結構與算法-字符串、數組和廣義表(String Array List)

3 字符串、數組和廣義表&#xff08;String Array List&#xff09; 3.1 字符串&#xff08;String&#xff09; 3.1.1 串的順序存儲 a. 定長順序&#xff1a; #define MAXLEN 255 // 串的定長順序存儲結構 typedef struct {char ch[MAXLEN 1]; // 字符串數據&#xff0c;…

【網絡運維】Shell 腳本編程:if 條件語句

Shell 腳本編程&#xff1a;if 條件語句 if 條件語句概述 if 條件語句是 Linux Shell 腳本編程中最基礎且使用頻率最高的控制結構之一&#xff0c;其語義類似于自然語言中的“如果…那么…”。熟練掌握 if 語句的用法&#xff0c;是成為一名合格運維工程師的基本要求。 if 語句…

浮點型的位結構和表示的值

位結構float 各部分的含義 符號位&#xff1a; 為 0 表示正數&#xff0c;為 1 表示負數。 指數部分&#xff1a; 指數部分是一個移碼。指數部分有 8 位&#xff0c;首先當成無符號整型&#xff0c;則值域是 [0, 255] .因為是移碼&#xff0c;所以 移碼值 無符號整型值 - 127 …

39_基于深度學習的行人摔倒檢測識別系統(yolo11、yolov8、yolov5+UI界面+Python項目源碼+模型+標注好的數據集)

目錄 項目介紹&#x1f3af; 功能展示&#x1f31f; 一、環境安裝&#x1f386; 環境配置說明&#x1f4d8; 安裝指南說明&#x1f3a5; 環境安裝教學視頻 &#x1f31f; 二、數據集介紹&#x1f31f; 三、系統環境&#xff08;框架/依賴庫&#xff09;說明&#x1f9f1; 系統環…

【系統分析師】高分論文:論企業數據治理

【摘要】 2022年3月&#xff0c;我作為系統分析師及IT 負責人&#xff0c;參加了我司的企業級數據平臺建設項目&#xff0c;該項目作為我司在企業數字化轉型過程中重要的里程碑&#xff0c;在我司數字化運營中扮演著關鍵的角色。該項目主要包含企業級數據倉庫&#xff0c;數據治…

Seata原理分析

簡介Apache Seata? (incubating) 是什么&#xff1f;Seata 是一款開源的分布式事務解決方案&#xff0c;致力于在微服務架構下提供高性能和簡單易用的分布式事務服務。在 Seata 開源之前&#xff0c;其內部版本在阿里系內部一直扮演著應用架構層數據一致性的中間件角色&#x…

力扣 30 天 JavaScript 挑戰 第38天 (第九題)學習了 語句表達式的區別 高級函數 promise async await 節流

開始答題 版本一&#xff1a; /*** param {Function} fn* return {Function}*/ var once function(fn) {let runCount0return function(...args){runCountrunCount 1 ? return fn(...args) :return undefined} };/*** let fn (a,b,c) > (a b c)* let onceFn once(fn)…

25年八月份寧德時代社招部分崗位入職Verify測評演繹數字推理SHL題型變更、題庫使用說明

開始測評前&#xff0c;請注意:1、挑選一個安靜的環境&#xff0c;選擇一臺網速正常且無任何網絡端口限制的電腦進行測評;2、移動設備無法兼容遠程監考功能&#xff0c;請使用配備有可正常運作的攝像頭的臺式機或筆記本電腦&#xff0c;建議使用最新版本的Chrome&#xff0c;Fi…

【KO】前端面試四

以下是剩余題目的詳細解答,結合前端知識體系和實際應用場景展開: 91. JS 放在 head 里和放在 body 里有什么區別? 對比維度 放在 <head> 放在 <body> 加載阻塞性 會阻塞頁面渲染,需等待 JS 下載/執行完成后,才繼續渲染頁面 一般放在 </body> 前,頁面渲…

[Vid-LLM] 數據集 | 基準測試

第5章&#xff1a;數據集與基準測試 在前一章中&#xff0c;我們探討了**視頻大語言模型(Vid-LLMs)**能夠執行的各種"工作"或"功能"&#xff0c;從視頻總結到充當智能代理。 我們了解了它們的構建方式和扮演的角色。 但這里有個關鍵問題&#xff1a;這些驚…

34、擴展倉儲管理系統 (跨境汽車零部件模擬) - /物流與倉儲組件/extended-warehouse-management

76個工業組件庫示例匯總 擴展倉儲管理系統 (跨境汽車零部件模擬) 概述 這是一個高級的倉儲管理系統 (WMS) 模擬組件&#xff0c;專為展示跨境汽車零部件的復雜物流場景而設計。它模擬了從海外供應商發貨&#xff0c;經過海運/空運、清關、質檢&#xff0c;到最終入庫上架&am…

nodejs koa留言板案例開發

包含功能 登錄注冊(不開放注冊只是用固定的賬號信息) 查看列表 查看詳情 發布信息 編輯信息 刪除信息 項目接口 npm init -y npm install koa --save npm istall koa-router --save (舊版本) 或者 npm install koa/router --save &#xff08;新版本&#xff09; npm instal…

4+ 圖論高級算法

強連通分量 基礎概念 強連通&#xff1a;在有向圖 GGG 中&#xff0c;如果兩個點 uuu 和 vvv 是互相可達的&#xff0c;即從 uuu 出發可以到達 vvv , 從 vvv 也可以到達 uuu , 則稱 uuu 和 vvv 是強連通的。如果 GGG 中任意兩個點都是互相可達的&#xff0c;則稱 GGG 是強連通圖…

從羅永浩訪談李想中學習現代家庭教育智慧

引言 在這個信息爆炸的時代&#xff0c;每個父母都在尋找培養孩子的最佳方式。在羅永浩與理想汽車創始人李想的深度訪談中&#xff0c;我們看到了一個成功企業家童年成長的真實樣本。李想的成長經歷為現代家庭教育提供了許多值得深思的啟示。 一、正義感與樂觀精神的種子 李想回…

AI實現超級客戶端打印 支持APP 網頁 小程序 調用本地客戶端打印

核心思路都是&#xff1a;需要一個安裝在用戶電腦上的“中間人”程序&#xff08;本地客戶端&#xff09;來接管打印任務&#xff0c;然后通過某種通信方式命令這個客戶端進行打印。下面我將分平臺詳細闡述各種實現思路、優缺點和適用場景。一、核心思路與公共組件&#xff1a;…

Java集合(Collection、Map、轉換)

? 推薦使用 ? 已過時 1. Collection Collection 是集合框架的根接口之一&#xff0c;它是所有單列集合&#xff08;如 List、Set、Queue 等&#xff09;的公共父接口。Collection 接口定義了集合的基本操作&#xff0c;比如添加、刪除、遍歷等。 Collection ├── List │ …