无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
查看: 2924|回复: 6
打印 上一主题 下一主题

[讨论] grub4dos 内部函数 与 外部命令 的一点发现。

[复制链接]
跳转到指定楼层
#
发表于 2013-5-19 10:05:33 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
本帖最后由 2011895866818 于 2013-5-20 10:30 编辑

我发现sratlf,chenall 等高人都是用什么内部函数,但是我找了一下,也没有找到相关说明文档。
这也太打击 grub4dos 爱好者的热情了吧?

我不甘心,所以自己看了一下源码(只是搜索了一下关键字)。

原来是一些内部函数的入口地址。
chenall为什么就不能稍微说一下呢!
本论坛也没有相关的文章,难道这里只交流menu.lst!

以下是我的发现
比如:
Fn.0
#define sprintf ((int (*)(char *, const char *, ...))((*(int **)0x8300)[0]))
Fn.6
#define cls ((void (*)(void))((*(int **)0x8300)[6]))

0x8300 是 grub4dos 系统函数(API)的入口点.  asm.S 源码定义.

比较全的说明宏定义如下
http://grubutils.googlecode.com/svn/trunk/src/include/grub4dos.h

grub4dos中call的实现(在源码中的builtins.c)

static int call_func(char *arg,int flags)
{
        errnum = 0;
        if (*arg==':')//这个脚本中的标签调用
        {
                return bat_run_script(NULL, arg, flags);
        }
        if (*(short *)arg == 0x6E46) //这个0x6E46是Fn(小端存储),调用内部函数地址
        {
                unsigned int func;
                unsigned long long ull;
                int i;
                char *ch[10]={0};
                arg += 3;
                if (! read_val(&arg,&ull))
                        return 0;
                func=(unsigned int)ull;
                arg[parse_string(arg)] = 0;
                for (i=0;i<10;++i)
                {
                        if (read_val(&arg,&ull))
                                ch = (char *)(int)ull;
                        else
                        {
                                ch = arg;
                                arg = skip_to(SKIP_WITH_TERMINATE,arg);
                                if (ch[0] == '\"')
                                {
                                        ++ch;
                                        ch[strlen(ch)-1] = 0;
                                }
                        }
                }
                errnum = 0;
                if (func<0xFF)
                        func = (*(int **)0x8300)[func];    //Fn调用的基址全部是 0x8300
                return ((int (*)())func)(ch[0],ch[1],ch[2],ch[3],ch[4],ch[5],ch[6],ch[7],ch[8],ch[9]);
        }
        else
                return run_line(arg,flags);//其它情况应该是返回外部命令吧
}



用头文件grub4dos.h提供的功能应该可以编写很好的外部命令了。
我根据README_GRUB4DOS_CN.txt尝试了一下

代码:
#include "grub4dos.h"
int i = 0x66666666;   
asm(".long 0x03051805");
asm(".long 0xBCBAA7BA");

int main(char *arg,int flags)
{
    return printf("%s \n","hello3");
}

ubuntu下编译:
gcc -Wl,--build-id=none -m32 -mno-sse -nostdlib -fno-zero-initialized-in-bss -fno-function-cse -fno-jump-tables -Wl,-N -fPIE  hello.c
#objdump -d a.out
#readelf -r a.out
objcopy -O binary a.out hello

最后 hello 在grub中运行成功。



6#
发表于 2013-5-21 01:41:54 | 只看该作者
太高端的用法,普通用户如我之类,用的时候很少,其实也搞不明白如何去用。当然了,要是有人能做一下这方面的资料,那也是功德无量的事情。
回复

使用道具 举报

5#
发表于 2013-5-20 11:45:51 | 只看该作者
不点 发表于 2013-5-20 09:36
目前最完整的编译方法,参看我修改的 hotkey 命令中的注释。这个修改已经被 chenall 提交到 google code 上 ...

我下次更新把这个改到Readme.txt中.
回复

使用道具 举报

4#
 楼主| 发表于 2013-5-20 10:29:41 | 只看该作者
不点 发表于 2013-5-20 09:36
目前最完整的编译方法,参看我修改的 hotkey 命令中的注释。这个修改已经被 chenall 提交到 google code 上 ...

以这个编译参数,成功运行了。
谢谢。
回复

使用道具 举报

3#
发表于 2013-5-20 09:36:50 | 只看该作者
目前最完整的编译方法,参看我修改的 hotkey 命令中的注释。这个修改已经被 chenall 提交到 google code 上的 svn 了。

/*
        20         +         * compile:
        21         +         *
        22         +         * gcc -Wl,--build-id=none -m32 -mno-sse -nostdlib -fno-zero-initialized-in-bss -fno-function-cse -fno-jump-tables -Wl,-N -fPIE hotkey.c -o hotkey.o
        23         +         *
        24         +         * disassemble: objdump -d hotkey.o
        25         +         * confirm no relocation: readelf -r hotkey.o
        26         +         * generate executable: objcopy -O binary hotkey.o hotkey
        27         +         *
        28         +         */

这是所有的外部命令的通用编译方法。这些编译参数,适用于 32 位 和 64 位 两种 Linux 环境。

一句话,请以 hotkey.c 为模板来制作 C 语言文件。

回复

使用道具 举报

2#
发表于 2013-5-20 09:03:30 | 只看该作者
是什么版本的GCC??

编译时再加以下参数试试.

-Wl,--build-id=none
回复

使用道具 举报

1#
发表于 2013-5-19 10:23:24 | 只看该作者
本帖最后由 chenall 于 2013-5-20 09:07 编辑

这些是非公开的,给开发者使用的,需要自己懂得函数的用法....
至少对C语言要有一些了解,否则一不小心,整个系统会被搞挂掉,甚至有可能会把硬盘的数据弄丢.

若是让普通用户使用,到时出现问题了,该怎么办??

这些功能不是提供给普通用户使用的..懂得用这些功能的的第一要求就是对GRUB4DOS有足够的了解.

熟悉了之后就自然懂得使用了.

内部函数调用方法.
call Fn.N 参数1 参数2 参数3....最多9个.
N是对应函数编号.

懂得C语言的,自己看grub4dos.h文件就明白了...
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2024-11-15 04:20

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表