通过spy调试引擎附加到notepad进程
PS D:\dist> notepad.exe
PS D:\dist> .\udbg.exe -A spy -a notepad.exe
在udbg内执行.edit temp
命令,会自动在script/autorun
目录下打开(创建)temp.lua
文件,并监控其写入,然后自动执行
udbg版本:https://gitee.com/udbg/udbg/releases/v0.1.0-nightly
udbg的spy调试引擎,会向目标进程内注入一个模块,然后使用封装好的udbg.uspy
模块可以在目标进程内执行lua脚本,然后通过uspy提供的lua接口完成Hook任意函数、调用任意函数的任务
在目标进程内执行lua代码的基本用法如下
后面的示例脚本没有特殊说明,默认都是通过uspy(function() ... end)
在目标进程内进行调用的
基本用法
Hook并进行参数替换
Hook并调用原函数、阻止原函数继续执行
上述Hook示例中,对 MessageBoxA 函数的调用就是一个无类型调用的例子
libffi.fn
函数直接传入一个整数(C函数地址),返回一个无类型的函数对象,无类型的函数对象会根据传入的lua参数类型自动为每个C参数分配类型,映射规则如下
无类型的调用在于写起来非常简单,能够覆盖大部分应用场景,但有些时候还是需要知道明确的函数参数才能成功调用一些函数,比如涉及到浮点数的函数、非标准的调用约定等情况
声明函数类型需要指定函数的返回值类型和参数类型 libffi.fn(returnType, {argsType...})
,支持的类型如下
指定x86调用约定: TODO
示例如下
有些函数只能在某些特定线程中调用,一般是UI主线程,可以Hook GetMessageW PeekMessageW之类的函数,Hook触发时,脚本则是在UI线程中调用的,然后通过libffi去调用想测试的函数
udbg本身功能也使用了很多libffi调用,比如 script/win/api.lua
script/win/win.lua
local uspy
=
require
"udbg.uspy"
local s
=
'hello'
uspy(function()
log(s,
'world'
)
end)
local uspy
=
require
"udbg.uspy"
local s
=
'hello'
uspy(function()
log(s,
'world'
)
end)
local uspy
=
require
"udbg.uspy"
local CreateFileW
=
PA
'kernelbase!CreateFileW'
uspy(function()
local libffi
=
require
'libffi'
local api
=
require
'win.api'
-
-
Hook CreateFileW 函数,并打印第一个参数
inline_hook(CreateFileW, function(args)
local path
=
libffi.read_pack(args[
1
],
'w'
)
log(
'CreateFileW'
, path)
end)
end)
local uspy
=
require
"udbg.uspy"
local CreateFileW
=
PA
'kernelbase!CreateFileW'
uspy(function()
local libffi
=
require
'libffi'
local api
=
require
'win.api'
-
-
Hook CreateFileW 函数,并打印第一个参数
inline_hook(CreateFileW, function(args)
local path
=
libffi.read_pack(args[
1
],
'w'
)
log(
'CreateFileW'
, path)
end)
end)
inline_hook(CreateFileW, function(args)
-
-
args[
1
] 在x64下相当于 args.rcx
local path
=
libffi.read_pack(args[
1
],
'w'
)
log(
'CreateFileW'
, path)
if
path:find
'a.txt$'
then
path
=
path:gsub(
'a.txt$'
,
'b.txt'
)
log(
'[redirect]'
,
'a.txt'
,
'->'
, path)
args[
1
]
=
topointer(path:to_utf16())
end
end)
inline_hook(CreateFileW, function(args)
-
-
args[
1
] 在x64下相当于 args.rcx
local path
=
libffi.read_pack(args[
1
],
'w'
)
log(
'CreateFileW'
, path)
if
path:find
'a.txt$'
then
path
=
path:gsub(
'a.txt$'
,
'b.txt'
)
log(
'[redirect]'
,
'a.txt'
,
'->'
, path)
args[
1
]
=
topointer(path:to_utf16())
end
end)
local MessageBoxA
=
api.GetProcAddress(api.LoadLibraryA(
'user32'
),
'MessageBoxA'
)
inline_hook(MessageBoxA, function(args)
-
-
手动调用原函数
libffi.fn(args.trampoline)(
0
,
'LALALA'
,
'AAAAAA'
,
0
)
-
-
返回后不再调用原函数
args
'reject'
end)
local msgbox
=
libffi.fn(MessageBoxA)
msgbox(
0
,
'ABC'
,
'DEF'
,
0
)
local MessageBoxA
=
api.GetProcAddress(api.LoadLibraryA(
'user32'
),
'MessageBoxA'
)
inline_hook(MessageBoxA, function(args)
-
-
手动调用原函数
libffi.fn(args.trampoline)(
0
,
'LALALA'
,
'AAAAAA'
,
0
)
-
-
返回后不再调用原函数
args
'reject'
end)
local msgbox
=
libffi.fn(MessageBoxA)
[招生]系统0day安全班,企业级设备固件漏洞挖掘,Linux平台漏洞挖掘!