无忧启动论坛
标题:
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