0x00 Preface
Preposition
Thank you for the total cultivation of eggs. This article was first published in spring and autumn. I do not agree to prohibit reprinting.
Explain
First of all, I would like to write NDK, but let's go through this process first. This process is essential.
Secondly, RMB is really a good thing.
time
At 23:05:33 on February 11, 2018, I wrote about it and went to bed.
Navigation
Because I do not want to paste too much code in order to save time, so I summarized a navigation column. And there is a description in the column. Help understand. Hope to make progress together.
Blog Series Navigation
In order to practise conveniently, apk is arranged by the way.
Exercise portal
content
1. Internal Purchasing Base
0x01 Buy-in Knowledge
Basic knowledge
What is internal purchase?
Buying in is purchasing in-game.
SDK manufacturers
1. Mobile
2. Telecommunications
3. Unicom
4. Alipay
5. WeChat
6. other
Other solutions
Thumb play
Cyberswordsman Mobile Station
7723
AI Wu
7yw fun tour
Soft sky
Xixi Software Park
The third floor of Hulu Xia
Game platform
1. Migu Game
Experience Summary of 0x02
General Summary of Key Points
General 1
The oldest way is to search for keywords:
"Success"
"Failure"
Bypassing the general purpose
switch
(1) Overlay switch failures turn to success.
(2) Change switch jump
(3) The last one, which I like best, has the clearest idea and uses goto to jump. Jump to success.
Summary of Migu Game
Method: onResult
Mobile summary
onbillingfinish()
dobilling()
onresult()
Unicom summary
payCallback()
PayResult()
Telecom summary
paySuccess()
Alipay summary
Failure to pay
9000
ResultStaus
0x03 Migu game cracking example
It can't be said that it's because of the space problem. It's just a little lazy and doesn't want to intercept some simple steps. So it can be abbreviated, so it can analyze several examples.
I just found an example.
Original version apk: Exercise portal Look here, number: 2001
Case study (1)
Suspension: 12 February 2018 00:34:05
Reason: It was noisy that my father was sleeping.
Starting time: 12 February 2018 14:58:17
Step 1: Try it out.
Play yourself
Step 2: Decompile and search for keywords.
1. Search for Success
Three data were searched here.
After the point goes in, there is such a method:
.method public static d()V
.locals 4
const/4 v3, 0x1
const/4 v2, 0x0
sget v0, Lcom/xy/kom/d/bk;->i:I
invoke-static {v0}, Lcom/xy/kom/g/p;->b(I)Z
sget v0, Lcom/xy/kom/d/bk;->h:I
invoke-static {v0}, Lcom/xy/kom/g/p;->c(I)Z
sget-boolean v0, Lcom/xy/kom/d/bk;->G:Z
if-eqz v0, :cond_4
sget-object v0, Lcom/xy/kom/GameActivity;->A:Lcom/xy/kom/GameActivity;
iget-object v0, v0, Lcom/xy/kom/GameActivity;->m:Lcom/xy/kom/g/p;
invoke-virtual {v0}, Lcom/xy/kom/g/p;->x()Ljava/util/ArrayList;
move-result-object v0
invoke-static {}, Lcom/xy/kom/g/f;->l()Lcom/xy/kom/g/f;
move-result-object v1
invoke-virtual {v0, v1}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z
:goto_0
sget-object v0, Lcom/xy/kom/GameActivity;->A:Lcom/xy/kom/GameActivity;
iget-object v0, v0, Lcom/xy/kom/GameActivity;->m:Lcom/xy/kom/g/p;
invoke-virtual {v0}, Lcom/xy/kom/g/p;->t()V
sget-object v0, Lcom/xy/kom/GameActivity;->A:Lcom/xy/kom/GameActivity;
iget-object v0, v0, Lcom/xy/kom/GameActivity;->r:Lcom/xy/kom/d/ei;
if-eqz v0, :cond_0
sget-object v0, Lcom/xy/kom/GameActivity;->A:Lcom/xy/kom/GameActivity;
iget-object v0, v0, Lcom/xy/kom/GameActivity;->r:Lcom/xy/kom/d/ei;
invoke-virtual {v0, v2}, Lcom/xy/kom/d/ei;->a(I)V
:cond_0
sget-object v0, Lcom/xy/kom/GameActivity;->A:Lcom/xy/kom/GameActivity;
const/4 v1, 0x6
invoke-virtual {v0, v1}, Lcom/xy/kom/GameActivity;->a(I)V
invoke-static {}, Lcom/xy/kom/d/bk;->h()V
sget-object v0, Lcom/xy/kom/GameActivity;->A:Lcom/xy/kom/GameActivity;
const-string v1, "\u8d2d\u4e70\u6210\u529f\uff01\u9053\u5177\u5df2\u53d1\u653e"
invoke-static {v0, v1, v2}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v0
invoke-virtual {v0}, Landroid/widget/Toast;->show()V
sget-object v0, Lcom/xy/kom/GameActivity;->N:Lcom/xy/kom/e/a;
invoke-virtual {v0, v3}, Lcom/xy/kom/e/a;->a(I)V
sput-boolean v3, Lcom/xy/kom/GameActivity;->M:Z
invoke-static {}, Lcom/xy/kom/a/h;->f()I
move-result v0
const/16 v1, 0xd
if-ne v0, v1, :cond_2
sget v0, Lcom/xy/kom/GameActivity;->h:I
const/4 v1, 0x2
if-ne v0, v1, :cond_2
sget-object v0, Lcom/xy/kom/GameActivity;->A:Lcom/xy/kom/GameActivity;
iget-object v0, v0, Lcom/xy/kom/GameActivity;->m:Lcom/xy/kom/g/p;
invoke-virtual {v0}, Lcom/xy/kom/g/p;->w()Ljava/util/ArrayList;
move-result-object v0
invoke-interface {v0}, Ljava/util/List;->size()I
move-result v1
sget-object v2, Lcom/xy/kom/GameActivity;->A:Lcom/xy/kom/GameActivity;
iget-object v2, v2, Lcom/xy/kom/GameActivity;->m:Lcom/xy/kom/g/p;
invoke-virtual {v2}, Lcom/xy/kom/g/p;->l()I
move-result v2
if-ne v1, v2, :cond_1
sget-object v1, Lcom/xy/kom/GameActivity;->A:Lcom/xy/kom/GameActivity;
iget-object v1, v1, Lcom/xy/kom/GameActivity;->r:Lcom/xy/kom/d/ei;
invoke-interface {v0}, Ljava/util/List;->size()I
move-result v2
add-int/lit8 v2, v2, -0x1
invoke-interface {v0, v2}, Ljava/util/List;->get(I)Ljava/lang/Object;
move-result-object v0
check-cast v0, Lcom/xy/kom/g/f;
invoke-virtual {v1, v0}, Lcom/xy/kom/d/ei;->b(Lcom/xy/kom/g/f;)V
:cond_1
sget-object v0, Lcom/xy/kom/GameActivity;->A:Lcom/xy/kom/GameActivity;
iget-object v0, v0, Lcom/xy/kom/GameActivity;->r:Lcom/xy/kom/d/ei;
sget-object v1, Lcom/xy/kom/d/bk;->d:Lcom/xy/kom/g/f;
invoke-virtual {v0, v1}, Lcom/xy/kom/d/ei;->a(Lcom/xy/kom/g/f;)V
invoke-static {}, Lcom/xy/kom/d/bk;->m()V
:cond_2
sget-boolean v0, Lcom/xy/kom/d/bk;->G:Z
if-nez v0, :cond_3
const/4 v0, 0x0
sput-object v0, Lcom/xy/kom/d/bk;->d:Lcom/xy/kom/g/f;
:cond_3
return-void
:cond_4
sget-object v0, Lcom/xy/kom/GameActivity;->A:Lcom/xy/kom/GameActivity;
iget-object v0, v0, Lcom/xy/kom/GameActivity;->m:Lcom/xy/kom/g/p;
invoke-virtual {v0}, Lcom/xy/kom/g/p;->x()Ljava/util/ArrayList;
move-result-object v0
sget-object v1, Lcom/xy/kom/d/bk;->d:Lcom/xy/kom/g/f;
invoke-virtual {v0, v1}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z
goto/16 :goto_0
.end method
When you see the method name, you know it's confused. So some things don't work.
Right-click directly to view the reference.
Here's a successful method to call. Let's go back to the source.
Discovery is an onResult method.
Here is another reminder of payment failure.
Well, how to say, this game has no protection at all, somehow encrypt the string or something. Then decrypt. At least one level of security can be improved.
Ignore her.
It turns out that this is a switch logic.
Solution:
(1) Overlay switch failures turn to success.
(2) Change switch jump
(3) The last one, which I like best, has the clearest idea and uses goto to jump. Jump to success.
Well, after the modification, the whole game will be cracked.
There's nothing to say.
Test results.
Successful, lazy play. Do not want to map, test it yourself, if you have any questions, you can find me.
Case study (2)
I haven't found it before, but I'm going to find it now.
There are three main points to pay attention to when looking for APK for practice.
(1) It's better to stand alone.
(2) When choosing size, choose a smaller one. Well, decompilation is fast. Our aim is to practice.
(3) No shell, at this stage can not be separated from the shell.
Find a game of cool running.
Three steps
Step One Trial
Original version apk: Exercise portal Look here, number: 2002
If you get the game, you have to play it first. You must know how people buy it. There may be new discoveries.
Decompilation cracking
Search keyword "success or failure"
Search results:
When I went in, I found that it was still an onResult.
.method public onResult(ILjava/lang/String;Ljava/lang/Object;)V
.locals 3
.param p1, "paramAnonymousInt" # I
.param p2, "paramAnonymousString" # Ljava/lang/String;
.param p3, "paramAnonymousObject" # Ljava/lang/Object;
.prologue
goto :pswitch_0
.line 26
packed-switch p1, :pswitch_data_0
.line 37
const-string v0, "Unity"
new-instance v1, Ljava/lang/StringBuilder;
const-string v2, "\u8d2d\u4e70\u9053\u5177\uff1a["
invoke-direct {v1, v2}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
invoke-virtual {v1, p2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1
const-string v2, "]\u53d6\u6d88\uff01"
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1
invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v1
invoke-static {v0, v1}, Landroid/util/Log;->v(Ljava/lang/String;Ljava/lang/String;)I
.line 38
invoke-static {}, Lcom/huibang/paopao/MainActivity;->access$0()Ljava/lang/String;
move-result-object v0
invoke-static {}, Lcom/huibang/paopao/MainActivity;->access$1()Ljava/lang/String;
move-result-object v1
const-string v2, "cancel"
invoke-static {v0, v1, v2}, Lcom/unity3d/player/UnityPlayer;->UnitySendMessage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
.line 41
:goto_0
return-void
.line 29
:pswitch_0
const-string v0, "Unity"
new-instance v1, Ljava/lang/StringBuilder;
const-string v2, "\u8d2d\u4e70\u9053\u5177\uff1a["
invoke-direct {v1, v2}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
invoke-virtual {v1, p2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1
const-string v2, "] \u6210\u529f\uff01"
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1
invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v1
invoke-static {v0, v1}, Landroid/util/Log;->v(Ljava/lang/String;Ljava/lang/String;)I
.line 30
invoke-static {}, Lcom/huibang/paopao/MainActivity;->access$0()Ljava/lang/String;
move-result-object v0
invoke-static {}, Lcom/huibang/paopao/MainActivity;->access$1()Ljava/lang/String;
move-result-object v1
const-string v2, "success"
invoke-static {v0, v1, v2}, Lcom/unity3d/player/UnityPlayer;->UnitySendMessage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
goto :goto_0
.line 33
:pswitch_1
const-string v0, "Unity"
new-instance v1, Ljava/lang/StringBuilder;
const-string v2, "\u8d2d\u4e70\u9053\u5177\uff1a["
invoke-direct {v1, v2}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
invoke-virtual {v1, p2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1
const-string v2, "] \u5931\u8d25\uff01"
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1
invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v1
invoke-static {v0, v1}, Landroid/util/Log;->v(Ljava/lang/String;Ljava/lang/String;)I
.line 34
invoke-static {}, Lcom/huibang/paopao/MainActivity;->access$0()Ljava/lang/String;
move-result-object v0
invoke-static {}, Lcom/huibang/paopao/MainActivity;->access$1()Ljava/lang/String;
move-result-object v1
const-string v2, "fail"
invoke-static {v0, v1, v2}, Lcom/unity3d/player/UnityPlayer;->UnitySendMessage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
goto :goto_0
.line 26
nop
:pswitch_data_0
.packed-switch 0x1
:pswitch_0
:pswitch_1
.end packed-switch
.end method
I don't know if I found any details before.
It's white here. Why is it white? It's probably hidden.
Migu's entire payment process is probably like this. (I guess)
The original game (hidden invisible) - Migu Payment Interface (visible) - Migu Payment Processing (invisible) - Return results (visible) - Feed back to the original game (invisible)
What we're doing is actually doing something about returning the results.
test
I did the test, but the screenshots are not available. If you are interested, you can try it yourself.
summary
One of the most obvious features of the Migu game is the onResult () method, which can be easily solved by changing it. Of course, you can also find its characteristics by other means. But experience can improve efficiency.
0x04 Concluding remark
Explain
These are just a summary of the methods. In summary, there may be no time to sort out the examples, but if there is time or encounter later, then we can find ways to crack the internal purchase and so on. Of course, it also includes the explanation of secondary cracking.
Then supplement if necessary.
Completion time
February 12, 2018, 20:34:20