actboy168 / lua-debug

Lua Debug Adapter for Visual Studio Code
MIT License
435 stars 94 forks source link

New launcher #222

Closed fesily closed 1 year ago

fesily commented 1 year ago

test:

fesily commented 1 year ago

我先改了一步,允许debuggerAttach失败

fesily commented 1 year ago

我觉得attach.lua应该有一个返回值,如果失败的话,来指示外部需不需要继续等待,之前的逻辑是调用了attach就解除了所有hook

actboy168 commented 1 year ago

自己调用luaL_openlibs会影响调试目标的行为,比如它并不想加载所有的标准库函数。remotedebug除了eval,其他应该都是不依赖luaL_openlibs的。eval的问题可以以后遇到问题再解决。

fesily commented 1 year ago

自己调用luaL_openlibs会影响调试目标的行为,比如它并不想加载所有的标准库函数。remotedebug除了eval,其他应该都是不依赖luaL_openlibs的。eval的问题可以以后遇到问题再解决。

如果是基于这种考虑,也就放弃这种连base库都不打开的环境了,放弃也无所谓吧,反正太特殊了

actboy168 commented 1 year ago

这种情况还挺常见的,至少我用的几个项目都不同程度地修改了luaL_openlibs。最常见的就是禁用io或者io指向非本地文件。

fesily commented 1 year ago

嗯,应该是只用了一部分的居多,完全不调用base库的应该不管他.

fesily commented 1 year ago

现在调试器加载的时候(call attach.lua),可能luaL_openlibs还没调用,所以前几次attach.lua会失败,直到某一次luaL_openlibs调用后才会成功。

可能的解决办法:

  1. 确保luaL_openlibs之后,再call attach.lua。
  2. 增加一个测试lua,检测需要的函数都已经存在,再call attach.lua。
  3. 调试器加载代码不依赖任何标准库函数。debugger内的大多数代码是在检测lua version、arch、os等,这些launcher都另一套逻辑在做,做两次没必要也可能导致两次计算不一致。然后可能需要写几个c函数(例如load remotedebug.dll)供attach.lua使用。

~我现在想想最准确的做法是launch模式应该hook lua_newstate,直接在这个地方挂上lua_hook,这样也就不用管其他地方的hook,但是还是要判断基础库初始化完成了没有~ 可以在launch模式里hook lua_newstate来挂lua_hook,但是对这个问题没有改善,只是改善了hook的流程,而且这种形式,100%出现这个问题

actboy168 commented 1 year ago

简单的解决这个问题,方案2就行了。不过我觉得方案3是一个更好的方案,只是更复杂。

fesily commented 1 year ago

简单的解决这个问题,方案2就行了。不过我觉得方案3是一个更好的方案,只是更复杂。

嗯,后面在加进去好了,顺带的事情

actboy168 commented 1 year ago

现在debugger.lua里判断luajit的方法是是否有全局变量jit。但是因为现在可能在luaL_openlibs之前,就开始加载,所以jit变量可能还没初始化,这个时候加载调试器就会被识别为lua5.1。

fesily commented 1 year ago

两个方案 一,跟之前一样hook luaL_openlobs 二,在外面就加载好remotedebug,因为下一步这个工作也是要做的

actboy168 commented 1 year ago

基本思路还是先怎么简单怎么做。先按旧方法做,下一步再做改进。

actboy168 commented 1 year ago

现在launch并没有保证一定能识别到lua的版本号,当识别为unknown时,是无法加载remotedebug的。

所以首先要改进launch的版本识别。几个可能的改进点:

  1. 用户配置lua版本,现在launch.json可以配置lua版本,但目前没有传递给launcher。
  2. 增加类似debugger.lua中的版本识别机制,这个需要读取全局变量,所以得在得到L之后,再识别一次?
  3. 所有的识别机制都识别不到,用户也没有配置,就让laucnher失败。
fesily commented 1 year ago

launch得到unknown不代表 lua层也得不到。这两两个机制应该是独立开。用户配置>launch得到的版本>attach.lua的版本,他们应该是一种覆盖关系,所以我觉得launch应该直接传入自己得到的版本号,除非是unknown.

actboy168 commented 1 year ago

现在的问题就是当launcher识别为unknown,lua层的luaL_openlibs不完全加载导致识别不出luajit,两者叠加,还是会让remotedebug加载错误的版本。所以得让这种情况下让launcher直接失败。

不过现在lua层的版本检测的问题是,无法区分这是一个luaL_openlibs不完全加载的luajit,还是一个lua51.

fesily commented 1 year ago

现在的问题就是当launcher识别为unknown,lua层的luaL_openlibs不完全加载导致识别不出luajit,两者叠加,还是会让remotedebug加载错误的版本。所以得让这种情况下让launcher直接失败。

不过现在lua层的版本检测的问题是,无法区分这是一个luaL_openlibs不完全加载的luajit,还是一个lua51.

按照之前的说法,hook luaL_openlibs之后将不会出现加载途中进入attach.lua, 所以这个问题应该不存在

actboy168 commented 1 year ago

嗯,我是说要用新的hook方法,需要解决的问题。

fesily commented 1 year ago

嗯,我是说要用新的hook方法,需要解决的问题。

我思考了一下,可以不依赖jit对象来确定是否为luajit版本.依赖luajit在标准库上的不一致结果就行了

fesily commented 1 year ago

嗯,我是说要用新的hook方法,需要解决的问题。

我思考了一下,可以不依赖jit对象来确定是否为luajit版本.依赖luajit在标准库上的不一致结果就行了

这样也不用hook luaL_openlibs了

actboy168 commented 1 year ago

windows 看起来已经没问题了。不过现在macos我编译会出这个警告,然后还是无法启动调试。

ld: warning: ignoring file 3rd/frida_gum/macos-x86_64/libfrida-gum.a, building for macOS-x86_64 but attempting to link with file built for unknown-unsupported file format ( 0x21 0x3C 0x61 0x72 0x63 0x68 0x3E 0x0A 0x23 0x31 0x2F 0x32 0x30 0x20 0x20 0x20 )
fesily commented 1 year ago

windows 看起来已经没问题了。不过现在macos我编译会出这个警告,然后还是无法启动调试。

ld: warning: ignoring file 3rd/frida_gum/macos-x86_64/libfrida-gum.a, building for macOS-x86_64 but attempting to link with file built for unknown-unsupported file format ( 0x21 0x3C 0x61 0x72 0x63 0x68 0x3E 0x0A 0x23 0x31 0x2F 0x32 0x30 0x20 0x20 0x20 )

clang是什么版本,我没有这个问题

Apple clang version 14.0.0 (clang-1400.0.29.202)
Target: arm64-apple-darwin22.2.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

顺带发一份你下载的libfrida-gum.a

actboy168 commented 1 year ago
Apple clang version 14.0.0 (clang-1400.0.29.202)
Target: arm64-apple-darwin22.1.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

我重新下一个frida看看

actboy168 commented 1 year ago

重新下载可以解决警告,但还是启动不了。

fesily commented 1 year ago

什么配置,发个launch,我试试

actboy168 commented 1 year ago

        {
            "type": "lua",
            "request": "launch",
            "name": "Test",
            "luaVersion": "latest",
            "stopOnEntry": true,
            "inject": "lldb",
            "runtimeExecutable": "${command:extensionPath}actboy168.lua-debug-1.61.0-darwin-arm64/runtime/darwin-arm64/lua54/lua",
            "runtimeArgs": "test.lua",
        },
fesily commented 1 year ago
       {
            "type": "lua",
            "request": "launch",
            "name": "Test",
            "luaVersion": "latest",
            "stopOnEntry": true,
            "inject": "lldb",
            "runtimeExecutable": "${command:extensionPath}actboy168.lua-debug-1.61.0-darwin-arm64/runtime/darwin-arm64/lua54/lua",
            "runtimeArgs": "test.lua",
        },

按照之前的逻辑你使用inject.lldb是无法进入的,使用hook是可以启动的. 现在我改了一下,可以使用lldb进入了

actboy168 commented 1 year ago

嗯现在可以了

fesily commented 1 year ago

lldb模式是支持在Linux进行注入的,但是相关代码都没写,所以我先把linux的入口都关掉

actboy168 commented 1 year ago

现在macos支持两种注入方式,但是其中一种要满足很多前置条件才能使用。我觉得不应该在失败是退到其他注入方式,而是给出错误提示,让用户自己切换。

此外lldb的注入方式,应该可以加个简单的检测,如果用户没有lldb,能给个更友好的错误提示。

fesily commented 1 year ago

现在macos支持两种注入方式,但是其中一种要满足很多前置条件才能使用。我觉得不应该在失败是退到其他注入方式,而是给出错误提示,让用户自己切换。

此外lldb的注入方式,应该可以加个简单的检测,如果用户没有lldb,能给个更友好的错误提示。

现在并不会自动🔙其他方案

现在没有lldb的提示是

Spwan lldb failed:subprocess::spawn: No such file or directory
fesily commented 1 year ago

现在macos支持两种注入方式,但是其中一种要满足很多前置条件才能使用。我觉得不应该在失败是退到其他注入方式,而是给出错误提示,让用户自己切换。 此外lldb的注入方式,应该可以加个简单的检测,如果用户没有lldb,能给个更友好的错误提示。

现在并不会自动🔙其他方案

现在没有lldb的提示是

Spwan lldb failed:subprocess::spawn: No such file or directory

我改善一下出错的提示,macos详细区分提示inject.hook模式下的错误来源

actboy168 commented 1 year ago

现在macos支持两种注入方式,但是其中一种要满足很多前置条件才能使用。我觉得不应该在失败是退到其他注入方式,而是给出错误提示,让用户自己切换。 此外lldb的注入方式,应该可以加个简单的检测,如果用户没有lldb,能给个更友好的错误提示。

现在并不会自动🔙其他方案 现在没有lldb的提示是

Spwan lldb failed:subprocess::spawn: No such file or directory

我改善一下出错的提示,macos详细区分提示inject.hook模式下的错误来源

我的意思是不符合hook模式的条件时就失败,而不是改到lldb模式

fesily commented 1 year ago

👌,删掉了,现在提示让用户手动切换

actboy168 commented 1 year ago

还有几个小问题。不过我先合并了,我再慢慢改。