Challenge RE #13
Let’s do another re challenge, if you’ve been reading my recent posts you know that I’m solving the challenges from challenges.re. This time, I’m going to analyze the short but not less interesting #13. Let’s start.
Analysis
This time we don’t have a binary file, instead we have a quite short assembly code. Using 128-bit registers, xmm0 and xmm1
. For this program we have three arguments, rsi, rdx and rdi
. The first two contains unsigned integers, given the way we are accessing them we can infer they are being passed on 2 arrays.
Here is the code
f:
xor rax, rax
.L4:
movdqu xmm0, XMMWORD PTR [rsi+rax]
movdqu xmm1, XMMWORD PTR [rdx+rax]
pmaxub xmm0, xmm1 ;; returns maximum of both
movdqu XMMWORD PTR [rdi+rax], xmm0
add rax, 16
cmp rax, 1024
jne .L4
rep ret
Immediately we can notice that we have a loop, and that the iteration will end when rax
will be 1024. On each iteration we increase rax
by 16, so we will iterate 64 times. Now what’s done on these iterations?
Actually quite simple, we are comparing each elements of the array, the one in rsi
and rdx
, and selecting the maximum value between the two to be saved in rdi
. Given that rdi
it’s a 64 bit register and we iterate exactly 64 times, we will fill rdi
with these maximum elements.
With this, we can already give our formal description of the program:
Formal description
Given two arrays, a and b, with unsigned integers, we return and array arr where for each i = 0, …, 64, we have arr[i] = max(a[i], b[i]).
That’s it!!