Android Reverse - Android Basic Reverse 7 (Buy-in Dry Collection)

Posted by willl on Thu, 16 May 2019 13:50:59 +0200

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

Above.

Topics: Mobile Unity shell Spring