无忧启动论坛

标题: grub4dos 内部函数 与 外部命令 的一点发现。 [打印本页]

作者: 2011895866818    时间: 2013-5-19 10:05
标题: grub4dos 内部函数 与 外部命令 的一点发现。
本帖最后由 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中运行成功。




作者: chenall    时间: 2013-5-19 10:23
本帖最后由 chenall 于 2013-5-20 09:07 编辑

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

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

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

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

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

懂得C语言的,自己看grub4dos.h文件就明白了...
作者: chenall    时间: 2013-5-20 09:03
是什么版本的GCC??

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

-Wl,--build-id=none
作者: 不点    时间: 2013-5-20 09:36
目前最完整的编译方法,参看我修改的 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 语言文件。


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

以这个编译参数,成功运行了。
谢谢。
作者: chenall    时间: 2013-5-20 11:45
不点 发表于 2013-5-20 09:36
目前最完整的编译方法,参看我修改的 hotkey 命令中的注释。这个修改已经被 chenall 提交到 google code 上 ...

我下次更新把这个改到Readme.txt中.
作者: xianglang    时间: 2013-5-21 01:41
太高端的用法,普通用户如我之类,用的时候很少,其实也搞不明白如何去用。当然了,要是有人能做一下这方面的资料,那也是功德无量的事情。





欢迎光临 无忧启动论坛 (http://bbs.c3.wuyou.net/) Powered by Discuz! X3.3