0

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
    add eax, DWORD PTR _z$[esp-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 answer

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

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.

5
  • 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.