How I Got Started With ARM

📆 Friday, 12th of March, 202

⏰ 09:00

☀ïļ It was a very deceptively sunny morning, children laughing and squeaking merrily. When I closed my eyes I could almoust believe it was late spring or summer…. And the soul was filling with joy and inspiration. But unfortunately the temperature was too low (-10 ❄ïļ ⛄ïļ if you believe Yandex) and going for a outside-working-day was impossible 😔.

I am finishing my cup of coffee ☕ïļ , my husband working in the adjacent room and my daughter playing with her new toys.

I should probably start with writing my own little application so that I have access to the source code which is utterly simple and I fully understand what my application can and cannot do. I am using basic Hello World application in Xcode project. It’s main function is to print Hello World string on the screen. Nothing else. Since I want to practice reversing ARM, I am adding some more functionality using SwiftUI (I owe this part to my husband). Let’s start… .

⏰ 09:14

This is what ContentView looks like now:

struct ContentView: View {
    @State private var code: String = ""
    
    var body: some View {
        Text("Enter the code!")
            .padding()
        
        Form {
            
            TextField(
                "Code",
                text: $code
            ) { isEditing in
                print(isEditing)
//                self.isEditing = isEditing
            } onCommit: {
                print(code)
            }
            .autocapitalization(.none)
            .disableAutocorrection(true)
            .border(Color(UIColor.separator))
            Button(action: signIn) {
                Text("Sign In")
            }
            
            
//            Text(username)
//                .foregroundColor(isEditing ? .red : .blue)
        }
    }
    
    func signIn() {
        if (code == "1234"){
            print("Good job ðŸĪŪ")
        }
        else{
            print("Try again ðŸĪŽ")
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    // something default here
}

And this is what my app’s UI looks like at the moment:

emulator1

So, my application is just about checking what a user enters against some hardcoded value. I suppose that this value will be visible with both rabin2 -zzz and r2, fs strings, f. Let’s check.

⏰ 09:17

strings1

The only four strings that I have placed in my application are visible here: str.Enter_the_code, str.1234, str.Try_again_ and str.Good_job_. Good job 👏 indeed. Another sip of coffee ☕ïļ .

Now, I would like to see the references to these strings (which function are using them) since I know, I would only need to patch the sign_in function in order to bypass my super-duper cool check. So, I first get to the strings section by fs strings and f and then running axt @@ str.* to see all the references. Well, that was the plan, but it didn’t work:

string2

May be, axt is broken? ðŸ˜Ą Let’s check with functions fs functions + f + axt @@ *. Hm… no functions at all!

no-functions

What am I doing wrong? … 😑 Mmmm, I guess the problem is that I haven’t run aa upon opening the application (analysis of the binary). I could run just af to analyse functions only, but I prefer to get more information. Since my binary is too small to be analysed for a long time, there is nothing to loose.

functions1

Now there are functions here, which is very good. I can now run fs functions and f and axt @@ * again:

it-works

It now works. Let’s try against strings again. Still nothing. Hm, let’s run more analysis with aaaa. Voila! 🎉

it-works2

I can now go to the calling funtion and see, where my switch to turn off is.

ARM uses a load-store model for memory access which means that only load/store (LDR and STR) instructions can access memory. While on x86 most instructions are allowed to directly operate on data in memory, on ARM data must be moved from memory into registers before being operated on. This means that incrementing a 32-bit value at a particular memory address on ARM would require three types of instructions (load, increment, and store) to first load the value at a particular address into a register, increment it within the register, and store it back to the memory from the register.

Only now I realise that I don’t see standard ARM registers like r1 or r2, but instead some creepy w0 or x2 etc. Although the operations seem to be the same (like tbnz check-this-and-jump-here-if-not-zero operation) or branching. Anyway, this code is probably simple to patch. But I cannot check now and I cannot try re-building my project for iOS device instead of simulator since I don’t have an appropriate USB wire to connect ðŸ˜Ē. The one that I have doesn’t work. So, it seems that I’ve stumbled upon a problem that cannot solve immediately and I will have to wait for the USB wire.

Off for now, but I hope to be back soon 🚀.

References

[1] ARM quick guide

[2] Megabeets radare2 quick guide