首页
社区
课程
招聘
[原创]什么,你想在内核跑lua?针对硬件断点的内核层快速调试工具集KernLuaBp
发表于: 2025-4-10 01:01 3229

[原创]什么,你想在内核跑lua?针对硬件断点的内核层快速调试工具集KernLuaBp

2025-4-10 01:01
3229

目前主流的调试工具依赖于ptrace接口,需要2个进程通过信号来互相唤醒处理调试事件。简单考察一次单点命中,目标tracee+trace线程至少需要 3次 用户/内核上下文切换:

{tracee执行直到命中hwbp_trap}
-[上下文切换,同步处理]->
(储存信号,唤醒tracer睡眠)
-[上下文切换+异步进程调度]->
{tracer被唤醒处理,重新执行tracee程序}
-[上下文切换+异步进程调度]->
{tracee重新开始运行}

符号标志意义为:[上下文开销] {用户态执行内容} (内核态执行内容)

可以看到上下文开销中直接由硬件异常导致的上下文切换是同步的,耗时较少,但是睡眠和唤醒tracer、tracee是一个不小的开销,并且tracer的处理函数需要反复使用ptrace调用陷入内核态以获取tracee的内存+寄存器信息,实际的运行开销比这里只考虑做ptrace_cont的场景更大。但是呢,为了能够在tracer线程里灵活执行可修改的调试操作,好像又是只能依赖这一套反复唤醒和切换的流程。对...对吗?

也并不一定,如果内核硬件调试异常的handler中直接把这个异常给处理完了,然后直接返回用户态,

{tracee执行直到命中hwbp_trap}
-[上下文切换,同步处理]->
(丢弃信号,内核内处理异常,硬件断点更新,直接返回用户态)
-[上下文切换,同步处理]->
{tracee重新开始运行}

这样的切换开销最多只是2次同步上下文切换,相比之下就是飞速。那么怎么实现可修改的异常处理功能呢?不妨把lua脚本植入进内核。查了下git,果然在内核层跑解释器语言这种烂点子已经有人想过。

截取自lunatik,目前只包含标准库和dostring功能(string直接从用户空间拷贝)
源码集合附上,放入待编译的内核子模块path/to/your/module/以子目录为lua-core为例

这样就算验证完了内核的lua执行环境

劫持系统调用实现

在lua代码中已安装实现的接口,可直接在lua代码中调用

未完待续...后续可以给大家演示一下常见的几个骚操作,包括

obj-$(CONFIG_YOUR_MODULE) += yourmoduleall.o
 
ccflags-y +=  -D_LUNATIK -D_KERNEL -DLUA_USE_C89 -I${PWD}/lua-core
 
# 假设yourmodule.c为你的内核子模块所有功能集成源码文件
 
yourmoduleall-y +=  yourmodule.o \
    lua-core/lapi.o lua-core/lcode.o lua-core/lctype.o lua-core/ldebug.o lua-core/ldo.o \
    lua-core/ldump.o lua-core/lfunc.o lua-core/lgc.o lua-core/llex.o lua-core/lmem.o \
    lua-core/lobject.o lua-core/lopcodes.o lua-core/lparser.o lua-core/lstate.o \
    lua-core/lstring.o lua-core/ltable.o lua-core/ltm.o \
    lua-core/lundump.o lua-core/lvm.o lua-core/lzio.o \
    lua-core/lauxlib.o lua-core/lbaselib.o \
    lua-core/lcorolib.o lua-core/ldblib.o lua-core/lstrlib.o \
    lua-core/ltablib.o lua-core/lutf8lib.o lua-core/lmathlib.o lua-core/linit.o \
    lua-core/loadlib.o lua-core/arm64/setjmp.o
obj-$(CONFIG_YOUR_MODULE) += yourmoduleall.o
 
ccflags-y +=  -D_LUNATIK -D_KERNEL -DLUA_USE_C89 -I${PWD}/lua-core
 
# 假设yourmodule.c为你的内核子模块所有功能集成源码文件
 
yourmoduleall-y +=  yourmodule.o \
    lua-core/lapi.o lua-core/lcode.o lua-core/lctype.o lua-core/ldebug.o lua-core/ldo.o \
    lua-core/ldump.o lua-core/lfunc.o lua-core/lgc.o lua-core/llex.o lua-core/lmem.o \
    lua-core/lobject.o lua-core/lopcodes.o lua-core/lparser.o lua-core/lstate.o \
    lua-core/lstring.o lua-core/ltable.o lua-core/ltm.o \
    lua-core/lundump.o lua-core/lvm.o lua-core/lzio.o \
    lua-core/lauxlib.o lua-core/lbaselib.o \
    lua-core/lcorolib.o lua-core/ldblib.o lua-core/lstrlib.o \
    lua-core/ltablib.o lua-core/lutf8lib.o lua-core/lmathlib.o lua-core/linit.o \
    lua-core/loadlib.o lua-core/arm64/setjmp.o
#include "lua-core/lua.h"
#include "lua-core/lauxlib.h"
#include "lua-core/lualib.h"
 
//取消lunatik中loadfile的功能
int lunatik_loadfile(lua_State *L, const char *filename, const char *mode){
  return 1;
}
 
//内核环境测试代码
 
 
 
int call_lua(char* simple_cmd){
 
  int result;
  lua_State *L = luaL_newstate();  /* create state */
  if (L == NULL) {
    printk(KERN_ALERT "Lua-cannot create state: not enough memory\n");
    return 1;
  }
  lua_gc(L, LUA_GCSTOP);  /* stop GC while building state */
   //lua基础库
  luaL_openlibs(L);
 
  // //load kernLuaBpLibs
  // luaL_openKernBplibs(L);
  result=luaL_dostring(L,simple_cmd);
  lua_close(L);
  return 0;
}
 
//用来搞笑的测试代码
//放入模块_init中测试
int test_lua(void){
  return call_lua("print('hello motherfucker')");
}
#include "lua-core/lua.h"
#include "lua-core/lauxlib.h"
#include "lua-core/lualib.h"
 
//取消lunatik中loadfile的功能
int lunatik_loadfile(lua_State *L, const char *filename, const char *mode){
  return 1;
}
 
//内核环境测试代码
 
 
 
int call_lua(char* simple_cmd){
 
  int result;
  lua_State *L = luaL_newstate();  /* create state */
  if (L == NULL) {
    printk(KERN_ALERT "Lua-cannot create state: not enough memory\n");
    return 1;
  }
  lua_gc(L, LUA_GCSTOP);  /* stop GC while building state */
   //lua基础库
  luaL_openlibs(L);
 
  // //load kernLuaBpLibs
  // luaL_openKernBplibs(L);
  result=luaL_dostring(L,simple_cmd);
  lua_close(L);
  return 0;
}
 
//用来搞笑的测试代码
//放入模块_init中测试
int test_lua(void){
  return call_lua("print('hello motherfucker')");

传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2025-8-14 14:15 被dadadasda编辑 ,原因: 追加编译设置,内核模块中的lua运行库源码,发布接口文档
上传的附件:
收藏
免费 29
支持
分享
最新回复 (15)
雪    币: 104
活跃值: (655)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
追加了可编译的lua-core源码,与当前开发完毕的内核lua接口
2025-8-14 14:12
0
雪    币: 29
活跃值: (1729)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
你真猛!
2025-8-17 08:57
0
雪    币: 477
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
谢谢你的细致分析,受益匪浅!
2025-8-17 09:04
0
雪    币: 146
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
mark
2025-9-3 02:15
0
雪    币: 0
活跃值: (1109)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
like!
2025-9-3 03:17
0
雪    币: 200
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
6666
2025-9-10 19:57
0
雪    币: 18
活跃值: (1367)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
gooooood
2025-9-22 13:28
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
Ara
9
good
2025-9-28 21:04
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
1
2025-9-28 21:09
0
雪    币: 113
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
11
看看
2025-9-30 19:10
0
雪    币: 71
活跃值: (1778)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
666
2025-10-10 10:03
0
雪    币: 23
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
13
1
2025-10-14 15:18
0
雪    币: 217
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
14
666
2025-11-9 11:40
0
雪    币: 3785
活跃值: (4085)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
6
2025-11-9 12:33
0
雪    币: 223
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
16
感谢分享技术干货!
2025-12-8 16:40
0
游客
登录 | 注册 方可回帖
返回