local
function
is_null(p)
if
p ==
0
or
p ==
nil
then
return
true
end
return
false
end
local
function
find_str(s1, s2)
local
n1,n2 =
string.find
(s1, s2,
1
, true)
if
(n1 ~=
nil
and
n2 ~=
nil
)
then
return
true
end
return
false
end
local
function
str_startswith(s1, s2)
local
n1, n2 =
string.find
(s1, s2,
1
, true)
if
(n1 ~=
nil
and
n2 ~=
nil
and
n1 ==
1
)
then
return
true
end
return
false
end
local
function
str_endswith(s1, s2)
local
n1, n2 =
string.find
(s1, s2,
1
, true)
if
(n1 ~=
nil
and
n2 ~=
nil
and
n2 == #s1)
then
return
true
end
return
false
end
local
function
open_file_exists(s_path)
local
is_valid_path = false
if
(str_startswith(s_path,
"/system/"
)
or
str_startswith(s_path,
"/data/"
)
or
str_startswith(s_path,
"/lib/"
)
or
str_startswith(s_path,
"/sbin/"
)
or
str_startswith(s_path,
"/sys/"
))
and
(str_endswith(s_path,
".so"
))
then
is_valid_path = true
end
if
not
is_valid_path
then
return
false
end
local
f =
io.open
(s_path,
"r"
)
if
f
then
io.close
(f)
end
return
f ~=
nil
end
local
function
bin2hex(s)
s=
string.gsub
(s,
"(.)"
,
function
(x)
return
string.format
(
"%02X"
,
string.byte
(x))
end
)
return
s
end
local
function
basename(str)
local
name =
string.gsub
(str,
"(.*[\\/])(.*)"
,
"%2"
)
return
name
end
local
function
check_elf_file_x86_emulator(file_path)
local
ret =
0
if
not
open_file_exists(file_path)
then
return
ret
end
local
f =
io.open
(file_path,
'rb'
)
if
f
then
local
sizes = f:
seek
(
"end"
)
if
sizes >
1024
then
f:
seek
(
"set"
)
local
content = f:read(
4
)
local
hexstr = bin2hex(content)
if
hexstr ==
"7F454C46"
then
local
is_32_64 = f:read(
1
)
hexstr = bin2hex(is_32_64)
if
hexstr ==
"01"
then
f:
seek
(
"set"
,
18
)
local
cpu_type = f:read(
2
)
hexstr = bin2hex(cpu_type)
if
hexstr ==
"0300"
then
ret =
1
end
end
end
end
f:close()
end
return
ret
end
local
function
get_int_value(key, deft)
local
value = TssSDK.get_value_by_key(key)
if
not
is_null(value)
then
local
int_val =
tonumber
(value)
if
int_val
then
return
int_val
end
end
return
deft
end
local
g_mark_scan_flag =
"llua_ser_20200421_scanned"
local
g_module_cnt =
0
local
g_libc_files_cnt =
0
local
g_has_x86_file =
0
local
g_x86_file_name =
""
local
g_tp_ver =
""
local
g_libhoudini_file_name =
""
local
g_libhoudini_file_size =
0
local
function
save_scan_result()
TssSDK.set_key_and_value(
"LEMC"
,
""
..g_module_cnt)
TssSDK.set_key_and_value(
"LEFC"
,
""
..g_libc_files_cnt)
TssSDK.set_key_and_value(
"LEHX"
,
""
..g_has_x86_file)
TssSDK.set_key_and_value(
"LEXN"
, g_x86_file_name)
TssSDK.set_key_and_value(
"LETV"
, g_tp_ver)
TssSDK.set_key_and_value(
"LENM"
, g_libhoudini_file_name)
TssSDK.set_key_and_value(
"LESZ"
,
""
..g_libhoudini_file_size)
end
local
function
load_scan_result()
g_module_cnt = get_int_value(
"LEMC"
,
0
)
g_libc_files_cnt = get_int_value(
"LEFC"
,
0
)
g_has_x86_file = get_int_value(
"LEHX"
,
0
)
g_x86_file_name = TssSDK.get_value_by_key(
"LEXN"
)
g_tp_ver = TssSDK.get_value_by_key(
"LETV"
)
g_libhoudini_file_name = TssSDK.get_value_by_key(
"LENM"
)
g_libhoudini_file_size = get_int_value(
"LESZ"
,
0
)
end
local
function
get_tp_ver()
local
try_cnt =
0
local
err_msg =
""
local
err_code =
0
local
dev_path =
"/dev/virtpipe-sec"
while
(try_cnt <
3
)
do
try_cnt = try_cnt +
1
local
ret, acode = TssSDK.access(dev_path)
if
(ret ~=
0
)
then
err_msg =
"unfound"
err_code = acode
else
local
session = TssSDK.OpenWBSession()
if
(is_null(session))
then
err_msg =
"open_failed"
local
file, err, ocode =
io.open
(dev_path,
"r+"
)
if
(file)
then
file:close()
end
if
(ocode ~=
nil
)
then
err_code = ocode
else
err_code =
0
end
else
local
tp_ver = TssSDK.SendWBCmd(session,
"func=WB_GetTPShellVersion"
)
TssSDK.CloseWBSession(session)
if
(is_null(tp_ver)
or
type(tp_ver) ~=
"string"
)
then
err_msg =
"get_failed"
err_code =
0
else
return
tp_ver..
"-"
..
tostring
(
0
)
end
end
end
TssSDK.sleep(
1000
)
end
return
err_msg..
"-"
..
tostring
(err_code)
end
local
function
scan_emulator()
local
try_cnt =
5
local
handle = TssSDK.open_tphm()
while
(try_cnt >
0
and
is_null(handle))
do
TssSDK.sleep(
1000
)
handle = TssSDK.open_tphm()
try_cnt = try_cnt -
1
end
if
is_null(handle)
then
return
end
local
libc_name =
"libc.so"
local
libc_files = {}
local
libhoudini_name =
"houdini"
while
g_module_cnt <
10000
do
local
module_info = TssSDK.enum_tphm(handle)
if
is_null(module_info)
then
break
end
g_module_cnt = g_module_cnt +
1
local
module_name = TssSDK.get_tphm_name(module_info)
local
module_size = TssSDK.get_tphm_size(module_info)
if
not
is_null(module_name)
and
not
is_null(module_size)
then
local
file_name = basename(module_name)
if
find_str(file_name, libc_name)
then
if
libc_files[module_name] ==
nil
then
g_libc_files_cnt = g_libc_files_cnt +
1
libc_files[module_name] = {}
end
elseif
find_str(file_name, libhoudini_name)
then
if
g_libhoudini_file_name ==
""
then
g_libhoudini_file_size = module_size
g_libhoudini_file_name = module_name
end
end
if
g_has_x86_file ==
0
then
g_has_x86_file = check_elf_file_x86_emulator(module_name)
if
g_has_x86_file ==
1
then
g_x86_file_name = module_name
g_tp_ver = get_tp_ver()
end
end
end
end
save_scan_result()
TssSDK.close_tphm(handle)
end
local
function
get_report_cnt()
local
cnt = get_int_value(
"LERC"
,
0
)
cnt = cnt %
1000
+
1
TssSDK.set_key_and_value(
"LERC"
,
""
..cnt)
return
cnt
end
local
function
report_emulator()
local
emu_name = TssSDK.QueryStr(
"emulator_name"
)
local
maybe_emu =
1
if
(emu_name ==
"NotEmulator"
)
then
maybe_emu =
0
end
local
is_download = TssSDK.IsEnabled(
"simulate"
,
0
)
local
report_cnt = get_report_cnt()
local
info =
tostring
(g_has_x86_file)..
"|"
..
tostring
(g_libc_files_cnt)..
"|"
..
tostring
(g_libhoudini_file_size)..
"|"
..
tostring
(maybe_emu)..
"|"
..
tostring
(report_cnt)
TssSDK.set_key_and_value(
"li_emu"
, info)
TssSDK.ReportQosByGame(
8
,
2020061700
, g_has_x86_file, g_libc_files_cnt, g_libhoudini_file_size, g_module_cnt, maybe_emu, is_download, report_cnt,
2
, emu_name..
','
..g_libhoudini_file_name, g_tp_ver..
','
..g_x86_file_name)
end
local
function
has_scanned()
return
(
not
is_null(TssSDK.get_value_by_key(g_mark_scan_flag)))
end
local
function
set_scanned()
TssSDK.set_key_and_value(g_mark_scan_flag,
"1"
)
end
local
function
do_exec()
if
TssSDK.get_platform() ~=
0
then
return
end
if
(has_scanned())
then
load_scan_result()
else
scan_emulator()
set_scanned()
end
report_emulator()
end
local
function
exec()
local
ver = TssSDK.get_sdk_version()
if
is_null(ver)
then
return
end
local
target_ver =
"3.7.13.548645"
if
ver < target_ver
then
return
end
do_exec()
end
exec()