MT查壳可以看到是360加固,直接使用在线网站可以进行脱壳,也可以找到360加固的脱壳点进行手动dump,都可以,只是这篇文章更偏向于算法还原,所以直接使用在线网站进行脱壳了
c77K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1j5#2y4W2)9J5k6h3q4D9i4K6u0r3
可以得到脱下来的dex文件

放到MT里面进行修复就行,MT没有会员也可以使用NP进行修复
然后将这些dex全部放到原始的APK里面,把原来dex的删掉就行,这样只是可以让我们把他放大jadx进行分析了,因为他还有一个oncreate被抽取了,以及许多stub的特征没有删除,这里要具体往下分析的话,大家使用Android Studio进行分析就行,看他的log日志哪里报错了,不过会有许多,建议大家找到一处,然后直接进行MT正则匹配全部替换为null,有的地方也许不能为null,尽量看就行,这里不再具体说明
我采用的方式是Reqable转发Burpsuit的方式,具体就是


然后在bp里面开一个端口转发监听

这样就可以抓到了,还是蛮好用的
这个APP是没有检测的,只不过我最开始没有抓到,最后还是重启手机抓到的,也可以具体分析,因为我之前在抓了几个字节系列的包,也是不行,看了一些网上的教程手动过了一下,这里大家可以参考一下
字节就是会魔改这个libsscronet.so,我是在内存种dump的,因为他的lib里面没有,那么其实大概率也是没有魔改,这里只是给大家分享一下

dump_so的脚本:
有两种把,第二种就是遍历内存了
大家搜索一下这个函数SSL_CTX_set_custom_verify()

交叉引用一下

其实它是有参数的,只不过没有显示出来,大家可以网上搜索一下,找到他的回调,也可以看汇编找

也就是这一个函数,大家写一个frida脚本,把他返回值写成0x0就行
这样就可以过掉了,一般会有两个地方出现这个函数,大家可以都测试一下,有的是第一个交叉引用,有的是第二个交叉引用出现
因为我也是第一次进行这样的抓包分析,我就把能抓到的包的值全部进行加密解密了
先看这个吧,这两个参数先还原了一下:

搜索关键词就行,可以定位到基本的


基本就是这个,只不过就是对请求类型进行判断了一下罢了

Java层其实就是这些,一个jmd,调用了So层的函数,不过so层函数有点不同寻常


这个其实隐藏起来了,看汇编找到这个注册函数表


继续看
我其实没看到有什么像加密的地方,不过这里是重点

加载了一些文件什么的,我这里没分析清楚,不过我用其他方法,主动调用这个函数,然后进行测试

得到这个,md大家可以用cmd解一下发现可以解密出来,但是我没次数,只能用别的方法,就是算法自吐脚本
可以根据需要来使用

可以发现有一个

这不就是我们的输入+一个字符串吗,这个字符串其实也在so层,大家搜索一下也可以看到,而且交叉引用也能定到md哪个函数里面,

这里就对上了
大家也可以写一个python代码来实现
m-request-did参数的分析
也是根据这个jadx搜索

获取设备码加密

可以定位到这里
分析就完事了

这样的

还是蛮清楚的
分析还原代码:
就可以得到了
下面这个处理起来还是蛮好玩的

hook代码以及主动调用的代码:

这里继续搜索就行

可以找到这个函数

一层层分析下去,可以看到这个so,以及so的代码
他就是静态注册的,但是有许多花指令


存在许多的垃圾代码,死代码,这时候咱们就得nop修复了,这个花指令也挺简单,就是插入了一段无用代码,永远不会执行,影响静态看
所以我写了一个idapython来帮助我们静态分析
这个使用就是这个

然后run就行


上面的就是成果,可以看了
接下来就是静态了,我使用frida脚本辅助我们静态看
下面附上我的分析的代码

这里有一个输入,我的frida代码应该也有记录,就直接分析代码了
首先就是输入拼接了一下这个ca8e86efb32e字符串然后进行MD5操作

接下来就是一个异或扰动,具体就是先加和(前15字节)再异或扰动

异或扰动完,就是另外一个加密

也就是encryfinal_xor这个函数,代码如下:
这里我写了一个unidbg的模拟执行
然后就是通过hook和调试去拿到这个加密解密函数:
总的加密解密代码如下:
就是这样

搜索这个x_data就行,定位到下面的函数

主要是下面这个,但是不知道为什么上面的咱们的哪个erciyuan2020这个出现在了咱们的地方,可能也是AES加密吧



可以看到so层又调用了java层的加密,应该也是标准的只不过加了参数罢了
hook一下就行

最终定位到这里,一个AES cbc模式的
通过上面的这个frida以及上面的算法自吐脚本可以得到key和iv,就是这样的
具体算法如下:(我没有进行对齐操作,需要进行填充,大家可以再完善一下)
就得了登录请求的所有参数,然后他的返回包就是一个png图片的base64,大家cyberchef搞一下就行
这一块我没具体分析,只是找到了一些关键位置
定位位置


这里分析就行,具体的我也没做
这次在这个APP上面收获了不少东西,frida使用,unidbg使用,idapython去除花指令等等
后面需要加强的就是学习一个360加固的修复运行这种,提高一下自己对壳修复的能力
如果上面文章有侵权行为,请联系我删除
function dump_so(so_name) {
Java.perform(function () {
let currentApplication = Java.use('android.app.ActivityThread').currentApplication()
let dir = currentApplication.getApplicationContext().getFilesDir().getPath()
let libso = Process.getModuleByName(so_name)
console.log('[name]:', libso.name)
console.log('[base]:', libso.base)
console.log('[size]:', ptr(libso.size))
console.log('[path]:', libso.path)
let file_path = dir + '/' + libso.name + '_' + libso.base + '_' + ptr(libso.size) + '.so'
let file_handle = new File(file_path, 'wb')
if (file_handle && file_handle != null) {
Memory.protect(ptr(libso.base), libso.size, 'rwx')
let libso_buffer = ptr(libso.base).readByteArray(libso.size)
file_handle.write(libso_buffer)
file_handle.flush()
file_handle.close()
console.log('[dump]:', file_path)
}
})
}
function dump_so(so_name) {
Java.perform(function () {
let currentApplication = Java.use('android.app.ActivityThread').currentApplication()
let dir = currentApplication.getApplicationContext().getFilesDir().getPath()
let libso = Process.getModuleByName(so_name)
console.log('[name]:', libso.name)
console.log('[base]:', libso.base)
console.log('[size]:', ptr(libso.size))
console.log('[path]:', libso.path)
let file_path = dir + '/' + libso.name + '_' + libso.base + '_' + ptr(libso.size) + '.so'
let file_handle = new File(file_path, 'wb')
if (file_handle && file_handle != null) {
Memory.protect(ptr(libso.base), libso.size, 'rwx')
let libso_buffer = ptr(libso.base).readByteArray(libso.size)
file_handle.write(libso_buffer)
file_handle.flush()
file_handle.close()
console.log('[dump]:', file_path)
}
})
}
function ssl_pass2() {
var offest = 0x301184;
var soName = 'libsscronet.so';
console.log("==")
const module = Process.findModuleByName(soName)
Interceptor.attach(module.base.add(offest), {
onEnter: function (args) {
}, onLeave: function (retval) {
retval.replace(0x0)
console.log("返回值", retval)
return retval
}
})
}
function ssl_pass2() {
var offest = 0x301184;
var soName = 'libsscronet.so';
console.log("==")
const module = Process.findModuleByName(soName)
Interceptor.attach(module.base.add(offest), {
onEnter: function (args) {
}, onLeave: function (retval) {
retval.replace(0x0)
console.log("返回值", retval)
return retval
}
})
}
let JNISecurity = Java.use("com.kanman.JNISecurity");
var str1 = "1"
var str2 = "2"
var ret1 = JNISecurity.jmd(str1, str2)
console.log("jmd加密:", ret1)
let JNISecurity = Java.use("com.kanman.JNISecurity");
var str1 = "1"
var str2 = "2"
var ret1 = JNISecurity.jmd(str1, str2)
console.log("jmd加密:", ret1)
function hook_tess() {
Java.perform(function () {
var base64 = Java.use('android.util.Base64');
var string = Java.use('java.lang.String');
var messageDigest = Java.use('java.security.MessageDigest');
for (var i = 0; i < messageDigest.update.overloads.length; i++) {
messageDigest.update.overloads[i].implementation = function () {
var name = this.getAlgorithm()
send("=================" + name + "====================");
send(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
if (arguments.length == 1) {
send(arguments[0]);
this.update(arguments[0]);
} else if (arguments.length == 3) {
send(arguments[0]);
send(arguments[1]);
send(arguments[2]);
this.update(arguments[0], arguments[1], arguments[2]);
}
}
}
for (var i = 0; i < messageDigest.digest.overloads.length; i++) {
messageDigest.digest.overloads[i].implementation = function () {
var name = this.getAlgorithm()
send("=================" + name + "====================");
send(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
if (arguments.length == 0) {
var data = this.digest();
send(data);
return data;
} else if (arguments.length == 1) {
send(arguments[0]);
var data = this.digest(arguments[0]);
send(data);
return data;
} else if (arguments.length == 3) {
send(arguments[0]);
send(arguments[1]);
send(arguments[2]);
var data = this.digest(arguments[0], arguments[1], arguments[2]);
send(data);
return data;
}
}
}
var cipher = Java.use('javax.crypto.Cipher');
});
}
function hook_tess() {
Java.perform(function () {
var base64 = Java.use('android.util.Base64');
var string = Java.use('java.lang.String');
var messageDigest = Java.use('java.security.MessageDigest');
for (var i = 0; i < messageDigest.update.overloads.length; i++) {
messageDigest.update.overloads[i].implementation = function () {
var name = this.getAlgorithm()
send("=================" + name + "====================");
send(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
if (arguments.length == 1) {
send(arguments[0]);
this.update(arguments[0]);
} else if (arguments.length == 3) {
send(arguments[0]);
send(arguments[1]);
send(arguments[2]);
this.update(arguments[0], arguments[1], arguments[2]);
}
}
}
for (var i = 0; i < messageDigest.digest.overloads.length; i++) {
messageDigest.digest.overloads[i].implementation = function () {
var name = this.getAlgorithm()
send("=================" + name + "====================");
send(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
if (arguments.length == 0) {
var data = this.digest();
send(data);
return data;
} else if (arguments.length == 1) {
send(arguments[0]);
var data = this.digest(arguments[0]);
send(data);
return data;
} else if (arguments.length == 3) {
send(arguments[0]);
send(arguments[1]);
send(arguments[2]);
var data = this.digest(arguments[0], arguments[1], arguments[2]);
send(data);
return data;
}
}
}
var cipher = Java.use('javax.crypto.Cipher');
});
}
let Utils = Java.use("com.kanman.allfree.ext.utils.Utils");
Utils["getDeviceId"].implementation = function () {
console.log('getDeviceId is called');
let ret = this.getDeviceId();
console.log('getDeviceId ret value is ' + ret);
return ret;
};
let InfoUtils = Java.use("com.kanman.allfree.utils.InfoUtils");
InfoUtils["getDeviceId"].implementation = function () {
console.log('getDeviceId is called');
let ret = this.getDeviceId();
console.log('getDeviceId ret value is ' + ret);
return ret;
};
let Utils = Java.use("com.kanman.allfree.ext.utils.Utils");
Utils["getDeviceId"].implementation = function () {
console.log('getDeviceId is called');
let ret = this.getDeviceId();
console.log('getDeviceId ret value is ' + ret);
return ret;
};
let InfoUtils = Java.use("com.kanman.allfree.utils.InfoUtils");
InfoUtils["getDeviceId"].implementation = function () {
console.log('getDeviceId is called');
let ret = this.getDeviceId();
console.log('getDeviceId ret value is ' + ret);
return ret;
};
from Cryptodome.Cipher import AES
import base64
from Cryptodome.Util.Padding import pad, unpad
def encryaes(data,key):
cipher=AES.new(key.encode('utf-8'),AES.MODE_ECB)
encrypted=cipher.encrypt(data.encode('utf-8'))
return base64.b64encode(encrypted).decode('utf-8')
def decryaes(base_enc,key):
enc=base64.b64decode(base_enc)
cipher=AES.new(key.encode('utf-8'),AES.MODE_ECB)
dec=cipher.decrypt(enc)
return dec.decode('utf-8')
s='S5aTaQe22BdwsExgr1ftHPPGb9Sxq69Pue/WdH1HcHI='
key='xujikmlioksjoped'
inp="4efa5850dab58086"
print(decryaes(s,key))
print(encryaes(inp,key))
from Cryptodome.Cipher import AES
import base64
from Cryptodome.Util.Padding import pad, unpad
def encryaes(data,key):
cipher=AES.new(key.encode('utf-8'),AES.MODE_ECB)
encrypted=cipher.encrypt(data.encode('utf-8'))
return base64.b64encode(encrypted).decode('utf-8')
def decryaes(base_enc,key):
enc=base64.b64decode(base_enc)
cipher=AES.new(key.encode('utf-8'),AES.MODE_ECB)
dec=cipher.decrypt(enc)
return dec.decode('utf-8')
s='S5aTaQe22BdwsExgr1ftHPPGb9Sxq69Pue/WdH1HcHI='
key='xujikmlioksjoped'
inp="4efa5850dab58086"
print(decryaes(s,key))
print(encryaes(inp,key))
function hook_sig1() {
Java.perform(function () {
let Orange = Java.use("com.yxcorp.kuaishou.addfp.android.Orange");
let KWEGIDDFP = Java.use("com.yxcorp.kuaishou.addfp.KWEGIDDFP");
KWEGIDDFP["doSign"].implementation = function (context, str) {
console.log('doSign is called' + ', ' + 'context: ' + context + ', ' + 'str: ' + str);
let ret = this.doSign(context, str);
console.log('doSign ret value is ' + ret);
return ret;
};
var current_application = Java.use('android.app.ActivityThread').currentApplication();
var context = current_application.getApplicationContext();
let bArr = Java.array('byte', [0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38]);
let i = 4;
let result = Orange.getClock(context, bArr, i);
console.log("[*] 参数:", "bArr", bArr, "i:", i)
console.log('[*] 返回值: ' + result);
console.log("=====")
})
}
hook_sig1()
function hook_sig1() {
Java.perform(function () {
let Orange = Java.use("com.yxcorp.kuaishou.addfp.android.Orange");
let KWEGIDDFP = Java.use("com.yxcorp.kuaishou.addfp.KWEGIDDFP");
KWEGIDDFP["doSign"].implementation = function (context, str) {
console.log('doSign is called' + ', ' + 'context: ' + context + ', ' + 'str: ' + str);
let ret = this.doSign(context, str);
console.log('doSign ret value is ' + ret);
return ret;
};
var current_application = Java.use('android.app.ActivityThread').currentApplication();
var context = current_application.getApplicationContext();
let bArr = Java.array('byte', [0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38]);
let i = 4;
let result = Orange.getClock(context, bArr, i);
console.log("[*] 参数:", "bArr", bArr, "i:", i)
console.log('[*] 返回值: ' + result);
console.log("=====")
})
}
hook_sig1()
import ida_bytes
import idc
import idaapi
def find_and_patch(start,end):
pattern=['STP', 'STP', 'ADR', 'SUBS', 'MOV', 'ADDS', 'STR','LDP','LDP','BR']
res=[]
while start<end:
ea=start
cnt=0
subs_offset=0
adds_offset=0
for i in range(len(pattern)):
if idc.print_insn_mnem(ea) =="SUBS":
subs_offset=get_offset(ea)
if idc.print_insn_mnem(ea) =="ADDS":
adds_offset=get_offset(ea)
if pattern[i] != idc.print_insn_mnem(ea):
break
else:
cnt+=1
ea=idc.next_head(ea,end)
if cnt==10:
res.append((start+8,start+0x24+adds_offset-subs_offset))
start+=0x20+adds_offset-subs_offset
else:
start+=4
return res
def get_offset(addr):
raw_ins=ida_bytes.get_bytes(addr,4)
instr=int.from_bytes(raw_ins,byteorder='little')
imm_val=(instr>>10)&0xff
return imm_val
def set_color(start,end):
for addr in range(start,end):
idc.set_color(addr,idc.CIC_ITEM,0xd0ffc0)
def do_patch(start,end):
nop_bytes = (0x1F2003D5).to_bytes(4, "big")
while start<=end:
ida_bytes.patch_bytes(start,nop_bytes)
start+=4
def upc(begin,end):
for i in range(begin,end):
idc.del_items(i)
for i in range(begin,end):
idc.create_insn(i)
for i in range(begin,end):
idaapi.add_func(i)
print("Finish!!!")
begin=0x4360
end=0x4A54
patchs=find_and_patch(begin,end)
print(patchs)
for i in range(len(patchs)):
set_color(patchs[i][0],patchs[i][1])
do_patch(patchs[i][0],patchs[i][1])
upc(begin,end)
import ida_bytes
import idc
import idaapi
def find_and_patch(start,end):
pattern=['STP', 'STP', 'ADR', 'SUBS', 'MOV', 'ADDS', 'STR','LDP','LDP','BR']
res=[]
while start<end:
ea=start
cnt=0
subs_offset=0
adds_offset=0
for i in range(len(pattern)):
if idc.print_insn_mnem(ea) =="SUBS":
subs_offset=get_offset(ea)
if idc.print_insn_mnem(ea) =="ADDS":
adds_offset=get_offset(ea)
if pattern[i] != idc.print_insn_mnem(ea):
break
else:
cnt+=1
ea=idc.next_head(ea,end)
if cnt==10:
res.append((start+8,start+0x24+adds_offset-subs_offset))
start+=0x20+adds_offset-subs_offset
else:
start+=4
return res
def get_offset(addr):
raw_ins=ida_bytes.get_bytes(addr,4)
instr=int.from_bytes(raw_ins,byteorder='little')
imm_val=(instr>>10)&0xff
return imm_val
def set_color(start,end):
for addr in range(start,end):
idc.set_color(addr,idc.CIC_ITEM,0xd0ffc0)
def do_patch(start,end):
nop_bytes = (0x1F2003D5).to_bytes(4, "big")
while start<=end:
ida_bytes.patch_bytes(start,nop_bytes)
start+=4
def upc(begin,end):
for i in range(begin,end):
idc.del_items(i)
for i in range(begin,end):
idc.create_insn(i)
for i in range(begin,end):
idaapi.add_func(i)
print("Finish!!!")
begin=0x4360
end=0x4A54
patchs=find_and_patch(begin,end)
print(patchs)
for i in range(len(patchs)):
set_color(patchs[i][0],patchs[i][1])
do_patch(patchs[i][0],patchs[i][1])
upc(begin,end)
function hook_so_sig1() {
var offest = 0x3F48;
var soName = 'libsgcore.so';
const module = Process.findModuleByName(soName)
console.log(module.base.add(offest))
Interceptor.attach(module.base.add(offest), {
onEnter: function (args) {
console.log("原始值", (this.context.x0))
console.log("开始调用参数")
console.log(args[0])
console.log(args[1])
console.log(args[2])
console.log(args[3])
console.log(Memory.readByteArray(this.context.x1, 0x40))
console.log(Memory.readByteArray(this.context.x2, 0x40))
}, onLeave: function (retval) {
console.log("返回值", retval)
}
})
}
function hook_findso() {
var offest = 0x22D0;
var soName = 'libsgcore.so';
const module = Process.findModuleByName(soName)
console.log("模块基址", module.base.add(offest))
Interceptor.attach(module.base.add(offest), {
onEnter: function (args) {
console.log("开始调用参数==============================")
console.log('[*] 参数一', (args[0]))
console.log('[*] 参数二', args[1])
console.log('[*] 参数三', args[2])
this.keys = args[0]
console.log('[*] 参数一数组', Memory.readByteArray(this.context.x0, 0x40))
console.log('[*] 参数二数组', Memory.readByteArray(this.context.x1, 0x40))
}, onLeave: function (retval) {
console.log('[*] 返回值2:', Memory.readByteArray(retval, 0x40))
console.log('[*] 返回值:', Memory.readByteArray(this.keys, 0x40))
}
})
}
function hook_enctypart() {
var offest = 0x24A0;
var soName = 'libsgcore.so';
const module = Process.findModuleByName(soName)
console.log("模块基址", module.base.add(offest))
Interceptor.attach(module.base.add(offest), {
onEnter: function (args) {
console.log("开始调用参数==============================")
this.keys = args[0]
console.log('[*] 中间值', this.context.x9, 0x40)
}, onLeave: function (retval) {
}
})
}
function hook_so_sig1() {
var offest = 0x3F48;
var soName = 'libsgcore.so';
const module = Process.findModuleByName(soName)
console.log(module.base.add(offest))
Interceptor.attach(module.base.add(offest), {
onEnter: function (args) {
console.log("原始值", (this.context.x0))
console.log("开始调用参数")
console.log(args[0])
console.log(args[1])
console.log(args[2])
console.log(args[3])
console.log(Memory.readByteArray(this.context.x1, 0x40))
console.log(Memory.readByteArray(this.context.x2, 0x40))
}, onLeave: function (retval) {
console.log("返回值", retval)
}
})
}
function hook_findso() {
var offest = 0x22D0;
var soName = 'libsgcore.so';
const module = Process.findModuleByName(soName)
console.log("模块基址", module.base.add(offest))
Interceptor.attach(module.base.add(offest), {
onEnter: function (args) {
console.log("开始调用参数==============================")
console.log('[*] 参数一', (args[0]))
console.log('[*] 参数二', args[1])
console.log('[*] 参数三', args[2])
this.keys = args[0]
console.log('[*] 参数一数组', Memory.readByteArray(this.context.x0, 0x40))
console.log('[*] 参数二数组', Memory.readByteArray(this.context.x1, 0x40))
}, onLeave: function (retval) {
console.log('[*] 返回值2:', Memory.readByteArray(retval, 0x40))
console.log('[*] 返回值:', Memory.readByteArray(this.keys, 0x40))
}
})
}
function hook_enctypart() {
var offest = 0x24A0;
var soName = 'libsgcore.so';
const module = Process.findModuleByName(soName)
console.log("模块基址", module.base.add(offest))
Interceptor.attach(module.base.add(offest), {
onEnter: function (args) {
console.log("开始调用参数==============================")
this.keys = args[0]
console.log('[*] 中间值', this.context.x9, 0x40)
}, onLeave: function (retval) {
}
})
}
jstring __fastcall Java_com_kwai_sgcore_SGCore_getClock(JNIEnv *JNIEnv, __int64 a2, __int64 a3, void *a4)
{
int n10;
int i;
jstring result;
jbyte *v10;
jbyte *v11;
jsize v13;
int n10_1;
unsigned int v15;
int v16;
__int64 s_1;
__int64 s_2;
__int64 ptr_1;
_BOOL4 v20;
const char *s_3;
int j_1;
int n10_2;
int v24;
__int64 j;
bool v26;
unsigned __int64 n0x10;
bool v28;
char v29;
unsigned int n0xFF;
unsigned __int64 n0xF;
int v32;
__int64 idx;
int v34;
__int64 v35;
__int64 v36;
unsigned __int8 *ptr;
int n10_3;
int v39;
__int64 k;
int m;
int v42;
size_t v43;
size_t v44;
__int128 v45;
__int128 v46;
__int128 v47;
char v48;
char v49[104];
char s[8];
__int64 v51;
__int64 v52;
JNIEnv *JNIEnv_1;
__int64 v54;
__int64 v55;
JNIEnv_1 = JNIEnv;
v54 = a2;
v55 = a3;
v52 = *(_ReadStatusReg(ARM64_SYSREG(3, 3, 13, 0, 2)) + 40);
n10 = ::n10;
i = (HIDWORD(::n10) - 1) * HIDWORD(::n10);
if ( !a4 )
{
result = 0LL;
goto LABEL_9;
}
while ( 1 )
{
v10 = (*JNIEnv)->GetByteArrayElements(JNIEnv, a4, 0LL);
n10 = ::n10;
v11 = v10;
if ( (::n10 & 0x80000000) != 0 || (((HIDWORD(::n10) - 1) * HIDWORD(::n10)) & 0x80000000) == 0 )
break;
(*JNIEnv)->GetByteArrayElements(JNIEnv, a4, 0LL);
}
if ( !v10 )
{
result = 0LL;
i = (HIDWORD(::n10) - 1) * HIDWORD(::n10);
if ( (::n10 & 0x80000000) == 0 )
goto LABEL_21;
goto LABEL_9;
}
if ( (*JNIEnv)->ExceptionCheck(JNIEnv) )
{
while ( 1 )
{
(*JNIEnv)->ExceptionClear(JNIEnv);
n10 = ::n10;
result = 0LL;
i = (HIDWORD(::n10) - 1) * HIDWORD(::n10);
if ( (::n10 & 0x80000000) != 0 || (i & 0x80000000) == 0 )
break;
(*JNIEnv)->ExceptionClear(JNIEnv);
}
goto LABEL_20;
}
if ( (::n10 & 0x80000000) == 0 && (HIDWORD(::n10) - 1) * HIDWORD(::n10) < 0 )
goto LABEL_25;
while ( 1 )
{
v13 = (*JNIEnv)->GetArrayLength(JNIEnv, a4);
n10_1 = ::n10;
v15 = v13;
v16 = (HIDWORD(::n10) - 1) * HIDWORD(::n10);
if ( (::n10 & 0x80000000) != 0 || (v16 & 0x80000000) == 0 )
break;
LABEL_25:
(*JNIEnv)->GetArrayLength(JNIEnv, a4);
}
if ( !::s )
{
while ( 1 )
{
s_1 = AES_encrypt_(byte_F8AB, 16LL);
n10_1 = ::n10;
::s = s_1;
v16 = (HIDWORD(::n10) - 1) * HIDWORD(::n10);
if ( (::n10 & 0x80000000) != 0 || (v16 & 0x80000000) == 0 )
break;
::s = AES_encrypt_(byte_F8AB, 16LL);
}
}
while ( n10_1 >= 0 && v16 < 0 )
;
if ( !s_0 )
{
s_2 = (sub_2710)(JNIEnv, a3);
n10_1 = ::n10;
s_0 = s_2;
v16 = (HIDWORD(::n10) - 1) * HIDWORD(::n10);
}
if ( (n10_1 & 0x80000000) == 0 && v16 < 0 )
{
while ( 1 )
;
}
ptr_1 = ::ptr;
if ( !::ptr )
{
while ( 1 )
{
ptr_1 = (sub_2A28)(JNIEnv, a3);
n10_1 = ::n10;
::ptr = ptr_1;
v16 = (HIDWORD(::n10) - 1) * HIDWORD(::n10);
if ( (::n10 & 0x80000000) != 0 || (v16 & 0x80000000) == 0 )
break;
::ptr = (sub_2A28)(JNIEnv, a3);
}
}
v20 = n10_1 < 10 || (v16 & 1) == 0;
while ( !v20 )
;
if ( !s_0 || (s_3 = ::s) == 0LL || !ptr_1 )
{
result = (JNIEnv[167])(JNIEnv, &byte_1046F);
n10 = ::n10;
for ( i = (HIDWORD(::n10) - 1) * HIDWORD(::n10);
(::n10 & 0x80000000) == 0 && i < 0;
i = (HIDWORD(::n10) - 1) * HIDWORD(::n10) )
{
(JNIEnv[167])(JNIEnv, &byte_1046F);
result = (JNIEnv[167])(JNIEnv, &byte_1046F);
n10 = ::n10;
}
goto LABEL_49;
}
while ( 1 )
{
*s = 0LL;
v51 = 0LL;
j_1 = strlen(s_3);
MD5_state(v49);
MD5_update(v49, v11, v15);
n10_2 = ::n10;
v24 = (HIDWORD(::n10) - 1) * HIDWORD(::n10);
if ( (::n10 & 0x80000000) != 0 || (v24 & 0x80000000) == 0 )
break;
*s = 0LL;
v51 = 0LL;
MD5_state(v49);
MD5_update(v49, v11, v15);
s_3 = ::s;
}
for ( j = 0LL; ; j += 2LL )
{
v26 = n10_2 >= 0 && v24 < 0;
if ( j >= j_1 )
break;
if ( v26 )
goto LABEL_60;
while ( 1 )
{
sprintf(s, "%c%c", *(::s + j), *(::s + j + 1));
MD5_update(v49, s, 2LL);
n10_2 = ::n10;
v24 = (HIDWORD(::n10) - 1) * HIDWORD(::n10);
if ( (::n10 & 0x80000000) != 0 || (v24 & 0x80000000) == 0 )
break;
LABEL_60:
sprintf(s, "%c%c", *(::s + j), *(::s + j + 1));
MD5_update(v49, s, 2LL);
}
}
if ( v26 )
(sub_6A2C)(v49);
(sub_6A2C)(v49);
n0x10 = 0LL;
v28 = ::n10 >= 0 && (HIDWORD(::n10) - 1) * HIDWORD(::n10) < 0;
do
{
v29 = v49[n0x10 + 88];
if ( v28 )
s[n0x10] = v29;
s[n0x10++] = v29;
}
while ( n0x10 < 0x10 );
if ( v28 )
{
while ( 1 )
LABEL_72:
;
}
n0xFF = 0;
n0xF = 0LL;
while ( n0xF < 0xF )
{
v32 = s[n0xF++];
n0xFF += v32;
if ( v28 )
goto LABEL_72;
}
idx = 0LL;
if ( n0xFF <= 0xFF )
LOBYTE(v34) = n0xFF;
else
v34 = -n0xFF;
do
{
s[idx] ^= v34 ^ idx;
++idx;
}
while ( idx != 15 );
while ( 1 )
{
HIBYTE(v51) = v34;
v44 = strlen(s_0);
v36 = MD5_func2(0, s_0, v44);
LODWORD(v44) = MD5_func2(v36, ::ptr, 32);
ptr = encryfinal_xor(s, 16LL, v44);
(*JNIEnv)->ReleaseByteArrayElements(JNIEnv, a4, v11, 2LL);
n10_3 = ::n10;
v39 = HIDWORD(::n10);
v48 = 0;
v46 = 0u;
v47 = 0u;
v45 = 0u;
if ( (::n10 & 0x80000000) != 0 || (((HIDWORD(::n10) - 1) * HIDWORD(::n10)) & 0x80000000) == 0 )
break;
HIBYTE(v51) = v34;
v43 = strlen(s_0);
v35 = MD5_func2(0, s_0, v43);
LODWORD(v43) = MD5_func2(v35, ::ptr, 32);
encryfinal_xor(s, 16LL, v43);
(*JNIEnv)->ReleaseByteArrayElements(JNIEnv, a4, v11, 2LL);
v48 = 0;
v46 = 0u;
v47 = 0u;
v45 = 0u;
}
for ( k = 0LL; ; ++k )
{
v42 = (v39 - 1) * v39;
while ( n10_3 >= 0 && v42 < 0 )
;
if ( k == 24 )
break;
for ( m = ptr[k]; ; m = ptr[k] )
{
sprintf(&v45 + 2 * k, "%02x", m);
n10_3 = ::n10;
v39 = HIDWORD(::n10);
if ( (::n10 & 0x80000000) != 0 || (((HIDWORD(::n10) - 1) * HIDWORD(::n10)) & 0x80000000) == 0 )
break;
sprintf(&v45 + 2 * k, "%02x", ptr[k]);
}
}
free(ptr);
result = (*JNIEnv)->NewStringUTF(JNIEnv, &v45);
n10 = ::n10;
i = (HIDWORD(::n10) - 1) * HIDWORD(::n10);
LABEL_49:
if ( (n10 & 0x80000000) == 0 && i < 0 )
{
while ( 1 )
;
}
LABEL_20:
if ( (n10 & 0x80000000) == 0 )
{
LABEL_21:
if ( i < 0 )
{
while ( 1 )
;
}
}
LABEL_9:
if ( (n10 & 0x80000000) == 0 && i < 0 )
{
while ( 1 )
;
}
return result;
}
jstring __fastcall Java_com_kwai_sgcore_SGCore_getClock(JNIEnv *JNIEnv, __int64 a2, __int64 a3, void *a4)
{
int n10;
int i;
jstring result;
jbyte *v10;
jbyte *v11;
jsize v13;
int n10_1;
unsigned int v15;
int v16;
__int64 s_1;
__int64 s_2;
__int64 ptr_1;
_BOOL4 v20;
const char *s_3;
int j_1;
int n10_2;
int v24;
__int64 j;
bool v26;
unsigned __int64 n0x10;
bool v28;
char v29;
unsigned int n0xFF;
unsigned __int64 n0xF;
int v32;
__int64 idx;
int v34;
__int64 v35;
__int64 v36;
unsigned __int8 *ptr;
int n10_3;
int v39;
__int64 k;
int m;
int v42;
size_t v43;
size_t v44;
__int128 v45;
__int128 v46;
__int128 v47;
char v48;
char v49[104];
char s[8];
[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!