我获得了以下代码,现在尝试理解它。
数组正在使用足够大的内存,在.bss中,代码预先初始化为0.
1 fib : file format elf 32−i386
2
3 Disassembly of section.text :
4
5 0 x08048080 <start>:
6 0 x08048080 : mov eax , 0x80490d0 <array>
7 0 x08048085 : push eax
8 0 x08048086 : mov eax , 0 x3
9 0 x0804808b : push eax
10 0 x0804808c : call 0 x8048098 <fib>
11 0 x08048091 : pop eax
12 0 x08048092 : pop eax
13 0 x08048093 : jmp 0 x80480c1 <Lend>
14
15 0 x08048098 <fib>:
16 0 x08048098 : mov ebx , [esp+0x8]
17 0 x0804809c : mov ecx , 0 x2
18 0 x080480a1 : xor edx , edx
19 0 x080480a3 : mov [ebx] , edx
20 0 x080480a5 : mov eax , 0x1
21 0 x080480aa : mov [ebx+0x4] , eax
22 0 x080480ad : jmp 0 x080480ba <Lloop_cond>
23
24 0 x080480b2 <Lloop >:
25 0 x080480b2 : push eax
26 0 x080480b3 : add eax , edx
27 0 x080480b5 : mov [ebx+ecx∗4] , eax
28 0 x080480b8 : pop edx
29 0 x080480b9 : inc ecx
30
31 0 x080480ba <Lloop_cond>:
32 0 x080480ba : cmp ecx , [esp+0x4]
33 0 x080480be : jle 0x080480b2 <Lloop>
34 0 x080480c0 : ret
35
36 0 x080480c1 <Lend>:
37 0 x080480c1 : mov ebx , 0 x0 ; Exit code 0 = success
38 0 x080480c6 : mov eax , 0 x1 ; Select System call exit
39 0 x080480cb : int 0 x80 ; System call
40
41 Disassembly of section.bss :
42
43 0 x080490d0 <array>:
44 . . .
它要求或者必要的我可以提供我的想法,但是担心它会比它更好地混淆。 感谢任何建设性的帮助。
答案 0 :(得分:2)
该函数被称为fib
,它正在创建一个Fibonacci序列数组。工作主体是在标签Lloop
之后的几条指令处完成的。
Lloop:
push eax ; save current term
add eax , edx ; add previous term
mov [ebx+ecx*4] , eax ; write to array
pop edx ; retrieve previous term for next loop
inc ecx ; loop control and array index
Lloop_cond:
cmp ecx , [esp+0x4] ; end test
jle Lloop ; repeat
ret ; done
我会把剩下的部分留给你。
答案 1 :(得分:1)
所以已经给出了正确的答案,问题的原因可能是阴暗的,但我也需要处理我的装配,这是一个有趣的练习。
我的逆向工程可以归结为这个功能:
void fib_simple(int* array, int n)
{
int i, j, tmp;
int count = 2;
array[0] = i = 0;
array[1] = j = 1;
for (count = 2; count <= n; count++) {
tmp = j;
j = array[2] = i + j;
i = tmp;
}
}
当然,这只是一个简洁的音译。实际的逆向工程功能看起来更像是这样:
void fib(int* array, int n)
{
int ecx, edx, tmp;
/* mov ebx , [esp+0x8]; ebx is the array */
/* mov ecx , 0x2; ecx is a counter, starting from 2 */
ecx = 2;
/* xor edx, edx ; set edx to zero */
edx = 0;
/* mov [ebx], edx; set array[0] to edx */
array[0] = edx;
/* mov eax , 0x1 */
eax = 1;
/* mov [ebx+0x4] , eax */
array[1] = 1;
/* The while loop condition is checked with a loop condition:
<Lloop_cond>: ; place to jump back to every iteration
cmp ecx , [esp+0x4] ; compare to n
jle 0x080480b2 <Lloop> ; if ecx <= n, jump to loop
*/
while (ecx <= n) {
/*
This is the inner loop
<Lloop >:
*/
/* push eax; eax is temporarily saved to stack */
tmp = eax;
/* add eax, edx */
eax += edx;
/* mov [ebx+ecx∗4], eax */
array[ecx] = eax;
/* pop edx */
edx = tmp;
/* inc ecx */
ecx++;
}
/* ret */
return;
}