猿人学第11题
将App下载后进行观察

界面还算简单,拖到jadx中进行反编译

全局搜索sign关键字进行定位很快就会找到sign生成的位置,仔细观察最后会发现sig方法在native层

到这里就可以直接将so文件拉出来看了
通过ida查看发现 sign方法是动态注册,所以直接搜JniOnload

点击方法进入

直接很清楚的就会发现getSign关键字,点击Tab键进入伪c代码界面

大致看了下,还是直接进行Unidbg调用so比较方便,这个是需要补JNi环境的
package com.dta.yuanrenxue8;
import com.github.unidbg.AndroidEmulator;
import com.github.unidbg.Module;
import com.github.unidbg.linux.android.AndroidEmulatorBuilder;
import com.github.unidbg.linux.android.AndroidResolver;
import com.github.unidbg.linux.android.dvm.*;
import com.github.unidbg.linux.android.dvm.wrapper.DvmLong;
import com.github.unidbg.memory.Memory;
import java.io.File;
import java.io.IOException;
import java.util.Random;
public class MainActivity2 {
private final AndroidEmulator emulator;
private final VM vm;
private final Module module;
private final DvmClass TTEncryptUtils;
private final boolean logging;
MainActivity2(boolean logging) {
this.logging = logging;
emulator = AndroidEmulatorBuilder.for32Bit().setProcessName("com.yuanrenxue.onlinejudge2020").build();
final Memory memory = emulator.getMemory();
memory.setLibraryResolver(new AndroidResolver(23));
vm = emulator.createDalvikVM(new File("unidbg-android/src/test/java/com/dta/yuanrenxue8/YuanRenXueOJ_1.2-release.apk"));
vm.setVerbose(logging);
vm.setJni(new AbstractJni() {
@Override
public DvmObject<?> callStaticObjectMethodV(BaseVM vm, DvmClass dvmClass, DvmMethod dvmMethod, VaList vaList) {
if ("android/os/Looper->myLooper()Landroid/os/Looper;".equals(dvmMethod.toString())){
return vm.resolveClass("android/os/Looper").newObject(null);
}
return null;
}
@Override
public DvmObject<?> newObjectV(BaseVM vm, DvmClass dvmClass, DvmMethod dvmMethod, VaList vaList) {
if ("java/util/Random-><init>()V".equals(dvmMethod.toString())){
return vm.resolveClass("java/util/Random").newObject(new Random());
}else if("java/util/Random-><init>(J)V".equals(dvmMethod.toString())){
return vm.resolveClass("java/util/Random").newObject(new Random(vaList.getLongArg(0)));
}
return null;
}
@Override
public int callIntMethodV(BaseVM vm, DvmObject<?> dvmObject, DvmMethod dvmMethod, VaList vaList) {
if ("java/util/Random->nextInt(I)I".equals(dvmMethod.toString())){
Random a = (Random)dvmObject.getValue();
return a.nextInt(vaList.getIntArg(0));
}
return 0;
}
@Override
public DvmObject<?> callObjectMethodV(BaseVM vm, DvmObject<?> dvmObject, DvmMethod dvmMethod, VaList vaList) {
if("android/content/ContextWrapper->getFilesDir()Ljava/io/File;".equals(dvmMethod.toString())){
return vm.resolveClass("java/io/File").newObject(new File("/"));
}else if("java/io/File->getAbsolutePath()Ljava/lang/String;".equals(dvmMethod.toString())){
return new StringObject(vm, "/");
}
return null;
}
@Override
public boolean acceptMethod(DvmClass dvmClass, String signature, boolean isStatic) {
return true;
}
});
DalvikModule dm = vm.loadLibrary(new File("unidbg-android/src/test/resources/example_binaries/armeabi-v7a/libyuanrenxue_native.so"), false);
DvmClass cContextWrapper = vm.resolveClass("android/content/ContextWrapper");
TTEncryptUtils = vm.resolveClass("com/yuanrenxue/onlinejudge2020/OnlineJudgeApp", cContextWrapper);
dm.callJNI_OnLoad(emulator);
module = dm.getModule();
}
void destroy() throws IOException {
emulator.close();
if (logging) {
System.out.println("destroy");
}
}
public static void main(String[] args) throws Exception {
MainActivity2 test = new MainActivity2(false);
test.ttEncrypt("1");
test.destroy();
}
void ttEncrypt(String number){
StringObject signobj = TTEncryptUtils.newObject(null).callJniMethodObject(emulator, "getSign(J)Ljava/lang/String;", DvmLong.valueOf(vm, Long.parseLong(number)));
String sign = signobj.getValue();
System.out.println(sign);
}
}
以下是Unidbg返回的结果

我这里是直接使用springboot+Unidbg通过接口将返回值传送给python进行调用,也可以使用jar包的形式传递给python进行调用,手机进行抓包查看该题的请求参数以及url

总体上也就这几个参数需要注意,到这里就可以使用python进请求了
import requests
def get_res(page):
global s
url = 'http://localhost:8080/getSign/' + str(page)
sign = requests.get(url=url).text
new_url = 'https://match.yuanrenxue.com/api/match/11/query'
params = {
'id': str(page),
'sign': sign
}
res = requests.get(url=new_url, params=params).json()
s += res['data']
print(res)
if __name__ == '__main__':
s = 0
for i in range(0, 100):
get_res(i)
print(s)
python返回结果如下:
