Part 17 - Hacking Float Primitive Datatype
For a complete table of contents of all the lessons please click below as it will give you a brief of each lesson in addition to the topics it will cover. https://github.com/mytechnotalent/hacking\_c-\_arm64
Today we hack the float from the last lesson.
First update our radare2 source code.
cd radare2
git pull
sys/user.sh
If you did not follow the instructions earlier you have to build radare2 from source for this to work as they rarely update releases.
https://github.com/radareorg/radare2
If you do not have the repo, clone it and follow the instructions above.
Let’s fire up radare2 in write mode.
radare2 -w ./0x05_asm64_float_primitive_datatype
Let’s auto analyze.
aaa
Seek to main.
s main
View disassembly.
v
Let’s get back to the terminal view.
q
We need to hack two instructions here. Let’s examine two very specific instructions.
movz w0, 0x999a
movk w0, 0x4121, lsl 16
Remember from last week that ultimately w0 is going to hold 0x4121999a as the lsl moves the bites in reverse byte order.
Currently this will produce a float of 10.1 as we have seen in the prior lessons. It is critical that you understand that in floating-point numbers there is a mantissa which in our case is 10 and an exponent which is the 1 to which they are separated by a . which ties them together.
Therefore to get 10.2 we would need to write assembly and update these instructions.
[0x000009b4]> wa movz w0, 0x3333 @0x000009bc
[0x000009b4]> wa movk w0, 0x4123, lsl 16 @0x000009c0
q
Now run the binary!
kali@kali:~/Documents/0x05_float_primitive_datatype$ ./0x05_float_primitive_datatype
10.2
I want you to take a close look at some examples I have put together for you so that you can understand how different values result in different results. Keep in mind these results are in an active debug session so the addresses will be different so your ASLR will have different values.
[0x555e6c29c4]> dr w0 = 0x4122999a
0x4121999a ->0x4122999a
[0x555e6c29c4]> dc
hit breakpoint at: 0x555e6c29c8
[0x555e6c29c8]> dc
10.1625
(238252) Process exited with status=0x0
[0x556215e9c4]> dr w0 = 0x41235555
0x4121999a ->0x41235555
[0x556215e9c4]> dc
hit breakpoint at: 0x556215e9c8
[0x556215e9c8]> dc
10.2083
(238258) Process exited with status=0x0
[0x558216c9c4]> dr w0 = 0x4123599a
0x4121999a ->0x4123599a
[0x558216c9c4]> dc
hit breakpoint at: 0x558216c9c8
[0x558216c9c8]> dc
10.2094
(238257) Process exited with status=0x0
[0x55868a79c4]> dr w0 = 0x4123999a
0x4121999a ->0x4123999a
[0x55868a79c4]> dc
hit breakpoint at: 0x55868a79c8
[0x55868a79c8]> dc
10.225
(238253) Process exited with status=0x0
[0x55826479c4]> dr w0 = 0x41233333
0x4121999a ->0x41233333
[0x55826479c4]> dc
hit breakpoint at: 0x55826479c8
[0x55826479c8]> dc
10.2
(238259) Process exited with status=0x0
[0x55716ab9c4]> dr w0 = 0x4125999a
0x4121999a ->0x4125999a
[0x55716ab9c4]> dc
hit breakpoint at: 0x55716ab9c8
[0x55716ab9c8]> dc
10.35
(238250) Process exited with status=0x0
[0x55880169c4]> dr w0 = 0x412f999f
0x4121999a ->0x412f999f
[0x55880169c4]> dc
hit breakpoint at: 0x55880169c8
[0x55880169c8]> dc
10.975
(238245) Process exited with status=0x0
[0x559130d9c4]> dr w0 = 0x412ff99e
0x4121999a ->0x412ff99e
[0x559130d9c4]> dc
hit breakpoint at: 0x559130d9c8
[0x559130d9c8]> dc
10.9984
(238246) Process exited with status=0x0
[0x557b1b39c4]> dr w0 = 0x412fff9e
0x4121999a ->0x412fff9e
[0x557b1b39c4]> dc
hit breakpoint at: 0x557b1b39c8
[0x557b1b39c8]> dc
10.9999
(238247) Process exited with status=0x0
[0x55931439c4]> dr w0 = 0x412ffffe
0x4121999a ->0x412ffffe
[0x55931439c4]> dc
hit breakpoint at: 0x55931439c8
[0x55931439c8]> dc
11
(238248) Process exited with status=0x0
You can start to see patterns here. TAKE THE TIME AND ACTUALLY TRY THESE OUT so you have a better understand of how these values ultimately go into the s0 register!
Next lesson we will discuss doubles.