rscloura / Doldrums

A Flutter/Dart reverse engineering tool
783 stars 117 forks source link

Exception: Unknown architecture #1

Closed winterdl closed 3 years ago

winterdl commented 3 years ago

I know the lib only support dart 2.1, when I test with a libapp.so from an app from playstore, it raised exception, how to detect the dart version of the libapp which was built. With the lib, could we patch the libapp.so to bypass some logic check of an app?


Traceback (most recent call last):
  File "main.py", line 53, in <module>
    isolate = parseELF(args.file)
  File "main.py", line 27, in parseELF
    vm = Snapshot(blobs[0], offsets[0], blobs[1], offsets[1])
  File "./Snapshot.py", line 28, in __init__
    self.fieldSetup() # Sets up deterministic information dependent on header entries
  File "./Snapshot.py", line 73, in fieldSetup
    raise Exception('Unknown architecture')
Exception: Unknown architecture``
`
winterdl commented 3 years ago

when I test with arm64, this is the output:


Traceback (most recent call last):
  File "main.py", line 53, in <module>
    isolate = parseELF(args.file)
  File "main.py", line 27, in parseELF
    vm = Snapshot(blobs[0], offsets[0], blobs[1], offsets[1])
  File "./Snapshot.py", line 36, in __init__
    self.clusters = [ self.readClusterAlloc() for _ in range(self.numClusters) ]
  File "./Snapshot.py", line 36, in <listcomp>
    self.clusters = [ self.readClusterAlloc() for _ in range(self.numClusters) ]
  File "./Snapshot.py", line 126, in readClusterAlloc
    deserializer = Cluster.getDeserializerForCid(self.includesCode, cid)
  File "./Cluster.py", line 1031, in getDeserializerForCid
    cidEnum = ClassId(cid)
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/enum.py", line 291, in __call__
    return cls.__new__(cls, value)
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/enum.py", line 533, in __new__
    return cls._missing_(value)
  File "/usr/local/Cellar/python/3.6.5/Frameworks/Python.framework/Versions/3.6/lib/python3.6/enum.py", line 546, in _missing_
    raise ValueError("%r is not a valid %s" % (value, cls.__name__))
ValueError: -2307 is not a valid ClassId```
rscloura commented 3 years ago

Hi! The latest commit implements support for 32-bit architectures and solves some bugs. Let me know if the error still persists, in which case I may need you to link me the problematic library.

You may use Doldrums to find the address of functions in the libapp.so file. Patching a function may not be trivial, as the code in the native library is virtualized, although it could be the case that the changes you're looking for are simple to implement. Before attempting any fiddling, however, please make sure the modification of the logic check you refer to is legal! :)

winterdl commented 3 years ago

Thanks for update the code, it works. I just wonder a flutter app could be cracked or not, I have some flutter apps checking customer purchase code, if they could bypass they could use it for free.

class StateProfile extends _StateProfile&State&TickerProviderStateMixin@230471557 {

    StateProfile StateProfile.(DynamicType) {
        Code at absolute offset: 0x112d4
    }

    VoidType initState(DynamicType) {
        Code at absolute offset: 0x3702b0
    }

    DynamicType getUserDetails(DynamicType) {
        Code at absolute offset: 0x339f9c
    }

    DynamicType _getHeader@230471557(DynamicType) {
        Code at absolute offset: 0x33a608
    }

    DynamicType _getDrawerFirst@230471557(DynamicType) {
        Code at absolute offset: 0x33a2b4
    }

    DynamicType _getDivider@230471557(DynamicType) {
        Code at absolute offset: 0x339ddc
    }

    DynamicType _getDrawerSecond@230471557(DynamicType) {
        Code at absolute offset: 0x3399cc
    }

    DynamicType _getDrawerItem@230471557(DynamicType, DynamicType, DynamicType, DynamicType) {
        Code at absolute offset: 0x33a0ec
    }

    DynamicType logOutDailog(DynamicType) {
        Code at absolute offset: 0x339e4c
    }

    Widget build(DynamicType, DynamicType) {
        Code at absolute offset: 0x3397f0
    }
}

class MyProfile extends StatefulWidget {

    State createState(DynamicType) {
        Code at absolute offset: 0x386728
    }
}
rscloura commented 3 years ago

Happy to hear it worked! If the purchase code is checked client-side, then it is indeed possible to alter the corresponding native function. In the output you pasted, suppose the logic is implemented in MyProfile.createState. Then one can achieve the bypass by correctly modifying the contents of libapp.so at offset 0x386728 into the file. This starts to be quite off topic, though, as it is far from the purpose of Doldrums.

Closing, as I don't think I can help you any further at the moment :)