| 
 | 
 
 本帖最后由 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中运行成功。 
 
 
 
 |   
 
 
 
 |