# RE4B challenge 65: how to determine the first dimension of the array?

Challenge 65: Try to determine the dimensions of the array, at least partially.

``````_array\$ = 8
_x\$ = 12
_y\$ = 16
_z\$ = 20
_f  PROC
mov eax, DWORD PTR _x\$[esp-4]
mov edx, DWORD PTR _y\$[esp-4]
mov ecx, eax
shl ecx, 4
sub ecx, eax
lea eax, DWORD PTR [edx+ecx*4]
mov ecx, DWORD PTR _array\$[esp-4]
lea eax, DWORD PTR [eax+eax*4]
shl eax, 4
mov eax, DWORD PTR [ecx+eax*4]
ret 0
_f  ENDP
``````

In this challenge, I can only determine the last two dimensions as 60 and 80, so how to determine the first dimension?

I determined:

``````array[?][60][80]
``````

Progress to determine last two dimensions:

``````return: array + 5*16*(4*(16*X-X)+Y)+Z
↓
return: array + 80*(60*X+Y)+Z
↓
The second dimension is 60 and the third dimension is 80.
``````

.

Answers from Chinese-published version of RE4B, ISBN:9787115434456, Page 944

• Would you consider providing more details and any previous attempt you've made? – NirIzr Oct 19 '18 at 8:30
• @Nirlzr I updated my questions – A.J Oct 19 '18 at 9:24

According to the given code here, I don't think its possible to recover the third dimension.

``````_array\$ = 8
_x\$ = 12
_y\$ = 16
_z\$ = 20
_f  PROC
mov eax, DWORD PTR _x\$[esp-4]
mov edx, DWORD PTR _y\$[esp-4]
mov ecx, eax
shl ecx, 4   ; ecx = x*16
sub ecx, eax ; ecx = x*16 - x
lea eax, DWORD PTR [edx+ecx*4] ; eax = y+(15*x)*4
mov ecx, DWORD PTR _array\$[esp-4]
lea eax, DWORD PTR [eax+eax*4] ; eax = (y+(15*x)*4)*5
shl eax, 4                     ; eax = (y+(15*x)*4)*5*16
add eax, DWORD PTR _z\$[esp-4]  ; eax = z+80*(y+(15*x)*4)
mov eax, DWORD PTR [ecx+eax*4] ; return array+4*(z+80*(y+(15*x)*4))
ret 0
_f  ENDP
``````

Final expressions are

``````array+4*(z+80*(y+(15*x)*4))
array + 4*z + 320*y + 19200*x
array + 80*60*4*x + 80*4*y + 4*z
``````

In z you have 80 elements of size 4, in y you have 60 z elements. Thats all the information we can get from here.

I also tried writing and compiling a similar function.

``````#include <stdio.h>

int arr[50][60][80];

int f(int a[50][60][80], int x, int y, int z) { return a[x][y][z]; }

int main(int argc, char **argv) {
f(arr, 5, 5, 5);
return 0;
}
``````

Compiling with `gcc -no-pie -fno-pic -m32 x.c -o x` and then analyzing with r2.

``````\$ r2 x
-- Change the registers of the child process in this way: 'dr eax=0x333'
[0x080482e0]> aaa
...
[0x080482e0]> s sym.f
[0x080483f6]> afvn arr arg_8h
[0x080483f6]> afvn x arg_ch
[0x080483f6]> afvn y arg_10h
[0x080483f6]> afvn z arg_14h
[0x080483f6]> pdf
┌ (fcn) sym.f 41
│   sym.f (int arr, int x, int y, int z);
│           ; arg int arr @ ebp+0x8
│           ; arg int x @ ebp+0xc
│           ; arg int y @ ebp+0x10
│           ; arg int z @ ebp+0x14
│           ; CALL XREF from sym.main (0x804842d)
│           0x080483f6      55             push ebp
│           0x080483f7      89e5           mov ebp, esp
│           0x080483f9      8b450c         mov eax, dword [x]          ; [0xc:4]=-1 ; 12
│           0x080483fc      69d0004b0000   imul edx, eax, 0x4b00
│           0x08048402      8b4508         mov eax, dword [arr]        ; [0x8:4]=-1 ; 8
│           0x08048405      8d0c02         lea ecx, [edx + eax]
│           0x08048408      8b5510         mov edx, dword [y]          ; [0x10:4]=-1 ; 16
│           0x0804840b      89d0           mov eax, edx
│           0x0804840d      c1e002         shl eax, 2
│           0x08048410      01d0           add eax, edx
│           0x08048412      c1e004         shl eax, 4
│           0x08048415      8b5514         mov edx, dword [z]          ; [0x14:4]=-1 ; 20
│           0x08048418      01d0           add eax, edx
│           0x0804841a      8b0481         mov eax, dword [ecx + eax*4]
│           0x0804841d      5d             pop ebp
└           0x0804841e      c3             ret
``````

Here 0x4b00 = 80*60*4. There's no information on the upper bound of x as is the case with simple 1-d arrays. SO you can't recover any more information from your snippet.

• I have seen more than one place to set the first (or the third) dimension as 50. How do you know if it is 50? – A.J Oct 22 '18 at 2:05
• From the code that I compiled there's no way to recover 50 as the third dimension. It was just an example in my code. Where do you see it as 50? – sudhackar Oct 22 '18 at 4:37
• In the Chinese version, it contains the answer to this question. – A.J Oct 22 '18 at 5:17
• I just checked this for multidimensional arrays. Seems similar to what I wrote. Can you link/paste your version? – sudhackar Oct 22 '18 at 7:28
• I updated my question to post the answer from the Chinese-published book. – A.J Oct 22 '18 at 8:16