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