2020年 IOS 逆向 反編譯 注入修改遊戲或APP調用參數系列新手教程——按鍵精靈腳本來模擬合成燈籠
開篇
首先聲明此教程僅做學習交流和知識記錄方便以後查看使用,如果涉及到利益相關的請告知本人進行刪帖處理。
2020年 IOS 逆向 反編譯 注入修改遊戲或APP調用參數系列新手教程,之所有特別提出是2020年的是因爲很多老的方法失效了,網絡上大部分的教程都是基於2018年左右的IOS10及以下老版本來破解,而且教程新手很難看明白,噹噹就安裝這些破解工具的環境的坑之多就足以勸退很多新手😭。本系列教程會列出破解的環境及工具版本,儘量避免新手入坑。
本人其實是對IOS領域從零開始的,都是通過看網上的博文和相關視頻資料自學的,之前是搞PHP和Python等後臺服務器程序的,對編程這方面是有熱情和多年積累的。爲什麼會想搞IOS的破解,就是因爲玩的一款遊戲想改裏面的頭像,做成動態GIF的顯示,遊戲里正常上傳圖片是會被裁剪的,導致動圖被剪成靜態jpg;還有一個合成燈籠🏮小遊戲,類似什麼合成豪車,陽光養豬場那種合成遊戲,我想寫個腳本讓它自動合成;還有修改遊戲的金幣啊、分數啊。就是覺得好玩~😂,OK,我這種學習過程是結果來驅動過程的,先把大的理念想好,接下來就是瀑布流一樣的把所需要的知識點逐一分解,碰到哪裏不懂就學哪裏,最終實現我要的效果!並且學到了很多知識,對各類APP的修改也就得心應手了。其實編程的樂趣就是在於最終結果如願以償後的那種成就感。
感覺我把很多語言和工具都折騰過了~,後端、前端、手機端、遊戲、都涉獵了。這些年接觸很多語言,從開始C 、C++、Java、PHP、易語言、Python、還有很多web的js等組件、shell腳本、還有linux和kali等操作系統的黑客工具,折騰過各種工具、到最近學習的IOS objective-c等,接觸多了,實際上語言只是實現的工具,語言的思路是一樣的,就是數據結構+算法,不同語言只是語法的不同,寫得好的軟件是要用到設計模式的。學編程應該瞭解一下。計算機真是博大,0與1就衍生出這麼多形式的計算機世界,就好比道生一一生二二生三三生萬物一樣,世界也如此,萬物歸根結底其實都是一,或者說是"道",抱歉,老子的道家書看多了😁。編譯是從高級語言翻譯成彙編、然後彙編又翻譯成機器語言、機器只知道1和0,所有語言最終都會被轉換成1和0被機器識別執行。當然這是對現代計算機的說法,未來量子計算機應該會改變這種0和1的傳統模式吧。反編譯就是從機器代碼中轉換成彙編再把彙編翻譯成僞代碼,通過僞代碼一般能讀懂七七八八以此來進行破解。
本人想通過這些博客記錄自己這兩週內折騰的過程以及分享最後成功的成果。另外想結交志同道合對IT行業感興趣的盆友,互相交流學習。可以通過博客聯繫我或加QQ號:1321691245
需求&最終效果
對於從來沒開發過IOS程序的我要怎麼搞?從何學起?
首先先講我上面提到的第二個我要實現的需求,讓燈籠自動合成。其他需求我會新寫文章來分享,大家可以關注或加我聯繫方式。
下圖是某遊戲的合成燈籠界面,通過拖拽把相同的燈籠合成更高一級的燈籠。我想用腳本來自動合成,完全自動化。
下圖是實現後的效果
通過腳本大大提高合成速度!
其實這裏並不是用到反編譯和逆向的知識,只是用了按鍵精靈寫了模擬合成的腳本,本篇文章就先講按鍵精靈的使用吧,反編譯的其他知識後面我會逐一分享,因爲這個按鍵精靈也是我這段時間折騰的一部分。
進入正題
折騰吧😂
環境要求與即將使用的工具
環境 | 版本 |
---|---|
操作系統 | 本人的mac是雙系統(MacOSX和win7),按鍵精靈腳本需要在windows開發 |
按鍵精靈手機助手 for windows | 3.5.2 |
按鍵精靈IOS版 | 1.5.2 |
手機系統 | Iphone7 IOS11 需要越獄 |
思路
一開始我的做法:
怎麼讓腳本知道是兩個相同的燈籠,然後又怎麼模擬燈籠拖拽去合併?我想到了按鍵精靈,早起用過電腦版的用來輔助遊戲,想不到現在有手機版的了!所以想看看怎麼弄,我基本也是從零學起的。瞭解按鍵精靈IOS版 可以模擬我們人手的任何觸摸指令,我就有信心做這個合成判斷了,按鍵精靈的代碼是MQ語言,有相關手冊大家可以去看。
思路是把12個燈籠區域分割成12個區域,座標存放在數組中,然後拿每一個燈籠來和第一個燈籠比較特徵,特徵相同就觸發模擬拖拽合併。
另一種做法:用冒泡算法不判斷色點,簡單粗暴每個格子都移動合併,不管是不是相同燈籠,沒想到效率更高!代碼更簡單效率更快!
實現代碼
這裏只列出核心代碼,具體代碼見:github
ShowMessage "啓動腳本。。。。。"
// 橫屏
//x
//|__ y
Dim offsetX = 260
Dim offsetY = 292
Dim CloseXPoint = array(988,2010)
// 3 個特徵點 array(y, x)
Dim point1 = array(876, 760)
Dim point2 = array(833,777)
Dim point3 = array(894,757)
// 第一個燈籠的特徵
Dim firstDengLong = array(array(point1(0), point1(1), GetPixelColor(point1(0), point1(1))), array(point2(0), point2(1), GetPixelColor(point2(0), point2(1))), array(point3(0), point3(1), GetPixelColor(point3(0), point3(1))) )
Dim dengLongArr = array()
Dim i=0,count=0
// 所有燈籠的比較座標點,12個 [[[5,3],[3,1]] , [[5,3],[3,1]]]
// 12 次循環
For i = 0 To 2
dim j = 0
For j = 0 To 3
dengLongArr(count) = array()
// 類似 dengLongArr[count][0]
dengLongArr(count, 0) = Array(firstDengLong(0, 0) - i * offsetX, firstDengLong(0, 1) + j * offsetY)
dengLongArr(count, 1) = Array(firstDengLong(1, 0) - i * offsetX, firstDengLong(1, 1) + j * offsetY)
dengLongArr(count, 2) = Array(firstDengLong(2, 0) - i * offsetX, firstDengLong(2, 1) + j * offsetY)
count = count + 1
Next
Next
// 合併燈籠
Function heBingDengLong()
i = 0
j = 0
// 第一個燈籠的特徵
Dim firstDengLong = array(array(point1(0), point1(1), GetPixelColor(point1(0), point1(1))), array(point2(0), point2(1), GetPixelColor(point2(0), point2(1))), array(point3(0), point3(1), GetPixelColor(point3(0), point3(1))) )
Dim currDengLongColorArr = array()
// 11 次循環
For i = 0 To 11
currDengLongColorArr = array( GetPixelColor(dengLongArr(i,0,0), dengLongArr(i,0,1)), GetPixelColor(dengLongArr(i,1,0), dengLongArr(i,1,1)), GetPixelColor(dengLongArr(i,2,0), dengLongArr(i,2,1)))
For j = 1 To 11
closeX ()
closeComm()
TracePrint "這一點"
dim str = dengLongArr(j,0,0)&"|"& dengLongArr(j,0,1) & "|" & currDengLongColorArr(0) & "-101010," & dengLongArr(j,1,0)&"|"& dengLongArr(j,1,1) & "|" & currDengLongColorArr(1) & "-101010," & dengLongArr(j,2,0)&"|"& dengLongArr(j,2,1) & "|" & currDengLongColorArr(2) & "-101010"
If Not(i = j) and CmpColorEx(str, 0.9 ) = 1 Then
TracePrint str & "找到沒有" & i+1 & "->" & j+1
// 合併燈籠
heBingDengLongTouch (dengLongArr(i,0,0), dengLongArr(i,0,1), dengLongArr(j,0,0), dengLongArr(j,0,1))
//EndScript
//Exit For
Else
//TracePrint 0
End If
Next
Next
End Function
Function hebingDengLong2()
i = 0
j = 0
Dim temp
// 11 次循環
For i = 0 To 10
closeX ()
closeComm()
temp = i
For j = 0 To 10
heBingDengLongTouch (dengLongArr(temp,0,0), dengLongArr(temp,0,1), dengLongArr(j,0,0), dengLongArr(j,0,1))
temp = j
Next
Next
End Function
// 移動指定燈籠到第一位置
Function moveToFirst(number)
TracePrint "----------------------------" & number
TouchDown dengLongArr(number-1,0,0),dengLongArr(number-1,0,1), 1//按住屏幕上的100,100座標不放,並設置此觸點ID=1
TouchMove firstDengLong(0,0),firstDengLong(0,1), 1//將ID=2的觸點花200毫秒移動至500,500座標
TouchUp 1//鬆開彈起ID=1的觸點
// TracePrint "移動力"
End Function
// 拖拽合併
Function heBingDengLongTouch(x1, y1, x2, y2)
TracePrint "----------------------------"
TouchDown x1,y1, 1//按住屏幕上的100,100座標不放,並設置此觸點ID=1
TouchMove x2, y2, 1//將ID=1的觸點花200毫秒移動至500,500座標
TouchUp 1//鬆開彈起ID=1的觸點
End Function
// 關
Function closeX()
// 免費升級的點擊
//各種彈層的關閉處理
End Function
Function closeComm()
// 也是各種彈層的關閉處理
End Function
Function isInGameWindow()
// 是否在遊戲窗口的判斷
End Function
// 廣告處理
Function adProcc()
// 各種廣告處理。。。。
TracePrint "開始廣告處理................"
// 存在倒計時形式的x按鈕
// 誤入橫版的app store 顯示頁面
End Function
// 腳本主函數
Function heBingDengLongMain()
For ii = 1 To 12
closeX ()
closeComm()
If hasShadowWindow() = False Then
// 原始的判斷邏輯,效率低
hebingDengLong()
// 如果想用第二種合併處理邏輯的話,上面的For可以去掉,下面的moveToFirst()也要去掉
//hebingDengLong2()
moveToFirst (ii)
Else
TracePrint "不合並"
End If
Next
End Function
If isInGameWindow() = False Then
TracePrint "不在遊戲界面"
ShowMessage "不在遊戲界面"
Delay 2000
adProcc()
Else
heBingDengLongMain()
End If
首先我用按鍵精靈窗口裏面的抓抓功能取點,取第一張圖片中第一個燈籠“SKR”的特徵,我採用三個色點來作爲一個燈籠的特徵。
第一個單元的3 個特徵點座標:
Dim point1 = array(876, 760)
Dim point2 = array(833,777)
Dim point3 = array(894,757)
然後
Dim offsetX = 260
Dim offsetY = 292
指的是12個格子單元的橫縱距離,也叫格子與格子之間的偏移量吧,這個是根據屏幕分辨率來算的,大屏小屏的手機是不同的,我這個腳本沒有做到適應多屏幕兼容,按鍵精靈有自動兼容多分辨率的函數,我就沒實現了,是用的iphone7 Pro 的1920×108的分辨率,換個手機就不準了哦。這裏主要講思路。
firstDengLong是指第一燈籠的特徵。
然後下面有一個嵌套For循環,就是通過偏移量算出12個格子的座標點,用來比色的點。放在dengLongArr數組裏面。
然後翻代碼看最底部。
isInGameWindow()是判斷當前窗口是否在遊戲界面,先講是的情況,會進入到heBingDengLongMain()就是合併燈籠的主主函數。首先執行closeX ()和 closeComm()是爲了關閉遊戲界面的離線收益遮罩層,因爲經常會彈出翻倍和升級提示的窗口,不關閉觸摸就失效了。總之人的操作是什麼順序邏輯的,腳本也是根據各種情況來做判斷的。然後進入具體合併邏輯hebingDengLong(),通過數組的遍歷,逐個拿出來和第一個燈籠的特徵比較,如果特徵一樣證明是相同級別的燈籠可以合併,
模擬拖拽的代碼就在heBingDengLongTouch()裏面,知道源座標點和目的座標點就能實現拖拽啦。核心就是每一個燈籠來和第一燈籠比較。合併後再在heBingDengLongMain()裏面有一個
moveToFirst (ii)的操作,就是保證每個燈籠有機會移動至第一個格子,有被拿來比較的機會。
雖然是實現了,但是效率太低,後面我用了另外的代碼實現,不需要比較特徵,簡單粗暴高效的做法,不判斷是否相同燈籠,直接每每合併得了,反而更快!代碼在hebingDengLong2()方法裏面。類似冒泡算法。
不再遊戲窗口的情況時就判斷是否在看廣告的界面的處理,經常會誤點擊到廣告,或者某些升級燈籠的彈窗需要來看廣告提高進度,是一種判斷策略吧,某些廣告看了收益高某些廣告彈窗就直接close X掉。
然後廣告處理部分也是抓取關閉按鈕特徵來判斷,具體代碼見github。
額外
shell 定時任務
其實上面的動圖之所有每格幾秒都有離線收益拿是因爲我利用了遊戲的一個bug實現的,這裏我就不透漏bug了,我手機裏面運行着shell的定時任務的腳本才能每隔幾秒就收穫離線收益。這裏我分享一下IOS手機裏面怎麼使用定時任務吧。
linux的定時任務是通過crontab來配置的,而ios是通過LaunchDaemons來實現的。配置文件寫在/Library/LaunchDaemons/下面。
比如我的配置文件(com.apple.mycrontest.plist)這樣定義
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.apple.mycrontest.plist</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>/var/root/myshelltest.sh</string>
</array>
<key>StartInterval</key>
<integer>1</integer>
</dict>
</plist>
以上配置文件指出每隔10秒執行一次/var/root/myshelltest.sh腳本。至於shell腳本里面寫了啥我就不說了,是實現離線收益的方式。
打開手機terminal命令行軟件,沒有的話去cydia搜索相關資源下載。
然後啓動配置文件命令如下:
launchctl load /Library/LaunchDaemons/com.apple.mycrontest.plist
需要root權限。
就會定時執行/var/root/myshelltest.sh啦
如果想關閉定時任務則:
launchctl unload /Library/LaunchDaemons/com.apple.mycrontest.plist
通過shell腳本和按鍵精靈腳本,實現了自動離線收益和自動合併燈籠的需求!😁
這是本人第一次寫按鍵精靈腳本,沒想到折騰一番還能搞出點花樣~因爲有了這一次成果,我纔有更大的需求,想改遊戲邏輯,這就需要用到逆向和IOS開發的知識了,致使我一步步折騰併入坑…
結束
此教程僅做學習交流和知識記錄方便以後查看使用,如果涉及到利益相關的請告知本人進行刪帖處理。
本人想通過這些博客記錄自己這兩週內折騰的過程以及分享最後成功的成果。另外想結交志同道合對IT行業感興趣的盆友,互相交流學習。可以通過博客聯繫我或加QQ號:1321691245
今天就先寫到這,後面我再把我學習的其他相關知識分享給大家。下一篇就介紹bfinject進行脫殼打包和注入dycript的相關知識吧。
博文主索引目錄入口
我會把這系列的文章更新到這個入口裏面,分享我的心得,大家互相學習。
2020年 IOS 逆向 反編譯 注入修改遊戲或APP的調用參數新手系列教程主目錄入口