Giter Site home page Giter Site logo

Comments (57)

Daniel-1647 avatar Daniel-1647 commented on June 12, 2024 5

https://developer.android.com/google/play/integrity#automatic-integrity-protection

https://support.google.com/googleplay/android-developer/answer/10183279

from apkid.

jackwpa avatar jackwpa commented on June 12, 2024 4

It looks like the latest JEB Pro can recover those missing strings.

In the blog at https://www.pnfsoftware.com/blog/recovering-jni-registered-natives/ they showcase a plugin that does that. It doesn't seem specific to libpairipcore.so, but it can work on it.

from apkid.

enovella avatar enovella commented on June 12, 2024 3

Found one:

> md5 northgard-2.0.3-mod.apk
MD5 (northgard-2.0.3-mod.apk) = 8a7aa55725d8f2a0b7a470c0ec9e60b2

> apkid northgard-2.0.3-mod.apk
[+] APKiD 2.1.4 :: from RedNaga :: rednaga.io
[*] northgard-2.0.3-mod.apk!classes.dex
 |-> anti_vm : Build.FINGERPRINT check, Build.MANUFACTURER check, Build.TAGS check, possible VM check
 |-> compiler : dexlib 2.x
[*] northgard-2.0.3-mod.apk!classes2.dex
 |-> anti_debug : Debug.isDebuggerConnected() check
 |-> anti_vm : Build.FINGERPRINT check, Build.HARDWARE check, Build.MANUFACTURER check, Build.MODEL check, Build.PRODUCT check, Build.TAGS check, SIM operator check, network operator name check, possible VM check
 |-> compiler : dexlib 2.x
[*] northgard-2.0.3-mod.apk!classes3.dex
 |-> anti_debug : Debug.isDebuggerConnected() check
 |-> anti_vm : Build.FINGERPRINT check
 |-> compiler : dexlib 2.x
[*] northgard-2.0.3-mod.apk!classes4.dex
 |-> anti_vm : Build.FINGERPRINT check, Build.MANUFACTURER check, Build.TAGS check, possible VM check
 |-> compiler : dexlib 2.x
[*] northgard-2.0.3-mod.apk!lib/arm64-v8a/libpairipcore.so
 |-> protector : Google Play Integrity
[*] northgard-2.0.3-mod.apk!lib/arm64-v8a/libRMS.so
 |-> packer : 5play.ru
[*] northgard-2.0.3-mod.apk!classes5.dex
 |-> compiler : dexlib 2.x

from apkid.

TIABRO avatar TIABRO commented on June 12, 2024 3

hello, has anyone got a solution for bypass pairip?

from apkid.

VanHoevenTR avatar VanHoevenTR commented on June 12, 2024 1

No need, I just like to report some info about it πŸ˜€

from apkid.

Daniel-1647 avatar Daniel-1647 commented on June 12, 2024 1

If you notice then many of the core strings in the dex file have been replaced with strings which are uninitialized and would be NULL by default. Thanks to research done by CmP, It seems that the libpairipcore.so is involved in initializing those strings. Now have to investigate more.

from apkid.

Yehh22 avatar Yehh22 commented on June 12, 2024 1

Did anyone actually bypassed it other than analyzing?

from apkid.

enovella avatar enovella commented on June 12, 2024

Hi,

I knew about this library and some protections behind it, but I don't know much who's behind. More samples at Koodous (after log in): https://koodous.com/rules/L3nkVGvq2X14jXDY/general

Would you like to open a pull-request?

Best

from apkid.

VanHoevenTR avatar VanHoevenTR commented on June 12, 2024

If you notice then many of the core strings in the dex file have been replaced with strings which are uninitialized and would be NULL by default. Thanks to research done by CmP, It seems that the libpairipcore.so is involved in initializing those strings. Now have to investigate more.

Yes, I'm aware of it

I have another info that pairipcore could possibly be related to Google Play. When pairipcore is enabled, APKCombo, the APK downloader that retrieves APK via Google Play API, would never be able to retrieve single APK and only give us option to download split APK (XAPK file). This is always the case for most apps with pairipcore... except Google Camera. Not sure why single APK is still available for Google Camera, it could be it's a system app for Google phones so split APK won't be supported for it. I once encountered single APK went available again on APKcombo after the removal of pairipcore.

It might sound non-sense but it is the fact in my experience

from apkid.

Daniel-1647 avatar Daniel-1647 commented on June 12, 2024

Change the "could be related to Google Play" to "is related to Google Play". :)

There are some Google documentations on it which further prove it out that this protection is from Google.

Also if you would like to discuss more about it then perhaps you can send me a message on discord or telegram as I am interested in reverse engineering it.

from apkid.

VanHoevenTR avatar VanHoevenTR commented on June 12, 2024

There are some Google documentations on it which further prove it out that this protection is from Google.

Can you link to the Google documentation here?

Change the "could be related to Google Play" to "is related to Google Play". :)

There is no reason to change, all I need is collect info and get rednaga or APKiD contributers to check and confirm it to be proposed as new detection

from apkid.

enovella avatar enovella commented on June 12, 2024

Thanks for the info guys! Feel free to discuss more topics in this thread.

from apkid.

Daniel-1647 avatar Daniel-1647 commented on June 12, 2024

It's not completely impossible. It will just take time to RE.

from apkid.

Yehh22 avatar Yehh22 commented on June 12, 2024

I see

from apkid.

Quicker666 avatar Quicker666 commented on June 12, 2024

Did anyone actually bypassed it other than analyzing?

Modders already start released mod with pairipcore

from apkid.

enovella avatar enovella commented on June 12, 2024

Did anyone actually bypassed it other than analyzing?

Modders already start released mod with pairipcore

@Quicker666 could you provide modded samples? And also, could you elaborate and tell us why this sample was modded? I could write a rule for it.

from apkid.

nitanmarcel avatar nitanmarcel commented on June 12, 2024

The weird asset you guys see being loaded are bytecode which get loaded and executed by the VM.

Normally, but not mandatory the protection should be in the first bytecode file it gets loaded, which can be seen by enabling debugging in com.pairip.VMRunner and adb logcat | grep VMRunner.

You can just block the asset from loading, but be careful that they might also contain things needed by the app so just block the one you need to block.

Also as an example, idk if there's something else hidden in the app, or the app needed something from the blocked asset but it can't verify the play integrity anymore with their server:

Screenshot_20230802-195524_ChatGPT

Aaand frida attached to the pairip protected application as a bonus xD

20230802_204714

from apkid.

nitanmarcel avatar nitanmarcel commented on June 12, 2024

The weird asset you guys see being loaded are bytecode which get loaded and executed by the VM.

Normally, but not mandatory the protection should be in the first bytecode file it gets loaded, which can be seen by enabling debugging in com.pairip.VMRunner and adb logcat | grep VMRunner.

You can just block the asset from loading, but be careful that they might also contain things needed by the app so just block the one you need to block.

Also as an example, idk if there's something else hidden in the app, or the app needed something from the blocked asset but it can't verify the play integrity anymore with their server:

Screenshot_20230802-195524_ChatGPT

Aaand frida attached to the pairip protected application as a bonus xD

20230802_204714

Found what's the deal with it, it was actuality even explained on the play integrity docs.

There's also a server side integrity check, the play server also sends the app singing certificate to the app server, which is then evaluated and the app server chooses if it will fulfill the API request or not.

Can't be bypassed by just modifying the app, since not the app sends the signature to the play server, as far as I saw.

Played a little and faked the signature of the app read by com.android.vending but

{
    "detail": {
        "description": "Something went wrong.",
        "param": "deviceRecognitionVerdict",
        "type": "invalid_verdict_response"
    }
}

from apkid.

I6MOxSGcHVo1bgUndxIyeIbrvRcs1rSYRtf1pl4 avatar I6MOxSGcHVo1bgUndxIyeIbrvRcs1rSYRtf1pl4 commented on June 12, 2024

The weird asset you guys see being loaded are bytecode which get loaded and executed by the VM.
Normally, but not mandatory the protection should be in the first bytecode file it gets loaded, which can be seen by enabling debugging in com.pairip.VMRunner and adb logcat | grep VMRunner.
You can just block the asset from loading, but be careful that they might also contain things needed by the app so just block the one you need to block.
Also as an example, idk if there's something else hidden in the app, or the app needed something from the blocked asset but it can't verify the play integrity anymore with their server:
Screenshot_20230802-195524_ChatGPT
Aaand frida attached to the pairip protected application as a bonus xD
20230802_204714

Found what's the deal with it, it was actuality even explained on the play integrity docs.

There's also a server side integrity check, the play server also sends the app singing certificate to the app server, which is then evaluated and the app server chooses if it will fulfill the API request or not.

Can't be bypassed by just modifying the app, since not the app sends the signature to the play server, as far as I saw.

Played a little and faked the signature of the app read by com.android.vending but

{
    "detail": {
        "description": "Something went wrong.",
        "param": "deviceRecognitionVerdict",
        "type": "invalid_verdict_response"
    }
}

In older version of parip, on frida attach app will crash until you reboot your device (emulators, real devices no matter). Now, how I can see, they making less protection, but pairip still easily removable as it was before.

from apkid.

nitanmarcel avatar nitanmarcel commented on June 12, 2024

The weird asset you guys see being loaded are bytecode which get loaded and executed by the VM.
Normally, but not mandatory the protection should be in the first bytecode file it gets loaded, which can be seen by enabling debugging in com.pairip.VMRunner and adb logcat | grep VMRunner.
You can just block the asset from loading, but be careful that they might also contain things needed by the app so just block the one you need to block.
Also as an example, idk if there's something else hidden in the app, or the app needed something from the blocked asset but it can't verify the play integrity anymore with their server:
Screenshot_20230802-195524_ChatGPT
Aaand frida attached to the pairip protected application as a bonus xD
20230802_204714

Found what's the deal with it, it was actuality even explained on the play integrity docs.
There's also a server side integrity check, the play server also sends the app singing certificate to the app server, which is then evaluated and the app server chooses if it will fulfill the API request or not.
Can't be bypassed by just modifying the app, since not the app sends the signature to the play server, as far as I saw.
Played a little and faked the signature of the app read by com.android.vending but

{
    "detail": {
        "description": "Something went wrong.",
        "param": "deviceRecognitionVerdict",
        "type": "invalid_verdict_response"
    }
}

In older version of parip, on frida attach app will crash until you reboot your device (emulators, real devices no matter). Now, how I can see, they making less protection, but pairip still easily removable as it was before.

You're going yo have unity games/apps.

They use pairip in their libunity.so ELF and calling it's ExecuteProgram which I have no idea what it does.

~ $ ldd libunity.so | grep pairip                                  libpairipcore.so => not found

Anyway, if you bypass pirip the way I explained above, the game crashes with SIGESIGV_MAPERR


08-05 09:47:04.921 30739 30739 F DEBUG   : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***

08-05 09:47:04.921 30739 30739 F DEBUG   : LineageOS Version: '20.0-20230715-UNOFFICIAL-miatoll'

08-05 09:47:04.921 30739 30739 F DEBUG   : Build fingerprint: 'Redmi/joyeuse_global/joyeuse:12/RKQ1.211019.001/V13.0.1.0.SJZMIXM:user/release-keys'

08-05 09:47:04.921 30739 30739 F DEBUG   : Revision: '0'

08-05 09:47:04.921 30739 30739 F DEBUG   : ABI: 'arm64'

08-05 09:47:04.921 30739 30739 F DEBUG   : Timestamp: 2023-08-05 09:47:04.821552126+0300

08-05 09:47:04.921 30739 30739 F DEBUG   : Process uptime: 1s

08-05 09:47:04.921 30739 30739 F DEBUG   : Cmdline: com.teenageengineering.pocketoperatorforpixel

08-05 09:47:04.921 30739 30739 F DEBUG   : pid: 30710, tid: 30710, name: peratorforpixel  >>> com.teenageengineering.pocketoperatorforpixel <<<

08-05 09:47:04.921 30739 30739 F DEBUG   : uid: 10295

08-05 09:47:04.921 30739 30739 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0000000000000000

08-05 09:47:04.921 30739 30739 F DEBUG   : Cause: null pointer dereference

08-05 09:47:04.921 30739 30739 F DEBUG   :     x0  0000007fe1318251  x1  0000006fe8f75040  x2  0000000000000010  x3  0000000000000000

08-05 09:47:04.921 30739 30739 F DEBUG   :     x4  0000006fe8f75050  x5  0000007fe1318261  x6  413738415a72396c  x7  486678526a4a434b

08-05 09:47:04.921 30739 30739 F DEBUG   :     x8  0000000000000020  x9  0000007fe1318250  x10 0000000000000003  x11 0000000000000003

08-05 09:47:04.921 30739 30739 F DEBUG   :     x12 00000070e54e0f80  x13 000000705f625f40  x14 fffffffffc000000  x15 fffffffffffffff9

08-05 09:47:04.921 30739 30739 F DEBUG   :     x16 0000007040670070  x17 00000070e55427a0  x18 000000710492c000  x19 0000000000000001

08-05 09:47:04.921 30739 30739 F DEBUG   :     x20 0000006fe8f75000  x21 0000000000000000  x22 0000006fe8f75040  x23 0000000000000010

08-05 09:47:04.921 30739 30739 F DEBUG   :     x24 0000007fe1318251  x25 000000710525a000  x26 0000007103df6000  x27 0000007fe13193e0

08-05 09:47:04.921 30739 30739 F DEBUG   :     x28 000000710525b9d8  x29 0000007fe1318350

08-05 09:47:04.921 30739 30739 F DEBUG   :     lr  0000007040669c34  sp  0000007fe1318150  pc  0000007040669c38  pst 0000000020001000

08-05 09:47:04.921 30739 30739 F DEBUG   : backtrace:

08-05 09:47:04.921 30739 30739 F DEBUG   :       #00 pc 0000000000050c38  /data/app/~~P0-wSvWFoFv990jstjMtCg==/com.teenageengineering.pocketoperatorforpixel-g8N9aBofc2NJIB-n1d2kVg==/lib/arm64/libpairipcore.so (ExecuteProgram+196)

from apkid.

Daniel-1647 avatar Daniel-1647 commented on June 12, 2024

@nitanmarcel Pairip has 3 levels of protection. Signature check and LicenseCheck make up the first level. It is easily removable and are found in smali. In the second level, Many strings from Dex files (generally around 1500 for most of the unity games) are removed by Google Play. Pairip restores them in runtime. In the third level, Data from library files is removed by Pairip. In runtime the library calls ExecuteProgram in the pairip library to restore that data.

You can check if a library invokes ExecuteProgram by searching for it in that library with some hex editor but not always the data gets removed as I have seen some exceptions.

Currently I am trying to analyze the VM and Bytecode of pairip. It's not very hard and with some persistence, You can remove it :)

Edit: I forgot to include the removed code from onReceived function of broadcast receivers. Pairip can replace the code there.

from apkid.

nitanmarcel avatar nitanmarcel commented on June 12, 2024

@nitanmarcel Pairip has 3 levels of protection. Signature check and LicenseCheck make up the first level. It is easily removable and are found in smali. In the second level, Many strings from Dex files (generally around 1500 for most of the unity games) are removed by Google Play. Pairip restores them in runtime. In the third level, Data from library files is removed by Pairip. In runtime the library calls ExecuteProgram in the pairip library to restore that data.

You can check if a library invokes ExecuteProgram by searching for it in that library with some hex editor but not always the data gets removed as I have seen some exceptions.

Currently I am trying to analyze the VM and Bytecode of pairip. It's not very hard and with some persistence, You can remove it :)

More like anti tempering protection than signature and license checks, since it includes multiple things such as frida detection and root most likely.

If you want to analyze the bytecode you can put a logcat on the VMRunner;->invoke(). You can see there that it reads and I think decrypts the asset file :)

About unity, I think ExecuteProgram is their main entry point for the game, unless they just put it there randomly to add a little but of protection, which sounds weird.

Anyway I won't be able to find what it does until I stop the library from calling that the specific function.

You can check if a library invokes ExecuteProgram by searching for it in that library with some hex editor but not always the data gets removed as I have seen some exceptions.

Yep, that's how I found libunity.so calls ExecuteProgram

from apkid.

nitanmarcel avatar nitanmarcel commented on June 12, 2024

Tho, I have a feeling that blocking the bytecode from the startup application also don't call ExecuteProgram, so stopping the library from calling it should work.

from apkid.

Daniel-1647 avatar Daniel-1647 commented on June 12, 2024

@nitanmarcel Yes it is a complete anti tampering solution. I mentioned them and not the anti debugging ones because I haven't paid much attention to them, yet.. :)

The asset file contains encrypted bytecode and they are passed over to the execVM function inside the library through JNI. The execVM function further calls the bytecode handling function in the library after the decryption of bytecode but due to the huge number of instructions and complex pseudocode...I haven't been able to understand it yet. I need to surely work up on my abilities.

The ExecuteProgram is not the main entry of the library. You are wrong there. The entry point is DT_INIT/.init_proc() function in the library which calls ExecuteProgram.

If you stop the execution of ExecuteProgram without restoring the library data then you will get a crash.

from apkid.

nitanmarcel avatar nitanmarcel commented on June 12, 2024

@nitanmarcel Yes it is a complete anti tampering solution. I mentioned them and not the anti debugging ones because I haven't paid much attention to them, yet.. :)

The asset file contains encrypted bytecode and they are passed over to the execVM function inside the library through JNI. The execVM function further calls the bytecode handling function in the library after the decryption of bytecode but due to the huge number of instructions and complex pseudocode...I haven't been able to understand it yet. I need to surely work up on my abilities.

The ExecuteProgram is not the main entry of the library. You are wrong there. The entry point is DT_INIT/.init_proc() function in the library which calls ExecuteProgram.

If you stop the execution of ExecuteProgram without restoring the library data then you will get a crash.

Ah, I didn't really took a long look at the lib.

DT_INIT is the library initialization (e.g: int main()..). So that's called when the library is loaded. But there's a function in libunity that's named ExecuteProgram πŸ€” well it could mean something else

from apkid.

nitanmarcel avatar nitanmarcel commented on June 12, 2024

Removed libpairipcore.so link from libunity.so. and at least it seems that on it's own calls ExecuteProgram of pairip library

Screenshot_20230805-115202_Logcat Extreme

from apkid.

Daniel-1647 avatar Daniel-1647 commented on June 12, 2024

IDA calls it as .init_proc() but ghidra calls it DT_INIT. Same thing basically and this function further calls ExecuteProgram.

The ExecuteProgram inside the libUnity is a reference to the ExecuteProgram function in libpairipcore.so

from apkid.

nitanmarcel avatar nitanmarcel commented on June 12, 2024

IDA calls it as .init_proc() but ghidra calls it DT_INIT. Same thing basically and this function further calls ExecuteProgram.

The ExecuteProgram inside the libUnity is a reference to the ExecuteProgram function in libpairipcore.so

Yes. But question is, if ExecuteProgram is also called in the pairip initialization, why does libunity needs to call it?

from apkid.

Daniel-1647 avatar Daniel-1647 commented on June 12, 2024

Are you sure that it's called in Pairip initialisation?

from apkid.

nitanmarcel avatar nitanmarcel commented on June 12, 2024

Are you sure that it's called in Pairip initialisation?

You said that is called in DT_INIT/.init_proc() with DT_INIT being the initialization function:



DT_INIT
--




Points to the address of an initialization function that must be called when the file is loaded.</span>

https://android.googlesource.com/platform/bionic/+/android-4.2_r1/linker/README.TXT

from apkid.

nitanmarcel avatar nitanmarcel commented on June 12, 2024

so if I don't understand wrong. when the library is loaded, it calls .init_proc() which calls ExecuteProgram as you mentioned. so when libunity loads pairip, it calls the initialization one more time which ends up calling ExecuteProgram

from apkid.

I6MOxSGcHVo1bgUndxIyeIbrvRcs1rSYRtf1pl4 avatar I6MOxSGcHVo1bgUndxIyeIbrvRcs1rSYRtf1pl4 commented on June 12, 2024

IDA calls it as .init_proc() but ghidra calls it DT_INIT. Same thing basically and this function further calls ExecuteProgram.
The ExecuteProgram inside the libUnity is a reference to the ExecuteProgram function in libpairipcore.so

Yes. But question is, if ExecuteProgram is also called in the pairip initialization, why does libunity needs to call it?

ExecuteProgram called not only in libunity. libil2cpp has it too. Unity games easily bypassable too.

from apkid.

nitanmarcel avatar nitanmarcel commented on June 12, 2024

IDA calls it as .init_proc() but ghidra calls it DT_INIT. Same thing basically and this function further calls ExecuteProgram.
The ExecuteProgram inside the libUnity is a reference to the ExecuteProgram function in libpairipcore.so

Yes. But question is, if ExecuteProgram is also called in the pairip initialization, why does libunity needs to call it?

ExecuteProgram called not only in libunity. libil2cpp has it too. Unity games easily bypassable too.

Yeah I just found out after I replaced the one in libunity with my own hook xD.

Now with both replaced, the SEGV_MAPERR crash is gone, and replace with another error xD:

08-05 13:47:28.127 11080 11080 I IL2CPP  : JNI_OnLoad
08-05 13:47:28.142  1453  2012 E DatabaseUtils: Writing exception to parcel
08-05 13:47:28.142  1453  2012 E DatabaseUtils: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.hashCode()' on a null object reference
08-05 13:47:28.142  1453  2012 E DatabaseUtils:         at com.android.providers.settings.SettingsProvider.enforceSettingReadable(SettingsProvider.java:2135)
08-05 13:47:28.142  1453  2012 E DatabaseUtils:         at com.android.providers.settings.SettingsProvider.getSystemSetting(SettingsProvider.java:1838)
08-05 13:47:28.142  1453  2012 E DatabaseUtils:         at com.android.providers.settings.SettingsProvider.call(SettingsProvider.java:434)
08-05 13:47:28.142  1453  2012 E DatabaseUtils:         at android.content.ContentProvider.call(ContentProvider.java:2511)
08-05 13:47:28.142  1453  2012 E DatabaseUtils:         at android.content.ContentProvider$Transport.call(ContentProvider.java:525)
08-05 13:47:28.142  1453  2012 E DatabaseUtils:         at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:295)
08-05 13:47:28.142  1453  2012 E DatabaseUtils:         at android.os.Binder.execTransactInternal(Binder.java:1280)
08-05 13:47:28.142  1453  2012 E DatabaseUtils:         at android.os.Binder.execTransact(Binder.java:1244)
08-05 13:47:28.142 11080 11080 D AndroidRuntime: Shutting down VM
08-05 13:47:28.143 11080 11080 E AndroidRuntime: FATAL EXCEPTION: main
08-05 13:47:28.143 11080 11080 E AndroidRuntime: Process: com.teenageengineering.pocketoperatorforpixel, PID: 11080
08-05 13:47:28.143 11080 11080 E AndroidRuntime: java.lang.RuntimeException: Unable to resume activity {com.teenageengineering.pocketoperatorforpixel/com.unity3d.player.UnityPlayerActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.hashCode()' on a null object reference
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4773)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4806)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:57)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:179)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2306)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.os.Handler.dispatchMessage(Handler.java:106)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.os.Looper.loopOnce(Looper.java:201)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.os.Looper.loop(Looper.java:288)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.app.ActivityThread.main(ActivityThread.java:7918)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at java.lang.reflect.Method.invoke(Native Method)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
08-05 13:47:28.143 11080 11080 E AndroidRuntime: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.hashCode()' on a null object reference
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.os.Parcel.createExceptionOrNull(Parcel.java:3021)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.os.Parcel.createException(Parcel.java:2999)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.os.Parcel.readException(Parcel.java:2982)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:190)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:142)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.content.ContentProviderProxy.call(ContentProviderNative.java:732)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.provider.Settings$NameValueCache.getStringForUser(Settings.java:3161)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.provider.Settings$System.getStringForUser(Settings.java:3755)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.provider.Settings$System.getIntForUser(Settings.java:3860)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.provider.Settings$System.getInt(Settings.java:3854)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at com.unity3d.player.OrientationLockListener.<init>(Unknown Source:22)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at com.unity3d.player.UnityPlayer.resume(Unknown Source:59)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at com.unity3d.player.UnityPlayerActivity.onResume(UnityPlayerActivity.java:116)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1570)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.app.Activity.performResume(Activity.java:8474)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4763)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        ... 13 more
08-05 13:47:28.143 11080 11080 E AndroidRuntime: Caused by: android.os.RemoteException: Remote stack trace:
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at com.android.providers.settings.SettingsProvider.enforceSettingReadable(SettingsProvider.java:2135)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at com.android.providers.settings.SettingsProvider.getSystemSetting(SettingsProvider.java:1838)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at com.android.providers.settings.SettingsProvider.call(SettingsProvider.java:434)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.content.ContentProvider.call(ContentProvider.java:2511)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.content.ContentProvider$Transport.call(ContentProvider.java:525)
08-05 13:47:28.143 11080 11080 E AndroidRuntime: 

from apkid.

nitanmarcel avatar nitanmarcel commented on June 12, 2024

I still couldn't hook in it with frida, so I created an empty library and patch libunity and libil2cpp with patchelf

#include <cstdio>

extern "C" void ExecuteProgram(int arg1, int arg2) {
}    

from apkid.

nitanmarcel avatar nitanmarcel commented on June 12, 2024

IDA calls it as .init_proc() but ghidra calls it DT_INIT. Same thing basically and this function further calls ExecuteProgram.
The ExecuteProgram inside the libUnity is a reference to the ExecuteProgram function in libpairipcore.so

Yes. But question is, if ExecuteProgram is also called in the pairip initialization, why does libunity needs to call it?

ExecuteProgram called not only in libunity. libil2cpp has it too. Unity games easily bypassable too.

Yeah I just found out after I replaced the one in libunity with my own hook xD.

Now with both replaced, the SEGV_MAPERR crash is gone, and replace with another error xD:

08-05 13:47:28.127 11080 11080 I IL2CPP  : JNI_OnLoad
08-05 13:47:28.142  1453  2012 E DatabaseUtils: Writing exception to parcel
08-05 13:47:28.142  1453  2012 E DatabaseUtils: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.hashCode()' on a null object reference
08-05 13:47:28.142  1453  2012 E DatabaseUtils:         at com.android.providers.settings.SettingsProvider.enforceSettingReadable(SettingsProvider.java:2135)
08-05 13:47:28.142  1453  2012 E DatabaseUtils:         at com.android.providers.settings.SettingsProvider.getSystemSetting(SettingsProvider.java:1838)
08-05 13:47:28.142  1453  2012 E DatabaseUtils:         at com.android.providers.settings.SettingsProvider.call(SettingsProvider.java:434)
08-05 13:47:28.142  1453  2012 E DatabaseUtils:         at android.content.ContentProvider.call(ContentProvider.java:2511)
08-05 13:47:28.142  1453  2012 E DatabaseUtils:         at android.content.ContentProvider$Transport.call(ContentProvider.java:525)
08-05 13:47:28.142  1453  2012 E DatabaseUtils:         at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:295)
08-05 13:47:28.142  1453  2012 E DatabaseUtils:         at android.os.Binder.execTransactInternal(Binder.java:1280)
08-05 13:47:28.142  1453  2012 E DatabaseUtils:         at android.os.Binder.execTransact(Binder.java:1244)
08-05 13:47:28.142 11080 11080 D AndroidRuntime: Shutting down VM
08-05 13:47:28.143 11080 11080 E AndroidRuntime: FATAL EXCEPTION: main
08-05 13:47:28.143 11080 11080 E AndroidRuntime: Process: com.teenageengineering.pocketoperatorforpixel, PID: 11080
08-05 13:47:28.143 11080 11080 E AndroidRuntime: java.lang.RuntimeException: Unable to resume activity {com.teenageengineering.pocketoperatorforpixel/com.unity3d.player.UnityPlayerActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.hashCode()' on a null object reference
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4773)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4806)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:57)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.app.servertransaction.ActivityTransactionItem.execute(ActivityTransactionItem.java:45)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:179)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:97)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2306)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.os.Handler.dispatchMessage(Handler.java:106)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.os.Looper.loopOnce(Looper.java:201)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.os.Looper.loop(Looper.java:288)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.app.ActivityThread.main(ActivityThread.java:7918)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at java.lang.reflect.Method.invoke(Native Method)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:936)
08-05 13:47:28.143 11080 11080 E AndroidRuntime: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.String.hashCode()' on a null object reference
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.os.Parcel.createExceptionOrNull(Parcel.java:3021)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.os.Parcel.createException(Parcel.java:2999)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.os.Parcel.readException(Parcel.java:2982)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:190)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:142)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.content.ContentProviderProxy.call(ContentProviderNative.java:732)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.provider.Settings$NameValueCache.getStringForUser(Settings.java:3161)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.provider.Settings$System.getStringForUser(Settings.java:3755)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.provider.Settings$System.getIntForUser(Settings.java:3860)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.provider.Settings$System.getInt(Settings.java:3854)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at com.unity3d.player.OrientationLockListener.<init>(Unknown Source:22)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at com.unity3d.player.UnityPlayer.resume(Unknown Source:59)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at com.unity3d.player.UnityPlayerActivity.onResume(UnityPlayerActivity.java:116)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1570)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.app.Activity.performResume(Activity.java:8474)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4763)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        ... 13 more
08-05 13:47:28.143 11080 11080 E AndroidRuntime: Caused by: android.os.RemoteException: Remote stack trace:
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at com.android.providers.settings.SettingsProvider.enforceSettingReadable(SettingsProvider.java:2135)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at com.android.providers.settings.SettingsProvider.getSystemSetting(SettingsProvider.java:1838)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at com.android.providers.settings.SettingsProvider.call(SettingsProvider.java:434)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.content.ContentProvider.call(ContentProvider.java:2511)
08-05 13:47:28.143 11080 11080 E AndroidRuntime:        at android.content.ContentProvider$Transport.call(ContentProvider.java:525)
08-05 13:47:28.143 11080 11080 E AndroidRuntime: 

Ok, these are unitialized strings:


    OrientationLockListener(Context context) {
        this.b = context;
        this.a = new k(context);
        ContentResolver contentResolver = this.b.getContentResolver();
        String str = fJRqkwjZyCbJn.MCPNoFLU; // Here
        nativeUpdateOrientationLockState(Settings.System.getInt(contentResolver, str, 0));
        this.a.a(this, str);
    }

from apkid.

Daniel-1647 avatar Daniel-1647 commented on June 12, 2024

Are you sure that it's called in Pairip initialisation?

You said that is called in DT_INIT/.init_proc() with DT_INIT being the initialization function:



DT_INIT
--




Points to the address of an initialization function that must be called when the file is loaded.</span>

https://android.googlesource.com/platform/bionic/+/android-4.2_r1/linker/README.TXT

To clear confusion, The .init_proc() function is found in libraries which will call ExecuteProgram. You can check libunity.so. The code inside init_proc will have a call to ExecuteProgram. During runtime, The reference inside libunity.so will be resolved by the linker and it will have the address of ExecuteProgram function which is inside libpairipcore.so

Sorry, I am bad at explaining.

from apkid.

nitanmarcel avatar nitanmarcel commented on June 12, 2024

@Daniel-1647 the ExecuteProgram command could exactly be the function pairip calls the bytecode.

For example given the asset l9rZA87AKCJjRxfH:

  • If you search it in the smali code you won't find it anywhere. But if you do a search for it in libunity.so you can find it there. That could also explain my null objects errors from above

image

from apkid.

nitanmarcel avatar nitanmarcel commented on June 12, 2024

Broke the smali and no idea where xD. Going to start again and hopefully I should be able to find where more exactly to load the assets. Maybe I'm onto something

from apkid.

nitanmarcel avatar nitanmarcel commented on June 12, 2024

@Daniel-1647 at least it doesn't crash anymore

Screenshot_20230805-182204_PO Pixel

from apkid.

nitanmarcel avatar nitanmarcel commented on June 12, 2024

@nitanmarcel Yes it is a complete anti tampering solution. I mentioned them and not the anti debugging ones because I haven't paid much attention to them, yet.. :)

The asset file contains encrypted bytecode and they are passed over to the execVM function inside the library through JNI. The execVM function further calls the bytecode handling function in the library after the decryption of bytecode but due to the huge number of instructions and complex pseudocode...I haven't been able to understand it yet. I need to surely work up on my abilities.

The ExecuteProgram is not the main entry of the library. You are wrong there. The entry point is DT_INIT/.init_proc() function in the library which calls ExecuteProgram.

If you stop the execution of ExecuteProgram without restoring the library data then you will get a crash.

Any with engendering ExecuteProgram? It has the first argument as the asset file, I'm not sure about the other two, and I'm not sure how it reads the asset file. It could just be there for doing some checks, and the arg2 could be the byte array, and third the length of the array

from apkid.

Daniel-1647 avatar Daniel-1647 commented on June 12, 2024

ExecuteProgram is not really hard to understand. Read the pseudocode and try to analyze the JNI calls

from apkid.

wenboly avatar wenboly commented on June 12, 2024

2222
Want to know the address of this native function!

from apkid.

Yehh22 avatar Yehh22 commented on June 12, 2024

Can you guys also analyze 5play mod? They are the one who got it work on Unity games without using signature killers. Best game to check is Motor Depot https://5play.ru/8121-motor-depot.html
What's interesting is, they replaced libpairipcore.so string to their own lib libRMS.so in libunity.so and libil2cpp.so, so that ExecuteProgram calls to libRMS.so instead

image

Unfortunately, I don't have much knowledge on the lib side so I have no idea what their own ExecuteProgram is doing. Here's the pseduocode. Also the lib is packed using a private program

void __fastcall ExecuteProgram(const char *a1)
{
  __int64 v1; // x30
  __int64 v3; // x0
  __int64 v4; // x19
  __int64 v5; // x21
  __int64 v6; // x0
  int v7; // w0
  unsigned __int64 i; // x8
  char *v9; // x20
  unsigned int v10; // w14
  __int64 v11; // x13
  bool v12; // cc
  __int64 v13; // x19
  __int64 v14; // x1
  unsigned int v15; // w8
  void *v16; // x0
  char *v17; // x9
  unsigned __int64 v18; // x8
  __int64 v19; // x10
  char v20; // t1
  void *ptr[2]; // [xsp+0h] [xbp-10h] BYREF

  ptr[1] = *(void **)(_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) + 40);
  v3 = sub_3B10(v1);
  if ( a1 )
  {
    if ( qword_ED858 )
    {
      if ( qword_ED860 )
      {
        if ( qword_ED868 )
        {
          if ( qword_ED870 )
          {
            v4 = v3;
            if ( v3 )
            {
              v5 = (unsigned int)crc32(0LL, 0LL, 0LL);
              v6 = strlen(a1);
              v7 = crc32(v5, a1, v6);
              for ( i = 0LL; i < 0x5816D; i += v11 + 17 )
              {
                v9 = (char *)&byte_956BC[i];
                v10 = byte_956BC[i];
                if ( v10 > 1 )
                  break;
                v11 = *(unsigned int *)(v9 + 13);
                v12 = v10 != 1 || (unsigned int)(v11 - 1) > 0x5816B;
                if ( !v12 && *(_DWORD *)(v9 + 1) == v7 && *(_DWORD *)(v9 + 5) && *(_DWORD *)(v9 + 9) && qword_ED878 )
                {
                  v13 = sub_3CF4(v4);
                  mprotect((void *)(v13 + *(unsigned int *)(v9 + 5)), *(_DWORD *)(v9 + 9), 7);
                  v14 = *(unsigned int *)(v9 + 13);
                  ptr[0] = 0LL;
                  v15 = sub_3838(v9 + 17, v14, ptr);
                  v16 = ptr[0];
                  if ( v15 && v13 && ptr[0] && v15 >= 5 )
                  {
                    v17 = (char *)ptr[0] + 4;
                    v18 = v15 / 5uLL;
                    do
                    {
                      v19 = *((unsigned int *)v17 - 1);
                      --v18;
                      v20 = *v17;
                      v17 += 5;
                      *(_BYTE *)(v13 + v19) = v20;
                    }
                    while ( v18 );
                  }
                  free(v16);
                  return;
                }
              }
            }
          }
        }
      }
    }
  }
}

from apkid.

wenboly avatar wenboly commented on June 12, 2024

good !

from apkid.

ufrprogramm avatar ufrprogramm commented on June 12, 2024

РСбята, ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π»ΠΈ Π²Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ ΠΏΡ€ΠΎΠ°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠΎΠ΄ 5play? ИмСнно ΠΎΠ½ΠΈ заставили Π΅Π³ΠΎ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Π² ΠΈΠ³Ρ€Π°Ρ… Unity Π±Π΅Π· использования сигнатурных ΡƒΠ±ΠΈΠΉΡ†. Π›ΡƒΡ‡ΡˆΠ°Ρ ΠΈΠ³Ρ€Π° для ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠΈ β€” Motor Depot https://5play.ru/8121-motor-depot.html Π§Ρ‚ΠΎ интСрСсно, ΠΎΠ½ΠΈ Π·Π°ΠΌΠ΅Π½ΠΈΠ»ΠΈ libpairipcore.soстроку Π½Π° свою ΡΠΎΠ±ΡΡ‚Π²Π΅Π½Π½ΡƒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΡƒ Π² libunity.so ΠΈ libil2cpp.so, Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ вмСсто этого libRMS.soвызываСтся ExecuteProgramlibRMS.so

ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅

К соТалСнию, Ρƒ мСня ΠΌΠ°Π»ΠΎ Π·Π½Π°Π½ΠΈΠΉ ΠΎ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ°Ρ…, поэтому я понятия Π½Π΅ имСю, Ρ‡Ρ‚ΠΎ Π΄Π΅Π»Π°Π΅Ρ‚ ΠΈΡ… собствСнная ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ExecuteProgram. Π’ΠΎΡ‚ псСвдокод. Π’Π°ΠΊΠΆΠ΅ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° ΡƒΠΏΠ°ΠΊΠΎΠ²Π°Π½Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΏΡ€ΠΈΠ²Π°Ρ‚Π½ΠΎΠΉ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹.

void __fastcall ExecuteProgram(const char *a1)
{
  __int64 v1; // x30
  __int64 v3; // x0
  __int64 v4; // x19
  __int64 v5; // x21
  __int64 v6; // x0
  int v7; // w0
  unsigned __int64 i; // x8
  char *v9; // x20
  unsigned int v10; // w14
  __int64 v11; // x13
  bool v12; // cc
  __int64 v13; // x19
  __int64 v14; // x1
  unsigned int v15; // w8
  void *v16; // x0
  char *v17; // x9
  unsigned __int64 v18; // x8
  __int64 v19; // x10
  char v20; // t1
  void *ptr[2]; // [xsp+0h] [xbp-10h] BYREF

  ptr[1] = *(void **)(_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) + 40);
  v3 = sub_3B10(v1);
  if ( a1 )
  {
    if ( qword_ED858 )
    {
      if ( qword_ED860 )
      {
        if ( qword_ED868 )
        {
          if ( qword_ED870 )
          {
            v4 = v3;
            if ( v3 )
            {
              v5 = (unsigned int)crc32(0LL, 0LL, 0LL);
              v6 = strlen(a1);
              v7 = crc32(v5, a1, v6);
              for ( i = 0LL; i < 0x5816D; i += v11 + 17 )
              {
                v9 = (char *)&byte_956BC[i];
                v10 = byte_956BC[i];
                if ( v10 > 1 )
                  break;
                v11 = *(unsigned int *)(v9 + 13);
                v12 = v10 != 1 || (unsigned int)(v11 - 1) > 0x5816B;
                if ( !v12 && *(_DWORD *)(v9 + 1) == v7 && *(_DWORD *)(v9 + 5) && *(_DWORD *)(v9 + 9) && qword_ED878 )
                {
                  v13 = sub_3CF4(v4);
                  mprotect((void *)(v13 + *(unsigned int *)(v9 + 5)), *(_DWORD *)(v9 + 9), 7);
                  v14 = *(unsigned int *)(v9 + 13);
                  ptr[0] = 0LL;
                  v15 = sub_3838(v9 + 17, v14, ptr);
                  v16 = ptr[0];
                  if ( v15 && v13 && ptr[0] && v15 >= 5 )
                  {
                    v17 = (char *)ptr[0] + 4;
                    v18 = v15 / 5uLL;
                    do
                    {
                      v19 = *((unsigned int *)v17 - 1);
                      --v18;
                      v20 = *v17;
                      v17 += 5;
                      *(_BYTE *)(v13 + v19) = v20;
                    }
                    while ( v18 );
                  }
                  free(v16);
                  return;
                }
              }
            }
          }
        }
      }
    }
  }
}

they using "libRMS" for hooking il2cpp games.

from apkid.

Yehh22 avatar Yehh22 commented on June 12, 2024

they using "libRMS" for hooking il2cpp games.

Of course, it unpacks the lib to unknown region and hooks the game, but in pairip mods, they are using custom ExecuteProgram code in libRMS

from apkid.

Daniel-1647 avatar Daniel-1647 commented on June 12, 2024

Guys... Even if you read the crash logs when you try to fix the modified dependencies... You will get closer to the answer. This is a great hint itself

from apkid.

qyzhaojinxi avatar qyzhaojinxi commented on June 12, 2024

Hi, is there any way to bypass it? I decomplie the apk and change nothing. Then pack it and resign the apk. But it crash when open it.

from apkid.

eebssk1 avatar eebssk1 commented on June 12, 2024

Does this work ? https://platinmods.com/threads/how-to-bypass-pairip-protections-latest-too-easy.203105/
And it seems use xposed on the protected app will crash on startup too.

from apkid.

qyzhaojinxi avatar qyzhaojinxi commented on June 12, 2024

I tried last tutorial by platinmods but failed. I will try this new later. Thank you!

from apkid.

nitanmarcel avatar nitanmarcel commented on June 12, 2024

You try pointlessly. The checks mostly happen in native side in libpairipcore.so, and it's mainly just a SVC call, at least for frida checks. I assume signature checks happen the same way by reading the signature directly from the apk. (Still using svc calls)

from apkid.

qyzhaojinxi avatar qyzhaojinxi commented on June 12, 2024

How to hack it by these modders? I see a lot of modded games with libpairipcore.

from apkid.

yntha avatar yntha commented on June 12, 2024

Does this work ? https://platinmods.com/threads/how-to-bypass-pairip-protections-latest-too-easy.203105/ And it seems use xposed on the protected app will crash on startup too.

no. simply disabling pairip isn't enough, and you will experience random crashes if you do so. pairip extracts pieces of code from the app's executables and recreates them as separate programs that are fed into the pairip vm to be executed. if you disable pairip, these programs won't run, and you will experience either a buggy, glitchy app, or a full on runtime crash.

let's not be lazy here, folks.

from apkid.

eebssk1 avatar eebssk1 commented on June 12, 2024

Does this work ? https://platinmods.com/threads/how-to-bypass-pairip-protections-latest-too-easy.203105/ And it seems use xposed on the protected app will crash on startup too.

no. simply disabling pairip isn't enough, and you will experience random crashes if you do so. pairip extracts pieces of code from the app's executables and recreates them as separate programs that are fed into the pairip vm to be executed. if you disable pairip, these programs won't run, and you will experience either a buggy, glitchy app, or a full on runtime crash.

let's not be lazy here, folks.

The problem is using [x/edx/ls]posed on it will crash the app on startup with invalid memory access fault. Which might totally defeat the purpose of [...]posed in the future.

from apkid.

SuperDuper77 avatar SuperDuper77 commented on June 12, 2024

Been using that bypass, so far works for all my games. I dont use any xposed shit, neither i care as long it works. That guy probably not actually 100% bypass but hey it still work lol, if you really want to get your xposed work.. try get work your own bypass then and stop complaining

from apkid.

strazzere avatar strazzere commented on June 12, 2024

from apkid.

VanHoevenTR avatar VanHoevenTR commented on June 12, 2024

@enovella please lock the issue. Thanks

from apkid.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.