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