Swift iOS standard library - parameter count and types

For Swift standard libraries IDA seems to have very sparse information about argument count and type of imported functions, especially for the lower level C bridging methods like _$sSS10FoundationE19_bridgeToObjectiveCSo8NSStringCyF ; String._bridgeToObjectiveC().

I have not found header files for Swift for generating a til file that could be added to IDA to improve Swift support.

At the moment I always have to manually edit this known function and ad the two arguments to the import stub’s definition. Unfortunately this stub can not be uploaded to Lumina server. What other options to I have to recognize IDA this very important function (and other similar Swift functions) that is used very often in Swift (iOS) code?

If there are no header files, you can create one yourself, put the common function prototypes there and process it with the tilib utility. This will give you a new type library file that can be loaded to any IDB for getting correct prototypes.

That is pretty much work, because I am not a C developer, thus never had created a header file for a library before.

If I use an AI system I get this:

#ifndef LIBSWIFTFOUNDATION_H
#define LIBSWIFTFOUNDATION_H

#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

// Declaration of the Swift function with __swiftcall calling convention
__attribute__((swiftcall)) NSString *_$sSS10FoundationE19_bridgeToObjectiveCSo8NSStringCyF(int64_t arg1, int64_t arg2);

#ifdef __cplusplus
}
#endif

#endif // LIBSWIFTFOUNDATION_H

Unfortunately tilib.exe can not handle this header file as it requires other header files and uses types NSString tilib.exe doesn’t know about. Isn’t there a easier way where you don’t have to provide a fully working header infrastructure. Something like an export function which exports the currently modified function type definition to a til file?

There is no need to define all prototypes, just add the ones that you have been adding in IDA, to facilitate your lfe.

For missing types, you can forward declare them, for example:

struct NSString;

and tilib won’t complain.

Thanks the forward declaration is good to know. The final result that worked

struct NSString;

__attribute__((swiftcall)) NSString *_$sSS10FoundationE19_bridgeToObjectiveCSo8NSStringCyF(__int64 arg1, __int64 arg2);
__attribute__((swiftcall)) NSString * __imp__$sSS10FoundationE19_bridgeToObjectiveCSo8NSStringCyF(__int64 arg1, __int64 arg2);

tilib.exe -c -hswift.h swift.til

The generated swift.til file I copied to the til/arm subdir of IDA and restarted IDA + recreated the database but I don’t see a difference. If I manually open the type tab (Shift+F11) and add my created swift.til file the decompiler correctly recognized the two arguments in the stub function:

// attributes: thunk
NSString __swiftcall String._bridgeToObjectiveC()()
{
  __int64 v0; // x0
  __int64 v1; // x1

  return __imp__$sSS10FoundationE19_bridgeToObjectiveCSo8NSStringCyF(v0, v1);
}

But the sub function itself remains with zero arguments instead of two arguments.

The stub function of this import is shown in bold - does that means it was included in some other til file with the wrong argument count?

Yes, if the function prototype is displayed in bold, it means that the type was defined by other means. It can be another til file.