实验材料:http://download.csdn.net/detail/u010560443/9458899
GDB教程:
http://heather.cs.ucdavis.edu/~matloff/UnixAndC/CLanguage/Debug.html
http://www.gnu.org/software/gdb/
x86手册:https://sourceware.org/binutils/docs/as/
//read_line读取到的字符串地址在ebp+8处
//答案:1 6 11 16 21 26
//要求:read_six_numbers拆分字符串为六个数字并存到phase_2但局部数组中,
//phase_2+51处要求数组中后一个元素必须比前一个元素大5
Dump of assembler code for function phase_2:
0x08048ba4 <+0>: push %ebp
0x08048ba5 <+1>: mov %esp,%ebp
0x08048ba7 <+3>: sub $0x28,%esp #esp=esp-40
0x08048baa <+6>: lea -0x1c(%ebp),%eax #eax=ebp-28
0x08048bad <+9>: mov %eax,0x4(%esp) ##arg2 of read_six_numbers
0x08048bb1 <+13>: mov 0x8(%ebp),%eax #eax=*(ebp+8) input string addr
0x08048bb4 <+16>: mov %eax,(%esp) #arg1=input string addr
0x08048bb7 <+19>: call 0x8048fcc
0x08048bbc <+24>: movl $0x1,-0x4(%ebp) #local i=1
0x08048bc3 <+31>: jmp 0x8048be3 63>
0x08048bc5 <+33>: mov -0x4(%ebp),%eax #eax=i
0x08048bc8 <+36>: mov -0x1c(%ebp,%eax,4),%edx #edx=a[1]
0x08048bcc <+40>: mov -0x4(%ebp),%eax #eax=i
0x08048bcf <+43>: dec %eax #eax=eax-1
0x08048bd0 <+44>: mov -0x1c(%ebp,%eax,4),%eax #eax=a[0]
0x08048bd4 <+48>: add $0x5,%eax #eax=a[0]+5
0x08048bd7 <+51>: cmp %eax,%edx #if(a[1]==a[0]+5)
0x08048bd9 <+53>: je 0x8048be0 60>
0x08048bdb <+55>: call 0x8049626
0x08048be0 <+60>: incl -0x4(%ebp) # i++
0x08048be3 <+63>: cmpl $0x5,-0x4(%ebp) # i<=5
0x08048be7 <+67>: jle 0x8048bc5 33>
0x08048be9 <+69>: leave
0x08048bea <+70>: ret
Dump of assembler code for function read_six_numbers:
0x08048fcc <+0>: push %ebp
0x08048fcd <+1>: mov %esp,%ebp
0x08048fcf <+3>: push %esi
0x08048fd0 <+4>: push %ebx
0x08048fd1 <+5>: sub $0x30,%esp #esp=esp-30
0x08048fd4 <+8>: mov 0xc(%ebp),%eax #local eax= *(ebp+12)= a
0x08048fd7 <+11>: add $0x14,%eax # &a[5] of int a[6]
0x08048fda <+14>: mov 0xc(%ebp),%edx
0x08048fdd <+17>: add $0x10,%edx
0x08048fe0 <+20>: mov 0xc(%ebp),%ecx
0x08048fe3 <+23>: add $0xc,%ecx
0x08048fe6 <+26>: mov 0xc(%ebp),%ebx
0x08048fe9 <+29>: add $0x8,%ebx
0x08048fec <+32>: mov 0xc(%ebp),%esi
0x08048fef <+35>: add $0x4,%esi # &a[1]
0x08048ff2 <+38>: mov %eax,0x1c(%esp) # arg8
0x08048ff6 <+42>: mov %edx,0x18(%esp) # 7
0x08048ffa <+46>: mov %ecx,0x14(%esp) # 6
0x08048ffe <+50>: mov %ebx,0x10(%esp) # 5
0x08049002 <+54>: mov %esi,0xc(%esp) # 4 = &a[1]
0x08049006 <+58>: mov 0xc(%ebp),%eax #eax= *(ebp+12)
0x08049009 <+61>: mov %eax,0x8(%esp) # arg3= &a[0]
0x0804900d <+65>: movl $0x8049c45,0x4(%esp) #arg2=format string
0x08049015 <+73>: mov 0x8(%ebp),%eax #input string addr
0x08049018 <+76>: mov %eax,(%esp) #arg1=input string
0x0804901b <+79>: call 0x8048868 @plt>
0x08049020 <+84>: mov %eax,-0xc(%ebp) # eax= return value of sscanf (string length)
0x08049023 <+87>: cmpl $0x5,-0xc(%ebp) # 5 > strlen
0x08049027 <+91>: jg 0x804902e 98>
0x08049029 <+93>: call 0x8049626
0x0804902e <+98>: add $0x30,%esp
0x08049031 <+101>: pop %ebx
0x08049032 <+102>: pop %esi
0x08049033 <+103>: pop %ebp
0x08049034 <+104>: ret
//答案:0 967
//要求:第一个输入是跳转地址在数组中的偏移,跳转后需要和一个立即数比较,第二个输入必须和这个立即数一样
//offset=0,Imm=0x3c7=967 ; offset=1,Imm=0x93......
Dump of assembler code for function phase_3:
0x08048beb <+0>: push %ebp
0x08048bec <+1>: mov %esp,%ebp
0x08048bee <+3>: sub $0x28,%esp #esp-28
0x08048bf1 <+6>: movl $0x0,-0x8(%ebp) # local2=*(ebp-8)=0
0x08048bf8 <+13>: movl $0x0,-0x4(%ebp) # local1=*(ebp-4)=0
0x08048bff <+20>: lea -0x10(%ebp),%eax # eax=ebp-16=(int *)&num2 local4=num2
0x08048c02 <+23>: mov %eax,0xc(%esp) # arg4=&num2
0x08048c06 <+27>: lea -0xc(%ebp),%eax # eax=ebp-12=(int *)&num1 local3=num1
0x08048c09 <+30>: mov %eax,0x8(%esp) # arg3=&num1
0x08048c0d <+34>: movl $0x8049947,0x4(%esp) #arg2=format string
0x08048c15 <+42>: mov 0x8(%ebp),%eax #eax=input string
0x08048c18 <+45>: mov %eax,(%esp) #arg1=input string
0x08048c1b <+48>: call 0x8048868 @plt>
0x08048c20 <+53>: mov %eax,-0x4(%ebp) #local1=ret value=num of digit
0x08048c23 <+56>: cmpl $0x1,-0x4(%ebp)
0x08048c27 <+60>: jg 0x8048c2e 67> #if(local1>1) jmp 67;
0x08048c29 <+62>: call 0x8049626 #else bomb;
0x08048c2e <+67>: mov -0xc(%ebp),%eax #eax=num1
0x08048c31 <+70>: mov %eax,-0x14(%ebp) #local5=*(ebp+20)=num1 (offset)
0x08048c34 <+73>: cmpl $0x7,-0x14(%ebp) #local5:7
0x08048c38 <+77>: ja 0x8048c8e 163> #if(local5>7) bomb ;
0x08048c3a <+79>: mov -0x14(%ebp),%edx #edx=num1
0x08048c3d <+82>: mov 0x8049950(,%edx,4),%eax #eax=0x8049950+4*num1 (array of address)
0x08048c44 <+89>: jmp *%eax # when num1=0,*(0x8049950+0)=0x08048c46
0x08048c46 <+91>: movl $0x3c7,-0x8(%ebp) #local2=0x3c7=967
0x08048c4d <+98>: jmp 0x8048c93 168>
0x08048c4f <+100>: movl $0x93,-0x8(%ebp)
0x08048c56 <+107>: jmp 0x8048c93 168>
0x08048c58 <+109>: movl $0x296,-0x8(%ebp)
0x08048c5f <+116>: jmp 0x8048c93 168>
0x08048c61 <+118>: movl $0x225,-0x8(%ebp)
0x08048c68 <+125>: jmp 0x8048c93 168>
0x08048c6a <+127>: movl $0x3a6,-0x8(%ebp)
0x08048c71 <+134>: jmp 0x8048c93 168>
0x08048c73 <+136>: movl $0x17a,-0x8(%ebp)
0x08048c7a <+143>: jmp 0x8048c93 168>
0x08048c7c <+145>: movl $0x1e5,-0x8(%ebp)
0x08048c83 <+152>: jmp 0x8048c93 168>
0x08048c85 <+154>: movl $0x16b,-0x8(%ebp)
0x08048c8c <+161>: jmp 0x8048c93 168>
0x08048c8e <+163>: call 0x8049626
0x08048c93 <+168>: mov -0x10(%ebp),%eax #eax=local4=num2
0x08048c96 <+171>: cmp %eax,-0x8(%ebp) #if(num2==local2)
0x08048c99 <+174>: je 0x8048ca0 181>
0x08048c9b <+176>: call 0x8049626
0x08048ca0 <+181>: leave
0x08048ca1 <+182>: ret
End of assembler dump.
数组第一个元素:
(gdb) x/wx 0x8049950
0x8049950: 0x08048c46
//答案:10
//要求:输入数的阶乘为0x375f00,即3628800
Dump of assembler code for function phase_4:
0x08048cd1 <+0>: push %ebp
0x08048cd2 <+1>: mov %esp,%ebp
0x08048cd4 <+3>: sub $0x28,%esp #esp-0x28
0x08048cd7 <+6>: lea -0xc(%ebp),%eax #eax=ebp-12=&local3
0x08048cda <+9>: mov %eax,0x8(%esp) #arg3=*(esp+8)=&local3
0x08048cde <+13>: movl $0x8049970,0x4(%esp) #arg2=format string
0x08048ce6 <+21>: mov 0x8(%ebp),%eax #eax=input string
0x08048ce9 <+24>: mov %eax,(%esp) #arg1=*(esp)=input string
0x08048cec <+27>: call 0x8048868 @plt>
0x08048cf1 <+32>: mov %eax,-0x4(%ebp) #local1=ret value
0x08048cf4 <+35>: cmpl $0x1,-0x4(%ebp) #if(local1!=1) bomb
0x08048cf8 <+39>: jne 0x8048d01 48>
0x08048cfa <+41>: mov -0xc(%ebp),%eax #eax=local3 = input
0x08048cfd <+44>: test %eax,%eax #if(local3>0)
0x08048cff <+46>: jg 0x8048d06 53>
0x08048d01 <+48>: call 0x8049626
0x08048d06 <+53>: mov -0xc(%ebp),%eax #eax=local3
0x08048d09 <+56>: mov %eax,(%esp) #arg=local3=input
0x08048d0c <+59>: call 0x8048ca2
0x08048d11 <+64>: mov %eax,-0x8(%ebp) #local2=ret value=input!
0x08048d14 <+67>: cmpl $0x375f00,-0x8(%ebp) #if(local2==0x375f00) 10!=0x375f00
0x08048d1b <+74>: je 0x8048d22 81>
0x08048d1d <+76>: call 0x8049626
0x08048d22 <+81>: leave
0x08048d23 <+82>: ret
End of assembler dump.
Dump of assembler code for function func4:
0x08048ca2 <+0>: push %ebp
0x08048ca3 <+1>: mov %esp,%ebp
0x08048ca5 <+3>: sub $0x8,%esp
0x08048ca8 <+6>: cmpl $0x1,0x8(%ebp)
0x08048cac <+10>: jg 0x8048cb7 21> #if(input<1) jmp 21
0x08048cae <+12>: movl $0x1,-0x4(%ebp) #else local1=1;
0x08048cb5 <+19>: jmp 0x8048ccc 42> #return local1;
0x08048cb7 <+21>: mov 0x8(%ebp),%eax #eax=input
0x08048cba <+24>: dec %eax #eax=input-1
0x08048cbb <+25>: mov %eax,(%esp) #arg1=input-1
0x08048cbe <+28>: call 0x8048ca2 #call func4 recursively
0x08048cc3 <+33>: mov %eax,%edx #edx=ret value
0x08048cc5 <+35>: imul 0x8(%ebp),%edx #edx=edx*input
0x08048cc9 <+39>: mov %edx,-0x4(%ebp) #local1=edx
0x08048ccc <+42>: mov -0x4(%ebp),%eax #eax=local1
0x08048ccf <+45>: leave
0x08048cd0 <+46>: ret
End of assembler dump.
//factorial function
//10!=3628800=0x375f00
int func4(int input)
{
int local1;
if(input>1)
local1=input*func4(input-1);
else
local1=1;
return local1;
}
//答案:111100
//解题:
//phase_5中50~59取输入字符串中每个字符的低4位的ascii码值当作偏移,然后根据偏移找到int型数组(位于0x804a5c0)中对应的值
//若6个字符对应的整形值相加的和等于44(phase_5+88处),则成功
(gdb) disass phase_5
Dump of assembler code for function phase_5:
0x08048d24 <+0>: push %ebp
0x08048d25 <+1>: mov %esp,%ebp
0x08048d27 <+3>: sub $0x18,%esp #esp-0x18
0x08048d2a <+6>: mov 0x8(%ebp),%eax #eax=input string
0x08048d2d <+9>: mov %eax,(%esp) #
0x08048d30 <+12>: call 0x8049035
0x08048d35 <+17>: mov %eax,-0x4(%ebp) #local1=string length
0x08048d38 <+20>: cmpl $0x6,-0x4(%ebp)
0x08048d3c <+24>: je 0x8048d43 31> #if(local1==6) jmp 31
0x08048d3e <+26>: call 0x8049626 #else bom6
0x08048d43 <+31>: movl $0x0,-0x8(%ebp) #local2=0
0x08048d4a <+38>: movl $0x0,-0xc(%ebp) #local3=0
0x08048d51 <+45>: jmp 0x8048d6f 75> #loop start
0x08048d53 <+47>: mov -0xc(%ebp),%eax #eax=local3 (init=0)
0x08048d56 <+50>: add 0x8(%ebp),%eax #eax+=input string addr
0x08048d59 <+53>: movzbl (%eax),%eax #eax=first char=0x000000??
0x08048d5c <+56>: movsbl %al,%eax #eax=0xffffff(??)
0x08048d5f <+59>: and $0xf,%eax #eax=0x0000000(?)=(lower 4 bits)
0x08048d62 <+62>: mov 0x804a5c0(,%eax,4),%eax#eax=*(0x804a5c0+4*eax) (watch *0x804a5c0 in mem)
0x08048d69 <+69>: add %eax,-0x8(%ebp) #local2+=eax;
0x08048d6c <+72>: incl -0xc(%ebp) #local3++
0x08048d6f <+75>: cmpl $0x5,-0xc(%ebp) #local3<=5 loop;
0x08048d73 <+79>: jle 0x8048d53 47>
0x08048d75 <+81>: cmpl $0x2c,-0x8(%ebp) #if(loca2==44) success; else bomb;
0x08048d79 <+85>: je 0x8048d80 92> #
0x08048d7b <+87>: call 0x8049626
0x08048d80 <+92>: leave
0x08048d81 <+93>: ret
End of assembler dump.
//整形数组
(gdb) x/4wx 0x804a5c0
0x804a5c0 .2480>: 0x00000002 0x0000000a 0x00000006 0x00000001
//可以看到4*0xa+2*0x2==44,偏移为2个0,4个1
//在6个字符中,只要4个字符的后4位为1,2个字符后2位为0 就可以成功。。
//比如0x313131313030,对应的字符串为111100
//答案:345
//解题:看到phase_6的第88行是和输入的数做比较,只要在这里设置断点直接查看edx中的值即可
(gdb) disass phase_6
Dump of assembler code for function phase_6:
0x08048e16 <+0>: push %ebp
0x08048e17 <+1>: mov %esp,%ebp
0x08048e19 <+3>: sub $0x18,%esp # esp-=0x18
0x08048e1c <+6>: movl $0x804a66c,-0x8(%ebp) # local2=0x804a66c
0x08048e23 <+13>: mov 0x8(%ebp),%eax # ax=input string
0x08048e26 <+16>: mov %eax,(%esp)
0x08048e29 <+19>: call 0x8048858 @plt> # eax=input number(string->int)
0x08048e2e <+24>: mov %eax,%edx # edx=input
0x08048e30 <+26>: mov -0x8(%ebp),%eax # eax=local2
0x08048e33 <+29>: mov %edx,(%eax) # *(0x804a66c)=input
0x08048e35 <+31>: mov -0x8(%ebp),%eax # eax=local2
0x08048e38 <+34>: mov %eax,(%esp) # arg=local2
0x08048e3b <+37>: call 0x8048d82
0x08048e40 <+42>: mov %eax,-0x8(%ebp) # local2=eax=ret value; (addr)
0x08048e43 <+45>: mov -0x8(%ebp),%eax
0x08048e46 <+48>: mov %eax,-0x4(%ebp) # local1=local2
0x08048e49 <+51>: movl $0x1,-0xc(%ebp) # local3=1
0x08048e50 <+58>: jmp 0x8048e5e 72>
#loop
0x08048e52 <+60>: mov -0x4(%ebp),%eax # eax=local1
0x08048e55 <+63>: mov 0x8(%eax),%eax # eax=*(eax+8)
0x08048e58 <+66>: mov %eax,-0x4(%ebp) # local1=eax
0x08048e5b <+69>: incl -0xc(%ebp) # local3++
0x08048e5e <+72>: cmpl $0x5,-0xc(%ebp) # compare 5:local3
0x08048e62 <+76>: jle 0x8048e52 60> # if(local3<=5) loop
0x08048e64 <+78>: mov -0x4(%ebp),%eax # eax=local1
0x08048e67 <+81>: mov (%eax),%edx # edx=*(local1)
0x08048e69 <+83>: mov 0x804a66c,%eax # eax=*(0x804a66c)=input
0x08048e6e <+88>: cmp %eax,%edx # if(edx==input)
0x08048e70 <+90>: je 0x8048e77 97>
0x08048e72 <+92>: call 0x8049626
0x08048e77 <+97>: leave
0x08048e78 <+98>: ret
End of assembler dump.
(gdb) disass 0x8048d82
Dump of assembler code for function fun6:
0x08048d82 <+0>: push %ebp
0x08048d83 <+1>: mov %esp,%ebp
0x08048d85 <+3>: sub $0x10,%esp # esp-0x10
0x08048d88 <+6>: mov 0x8(%ebp),%eax # eax=arg=local2=0x804a66c
0x08048d8b <+9>: mov %eax,-0x10(%ebp) # local4=arg
0x08048d8e <+12>: mov 0x8(%ebp),%eax #
0x08048d91 <+15>: mov %eax,-0x10(%ebp)
0x08048d94 <+18>: mov 0x8(%ebp),%eax # eax=arg
0x08048d97 <+21>: mov 0x8(%eax),%eax # eax=*(arg+8)=*(0x804a66c)
0x08048d9a <+24>: mov %eax,-0xc(%ebp) # local3=eax=*(0x804a66c)
0x08048d9d <+27>: mov -0x10(%ebp),%eax # eax=local4=0x804a66c
0x08048da0 <+30>: movl $0x0,0x8(%eax) # *(0x804a66c)=0
0x08048da7 <+37>: jmp 0x8048e0b 137>
#loop
0x08048da9 <+39>: mov -0x10(%ebp),%eax # eax=local4
0x08048dac <+42>: mov %eax,-0x4(%ebp) # local1=local4
0x08048daf <+45>: mov -0x10(%ebp),%eax
0x08048db2 <+48>: mov %eax,-0x8(%ebp) # local2=local4
0x08048db5 <+51>: jmp 0x8048dc6 68>
0x08048db7 <+53>: mov -0x4(%ebp),%eax
0x08048dba <+56>: mov %eax,-0x8(%ebp)
0x08048dbd <+59>: mov -0x4(%ebp),%eax
0x08048dc0 <+62>: mov 0x8(%eax),%eax
0x08048dc3 <+65>: mov %eax,-0x4(%ebp)
0x08048dc6 <+68>: cmpl $0x0,-0x4(%ebp)
0x08048dca <+72>: je 0x8048dda 88> # if(local1==0)
0x08048dcc <+74>: mov -0x4(%ebp),%eax
0x08048dcf <+77>: mov (%eax),%edx
0x08048dd1 <+79>: mov -0xc(%ebp),%eax
0x08048dd4 <+82>: mov (%eax),%eax
0x08048dd6 <+84>: cmp %eax,%edx
0x08048dd8 <+86>: jg 0x8048db7 53>
0x08048dda <+88>: mov -0x8(%ebp),%eax # eax=local2
0x08048ddd <+91>: cmp -0x4(%ebp),%eax # local2:local1
0x08048de0 <+94>: je 0x8048ded 107> # if(local2==local1)
0x08048de2 <+96>: mov -0x8(%ebp),%edx
0x08048de5 <+99>: mov -0xc(%ebp),%eax
0x08048de8 <+102>: mov %eax,0x8(%edx)
0x08048deb <+105>: jmp 0x8048df3 113>
0x08048ded <+107>: mov -0xc(%ebp),%eax # eax=local3
0x08048df0 <+110>: mov %eax,-0x10(%ebp) # local4=local3
0x08048df3 <+113>: mov -0xc(%ebp),%eax # eax=local3
0x08048df6 <+116>: mov 0x8(%eax),%eax # eax=*(local3+8)
0x08048df9 <+119>: mov %eax,-0x8(%ebp) # local2=eax
0x08048dfc <+122>: mov -0xc(%ebp),%edx # edx=local3
0x08048dff <+125>: mov -0x4(%ebp),%eax # eax=local1
0x08048e02 <+128>: mov %eax,0x8(%edx) # *(local3+8)=local1
0x08048e05 <+131>: mov -0x8(%ebp),%eax # eax=local2
0x08048e08 <+134>: mov %eax,-0xc(%ebp) # local3=local2
0x08048e0b <+137>: cmpl $0x0,-0xc(%ebp)
0x08048e0f <+141>: jne 0x8048da9 39> #if(local3!=0) jump 39;
0x08048e11 <+143>: mov -0x10(%ebp),%eax
0x08048e14 <+146>: leave
0x08048e15 <+147>: ret
End of assembler dump.
0x159=345