Assembly★★★★

Simple X86 Assembly
hint

(gdb) disas main
Dump of assembler code for function main:
    0x0804848f <+0>: push %ebp
    0x08048490 <+1>: mov %esp,%ebp
    0x08048492 <+3>: and $0xfffffff0,%esp
    0x08048495 <+6>: sub $0x20,%esp
    0x08048498 <+9>: movl $0x0,0x18(%esp)
    0x080484a0 <+17>: jmp 0x80484e6 
    0x080484a2 <+19>: movl $0x0,0x1c(%esp)
    0x080484aa <+27>: jmp 0x80484da 
    0x080484ac <+29>: mov 0x1c(%esp),%eax
    0x080484b0 <+33>: mov 0x804a020(,%eax,4),%edx
    0x080484b7 <+40>: mov 0x1c(%esp),%eax
    0x080484bb <+44>: add $0x1,%eax
    0x080484be <+47>: mov 0x804a020(,%eax,4),%eax
    0x080484c5 <+54>: cmp %eax,%edx
    0x080484c7 <+56>: jle 0x80484d5 
    0x080484c9 <+58>: mov 0x1c(%esp),%eax
    0x080484cd <+62>: mov %eax,(%esp)
    0x080484d0 <+65>: call 0x804841d 
    0x080484d5 <+70>: addl $0x1,0x1c(%esp)
    0x080484da <+75>: cmpl $0x4,0x1c(%esp)
    0x080484df <+80>: jle 0x80484ac 
    0x080484e1 <+82>: addl $0x1,0x18(%esp)
    0x080484e6 <+87>: cmpl $0x5,0x18(%esp)
    0x080484eb <+92>: jle 0x80484a2 
    0x080484ed <+94>: movl $0x804a03c,(%esp)
    0x080484f4 <+101>: call 0x80482f0 
    0x080484f9 <+106>: leave
    0x080484fa <+107>: ret
End of assembler dump.
(gdb) disas swap
Dump of assembler code for function swap:
    0x0804841d <+0>: push %ebp
    0x0804841e <+1>: mov %esp,%ebp
    0x08048420 <+3>: sub $0x10,%esp
    0x08048423 <+6>: mov 0x8(%ebp),%eax
    0x08048426 <+9>: mov 0x804a020(,%eax,4),%eax
    0x0804842d <+16>: mov %eax,-0x4(%ebp)
    0x08048430 <+19>: mov 0x8(%ebp),%eax
    0x08048433 <+22>: add $0x1,%eax
    0x08048436 <+25>: mov 0x804a020(,%eax,4),%edx
    0x0804843d <+32>: mov 0x8(%ebp),%eax
    0x08048440 <+35>: mov %edx,0x804a020(,%eax,4)
    0x08048447 <+42>: mov 0x8(%ebp),%eax
    0x0804844a <+45>: lea 0x1(%eax),%edx
    0x0804844d <+48>: mov -0x4(%ebp),%eax
    0x08048450 <+51>: mov %eax,0x804a020(,%edx,4)
    0x08048457 <+58>: mov 0x8(%ebp),%eax
    0x0804845a <+61>: add $0x804a03c,%eax
    0x0804845f <+66>: movzbl (%eax),%eax
    0x08048462 <+69>: mov %al,-0x5(%ebp)
    0x08048465 <+72>: mov 0x8(%ebp),%eax
    0x08048468 <+75>: add $0x1,%eax
    0x0804846b <+78>: movzbl 0x804a03c(%eax),%eax
    0x08048472 <+85>: mov 0x8(%ebp),%edx
    0x08048475 <+88>: add $0x804a03c,%edx
    0x0804847b <+94>: mov %al,(%edx)
    0x0804847d <+96>: mov 0x8(%ebp),%eax
    0x08048480 <+99>: lea 0x1(%eax),%edx
    0x08048483 <+102>: movzbl -0x5(%ebp),%eax
    0x08048487 <+106>: mov %al,0x804a03c(%edx)
    0x0804848d <+112>: leave
    0x0804848e <+113>: ret
End of assembler dump.
(gdb) x/7xw 0x804a020
0x804a020: 0x01709e79 0x008cccc9 0x0035c7e2 0x005704e7
0x804a030: 0x00213d05 0x00e3d1b0 0x00000000
(gdb) x/7xb 0x804a03c
0x804a03c: 0x45 0x38 0x55 0x42 0x38 0x4c 0x00
(gdb) q

지금까지 핸드레이를 한번도 해본적이 없었기 때문에 조금 막막했지만 차근차근 해보니 별 갯수에 맞게 그렇게 어려운 문제는 아니였다.

일단 AT&T 문법보다는 Intel문법이 익숙했기 때문에 Intel문법으로 바꾸고 한줄 한줄 해석하며 C코드로 바꿔 나갔다.

int arr: 0x01709e79 0x008cccc9 0x0035c7e2 0x005704e7
0x804a030: 0x00213d05 0x00e3d1b0 0x00000000

char arr2: 0x45 0x38 0x55 0x42 0x38 0x4c 0x00

v1 == [esp + 0x18]
v2 == [esp + 0x1c]
(main function)  
0x0804848f <+0>:   push   ebp
0x08048490 <+1>:   mov    ebp, esp
0x08048492 <+3>:   and    esp, -0x10
0x08048495 <+6>:   sub    esp, 0x20
0x08048498 <+9>:   mov    dword ptr [esp + 0x18], 0x0 # v1 = 0
 ┌0x080484a0 <+17>:  jmp    0x080484e6 
┌├>0x080484a2 <+19>:  mov    dword ptr [esp + 0x1c], 0x0 # v2 = 0
││ ┌0x080484aa <+27>:  jmp    0x080484da 
││┌├>0x080484ac <+29>:  mov    eax, dword ptr [esp + 0x1c] # eax = v2
││││0x080484b0 <+33>:  mov    edx, dword ptr [4*eax + arr] # edx = arr[eax];
││││0x080484b7 <+40>:  mov    eax, dword ptr [esp + 0x1c] # eax = v2;
││││0x080484bb <+44>:  add    eax, 0x1 # eax += 1;
││││0x080484be <+47>:  mov    eax, dword ptr [4*eax + arr] # eax = arr[eax];
││││0x080484c5 <+54>:  cmp    edx, eax
││││┌0x080484c7 <+56>:  jle    0x080484d5 # if edx <= eax jmp to 0x080484d5
│││││0x080484c9 <+58>:  mov    eax, dword ptr [esp + 0x1c] # eax = v2;
│││││0x080484cd <+62>:  mov    dword ptr [esp], eax # *esp = eax;
│││││0x080484d0 <+65>:  call   0x0804841d # swap
││││└>0x080484d5 <+70>:  add    dword ptr [esp + 0x1c], 0x1
│││└>0x080484da <+75>:  cmp    dword ptr [esp + 0x1c], 0x4 
││└0x080484df <+80>:  jle    0x080484ac # if v2 <= 4 jmp to 0x080484a2
││0x080484e1 <+82>:  add    dword ptr [esp + 0x18], 0x1 # v1 += 1
│└>0x080484e6 <+87>:  cmp    dword ptr [esp + 0x18], 0x5 # 
└0x080484eb <+92>:  jle    0x080484a2  # if v1 <= 5 jmp to 0x080484a2
0x080484ed <+94>:  mov    dword ptr [esp], 0x0804a03c
0x080484f4 <+101>: call   0x080482f0  # ???
0x080484f9 <+106>: leave  
0x080484fa <+107>: ret

v1 = 0;
while (v1 <= 5) {
    v2 = 0;
    while (v2 <= 4) {
        eax = v2;
        edx = arr[eax];
        eax = v2;
        eax += 1;
        eax = arr[eax];
        if (!(edx <= eax)) {
            eax = v2;
            swap(eax);
        }
        v2 += 1;
    }
    v1 += 1;
}

f1 == [ebp + 0x8] : 인자값
v2 == [ebp - 0x4] : tmp
c3 == [ebp - 0x5] : tmp2
(swap function)
push   ebp
mov    ebp, esp
sub    esp, 0x10
mov    eax, dword ptr [ebp + 0x8] 
mov    eax, dword ptr [4*eax + arr]
mov    dword ptr [ebp - 0x4], eax
mov    eax, dword ptr [ebp + 0x8]
add    eax, 0x1
mov    edx, dword ptr [4*eax + arr]
mov    eax, dword ptr [ebp + 0x8]
mov    dword ptr [4*eax + arr], edx
mov    eax, dword ptr [ebp + 0x8]
lea    edx, [eax + 0x1]
mov    eax, dword ptr [ebp - 0x4]
mov    dword ptr [4*edx + arr], eax
mov    eax, dword ptr [ebp + 0x8]
add    eax, arr2
movzx  eax, byte ptr [eax]
mov    byte ptr [ebp - 0x5], al
mov    eax, dword ptr [ebp + 0x8]
add    eax, 0x1
movzx  eax, byte ptr [eax + arr2]
mov    edx, dword ptr [ebp + 0x8]
add    edx, arr2
mov    byte ptr [edx], al
mov    eax, dword ptr [ebp + 0x8]
lea    edx, [eax + 0x1]
movzx  eax, byte ptr [ebp - 0x5]
mov    byte ptr [edx + arr2], al
leave  
ret

int eax = f1;
eax = arr[eax];
int v2 = eax; // v2 = arr[f1]
eax = f1;
eax += 1;
int edx = arr[eax];
eax = f1;
arr[eax] = edx; // arr[f1] = arr[f1+1]
eax = f1;
edx = eax+1;
eax = v2;
arr[edx] = eax; // arr[f1+1] = v2
eax = f1;
eax += arr2; <- eax = &arr2[eax]
eax = (char)eax;
char c3 = eax; // c3 = arr2[f1]
eax = f1;
eax += 1;
eax = arr2[eax];
edx = f1;
edx += arr2; <- edx = &arr2[edx]
*edx = eax; // arr2[f1] = arr2[f1+1]
eax = f1;
edx = eax+1;
eax = c3;
arr2[edx] = eax; // arr2[f1+1] = c3;

어셈을 기반으로 구한 알고리즘을 똑같이 구현해서 돌려주면 답이 나오게 된다.

import struct

arr  = [0x01709e79, 0x008cccc9, 0x0035c7e2, 0x005704e7, 0x00213d05, 0x00e3d1b0, 0x00000000]
arr2 = [0x45, 0x38, 0x55, 0x42, 0x38, 0x4c, 0x00]

for i in range(0, 6):
    for j in range(0, 5):
        if arr[j] > arr[j+1]:
            arr[j], arr[j+1] = arr[j+1], arr[j]
            arr2[j], arr2[j+1] = arr2[j+1], arr2[j]

print ''.join(map(chr, arr2)) #8UB8LE

Flag : 8UB8LE

results matching ""

    No results matching ""