APEX 游戏压枪宏逆向

前言

从某位同学手里拿到了这个压枪的辅助,问我能不能也写一个,作为游戏安全基本没什么了解的摆烂二进制手来说确实有点难度。但是出于好奇的心理,采用逆向的方式进行了点简单的分析,观察程序的相关执行逻辑。

开工

此次拿到的程序主要包含以下文件:

我们可以看到其包含一个文件夹、一个jar包、一个图标以及Opencv的动态链接库和相关的鼠标宏lua脚本

点开文件夹可以发现有许多图片,可以猜测到对应的是通过Opencv提供的图片识别对电脑屏幕进行截屏,之后判断所持枪械,来进行不同程度的进行压枪处理

jar

先简单的观察一下jar包,将其拖入反编译器中,可以十分清晰的看到其代码,没有带有混淆

简单的观察一下可以发现其创建了一个函数类用来将屏幕数据进行绘制

同时下面便是对应的图片匹配,来判断不同的枪械

与此同时作者也”贴心“的留下了自己的联系方式,以及相关视频展示

简单溯源

对于上述信息我们看看能不能溯源,比较遗憾的是访问对应视频链接的时候对应的视频已经被作者撤销了

查询对应QQ可以发现是个等级低的小号,基本上查相关信息没头绪了,但是幸运的是其还留下了一个淘宝店

访问一下留下的淘宝店链接

看了一下淘宝店铺,发现是等级低的新店

image-20230918124547485

基本上到这看上去就没什么信息了,关注点还是回到原来的程序中去吧…

lua

在jar包中我们可以看到其还释放了lua文件,与此同时原来程序也自带有一个lua,可以猜测到压枪的核心便是这些lua文件了

我们首先拿外置的Script.lua导入驱动Script.lua进行分析,先观察导入驱动这项

可以看到其导入了一些变量,后面使用dofile来执行对应Script.lua文件

1
dofile("C:/Users/Public/Downloads/Script.lua")

观察对应的Script.lua文件,我们大致可以判断其进行了混淆,通过一串加密将对应代码进行解密出来后通过load来进行执行

我们简单的格式化一下代码,大致可以得到以下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
local a=load(
(
function(b,c)
function bxor(d,e)
local f={{0,1},{1,0}}
local g=1
local h=0
while d>0 or e>0 do
h=h+f[d%2+1][e%2+1]*g
d=math.floor(d/2)
e=math.floor(e/2)
g=g*2 end
return h
end
local i=function(b)
local j={}
local k=1
local l=b[k]
while l>=0 do
j[k]=b[l+1]k=k+1
l=b[k]
end
return j
end
local m=function(b,c)
if#c<=0 then
return{}
end
local k=1
local n=1
for k=1,#b do
b[k]=bxor(b[k],string.byte(c,n))n=n+1
if n>#c then
n=1
end
end
return b
end
local o=function(b)
local j=""
for k=1,#b do
j=j..string.char(b[k])
end
return j
end
return o(m(i(b),c))
end
)(
...相关数据..., key
)
)

可以看到的是代码就本质逻辑上就是一个异或处理,因为对应load是需要加载代码的,所以我们我们简单的修改一下,把load替换为print便可以拿到对应数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function mathing(sj)
local sj1 = ""
for i =1,#sj
do
sj1 = sj1 .. string.char(sj[i])
end
return sj1 end

method={0,1,2,3,4,5,6,7,8}
info = "APEX顶点鼠标宏"

offset_pattern1= offset_pattern2

a1 = 1

text_bbdate = "2023-08-12"

offset_pattern = 2

对后面的内容进行解密时发现代码需要用到一个key值,有以下关系

1
key=mathing(OnEvent) 

我们将key进行测试输出,可以得到一串“问候语”

属于是无能狂怒 :)

之后以同样的方式对后续代码进行解密,我们可以拿到相关数据如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
if (l080or2k == 1) then

location = {{243/1920,658/1080},{220/1920,740/1080},{219/1920,805/1080},{216/1920,885/1080}}

elseif(l080or2k == 2)then

location = {{325/2560,883/1440},{325/2560,982/1440},{325/2560,1082/1440},{325/2560,1182/1440}}

end


GunCombination1_1 = {"R99","R301","ZHZ","DN","ZZ","PX","LSLF","HMLK_DD","P20","M600","Lstar","XBS","RE45","R301DD","PXDD","HWK","G7","CN","BZ","CAR","FCNS","LSQZD","HMLKLF"}

GunCombination1_2 ={"Y_R99","Y_R301","Y_ZHZ","Y_DN","Y_ZZ","Y_PX","Y_LSLF","Y_LSQZD","Y_P20","Y_M600","Y_Lstar","Y_XBS","Y_RE45"}


squatKey = "l" --下蹲按键


BZ_offset_trim_list = {

{1 ,0,0}, {2 ,0,0}, {3 ,0,0},
{4 ,0,0}, {5 ,0,0}, {6 ,0,0},
{7 ,0,0}, {8 ,0,0}, {9 ,0,0},
{10,0,0}, {11,0,0}, {12,0,0},
{13,0,0}, {14,0,0}, {15,0,0},
{16,0,0}, {17,0,0}, {18,0,0},
{19,0,0}, {20,0,0}, {21,0,0},
{22,0,0}, {23,0,0}, {24,0,0},
{25,0,0}, {26,0,0}, {27,0,0},
{28,0,0}, {29,0,0}, {30,0,0},
{31,0,0}, {32,0,0}, {33,0,0},
{34,0,0}, {35,0,0}, {36,0,0},
{37,0,0}, {38,0,0}, {39,0,0},
{40,0,0}
}
BZ_offset_trim_ratio = {1,1}
BZ_offset_trim_amend = {0,0}

...
后面太多了就不放了

后续几个释放的lua文件就只有一行,整理集合如下:

1
2
3
4
5
6
7
8
-- main.lua
qx1_1 = GunCombination1_1[18] -- 记录当前枪编号

-- turbo_state.lua
turbo_state = 1 -- 判断是否加了涡轮 1 为添加 0 为未添加

-- thermite.lua
BZ_LRJ = 0 -- 0 为暴走 1 为 暴走 + 铝热剂

结合之前已有的代码,猜测Script.lua这些解密出来的数据应该是对应调整弹道的参数

一些问题

查询了一下罗技相关鼠标上lua宏相关的API接口,发现上述代码中没有调用相关的API同时对应的函数都没有,网上关于其驱动编程的文档似乎都不是很全,找了一个Github上的相关项目,里面的接口也没有被使用,确实有点奇怪这个是怎么实现的,可能是相关特性?

kiccer/logitech-macro-frame: 罗技宏框架 - 提炼自 kiccer/Soldier76 项目 (github.com)

总结

大致来说所给的就是使用opencv提供的AI识别来辨别枪支种类,进而通过写入不同的参数到lua文件中去,之后使用鼠标宏来完成相关的工作,有些奇怪的是对应宏的调用逻辑是什么不是很清楚,但是可以猜测其数据应该是逆向拿到的Script.lua中的。


APEX 游戏压枪宏逆向
https://equinox-shame.github.io/2023/09/18/APEX 游戏压枪宏逆向/
作者
梓曰
发布于
2023年9月18日
许可协议