更新
填坑|南X周易程序超出試用的解決辦法
(出處: 吾愛破解論壇)
1.緣起
前幾天在咱們論壇發了一篇x奧周易系列軟件逆向思路\更新了視頻演示,反響還不錯。然后正好找到了一款競品,就是下面這位了。其實這篇文章從發完X奧就一直在醞釀了,但是技術不過關,一直沒達到完美的欺騙效果。今天順藤摸瓜就摸到了一個關鍵點,改一下就好。如果不想看思路的就直接看第6部分,如果想看思路的就往下翻翻,看完全文,不過思路挺長的,但是如果您像我一樣,也是小白,看完還是有收獲的。
2.軟件介紹
八字、六爻、風水、奇門、姓名、擇吉、合婚,多種平臺上應用,不斷完善!
3.軟件列表(版本在支持系統里面有區分)
練手包下載地址在附件里
以下安卓手機軟件都可免費試用30次。
當然,跟著我做完以后就沒有使用限制了
批八字算命玄空風水綜合排盤六爻斷卦奇門適甲專業起名八字合婚擇吉程序金口訣八字用神南方萬年歷家居風水六爻排盤八字排盤4.支持系統
V1.73,適用于安卓系統4.0版至安卓7.11版。
V1.81,適用于安卓8.0及以上版本。
5.逆向程序
MT管理器
6.害,我都不好意思寫標題
方法很簡單,MT進入安裝包,DEX++編輯器打開classes.dex文件,打開An_xxxxxActivity,搜索add,第一個結果如下:
add-int/lit8 v0,v0,0x1
刪除這一行,一路保存后編譯、簽名。
好了,破解完了。
說句題外話,兄弟們,看著玩意沒用,這句add-int/lit8 v0,v0,0x1是我找出來的,不是你。就像我能按照小夜大佬交代的查找ChkNum來欺騙X奧系列軟件一樣。換成這個系列我又啥都不會了。所以你只看這句價值不大,想學點東西還得看下面的思路。
至于成品嘛,這么簡單你還好意思要成品?
7逆向過程
以“八字排盤 V1.73”為例,首先安裝原版軟件點完試用的30次,從第31次開始,則無法正常排盤,會引導注冊。如圖
我們點擊注冊,然后會彈出注冊頁面
然后有以下幾種情景:
? ? - 點擊“確定”,提示“您還沒有輸入注冊碼”
? ? - 隨便輸入注冊碼,點擊“確定”,提示“您輸入的注冊碼不對”
? ? - 點擊“退出”,則返回軟件主頁面
好了,直接進到MT管理器里,打開apk文件,使用DEX編輯器++打開classes.dex
隨便瀏覽一下類列表,有一個“activity_register”類。
然后點擊搜索,搜索上面幾個關鍵詞。
比如搜索“注冊”可以看到以下結果
我們點擊“您已經注冊了本程序”這一條,看到如下代碼:
? ? if-nez v1, :cond_96
? ? sget-boolean v1, Lcom/nfbazi/PaiBazi/a/a;->f:Z
? ? if-eqz v1, :cond_aa
? ? :cond_96
? ? const v1, -0xffff01
? ? invoke-virtual {v0, v1}, Landroid/widget/TextView;->setTextColor(I)V
? ? const-string v1, "您已經注冊了本程序。"
? ? invoke-virtual {v0, v1}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
? ? const-string v0, "************"
? ? invoke-virtual {v6, v0}, Landroid/widget/EditText;->setText(Ljava/lang/CharSequence;)V
? ? const/4 v0, 0x0
? ? invoke-virtual {v6, v0}, Landroid/widget/EditText;->setEnabled(Z)V
? ? :cond_aa
? ? return-void
.end method
這里面有兩條判斷:
? ? if-nez v1, :cond_96
? ? if-eqz v1, :cond_aa
關于Smali語法的解讀,我們可以參考這篇文章:
if-eq 如果等于
if-ne 如果不等于
if-lt 如果小于
if-le 如果小于等于
if-gt 如果大于
if-ge 如果大于等于
if-eqz 如果等于零
if-nez 如果不等于0
if-ltz 如果小于零
if-lez 如果小于等于零
if-gtz 如果大于零
if-gez 如果大于等于零
————————————————
版權聲明:本文為CSDN博主「Ceryool」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:
我們現在知道了
if-nez v1, :cond_96 #如果v1不等于0,就執行cond_96的代碼
if-eqz v1, :cond_aa #如果v1等于0,就執行cond_aa的代碼
我們通過第一個代碼塊可以發現cond_96的代碼就是包含"您已經注冊了本程序。"的那一堆,cond_aa返回空,就是什么都不返回。
可以推斷一下,未注冊的情況下,v1應該是0,注冊后,v1就不是0了,此時返回cond_96,也就是"您已經注冊了本程序。"
那我們就欺騙一下,讓未注冊情況下,也能返回"您已經注冊了本程序。"有兩種途徑可以實現此目的
? ? - 修改if-nez v1, :cond_96為if-eqz v1, :cond_96
? ? - 修改if-eqz v1, :cond_aa為if-eqz v1, :cond_96
修改之后,我們可以看到效果如圖
但是經過測試之后我發現,這只是個美化效果,也就是說,我們只是更改了外觀,并沒有欺騙軟件以達到注冊的目的
好,接下來接著操作。
回到MT管理器,先反編譯一下AndroidManifest.xml,這里是軟件權限,我感覺給它聯網權限不太好,那么刪除android.permission.INTERNET就行了
......
? ?
? ?
? ?
? ?
? ?
? ?
? ?
? ?
? ?
? ?
? ?
? ?
? ?
下面是軟件的Activity
? ?
? ?? ???
? ?? ?? ?? ?
? ?? ?
? ?? ?? ?? ?? ?
? ?? ?? ?? ?? ?
? ?? ?? ?? ?
? ?? ???
? ?
? ?? ???
? ?? ???
? ?? ???
? ?? ???
? ?? ???
? ?? ???
? ?? ???
? ?? ???
? ?? ???
? ?? ???
? ?? ???
? ?? ???
看完之后,接著使用DEX編輯器++打開classes.dex,剛才咱們修改了activity_register,并且發現這里面并不是驗證是否激活的關鍵所在。
然后看一眼An_PaiBaziActivity,畢竟這是主界面,信息會多一些。Smali可讀性比較差,我們轉化成Java代碼,可是代碼有很多,看哪?咱們在一開始測試過,試用次數沒了之后,再使用就會跳轉到軟件續用界面,那我們就搜一搜什么條件下跳轉,搜索我們在AndroidManifest.xml看到的RuanjianXuyong,然后我們發現就一處可以找到:
? ? public void b() {
? ?? ???Intent intent = new Intent();
? ?? ???intent.setClass(this, RuanjianXuyong.class);
? ?? ???startActivity(intent);
? ? }
這句代碼是什么意思呢。因為我沒學過Java。所以我也沒看明白,不過我清楚,肯定就是從這里跳轉到軟件續用界面去了。
我們不想見到軟件續用界面,因此就不能讓它intent.setClass(this, RuanjianXuyong.class);
所以,我就興致勃勃的在Smali代碼中定位RuanjianXuyong
.method public b()V
? ? .registers 3
? ? new-instance v0, Landroid/content/Intent;
? ? invoke-direct {v0}, Landroid/content/Intent;->()V
? ? const-class v1, Lcom/nfbazi/PaiBazi/RuanjianXuyong;
? ? invoke-virtual {v0, p0, v1}, Landroid/content/Intent;->setClass(Landroid/content/Context;Ljava/lang/Class;)Landroid/content/Intent;
? ? invoke-virtual {p0, v0}, Lcom/nfbazi/PaiBazi/An_PaiBaziActivity;->startActivity(Landroid/content/Intent;)V
? ? return-void
.end method
用我這腦子想,就是,我不想要哪一行就直接注釋掉哪一行,于是我在 const-class v1, Lcom/nfbazi/PaiBazi/RuanjianXuyong;前面加了一個#,然后心滿意足的轉進Java看了一眼,注釋錯了,然后我返回Smali代碼,又把 invoke-virtual {v0, p0, v1}, Landroid/content/Intent;->setClass(Landroid/content/Context;Ljava/lang/Class;)Landroid/content/Intent;注釋掉了,結果還是不行。
我不禁陷入了深思!我為啥要注釋掉它?因為我不想見到軟件續用??;那我想見到什么?肯定是排盤結果?。∧俏抑苯影裄uanjianXuyong替換成webshow不就行了嗎?!我可真是個小機靈鬼,說干就干。
然后我就把這行代碼改成了:
? ? const-class v1, Lcom/nfbazi/PaiBazi/webshow;
一路保存,反編譯,覆蓋安裝,排個八字
嘿嘿,劇本好像有點不一樣,軟件試用界面是沒了,排盤界面也出來了,可是內容去哪了?玩呢?氣得我腦瓜子嗡嗡的,算了,先不破了,看看這軟件哪里還有驗證的地方。。咋這么麻煩呢?
這還有一個顯示命例,按鈕,點進去一看就是個檔案夾的功能,可以時不時的把保存的案例拿出來復盤。然后我隨便點了一個,想要看看復原效果,結果又看到這個熟悉的面孔了:
事情進行到這里,我又要開始深思了
嗯~總的,我好像嗅到成功的味道了,突破點在試用次數上!試用期間功能不受限制,說干就干。成功我來了。
痛定思痛、細心研讀An_PaiBaziActivity的Java代碼(我能看懂?其實我就是看看我認識哪幾個單詞)
147行:如果我沒猜錯的話,trytimes就是試用次數吧,我真是個小機靈鬼
private void e() {
? ?? ???this.h = getSharedPreferences("trytimesxml", 0);
? ?? ???a.k = Integer.parseInt(this.a.b(this.h.getString("tms", this.a.a("65AB24201"))).substring(7, 9));
? ?? ???if (a.k < 32) {
? ?? ?? ?? ?a.k++;
? ?? ???}
? ?? ???this.h.edit().putString("tms", this.a.a("65AB242" + String.valueOf(h.e(a.k)))).commit();
? ?? ???a.d("trytimesxml");
? ?? ???a.a("trytimesxml.xml", "system.out");
? ? }
看完之后,啊,這段代碼就是。。嗯,,那啥的、、是吧。(球都沒看懂)
不過,這段代碼過于眼熟
? ?? ???if (a.k < 32) {? ?? ?? ?? ?? ? /*如果a.k < 32,就執行a.k++*/
? ?? ?? ?? ?a.k++;? ?? ?? ?? ?? ?? ?? ?? ?/*a.k++ 就是 a.k = a.k + 1*/
? ?? ???}? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ? /*a.k = a.k + 1就是說a.k每次加1*/
我混跡吾愛數載,一看這貨就是在計數,沒猜錯的話,應該是這樣的:
if(使用次數 < 32) {
? ? 使用次數++;
}
/*“使用次數”在具體程序中會對應不一樣的變量名,表示的都是使用次數的意思*/
然后我又開始我的腦洞了:
啊哈,直接把使用次數++;刪掉不就行了,我真是個小機靈鬼。當然上面是java代碼,咱不能修改,那咱就去改Smali代碼,怎么定位呢?反正我看不懂這東西,翻也不見得能翻到,先去網上沖一會兒浪:
ARM常用指令
ADD 加指令
SUB 減指令
STR 把寄存器內容存到棧上
LDR 把棧上內容載入一個寄存器中
.W 是一個可選指令寬度說明符。不會影響為此指令的行為,它只是確保生成32位指令。
BL 執行函數調用,并把使lr指向調用者的下一條指令,即函數的返回地址
BLX 同上,但是在ARM和thumb指令集間切換
CMP 指令進行比較兩個操作數的大小