目錄
專案
資料
Hooking
尋找 hook 的位置
HookCase
寻找 sub_100CC2E20
Hooking sub_100CC2E20
首頁 運維 安全 如何逆向分析Spotify.app並hook其功能取得數據

如何逆向分析Spotify.app並hook其功能取得數據

May 13, 2023 am 08:37 AM
app spotify

專案

該專案的目標是建立一個Spotify客戶端,讓它能夠學習我的聽曲習慣並跳過一些我通常會跳過的歌曲。不得不承認,這種需求來自於我的懶惰。我不想在當我有心情想要聽某些音樂時,創建或尋找播放清單。我希望的是在我的庫中選擇一首歌,然後可以隨機播放其他歌曲,並從隊列中刪除不“flow(節奏與旋律的流暢度)”的歌曲。

為了實現這一點,我需要學習某種能夠執行此任務的模型(在未來的帖子中可能更多)。但是為了能夠訓練一個模型,我首先需要資料來訓練它。

資料

我需要完整的聽歌歷史記錄,包括我跳過的那些歌曲。取得歷史記錄很簡單。雖然Spotify API僅允許取得最近50首播放的歌曲,但我們可以設定一個cron job來重複輪詢該端點。完整程式碼已經發佈在此處:https://gist.github.com/SamL98/c1200a30cdb19103138308f72de8d198

最困難的部分是追蹤跳過。 Spotify Web API並沒有為此提供任何的端點。之前我使用Spotify AppleScript API創建了一些控製播放的服務(本文的其餘部分將涉及到MacOS Spotify客戶端)。我可以使用這些服務來追蹤跳過的內容,但這感覺像是在迴避挑戰。我怎麼能完成它?

Hooking

我最近學習了解了有關hooking的技術,你可以在其中「攔截」從目標二進位產生的函數呼叫。我認為這將是追蹤跳過的最佳方法。

最常見的鉤子類型是interpose hook。這種類型的鉤子會覆蓋PLT中的重定位,但這究竟意味著什麼呢?

PLT或過程連結表允許你的程式碼引用外部函數(想想libc)而不知道該函數在記憶體中的位置,你只需引用PLT中的一個條目。連結器在運行時為PLT中的每個函數或符號執行「重定位」。這種方法的一個好處是,如果外部函數在不同的位址加載,則只需要更改PLT中的重定位,而不是每次對程式碼中該函數的參考。

因此,當我們為printf建立一個interpose hook時,每當我們hooking的程序呼叫printf時,我們將呼叫printf的實作而不是libc(我們的自訂函式庫通常也會呼叫標準實作) 。

在對鉤子有了一些基本的知識背景後,下面我們準備嘗試在Spotify中插入一個鉤子。但首先我們需要弄清楚我們想要hook的是什麼。

尋找 hook 的位置

如前所述,只能為外部函數建立一個interpose hook,因此我們將在libc或Objective-C runtime中尋找函數。

在研究在哪裡hook時,我認為一個開始hooking的好地方是Spotify處理「media control keys」或我MacBook上的F7-F9。假設這些鍵的處理程序在spotify應用程式中按一下Next按鈕被呼叫時會呼叫函數。我最終在:https://github.com/nevyn/spmediakeytap上找到了SPMediaKeyTap庫。我想我可以試一試,看看Spotify是否複製並貼上了這個庫中的程式碼。在SPMediaKeyTap庫中,有一個方法startWatchingMediaKeys。我在Spotify二進位檔案上執行了strings指令,看看他們是否有這個方法,果然:

如何逆向分析Spotify.app並hook其功能取得數據

Bingo!!如果我們將Spotify二進位檔案載入到IDA(當然是免費版本)並蒐索此字串,我們就會找到相應的方法:

如何逆向分析Spotify.app並hook其功能取得數據

##如果我們查看這個函數對應的源碼,我們會發現CGEventTapCreate函數的有趣參數tapEventCallback:

如何逆向分析Spotify.app並hook其功能取得數據

如果我們回顧一下反彙編,我們可以看到sub_10010C230子程式作為tapEventCallback參數傳遞。如果我們查看這個函數的原始碼或反彙編,我們看到只呼叫了一個函式庫函數CGEventTapEnable:

如何逆向分析Spotify.app並hook其功能取得數據

讓我們嘗試hook這個函數。

我們需要做的第一件事是建立一個函式庫來定義我們的自訂CGEventTapEnable。程式碼如下:

#include <corefoundation>
#include <dlfcn.h>
#include <stdlib.h>
#include <stdio.h>
void CGEventTapEnable(CFMachPortRef tap, bool enable) 
{
  typeof(CGEventTapEnable) *old_tap_enable;
  printf(“I'm hooked!\n”);
  old_tap_enable = dlsym(RTLD_NEXT, “CGEventTapEnable”);
  (*old_tap_enable)(tap, enable);
}</stdio.h></stdlib.h></dlfcn.h></corefoundation>
登入後複製
dlsym函式呼叫取得實際函式庫CGEventTapEnable函數的位址。然後我們呼叫舊的實現,這樣我們就不會意外地破壞任何東西。讓我們像這樣編譯我們的函式庫(https://ntvalk.blogspot.com/2013/11/hooking-explained-detouring-library.html):

gcc -fno-common -c <filename>.c 
gcc -dynamiclib -o <library> <filename>.o</filename></library></filename>
登入後複製

现在,让我们尝试在插入钩子时运行Spotify:DYLD_FORCE_FLAT_NAMESPACE=1 DYLD_INSERT_LIBRARIES= /Applications/Spotify.app/Contents/MacOS/Spotify。点击进入:

如何逆向分析Spotify.app並hook其功能取得數據

Spotify打开正常,但Apple的系统完整性保护(SIP)没有让我们加载未签名库:(。

幸运的是,我是Apple的reasonably priced developer项目的成员,所以我可以对库进行代码签名。这个问题算是得到了解决。让我们用100美元证书签名我们的库,运行上一个命令,然后......

如何逆向分析Spotify.app並hook其功能取得數據

失败。这一点不奇怪,Apple不允许你插入使用任何旧标识签名的库,只允许使用签名原始二进制文件时使用的库。看起来我们必须要找到另一种方法来hook Spotify了。

作为补充说明,细心的读者可能会注意到我们hook的函数CGEventTapEnable,只有在media key event超时时才会被调用。因此,即使我们可以插入钩子,我们也可能不会看到任何的输出。本节的主要目的是详细说明我最初的失败(和疏忽),并作为一个学习经验。

HookCase

经过一番挖掘,我发现了一个非常棒的库HookCase:https://github.com/steven-michaud/HookCase。HookCase让我们实现一种比插入钩子( patch hook)更为强大的钩子类型。

通过修改你希望hook的函数触发中断插入Patch hooks。然后,内核可以处理此中断,然后将执行转移到我们的个人代码中。对于那些感兴趣的人,我强烈建议你阅读HookCase文档,因为它更为详细。

Patch hooks不仅允许我们对外部函数的hook调用,而且允许我们hook目标二进制文件内的任何函数(因为它不依赖于PLT)。HookCase为我们提供了一个框架来插入patch和/或interpose hooks,以及内核扩展来处理patch hooks生成的中断,并运行我们的自定义代码。

寻找 sub_100CC2E20

既然我们已经有办法hook Spotify二进制文件中的任何函数了,那么只剩下最后一个问题......就是位置在哪?

让我们重新访问SPMediaKeyTap源码,看看如何处理媒体控制键。在回调函数中,我们可以看到如果按下F7,F8或F9(NX_KEYTYPE_PREVIOUS,NX_KEYTYPE_PLAY等),我们将执行handleAndReleaseMediaKeyEvent选择器:

如何逆向分析Spotify.app並hook其功能取得數據

然后在所述选择器中通知delegate:

如何逆向分析Spotify.app並hook其功能取得數據

让我们看看repo中的这个delegate方法:

如何逆向分析Spotify.app並hook其功能取得數據

事实证明它只是为处理keys设置了一个模板。让我们在IDA中搜索receiveMediaKeyEvent函数,并查看相应函数的图形视图:

如何逆向分析Spotify.app並hook其功能取得數據

看起来非常相似,不是吗?我们可以看到,对每种类型的键都调用了一个公共函数sub_10006FE10,只设置了一个整数参数来区分它们。让我们hook它,看看我们是否可以记录按下的键。

我们可以从反汇编中看到,sub_10006FE10获得了两个参数:1)指向SPTClientAppDelegate单例的playerDelegate属性的指针,以及2)指定发生了什么类型事件的整数(0表示暂停/播放,3表示下一个,4表示上一个)。

看看sub_10006FE10(我不会在这里包含它,但我强烈建议你自己检查一下),我们可以看到它实际上是sub_10006DE40的包装器,其中包含了大部分内容:

如何逆向分析Spotify.app並hook其功能取得數據

哇!这看起来很复杂。让我们试着把它分解一下。

从这个图的结构来看,有一个指向顶部的节点有许多outgoing edges:

如何逆向分析Spotify.app並hook其功能取得數據

正如IDA所建议的那样,这是esi(前面描述的第二个整数参数)上的switch语句。看起来Spotify的处理的不仅仅是Previous,Pause/Play和Next。让我们把关注点集中到处理Next或3 block:

如何逆向分析Spotify.app並hook其功能取得數據

不可否認,為此我花了一些時間,但我想請你注意底部第四行的call r12。如果你查看其他的一些情況,你會發現一個非常相似的呼叫暫存器的模式。這似乎是一個很好的函數,但我們如何知道它在哪裡?

讓我們開啟一個新工具:debugger(偵錯器)。我最初嘗試調試Spotify時遇到了很多麻煩。現在可能是因為我對調試器不太熟悉的原因,但我認為我想出了一個相當聰明的解決方案。

我們先在sub_10006DE40上設定一個hook,然後我們在程式碼中觸發一個斷點。我們可以透過執行彙編指令int 3來做到這一點(例如像GDB和LLDB之類的偵錯)。

以下是在HookCase框架中hook的樣子:

如何逆向分析Spotify.app並hook其功能取得數據

將此加入HookCase範本庫後,你也必須將其加入user_hooks陣列:

如何逆向分析Spotify.app並hook其功能取得數據

然後我們可以使用Makefile HookCase提供的模板來編譯它。然後可以使用以下指令將庫插入Spotify:HC_INSERT_LIBRARY= /Applications/Spotify.app/Contents/MacOS/Spotify。

然後我們可以執行LLDB並將其attach到正在運行的Spotify進程,如下所示:

如何逆向分析Spotify.app並hook其功能取得數據

嘗試按F9(如果Spotify不是活動窗口,它可能會打開iTunes)。鉤子中的int $3行應該觸發了調試器。

現在我們可以進入到sub_10006DE40入口點這一步。請注意,PC將位於與IDA中顯示的位址相對應的位置(我認為這是由於進程載入到記憶體的位置所導致的)。在我目前的進程中,push r15指令位於0x10718ee44:

如何逆向分析Spotify.app並hook其功能取得數據

在IDA中,該指令的位址為0x10006DE44,它給了我們一個偏移量0x7121000。在IDA中,呼叫r12指令的位址為0x10006E234。然後我們可以將偏移量加到該位址,並相應地設定一個斷點,b -a 0x10718f234,然後繼續。

當我們點擊目標指令時,我們可以列印出暫存器r12的內容:

如何逆向分析Spotify.app並hook其功能取得數據

我們要做的就是從這個位址減去偏移量,看,我們取得到了我們名義上的地址:0x100CC2E20。

Hooking sub_100CC2E20

現在,讓我們來hook這個函數:

如何逆向分析Spotify.app並hook其功能取得數據

將其加入到user_hooks數組,編譯,運行,並觀察:每次按F9或點選Spotify應用程式中的next按鈕,都會記錄我們的訊息。

現在我們已經hook了skip功能,

如何逆向分析Spotify.app並hook其功能取得數據

我將發布剩餘的程式碼,但我不會完成其餘部分的逆向工作,因為這篇文章已經夠長的了。

簡而言之,我也hook了previous功能(如果你照著做的話,這會是一個很好的練習)。然後,在這兩個鉤子中,我首先檢查當前的歌曲是否已經過了一半。如果是的話,我什麼都不做,假設我只是對這首歌感到厭倦,而不是覺得它不合適。然後在backs (F7),我彈出last skip。

針對如何檢查當前歌曲是否已經過了一半的方法我想說幾句。我最初的方法是實際呼叫popen,然後運行相應的AppleScript命令,但感覺這不太對。

我在Spotify二進位檔案上運行了class-dump,發現了兩個類別:SPAppleScriptObjectModel和SPAppleScriptTrack。這些方法公開了播放位置,持續時間和曲目ID所需的必要屬性。然後,我為這些屬性hook了getter,並使用next和back hooks調用它們(我認為Swizzle更合理,但我無法讓它正常工作)。

我使用一個檔案來追蹤skips,其中第一行包含跳過次數,在跳過時我們增加這個計數器,並將追蹤ID和時間戳寫入計數器指定行上的檔案。在back按鈕,我們只是減少這個計數器。這樣,當我們按下back按鈕時,我們只是將檔案設定為對已回溯檔案寫入new skips。

以上是如何逆向分析Spotify.app並hook其功能取得數據的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

京東商城APP如何進行實名認證 京東商城APP如何進行實名認證 Mar 19, 2024 pm 02:31 PM

京東商城APP實名認證怎麼搞?京東商城是許多朋友常用的網路購物平台,大家在購物前,最好先進行實名認證,這樣才能享受到完整的服務,獲得更好的購物體驗。以下帶來京東商城實名認證方法,希望對網友們有幫助。 1.安裝並開啟京東商城,接著登入個人帳號;2、然後點選頁面下方【我的】,進入個人中心頁面;3、之後再點選右上角的【設定】小圖標,前往設定功能介面;4、選擇【帳號與安全】這一項,來到帳戶設定頁面;5、最後再點擊【實名認證】選項,前往填寫實名資訊;6、安裝系統要求填寫個人真實信息,完成實名認證

cocos2d-LUA逆向中如何解密app資源 cocos2d-LUA逆向中如何解密app資源 May 16, 2023 pm 07:11 PM

還是以大神apk為例,透過前面分析app解密lua腳本,我們能夠解密大神apk的lua腳本,現在我們來解密其資源(設定檔和圖片等)。我們以比較重要的設定檔為例,未解密之前:檔案頭也有簽名值:fuckyou!。看到這,我們首先就想到是不是也是用xxtea加密的,我們用上面的方法,先xxtea解密,再解壓,發現依舊是亂碼,在操作的過程中就出現了錯誤,顯然,要否定我們剛才的猜想。我們繼續按部就班的解密設定檔。稍微思考一下,文件頭部是:fuckyou!如果想要對文件進行解密,那麼不可避免的需要處理

Spotify AI DJ未在Android或桌上型電腦上顯示 Spotify AI DJ未在Android或桌上型電腦上顯示 Feb 20, 2024 am 09:36 AM

SpotifyAIDJ是最新推出的功能,能為用戶提供個人化的音樂推薦服務。如果您在Android或桌面上找不到SpotifyAIDJ,本文將引導您解決這個問題。透過人工智慧技術,SpotifyDJ模擬了人類DJ的音樂選擇過程,為使用者帶來更出色的音樂體驗。在繼續排查問題之前,請確保您的網路連線是穩定的。您可以嘗試重新啟動WiFi路由器,看看是否有任何改善。另外,您也可以查看Spotify伺服器的運作狀態。關注@SpotifyStatus(Twitter帳號)可以取得最新資訊。如果伺服器出現問題,耐

註冊香港AppleID的步驟及注意事項(享受香港AppleStore的獨特優勢) 註冊香港AppleID的步驟及注意事項(享受香港AppleStore的獨特優勢) Sep 02, 2024 pm 03:47 PM

在全球範圍內,Apple公司的產品和服務一直備受用戶喜愛。註冊一個香港AppleID將帶給用戶更多的便利和特權,讓我們一起來了解一下註冊香港AppleID的步驟以及需要注意的事項。如何註冊香港AppleID在使用蘋果設備時,許多應用程式和功能都需要使用AppleID進行登入。如果您想下載香港地區的應用程式或享受香港AppStore的優惠內容,那麼註冊一個香港AppleID就非常必要。本文將詳細介紹如何註冊香港AppleID的步驟以及需要注意的事項。步驟:選擇語言與地區:在蘋果設備上找到「設定」選項,進入

中國聯通app怎麼退訂流量包 中國聯通怎樣退訂流量包 中國聯通app怎麼退訂流量包 中國聯通怎樣退訂流量包 Mar 18, 2024 pm 10:10 PM

中國聯通app能夠輕鬆的滿足大家的使用,多樣的功能,解決你們的需求,想要辦理各種業務,都可以在這裡輕鬆的搞定,有不需要的都可以在這裡及時的退訂掉,有效的避免後續的損失,很多人在使用手機時,有時感覺流量不夠用,就購買了額外的流量包,但下個月又不想要要,就想要馬上的退訂掉,在這裡小編為大家提供退訂的方法,讓需要的朋友們,都可以來使用起來!  在中國聯通app中,找到右下角的「我的」選項,點擊它。  在我的介面裡,滑動我的服務一欄,點擊其中的「我已訂購」選

多點app如何開發票 多點app如何開發票 Mar 14, 2024 am 10:00 AM

發票作為購物憑證,對於我們的日常生活和工作都至關重要。那麼我們平常在使用多點app進行購物的時候,如何在多點app中輕鬆開立發票呢?下文中本站小編將為大家帶來詳細的多點app開立發票詳細操作步驟攻略,想要了解的用戶們千萬不容錯過,快來跟著文本一起操作了解一下吧!在【發票中心】點選【多點超市/自由購】在已完成的訂單頁中選擇需要開立發票的訂單,點選下一步填寫【發票資訊】,【收件者資訊】,確認無誤後點選提交過個幾分鐘後,進入收件信箱,打開郵件,點選電子發票下載地址最後,下載列印電子發票

如何利用深度連結方式後門化Facebook APP 如何利用深度連結方式後門化Facebook APP May 19, 2023 pm 02:49 PM

近期,作者發現了Facebook安卓APP應用的一個深度連結漏洞,利用該漏洞,可以將用戶手機上安裝的Facebook安卓APP應用轉變成後門程式(Backdoor),實現後門化。另外,利用該漏洞還可以重打包FacebookAPP,並將其傳送給特定目標受害者安裝使用。以下就來看看作者對此漏洞的發現過程,以及如何透過Payload構造,最終將其轉化為FacebookAPP實際生產環境中的安全隱患。漏洞發現通常做眾測時,我會先認真了解目標系統的應用機制。在我的上一篇部落格中,我已經分享了透過解析Face

Spotify 在 iOS 和 Android 上推出'迄今為止最大的進化” Spotify 在 iOS 和 Android 上推出'迄今為止最大的進化” May 28, 2023 pm 03:53 PM

在今天的「StreamOn」活動中,Spotify展示了針對其iOS和Android應用程式推出的重大改革。兩個最大的組成部分包括主頁提要中音樂、播客和有聲讀物的視訊和音訊預覽,以及用於在搜尋中發現的新視訊提要。該公司將主要的UI改革稱為“一個新的、動態的行動介面,旨在更深入地發現藝術家和粉絲之間更有意義的聯繫”,並且它是“我們迄今為止最大的進步”。 Spotify表示,“下一代聽眾渴望在完全沉浸之前以更好的方式對音訊進行採樣”,這就是為什麼它正在通過“全新的互動式設計”轉向“更積極的體驗

See all articles