In the previous blog post we looked into a simple iOS Swift app decompiled with Hopper Disassembler. If you have not yet looked into it I highly recommend to do so, otherwise you may not get the point. This is a follow up post, which covers an additional question that was raised during the analysis:
- Why are the string values handled different?
Recap.
As you may remember, there were three string values inside of the Swift code:
- „1234“
- „Passed!“
- „You shall not pass!“
Analysis.
Analyzing the decompiled binary in Hopper, looking at the Str section, only the string „You shall not pass!“ was discovered. The only difference I saw between the three strings, was obviously the length of the values. Both strings, that were not present in the Str section were shorter than 16 bytes. Playing with the length of the strings revealed, that indeed a string that is longer than 15 characters will appear in the Str section.
- „AAAAAAAAAAAAAAAA“ <- will appear in Str section, >= 16-bytes
- „AAAAAAAAAAAAAAA“ <- will not appear in Str section < 16-bytes
The following screenshot will show the 15-byte string moved into two registers:
As you can see not only the „AAAA…“ values were moved into the register, but also an additional byte 0xef. As you may know every arm64 register can hold up to 64-bit, following this assumption the 16-byte string (= 128-bit) should perfectly fit in two registers, e.g. x1 and x2, but as we can see the additional byte (see 0000000100005e28) 0xef extends the string length to 17-byte (= 136-bit). That explains, why the values do no longer fit in two registers.
According to the following extract of the analyzed function a pointer to the address #0x100006790, which holds our „You shall not pass!“ string, is passed to x8.
Conclusion.
- String values < 16-bytes are treated different then values >= 16-bytes
- String values >= 16-bytes are treated as pointer values. Therefore, they appear in the Str section