1.从朋友哪收到的文件,分析了一波。
是罗技鼠标宏的xml文件,可以通过软件导入。
2.内容被加密混淆了
观察后发现,它是通过 loadstring(a) -> a 是一个函数用来解密字符串
百度查到的信息
[Lua] 纯文本查看 复制代码 LUA loadstring
类似加载,从给定的字符串得到块。
要加载和运行一个给定的字符串
一般如下用法:
assert(loadstring(script))()
3.这类做法在做CTF的时候都做烂了,有个非常简单的思路,首先loadstring 的参数一定是具体代码的字符串,所以只要直接打印出其参数内容即可。
首先简单的格式化下代码
[Lua] 纯文本查看 复制代码 local code = (function()local __d = xxxxxxx 省略一万个字符串 )()
loadstring()()
4.尝试对code直接进行打印
使用罗技自带的脚本测试工具,进行调试
查看API文档,发现其有2个函数用来打印字符串。
另外一个函数基本一致,不过是用dbgview来接受。
5. 尝试打印
喜闻乐见的报了错,猜测是因为字符串里包含转义字符串导致的
就比如 %d 但是参数不带 整数于是就出错了。
多次调试添加各种参数还是出错,感觉有点麻烦,于是尝试替换字符串。
6.替换字符串
函数原型 string.gsub(s, pat, repl [, n])
就是 global 全局替换子字符串的意思
s: 源字符串
pat: 即 pattern, 匹配模式
repl: replacement, 将 pat 匹配到的字串替换为 repl
[, n]: 可选, 表示只看源字符串的前 n 个字符
喜闻乐见的又出错了,因为对于lua还是不太熟悉,如果有知道原因的可以说一下。
不想多纠缠于是决定直接把内容进行base64 再打印 (base64 是通过用所有可视字符为所有字符编码,理论上会多4/3字节,具体原理可以自己百度)
7.网上抄来的函数
[Lua] 纯文本查看 复制代码 local function encodeBase64(source_str)
local b64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
local s64 = ''
local str = source_str
while #str > 0 do
local bytes_num = 0
local buf = 0
for byte_cnt=1,3 do
buf = (buf * 256)
if #str > 0 then
buf = buf + string.byte(str, 1, 1)
str = string.sub(str, 2)
bytes_num = bytes_num + 1
end
end
for group_cnt=1,(bytes_num+1) do
local b64char = math.fmod(math.floor(buf/262144), 64) + 1
s64 = s64 .. string.sub(b64chars, b64char, b64char)
buf = buf * 64
end
for fill_cnt=1,(3-bytes_num) do
s64 = s64 .. '='
end
end
return s64
end
local function decodeBase64(str64)
local b64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
local temp={}
for i=1,64 do
temp[string.sub(b64chars,i,i)] = i
end
temp['=']=0
local str=""
for i=1,#str64,4 do
if i>#str64 then
break
end
local data = 0
local str_count=0
for j=0,3 do
local str1=string.sub(str64,i+j,i+j)
if not temp[str1] then
return
end
if temp[str1] < 1 then
data = data * 64
else
data = data * 64 + temp[str1]-1
str_count = str_count + 1
end
end
for j=16,0,-8 do
if str_count > 0 then
str=str..string.char(math.floor(data/math.pow(2,j)))
data=math.mod(data,math.pow(2,j))
str_count = str_count - 1
end
end
end
local last = tonumber(string.byte(str, string.len(str), string.len(str)))
if last == 0 then
str = string.sub(str, 1, string.len(str) - 1)
end
return str
end
8.终于成功打印了内容
试图去复制内容的时候,又碰到了一个非常傻的情况,一旦我点击右键,它会尝试去调用null的值,选中的内容又没了,没办法复制。
这里我想到了几个办法去解决
1.使用前面提到的dbgview来接受,但是它直接卡死了。。。。。。。。。。。可能是太长了
2.直接像窗口投递消息复制内容,发现这货是不是win32的窗口,而是画出来的界面,失败
9.尝试解决这个错误。
再次查看api文档
有个回调函数的设置,猜测就是它直接用它覆盖前面解密函数里的回调函数(我猜是在那里)
[Lua] 纯文本查看 复制代码 function OnEvent(event, arg)
end
成功获取到内容,进行base64decode
内容完成,如果你好奇怎么装回去,你就把修改好的内容base64encode 直接 给之前的变量 code,再拿去loadstring就好了。
|