Locating the SM4 Encryption Key (iOS ARM64)
About the author. I’m Colin Xiao — an independent reverse engineer, mostly working solo on contract jobs. I dig into compiled code of every kind, including but not limited to: Android and iOS apps, x86/x64/ARM native binaries, packers and obfuscators, DRM and license checks, network protocols and APIs, crypto and signature algorithms, malware, game binaries, and embedded/IoT firmware. I also handle large-scale data collection and vulnerability research. If you have any project in mind, I’d be glad to take it on — whatever it is, as long as it’s within my wheelhouse. Just reach out. You can reach me on X at @colinxiao_lab or on Telegram at https://t.me/ColinXiao666.
This research is published for educational and defensive purposes. The target sample is anonymized throughout.
Locating the SM4 Encryption Key (iOS ARM64)
Problem
I needed to locate the key used by the SM4 algorithm in an app.
Solution
First, what is SM4? A quick search for “SM4.0” turns up explanations and multi-language implementations. You don’t need to deeply understand its underlying math. For a reverse engineer, it’s enough to know the algorithm’s characteristics: how data participates in the computation, and where the key is used.
From the spec, SM4 has three fixed data tables — CK, FK, and Sbox. The key is a fixed 16 bytes, and it’s used exactly once in the whole algorithm, as shown in this Python reference:

This step also uses the CK data, which hints that we might locate the key by finding where CK is referenced.
Now let’s see how the key is used. Look inside GET_UINT32_BE(key[0:4]):
def GET_UINT32_BE(key_data):
return int((key_data[0] << 24) | (key_data[1] << 16) | (key_data[2] << 8) | (key_data[3]))
Its signature is a chain of left-shifts (<<) combined with ORs (|). That gives us a plan:
- Locate the
CKorSboxdata segment in the binary (or memory). The data is fixed, so we can binary-search for it or memory-scan for the specific bytes. - From the data’s references, locate the SM4 code region.
- Near where
CKis used, look for the code signature: shift and OR operations (if obfuscated, de-obfuscate first or use data tracing).
That lands us on the ARM64 version of the GET_UINT32_BE function inside the app:

LSL is << — note that 0x18 is 24 decimal — and ORR is |, which lines up exactly with the algorithm. As for BFI, it’s a bit-level scalpel for moving bits.
For example, BFI X3, X4, #0x10, #8 replaces bits 16–23 of X3 with the 8 LSB bits of X4. And BFI X3, X4, #0x8, #8 replaces bits 8–15 of X3 with the 8 LSB bits of X4.
So X1 here is the address of the key — reading 16 bytes from that address yields the key.
Summary
Locating an SM4 key only requires understanding the algorithm’s characteristics: use CK to find the code region, then use the code-operation signature to find the key.
References
- SM4.0 specification (GB/T 32907)
- SM4 overview
- ARM64 assembly: the
BFIinstruction
Colin Xiao — I take on contract reverse-engineering work, and writeups like this are how I show what I can do. If you need help with anything in this space — including but not limited to the areas I cover above — I’m available. No project is too big or too small — if it’s reverse engineering and I can do it, I’ll take it. DM me on X (@colinxiao_lab) or Telegram (@ColinXiao666).
Get in touch