Problem
This problem comes from pwn.college: Assembly Crash Course ⤴.
In this level, you will be working with registers. You will be asked to modify or read from registers.
We will set some values in memory dynamically before each run. On each run, the values will change. This means you will need to perform some type of formulaic operation with registers. We will tell you which registers are set beforehand and where you should put the result. In most cases, it’s
rax.In this level, you will be working with bit logic and operations. This will involve heavy use of directly interacting with bits stored in a register or memory location. You will also likely need to make use of the logic instructions in x86:
and,or,not,xor.Shifting bits around in assembly is another interesting concept!
x86 allows you to ‘shift’ bits around in a register.
Take, for instance,
al, the lowest 8 (or least significant 8) bits ofrax.The value in
al(in bits) is:al = 10001010If we shift once to the left using the
shlinstruction:shl al, 1The new value is:
al = 00010100Everything shifted to the left, and the highest (or most significant) bit fell off while a new 0 was added to the right side.
You can use this to do special things to the bits you care about.
Shifting has the nice side effect of doing quick multiplication (by 2) or division (by 2), and can also be used to compute modulo.
Here are the important instructions:
shl reg1, reg2⇿ Shiftreg1left by the amount inreg2shr reg1, reg2⇿ Shiftreg1right by the amount inreg2Note: ‘reg2’ can be replaced by a constant or memory location.
When we say significant bit or least significant byte, significant means “most important for the value.”
- The least significant bit/byte carries the smallest weight (the “lowest” place value). For example, when you modify the “lowest” or “rightmost” bit, the value changes just by 1.
- The most significant bit/byte carries the highest weight (the “highest” place value).
For this challenge, using only the following instructions:
mov,shr,shlPlease perform the following: Set
raxto the 5th least significant byte ofrdi.For example:
rdi = | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 | Set rax to the value of B4
Solution
shl and shr shifts the bits in the register by a number of bits. So, after placing rdi into rax, we first shift rax to the left by 3 bytes, which is 3×8-bits. This gives us:
rax = | B4 | B3 | B2 | B1 | B0 | 0 | 0 | 0 |
Then we shift rax to the right by 7 bytes, which is 7×8-bits. This gives us:
rax = | 0 | 0 | 0 | 0 | 0 | 0 | 0 | B4 |
.intel_syntax noprefix
.global _start
_start:
mov rax, rdi
shl rax, 3*8
shr rax, 7*8