-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathParsast Hex Founder.lua
176 lines (153 loc) · 6.18 KB
/
Parsast Hex Founder.lua
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
local gg = gg
-- Function to gather memory ranges for libraries and filter out unwanted ones
function GetResults()
gg.clearResults()
gg.setVisible(false)
local Lib_start_address = gg.getRangesList('*.so')
local LibChoose = {}
-- Filter libraries and present a choice to the user
for _, v in ipairs(Lib_start_address) do
if v.state == "Cd" then
local result = v.name:match(".+/(.+)")
if not (result == "libil2cpp.so" or result == "libunity.so" or result == "libcrashlytics.so" or result == "libmain.so" or result == "libFirebaseCppApp-12_2_0.so") then
table.insert(LibChoose, result)
end
end
end
-- Check if no suitable libraries are found
if #LibChoose == 0 then
gg.alert("No suitable libraries found.")
return
end
local Chosen = gg.choice(LibChoose, "Choose the lib of mod menu:")
if not Chosen then return end
local Lib_start_address = gg.getRangesList(LibChoose[Chosen])
local GetCB = {}
-- Iterate through memory addresses and collect data
for _, v in ipairs(Lib_start_address) do
if v.state == "Cd" then
for addr = v.start, v['end'], 0x4 do
table.insert(GetCB, { address = addr, flags = gg.TYPE_DWORD })
end
end
end
gg.setRanges(gg.REGION_C_DATA | gg.REGION_CODE_APP)
gg.loadResults(GetCB)
local GetPointers = gg.getResults(gg.getResultsCount(), nil, nil, nil, nil, nil, nil, nil, gg.POINTER_EXECUTABLE_WRITABLE | gg.POINTER_EXECUTABLE | gg.POINTER_WRITABLE)
gg.clearResults()
for _, v in ipairs(GetPointers) do
v.address = v.value
end
KeepChecking(gg.getValues(GetPointers))
end
-- Function to monitor changes in memory values and handle detected changes
function KeepChecking(refinedResults)
local valuesToDetect = refinedResults
gg.setVisible(false)
while not gg.isVisible() do
gg.toast("Detecting Values")
local valuesToDetectSecond = gg.getValues(valuesToDetect)
local changedValuesList = {}
-- Check for changes in detected memory values
for i, v in ipairs(valuesToDetect) do
if v.value ~= valuesToDetectSecond[i].value then
table.insert(changedValuesList, {
address = v.address,
flags = v.flags,
newHex = valuesToDetectSecond[i].value
})
end
end
-- If changes are detected, process them
if #changedValuesList > 0 then
local changedValues = "Some values were detected\n"
gg.loadResults(changedValuesList)
local gettedValue = GetAddress(checkAndReturn())
-- Format and display the changed values
for i, v in ipairs(gettedValue) do
local HexValue1 = string.format("%08X", changedValuesList[i].newHex or 0x111111)
HexValue1 = littleEndianToBigEndian(HexValue1):sub(9):gsub('(..)', '%1 '):gsub('%s$', '')
local Offset = "0x" .. string.upper(v.offset:sub(3))
if i > 1 then
changedValues = changedValues .. "\n\n"
end
changedValues = changedValues .. string.format("Offset: %s\nHex: %s", Offset, HexValue1)
end
-- Allow the user to choose what to do with the results
local choose = gg.alert(changedValues, "Continue", "Copy", "Exit")
if choose == 2 then
gg.copyText(changedValues, false)
gg.clearResults()
end
if choose == 3 then
gg.clearResults()
gg.setVisible(true)
os.exit()
end
end
valuesToDetect = valuesToDetectSecond
end
os.exit()
end
-- Function to convert a hexadecimal value from little-endian to big-endian
function littleEndianToBigEndian(hexString)
return hexString:gsub('(..)(..)(..)(..)', '%4%3%2%1')
end
-- Function to display the main menu and handle user input
function UserMenu()
local firstMenu = gg.choice({"Real Time Show", "Exit"}, "Main Menu")
if firstMenu == 1 then
GetResults()
elseif firstMenu == 2 then
os.exit()
end
end
-- Function to calculate the base address and offsets of detected memory values
function GetAddress(valueTable)
local FinalOutputSchema = {}
for _, v in ipairs(valueTable) do
local libStart = gg.getRangesList(v.lib)[1].start
table.insert(FinalOutputSchema, {
lib = v.lib,
offset = "0x" .. string.upper(v.offset:sub(3)),
address = libStart + v.offset,
flags = gg.TYPE_DWORD
})
end
return FinalOutputSchema
end
-- Function to extract the short name of a library from its full path
function getShortName(str)
return str:match(".+/(.+)") or str
end
-- Function to retrieve library names and their base addresses
function getLibAndBase(var)
local name, base = {}, {}
for _, v in ipairs(var) do
if v.type:sub(3, 3) == 'x' and gg.getValues({ { address = v.start, flags = 4 } })[1].value == 0x464C457F then
table.insert(name, getShortName(v.internalName))
table.insert(base, v.start)
end
end
return name, base
end
-- Function to calculate the offsets of results relative to their library base
function checkAndReturn()
local res = gg.getResults(gg.getResultsCount())
local lib = gg.getRangesList('/data/*' .. gg.getTargetInfo().packageName .. '*.so')
local name, base = getLibAndBase(lib)
local t = {}
for _, v in ipairs(res) do
for i, b in ipairs(lib) do
if v.address >= b.start and v.address < b['end'] then
for j, d in ipairs(name) do
if getShortName(b.internalName) == d then
table.insert(t, { lib = d, offset = "0x" .. string.upper(string.format('%x', v.address - base[j])) })
end
end
end
end
end
return t
end
UserMenu()