Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: Couldn't parse function with signature #5

Open
0xElessar opened this issue Sep 12, 2022 · 8 comments
Open

Error: Couldn't parse function with signature #5

0xElessar opened this issue Sep 12, 2022 · 8 comments

Comments

@0xElessar
Copy link

Hello @hot3eed ,

thanks for the great extension. However, I am failing miserably with Interceptor. I am getting this error message:

Error: Couldn't parse function with signature: static APP.CFMKeyChain.get(APP.CFMKeyChain.Items) -> Swift.Optional<Swift.String>
here is the function definition in the decompiler:

int _$s15APP11CFMKeyChainC3getySSSgAC5ItemsOFZ(int arg0) {

I am using the following Frida script:

var dummy = Process.getModuleByName('APP');
var symbols = dummy.enumerateSymbols();
symbols = symbols.filter(s => s.name == '$s15APP11CFMKeyChainC3getySSSgAC5ItemsOFZ');
var target = symbols[0].address;
var Int = Swift.structs.Int;
var String = Swift.structs.String;
var getLoadableStruct = Swift.NativeFunction(target, String , [ Int ]);
Swift.Interceptor.attach(getLoadableStruct.address, {
    onLeave: function(retval) {
            console.log("IN2");
            console.log(JSON.stringify(retval));
            console.log(retval.$class);
        }

I am getting the same output if I put 2 Int:

var dummy = Process.getModuleByName('APP');
var symbols = dummy.enumerateSymbols();
symbols = symbols.filter(s => s.name == '$s15APP11CFMKeyChainC3getySSSgAC5ItemsOFZ');
var target = symbols[0].address;
var Int = Swift.structs.Int;
var getLoadableStruct = Swift.NativeFunction(target, Int , [ Int ]);
Swift.Interceptor.attach(getLoadableStruct.address, {
    onLeave: function(retval) {
            console.log("IN2");
            console.log(JSON.stringify(retval));
            console.log(retval.$class);
        }

Any advice? I am losing my head here :(

thanks

@hot3eed
Copy link
Collaborator

hot3eed commented Oct 15, 2023

Hi, sorry it's been a long time since I worked on this project. Can you upload the binary or link to it so I can reproduce?

@0xElessar
Copy link
Author

Thanks for the response, @hot3eed . But this application belonged to a customer, so I cannot share it unfortunately :(

@hot3eed
Copy link
Collaborator

hot3eed commented Oct 22, 2023

Hey, actually I don't need the binary for this specific error. Thanks for reporting, this bug is next in queue to be fixed.

@0xElessar
Copy link
Author

Fantastic. Thank you, @hot3eed !

@0xElessar
Copy link
Author

0xElessar commented Nov 29, 2023

Hello @hot3eed ,

apologies for this message. But there is so little information available about Frida Swift scripts and examples, it is extremely difficult to do anything, without some developer knowledge.

When you have a moment, could you have a look at the below, please? Any suggestion, pointers, examples, or forum I can ask such question would be greatly appreciated.

I have the following class definition dumped with DSDUMP:

 class APP.RefreshableCredentials : _SwiftObject @rpath/libswiftCore.dylib {
        // Properties
        var networkManager : NetworkManager
        var priveleges : CredentialPriveleges
        var customerAppKeychainAccess : CustomerAppKeychainAccess

        // Swift methods
        0x10004d45c  func RefreshableCredentials.networkManager.getter // getter
        0x10004d49c  func RefreshableCredentials.networkManager.setter // setter
        0x10004d4ec  func RefreshableCredentials.networkManager.modify // modifyCoroutine
        0x10004d620  class func RefreshableCredentials.__allocating_init(networkManager:) // init
        0x10004d70c  func RefreshableCredentials.verifyPincodeHash(pincodeHash:) // method
        0x10004de4c  func RefreshableCredentials.createNewPincode(newPincodeHash:completionHandler:) // method
[...]
 }

Some frida console output:

var RefreshableCredentials = Swift.classes.RefreshableCredentials (worked)
RefreshableCredential (produces the below output)
{
   "address": "0x102cc3894",
   "name": "APP.RefreshableCredentials.verifyPincodeHash(pincodeHash: Swift.String) -> Swift.Bool",
   "type": "Method"
},
{
   "address": "0x102cc4470",
   "name": "APP.RefreshableCredentials.createNewPincode(newPincodeHash: Swift.String, completionHandler: () -> ()) -> ()",
   "type": "Method"
},
[...]

Could you advise how I can execute 'createNewPincode' or 'verifyPincodeHash' method from Frida interface? Also, how I can intercept the 'verifyPincodeHash' method and read the 'pincodeHash' value?

I don't want to waste your time. I spend many hours trying different approaches, scripts (like your test-suite), but nothing worked for me. Other scripts on the internet like "https://codeshare.frida.re/@Numenorean/cryptoswiftsha1/" are extremely manual in translating different types.

thanks a lot for any advice

@hot3eed
Copy link
Collaborator

hot3eed commented Dec 3, 2023

Hi @0xElessar. For interception, have you tried using the Swift.Interceptor API? Since you have symbols, it can work. (can since the bridge is really experimental quality at the moment).

For executing those APIs ad-hoc, you can also theoretically use the Swift.NativeFunction, and in order to construct the arguments, you can use the new Swift.Struct(type, options) API, where type can be retrieved using Swift.modules.Swift.structs.String in your case of APP.RefreshableCredentials.verifyPincodeHash, you would then have to construct the string manually using raw bytes.

PS: try using the bridge from git since the one bundled with Frida can be lagging behind in releases.

@0xElessar
Copy link
Author

Thank you, @hot3eed . Much appreciated.

I have managed to use frida-trace successfully. Although the new Swift supported frida-trace (https://frida.re/news/2023/11/04/frida-16-1-5-released/ -option '-y') does not work, I am getting the Swift version not supported, but the standard 'module/function' tracing works fine for me:

frida-trace -U APP -i 'APP!*Keychain*'

I also found on the Internet a nice trick to display Swift strings:

[...]
  onEnter(log, args, state) {
    log('$sSS11CryptoSwiftE6sha256SSyF()');
[...]

var toStringAddr = Module.findExportByName("libswiftFoundation.dylib","$sSS10FoundationE19_bridgeToObjectiveCSo8NSStringCyF");
var toStringCall = new NativeFunction(toStringAddr, 'pointer', ['pointer', 'pointer']);

function create_swift_string(ptr1,ptr2)
{
        var str = toStringCall(ptr1,ptr2);
        return ObjC.Object(str);
};

   log(create_swift_string(args[0],args[1])); // displays the string, which will be hashed by SHA256 function
[...]

I wanted to avoid to play with RAW bytes, but it seems it is unavoidable with String creation. Fortunately, I found another Swift method to bypass the authentication by modifying the BOOL value returned from the function. Suprisingly the code I used with Obj-C, worked fine with the Swift function:

 onEnter(log, args, state) {
    log('$s17APP0aB14KeychainC13verifyPincode04withG4HashSbSS_tFZ()');
  },

   onLeave(log, retval, state) {
    log('RETVAL:' + retval.toString());
    retval.replace(0x01)
    log('Modified RETVAL:' + retval.toString());
  }

Thanks a lot for your help, @hot3eed .

@cherpake
Copy link

Still can't figure out how to get string from retval.
Please help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants