📄 382.html
字号:
bne,a .+16 ! 是子进程,跳转<br> mov %g0, %o0 ! 延迟插槽,注意理解延迟插槽的执行顺序<br> call .+8<br> nop<br> nop ! 需要替换,此时%o0为0,子进程继续<br> ");<br>} /* end of main */<br>--------------------------------------------------------------------------<br><br>可以用truss ./asm观察一下上述代码是否成功执行了fork()系统调用,man手册里提<br>到fork()失败会返回-1。<br><br>下面来观察syscall( 39, 3 ):<br><br>--------------------------------------------------------------------------<br>0x101d4 <main+32> : mov 0x27, %o0 ! 0x27<br>0x101d8 <main+36> : mov 3, %o1<br>0x101dc <main+40> : call 0x10fec <syscall><br>0x101e0 <main+44> : nop <br><br>0x10fec <syscall> : clr %g1<br>0x10ff0 <syscall+4> : ta 8<br>0x10ff4 <syscall+8> : bcc 0x11008 <syscall+28><br>0x10ff8 <syscall+12>: sethi %hi(0x16000), %o5<br>0x10ffc <syscall+16>: or %o5, 0x90, %o5 ! 0x16090 <_cerror><br>0x11000 <syscall+20>: jmp %o5<br>0x11004 <syscall+24>: nop <br>0x11008 <syscall+28>: retl <br>0x1100c <syscall+32>: nop <br>--------------------------------------------------------------------------<br><br>综合判断后提炼如下:<br><br>--------------------------------------------------------------------------<br>/* gcc -o asm asm.c */<br>int main ( int argc, char * argv[] )<br>{<br> __asm__<br> ("<br> mov 0x27, %o0<br> mov 3, %o1<br> clr %g1<br> ta 8<br> ");<br>} /* end of main */<br>--------------------------------------------------------------------------<br><br>同样可以用truss ./asm观察一下上述代码是否成功执行了setsid()系统调用。<br><br>下面来观察syscall( 48, 1, 1 ):<br><br>--------------------------------------------------------------------------<br>0x101e4 <main+48>: mov 0x30, %o0 ! 0x30<br>0x101e8 <main+52>: mov 1, %o1<br>0x101ec <main+56>: mov 1, %o2<br>0x101f0 <main+60>: call 0x10fec <syscall><br>0x101f4 <main+64>: nop <br>--------------------------------------------------------------------------<br><br>综合判断后提炼如下:<br><br>--------------------------------------------------------------------------<br>/* gcc -o asm asm.c */<br>int main ( int argc, char * argv[] )<br>{<br> __asm__<br> ("<br> mov 0x30, %o0<br> mov 1, %o1<br> mov 1, %o2<br> clr %g1<br> ta 8<br> ");<br>} /* end of main */<br>--------------------------------------------------------------------------<br><br>有了上面的研究基础,下面直接编写syscall( 1, 0 ):<br><br>--------------------------------------------------------------------------<br>/* gcc -o asm asm.c */<br>int main ( int argc, char * argv[] )<br>{<br> __asm__<br> ("<br> mov 0x01, %o0<br> clr %o1<br> clr %g1<br> ta 8<br> ");<br>} /* end of main */<br>--------------------------------------------------------------------------<br><br>ok,到此为止,我们不急于分析网络系统调用,计划先整和出一个汇编版本的daemon<br>框架:<br><br>--------------------------------------------------------------------------<br>/* gcc -o asm asm.c */<br>int main ( int argc, char * argv[] )<br>{<br> __asm__<br> ("<br> mov 2, %g1<br> ta 8<br> tst %o1 ! %o1不为0表示是子进程<br> bne,a .+16 ! 是子进程,跳转<br> mov %g0, %o0 ! 延迟插槽<br> call exit<br> nop<br> mov 0x27, %o0 ! 此前%o0为0,子进程继续<br> mov 3, %o1<br> clr %g1<br> ta 8<br> mov 0x30, %o0<br> mov 1, %o1<br> mov 1, %o2<br> clr %g1<br> ta 8<br> mov 2, %g1<br> ta 8<br> tst %o1 ! %o1不为0表示是子进程<br> bne,a .+16 ! 是子进程,跳转<br> mov %g0, %o0 ! 延迟插槽<br> call exit<br> nop<br>exit:<br> mov 0x01, %o0<br> clr %o1<br> clr %g1<br> ta 8<br> ");<br>} /* end of main */<br>--------------------------------------------------------------------------<br><br>哈哈,虽然SPARC总是和我过不去,可也要留下点回忆嘛。<br><br>接下来观察s = syscall( 230, 2, 2, 6 ):<br><br>--------------------------------------------------------------------------<br>0x10244 <main+144>: mov 0xe6, %o0<br>0x10248 <main+148>: mov 2, %o1<br>0x1024c <main+152>: mov 2, %o2<br>0x10250 <main+156>: mov 6, %o3<br>0x10254 <main+160>: call 0x10fec <syscall><br>0x10258 <main+164>: nop <br>0x1025c <main+168>: sethi %hi(0x27800), %o1<br>0x10260 <main+172>: st %o0, [ %o1 + 0x1b4 ] ! 0x279b4 <s><br>--------------------------------------------------------------------------<br><br>从这里可以看出s由%o0返回,其余的对于我们已经不新鲜了:<br><br>--------------------------------------------------------------------------<br>/* gcc -o asm asm.c */<br>int main ( int argc, char * argv[] )<br>{<br> __asm__<br> ("<br> mov 0xe6, %o0<br> mov 0x02, %o1<br> mov 0x02, %o2<br> mov 0x06, %o3<br> clr %g1<br> ta 8<br> st %o0, [ %l7 ] ! [ %l7 ]存放s<br> ");<br>} /* end of main */<br>--------------------------------------------------------------------------<br><br>如果去掉最后的st指令,可以用truss ./asm检验效果,最后的st指令是保存s的意思,<br>这里假设%l7已经指向正确的内存空间。<br><br>接下来观察syscall( 232, s, ( struct sockaddr * )&serv_addr, 16 ):<br><br>--------------------------------------------------------------------------<br>0x1020c <main+88> : sethi %hi(0x27800), %o0<br>0x10210 <main+92> : mov 2, %o1<br>0x10214 <main+96> : sth %o1, [ %o0 + 0x1b8 ] ! serv_addr.sin_family = 2;<br>0x10218 <main+100>: sethi %hi(0x27800), %o0<br>0x1021c <main+104>: mov 4, %o1<br>0x10220 <main+108>: or %o0, 0x1b8, %o2 ! 0x279b8 <serv_addr><br>0x10224 <main+112>: add %o1, %o2, %o0 ! 0x279bc <serv_addr+4><br>0x10228 <main+116>: clr [ %o0 ] ! serv_addr.sin_addr.s_addr = 0;<br>0x1022c <main+120>: sethi %hi(0x27800), %o0<br>0x10230 <main+124>: mov 2, %o1<br>0x10234 <main+128>: or %o0, 0x1b8, %o2 ! 0x279b8 <serv_addr><br>0x10238 <main+132>: add %o1, %o2, %o0 ! 0x279ba <serv_addr+2><br>0x1023c <main+136>: sethi %hi(0x2000), %o1<br>0x10240 <main+140>: sth %o1, [ %o0 ] ! serv_addr.sin_port = 0x2000;<br><br>0x10264 <main+176>: sethi %hi(0x27800), %o1<br>0x10268 <main+180>: mov 0xe8, %o0<br>0x1026c <main+184>: ld [ %o1 + 0x1b4 ], %o1 ! %o1设置成s<br>0x10270 <main+188>: sethi %hi(0x27800), %o3<br>0x10274 <main+192>: or %o3, 0x1b8, %o2 ! 0x279b8 <serv_addr><br>0x10278 <main+196>: mov 0x10, %o3 ! 16<br>0x1027c <main+200>: call 0x10fec <syscall><br>0x10280 <main+204>: nop <br>--------------------------------------------------------------------------<br><br>这两段比较晦涩难懂,我也无法确认该如何提炼,先尝试如下:<br><br>--------------------------------------------------------------------------<br>/* gcc -o asm asm.c */<br>int main ( int argc, char * argv[] )<br>{<br> __asm__<br> ("<br> mov 2, %o1<br> sth %o1, [ %l7 + 0x04 ] ! serv_addr.sin_family<br> clr [ %l7 + 0x08 ] ! serv_addr.sin_addr.s_addr<br> sethi %hi(0x2000), %o1<br> sth %o1, [ %l7 + 0x06 ] ! serv_addr.sin_port<br> mov 0xe8, %o0 ! 第一个参数232<br> ld [ %l7 ], %o1 ! 第二个参数s<br> mov 4, %o2<br> add %l7, %o2, %o2 ! 第三个参数&serv_addr<br> mov 0x10, %o3 ! 最后一个参数16<br> clr %g1<br> ta 8<br> ");<br>} /* end of main */<br>--------------------------------------------------------------------------<br><br>不用观察syscall( 233, s, 1 )、syscall( 48, 18, 1 ),直接编写它们:<br><br>--------------------------------------------------------------------------<br>/* gcc -o asm asm.c */<br>int main ( int argc, char * argv[] )<br>{<br> __asm__<br> ("<br> mov 0xe9, %o0 ! 第一个参数233<br> ld [ %l7 ], %o1 ! 第二个参数s<br> mov 0x01, %o2 ! 第三个参数1<br> clr %g1<br> ta 8<br> mov 0x30, %o0<br> mov 0x12, %o1<br> mov 0x01, %o2<br> clr %g1<br> ta 8<br> ");<br>} /* end of main */<br>--------------------------------------------------------------------------<br><br>下面是c = syscall( 234, s, 0, 0 )的相关代码片段,尚未提炼:<br><br>--------------------------------------------------------------------------<br>0x102c0 <main+268>: sethi %hi(0x27800), %o1<br>0x102c4 <main+272>: mov 0xea, %o0<br>0x102c8 <main+276>: ld [ %o1 + 0x1b4 ], %o1<br>0x102cc <main+280>: clr %o2<br>0x102d0 <main+284>: clr %o3<br>0x102d4 <main+288>: call 0x10fec <syscall><br>0x102d8 <main+292>: nop <br>0x102dc <main+296>: sethi %hi(0x27800), %o1<br>0x102e0 <main+300>: st %o0, [ %o1 + 0x1b0 ] ! 0x279b0 <c><br>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -