免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: vupiggy
打印 上一主题 下一主题

老问题,仍没有满意答案 -- 可变参数列表传递 [复制链接]

论坛徽章:
0
11 [报告]
发表于 2007-07-18 21:45 |只看该作者
会手工写printf函数吗?
自己分析arg,找出所有的参数,如果参数的类型不是字符串,转换。比如
fun(path,"%d %s",20,"abc")
最后根据%d %s 得到20 "abc",把20转换成"20".
exec*之间转换就简单了。

论坛徽章:
0
12 [报告]
发表于 2007-07-18 22:24 |只看该作者
int func(const char *path,const char *arg,...)
{
        //to simplify argv
        char argv[ARGV_MAX][ARGV_BUF_MAX];
        int argc = 0;
        va_list va;
        va_list ap;
        int retval;
        va_start(ap, format);

        char *cur = arg;
        char *tmp;
       

        while(argc < ARGV_MAX && cru) {       
                tmp = argv[argc];
                while(*cur != ' ' && tmp-argv[argc] < ARGV_BUF_MAX - 1) {
                        switch (*cur) {
                                case '\0':
                                        *tmp = '\0';
                                        break;
                                case '%':
                                        if (*cur == 'd') {
                                                int iv = va_arg(ap,int);
                                                sprintf(tmp,"%d",iv);
                                                while(*tmp)
                                                        ++tmp;
                                        } else if (*cur == 's') {
                                                char *sv = va_arg(ap,char *);
                                                sprintf(tmp,"%s",iv);
                                                while(*tmp)
                                                        ++tmp;
                                        } //else ...//other
                                        else {
                                                *tmp++ = '%';
                                                *tmp = *cur;
                                        }
                                       
                                        break;
                                case ' ':
                                        *tmp == '\0';
                                        --cru;
                                        break;
                                default :
                                        *tmp = *cru;
                        }
                }
                if (tmp - argv[argc] >= ARGV_BUF_MAX)
                        *tmp == '\0';
                ++argc;

        }       
}


上面抄的,突然发现直接vsprintf就可以了。不明白你需要什么

论坛徽章:
0
13 [报告]
发表于 2007-07-18 22:26 |只看该作者
总之能检查到函数的所有参数,也能execl之前执行你的动作,不知道你想干什么,原封不动不行,参数都不一样,execl都是char*,而fun可以有int

论坛徽章:
0
14 [报告]
发表于 2007-07-18 23:06 |只看该作者
va_start, va_arg, va_end三部曲在教科书上有

这个问题的本质上是看有没有一个纯C的方法将调用者的栈拷贝进被调用者的栈,保持数量,值和顺序相同或者干脆让将要调用的函数使用调用者的栈。

得,用纯C的方法目前来看来是没有希望的,已经说服老板接受汇编版本了。

汇编就简单了,将给func的参数push,然后call glibc的execl,最后恢复esp。一个高手告诉我的妙方是将func声明为__attribute__ ((naked)),这样就编译出来的代码里头就没有push ebp这一步,不声明任何局部变量,要调用execl时,就一个jmp语句足矣。

[ 本帖最后由 vupiggy 于 2007-7-18 16:08 编辑 ]

论坛徽章:
0
15 [报告]
发表于 2007-07-19 09:14 |只看该作者
是我理解错了,不好意思。
execl最后也要用va_arg,类型为char*然后找到参数为NULL就停止。再构造成execve所需的参数。

没发现为什么要汇编,
将给func的参数push,然后call glibc的execl,最后恢复esp。
这个用C不可以吗

论坛徽章:
0
16 [报告]
发表于 2007-07-19 09:19 |只看该作者
我终于理解你的意思了,真不好意思,你是想直接就调用
没有局部变量的函数能有什么用?
还是自己找参数出来,然后调用比较合适吧。这就像你说的一样,也不费事,就几条语句,干嘛非要整个汇编找参数

论坛徽章:
0
17 [报告]
发表于 2007-07-19 11:37 |只看该作者
呵呵,本来以为这个问题已经结束了。

目前为止我所问过的人都认为用C是基本无解的,因为关键不是找参数的问题,用va_arg宏可以找到所有的参数,可恶的是怎么用C语句把它们原封不动地传给execl,这个目前来看非用push指令不可,C语句提供了函数调用的语法,栈就被按照C调用惯例设置好了。

老哥如果有兴趣可以试试怎么用C实现,不要像二楼的大哥那样想当然哦,写几个例子试试,呵呵,指针,栈,一准搞到你疲惫不堪,反正我是有点。但是要证明不可能总是比较难的事情,所以总希望能得到一个好看的C解法,故有此问。

P.S,没有局部变量的好处,想调用execl可以直接用jmp,不用考虑栈指针一类讨厌的事。否则要用循环来push,call execl之后要对esp做减法,麻烦死了,算不准的话下场可耻。至于需要局部变量的时候呢?呵呵,将需要局部变量的功能封到另外一个函数里去,这样在那个函数返回之后就栈指针就在它该在的地方。

论坛徽章:
0
18 [报告]
发表于 2007-07-19 11:55 |只看该作者
因为关键不是找参数的问题,是原封不动?

什么是原封不动?

论坛徽章:
0
19 [报告]
发表于 2007-07-19 11:56 |只看该作者
不用汇编,你是认为不能解决还是不好解决

目前为止我所问过的人都认为用C是基本无解的
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP