嵌入式汇编实现系统调用-rename

11 篇文章 1 订阅

原创文章,转载请标注出处~

平台为兆芯x86-64环境

rename系统调用有两个入参,有一个返回值,首先用libc实现功能:

#include <stdio.h>
#include <string.h>
int main(void)
{
    int error = -1;
    char *oldname = "hello.c";
    char *newname = "newhello.c";
    error = rename(oldname,newname);
    if(error == 0)
    {
        printf("Rename successfully!\n");
    }
    else
    {
        printf("Rename fail! %s(%d) !\n",strerror(-error),error);
    }
}

编译:

root@henry-002:/usr/test_code# gcc rename_syscall.c  -o rename_syscall --static

执行结果正常:

root@henry-002:/usr/test_code# ./rename_libc 
Rename successfully!

不修改文件名的情况下再次执行:

root@henry-002:/usr/test_code# ./rename_libc 
Rename fail! Operation not permitted(-1) !

发现明明是文件不存在,但是返回值却是-1,这里比较奇怪,详细分析可以查看《用GDB跟踪汇编代码排查返回值》。

反汇编:

root@henry-002:/usr/test_code# objdump -dlt rename_libc > rename_libc.dis

找到关键的代码部分:

000000000040105e <main>:
main():
  40105e:	55                   	push   %rbp
  40105f:	48 89 e5             	mov    %rsp,%rbp
  401062:	48 83 ec 20          	sub    $0x20,%rsp
  401066:	c7 45 ec ff ff ff ff 	movl   $0xffffffff,-0x14(%rbp)
  40106d:	48 c7 45 f0 04 3a 49 	movq   $0x493a04,-0x10(%rbp)
  401074:	00 
  401075:	48 c7 45 f8 0c 3a 49 	movq   $0x493a0c,-0x8(%rbp)
  40107c:	00 
  40107d:	48 8b 55 f8          	mov    -0x8(%rbp),%rdx
  401081:	48 8b 45 f0          	mov    -0x10(%rbp),%rax
  401085:	48 89 d6             	mov    %rdx,%rsi
  401088:	48 89 c7             	mov    %rax,%rdi
  40108b:	e8 70 6f 00 00       	callq  408000 <rename>
  401090:	89 45 ec             	mov    %eax,-0x14(%rbp)
  401093:	83 7d ec 00          	cmpl   $0x0,-0x14(%rbp)
  401097:	75 0c                	jne    4010a5 <main+0x47>
  401099:	bf 17 3a 49 00       	mov    $0x493a17,%edi
  40109e:	e8 ad 76 00 00       	callq  408750 <_IO_puts>
  4010a3:	eb 21                	jmp    4010c6 <main+0x68>
  4010a5:	8b 45 ec             	mov    -0x14(%rbp),%eax
  4010a8:	f7 d8                	neg    %eax
  4010aa:	89 c7                	mov    %eax,%edi
  4010ac:	e8 df 83 01 00       	callq  419490 <strerror>
  4010b1:	8b 55 ec             	mov    -0x14(%rbp),%edx
  4010b4:	48 89 c6             	mov    %rax,%rsi
  4010b7:	bf 2c 3a 49 00       	mov    $0x493a2c,%edi
  4010bc:	b8 00 00 00 00       	mov    $0x0,%eax
  4010c1:	e8 0a 6e 00 00       	callq  407ed0 <_IO_printf>
  4010c6:	c9                   	leaveq 
  4010c7:	c3                   	retq   
  4010c8:	0f 1f 84 00 00 00 00 	nopl   0x0(%rax,%rax,1)
  4010cf:	00 
.................
0000000000408000 <rename>:
rename():
  408000:	b8 52 00 00 00       	mov    $0x52,%eax
  408005:	0f 05                	syscall 
  408007:	48 3d 01 f0 ff ff    	cmp    $0xfffffffffffff001,%rax
  40800d:	0f 83 bd 09 03 00    	jae    4389d0 <__syscall_error>
  408013:	c3                   	retq   
  408014:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
  40801b:	00 00 00 
  40801e:	66 90                	xchg   %ax,%ax

 

 

 

下边就通过嵌入式汇编进行替换:

#include <stdio.h>
#include <string.h>
int main(void)
{
    int error = -1;
    char *oldname = "hello.c";
    char *newname = "newhello.c";
    asm volatile(
        "mov %1,%%rdi\n\t"
        "mov %2,%%rsi\n\t"
        "mov $0x52,%%eax\n\t"
        "syscall\n\t"
        :"=a"(error)
        :"m"(oldname),"m"(newname)
    );
    if(error == 0)
    {
        printf("Rename successfully!\n");
    }
    else
    {
        printf("Rename fail! %s(%d) !\n",strerror(-error),error);
    }
}

编译:

root@henry-002:/usr/test_code# gcc rename_syscall.c  -o rename_syscall --static

执行:

root@henry-002:/usr/test_code# ./rename_syscall 
Rename fail! No such file or directory(-2) !
root@henry-002:/usr/test_code# 
root@henry-002:/usr/test_code# 
root@henry-002:/usr/test_code# mv newhello.c hello.c
root@henry-002:/usr/test_code# ./rename_syscall 
Rename successfully!

发现自己实现的嵌入式系统调用返回的异常值是正确的,反汇编:

root@henry-002:/usr/test_code# objdump -dlt rename_syscall > rename_syscall.dis

找到关键执行代码:

000000000040105e <main>:
main():
  40105e:	55                   	push   %rbp
  40105f:	48 89 e5             	mov    %rsp,%rbp
  401062:	48 83 ec 20          	sub    $0x20,%rsp
  401066:	c7 45 ec ff ff ff ff 	movl   $0xffffffff,-0x14(%rbp)
  40106d:	48 c7 45 f0 e4 39 49 	movq   $0x4939e4,-0x10(%rbp)
  401074:	00 
  401075:	48 c7 45 f8 ec 39 49 	movq   $0x4939ec,-0x8(%rbp)
  40107c:	00 
  40107d:	48 8b 7d f0          	mov    -0x10(%rbp),%rdi
  401081:	48 8b 75 f8          	mov    -0x8(%rbp),%rsi
  401085:	b8 52 00 00 00       	mov    $0x52,%eax
  40108a:	0f 05                	syscall 
  40108c:	89 45 ec             	mov    %eax,-0x14(%rbp)
  40108f:	83 7d ec 00          	cmpl   $0x0,-0x14(%rbp)
  401093:	75 0c                	jne    4010a1 <main+0x43>
  401095:	bf f7 39 49 00       	mov    $0x4939f7,%edi
  40109a:	e8 91 76 00 00       	callq  408730 <_IO_puts>
  40109f:	eb 21                	jmp    4010c2 <main+0x64>
  4010a1:	8b 45 ec             	mov    -0x14(%rbp),%eax
  4010a4:	f7 d8                	neg    %eax
  4010a6:	89 c7                	mov    %eax,%edi
  4010a8:	e8 c3 83 01 00       	callq  419470 <strerror>
  4010ad:	8b 55 ec             	mov    -0x14(%rbp),%edx
  4010b0:	48 89 c6             	mov    %rax,%rsi
  4010b3:	bf 0c 3a 49 00       	mov    $0x493a0c,%edi
  4010b8:	b8 00 00 00 00       	mov    $0x0,%eax
  4010bd:	e8 0e 6e 00 00       	callq  407ed0 <_IO_printf>
  4010c2:	c9                   	leaveq 
  4010c3:	c3                   	retq   
  4010c4:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
  4010cb:	00 00 00 
  4010ce:	66 90                	xchg   %ax,%ax

本篇文章实现了两个参数的系统调用,并正确的接收到了返回值~

 

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值