<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    MRCTF2022 stuuuuub 題解

    VSole2023-02-07 10:15:04

    Overview

    學了這么一段時間的Android,難得見到的一道比較對口的逆向題。不過比較遺憾的是,題目用的函數抽取的方法的文章我剛好看過,還研究了蠻久,不過當時就一直沒有怎么看懂,只死磕出了在抽取指令時的操作,但是卻不明白他是通過什么以及如何將指令給填充回去的。

    不過經過實打實分析了這個題目后,對指令填充有了一定的理解,雖然這個題目填充的方式比較簡易,但是至少知道了核心思想。果然知識表面上看懂了都還不是自己的,只有真正上手實踐了才能理解的更加深刻。

    一、StubApp-一代殼分析

    attachBaseContext

    首先通過AndroidManifest.xml找到入口Activity:com.mrctf.android2022.StubApp

    StubApp類里先看attachBaseContext。

    判斷了e類的a函數返回值,如果True則取e.d()的ClassLoader。

    e.a()

    設置了兩個so文件的路徑、API的檢查以及

    e.f() => e.e() => e.b() e.c()

    e.b()函數通過在su常見路徑下創建su文件來檢查是否被root。

    e.c()通過執行which su命令后讀取輸出來檢查是否有su文件。

    如果有su則會輸出:

    如果沒有su則沒有輸出:

    所以總的來說 attachBaseContext的e.a函數加載了兩個數據文件夾下so文件的路徑以及運行環境和root的檢測。

    e.d()

    e.d()中分別讀取并解密了assets文件夾下的三個文件res.dat、libc++_shared.so和build.json。

    其中res.dat和libc++_shared.so作為兩個so文件。

    build.json作為Dex文件通過InMemoryDexClassLoader加載。

    InMemoryDexClassLoader能夠通過從一個包含著DEX文件的緩沖區中加載類。可以用來執行沒有被寫進本地文件系統的代碼。

    爾后調用了e.g()來將當前的Activity的classLoader替換成我們加載了自定義類的classLoader。

    因為當前的Activity的mClassLoader已經是Activity默認的PathClassLoader,而該PathClassLoader并沒有加載我們的自定義類,而且我們接下來要啟動的MainActivity也是由PathClassLoader加載的,而且我們的InMemoryDexClassLoader和PathClassLoader都是繼承于BaseDexClassLoader,所以后續如果要調用自定義類的話就會找不到。

    接下來分析解密幾個so。

    二、libstub.so

    res.dat

    首先是由res.dat解密得到libnative.so。

    讀取res.dat文件后調用了decodeSo函數進行解密存放在應用的數據目錄下的libnative.so,而decodeSo是libstub.so里的native函數。

    但是在libstub.so里卻沒有直接找到decodeSo函數,因此應該是JNI_OnLoad里動態注冊的。

    decode String

    另外libstub.so使用了Ollvm的字符串加密和控制流平坦化。

    字符串在加載時調用了.init_array里的以.datadiv_decode開頭的函數對字符串進行解密。

    因此對于字符串解密有兩種方法:

    ① 手寫idapython腳本執行這幾個函數,對字符串進行解密。

    ② 使用unicorn引擎模擬執行,在進行寫操作時對操作數的地址進行Hook,即可獲取初始化后的so文件。

    這里參考官方給的WP中使用了AndroidNativeEmu框架。

    import loggingimport sys from unicorn import *import struct from androidemu.emulator import Emulatorfrom UnicornTraceDebugger import udbg logging.basicConfig(    stream=sys.stdout,    level=logging.DEBUG,    format='%(asctime)s %(levelname)7s %(name)34s | %(message)s')logger = logging.getLogger(__name__)emulator = Emulator(vfp_inst_set=True, vfs_root='vfs')str_datas = {}def hook_mem_write(uc,type,address,size,value,userdata):    try:        curdata = struct.pack("I", value)[:size]        str_datas[address] = curdata    except:        print(size) emulator.mu.hook_add(UC_HOOK_MEM_WRITE,hook_mem_write) emulator.load_library('lib/libc.so',do_init=False) lib_module = emulator.load_library('lib/libstub.so',do_init=True)  base_addr = lib_module.basesodata = open('lib/libstub.so', 'rb').read() for address,value in str_datas.items():    if base_addr < address < base_addr + lib_module.size:        offset = address - base_addr - 0x1000        print('address:0x%x data:%s offset:0x%x ' % (address, value, offset))        sodata = sodata[:offset] + value + sodata[offset+len(value):] with open('lib/libstub_new.so','wb') as file:    file.write(sodata)
    

    解密前:

    解密后:

    decodeSo

    sub_3F44里調用了sub_4D06是RegisterNatives動態注冊函數。

    RegisterNatives的定義

    jint RegisterNatives(JNIEnv *env, jclass clazz,const JNINativeMethod *methods, jint nMethods);
    

    所以可以看到sub_3A74就是實際調用的decodeSo函數。

    因為

    a & ~b | ~a & b = a ^ b
    

    實際上干的內容就是逐字節異或0x22,然后保存到文件,即可得到libnative.so

    JNI_OnLoad

    但是后面JNI_OnLoad還沒有分析完。后面調用了sub_2A2C和sub_2DEC。

    后面看了源碼后才知道這兩個函數分別是通過inLine Hook來Hook libc.so的execve和Hook libart.so的loadMethod。

    Inline hook

    項目地址:https://github.com/ele7enxxh/Android-Inline-Hook

    大致使用方法:

    if(registerInlineHook(target_func,read_func,tmp_func) == ELE7EN_OK){    if(inlineHook(target_func != ELE7EN_OK)){        return -1;    }    else{        return 0;    }}
    

    三、libnative.so

    分析MainActivity

    MainActivity存在的dex由build.json異或49即可得到。

    MainActivity里檢查了輸入長度然后調用了Utils.nativeCheck。

    Utils加載了libnative.so。

    我們直接搜索發現好像有nativeCheck,但是查看了函數內容提示是個錯誤的flag。

    仔細看發現這里的函數在Utils前有兩個下劃線:

    因此實際上的函數又是一個動態注冊的。

    使用以下腳本去除一些混淆:

    for addr,name in Names():    if name.startswith('x.') or name.startswith('y.'):        patch_dword(addr,0)
    

    sub_3D74

    我們可以看到是有注冊nativeCheck和check函數,但是注冊的函數處的參數的地址沒有有用的東西。后來看了源碼之后,在sub_3D74又是一個Inline Hook,dword_1B37C是在JNI_OnLoad里賦了JNIEnv*類型。

    而+860偏移是RegisterNatives函數(前面分析的是有看到過,所以還算比較熟悉,或者是查看Structures里的JNINativeInterface的定義)。

    sub_3834

    因此sub_3D74函數里Hook了RegisterNatives函數,實際調用的是sub_3834

    由前面定義知道a3是JNINativeMethod。

    typedef struct{    const char* name;    const char* signature;    void* fnPtr;}JNINativeMethod;
    

    所以干的事情就是把傳進去的函數減了2022才是實際的函數地址。

    nativeCheck

    nativeCheck函數的地址為0x29BC+3-2022=0x21D8。

    nativeCheck內對輸入的參數調用了Utils的test函數,但是我們看到的函數只有一個return true。

    這涉及到nativeCheck里的其他操作。

    四、函數抽取殼-二代殼分析

    myloadmethod

    首先我們先回到libstub里對loadMethod的Hook上分析。

    Hook后的函數將dexfile偏移0xB24的地址給讀取了出來并存到了shm文件下。

    我們從dex中可以看到該處地址剛好是存放test函數地址的地址。

    getPath

    然后在libnative.so的JNI_OnLoad函數讀取了shm文件里的內容,賦給了methodAddr。

    nativeCheck

    爾后在nativeCheck里給該地址賦了值,即把指令填了回去。

    再調用test函數。

    然后再把test函數里的指令給清空。

    recovery

    因此只需將指令填回去即可恢復test函數的內容。

    對輸入進行異或后,又調用了check函數。

    五、解題

    check函數里對輸入進行了填充,然后又調用了Encrypto函數后和簽名進行異或,最后與目標數據進行比較。

    enc = [38,43,44,115,20,17,22,19,32,119,42,41,19,68,19,26,117,112,38,33,18,67,19,18,32,38,35,38,19,69,17,23,117,112,44,112,19,27,20,21,39,32,37,39,23,76,21,20,47,32,32,120,31,24,67,70,35,39,34,39,23,74,23,16,32,115,32,37,21,20,18,27,36,38,16,67,36,39,16,26]signByte = [0x33,0x31,0x3a,0x31,0x34,0x36,0x34,0x61,0x3b,0x39,0x32,0x39,0x3c,0x3f,0x3f,0x38,0x71,0x21,0x22,0x20,0x24,0x27,0x26,0x26,0x28,0x2b,0x2a,0x29,0x2c,0x29,0x29,0x2d,0x44,0x43,0x1b,0x47,0x16,0x15,0x15,0x17,0x18,0x4d,0x1a,0x36,0x31,0x3b,0x31,0x65,0x3d,0x30,0x33,0x30,0x31,0x3c,0x6d,0x3b,0x3d,0x6a,0x3f,0x21,0x21,0x23,0x23,0x76,0x25,0x23,0x27,0x28,0x2a,0x2a,0x2f,0x24,0x2e,0x2f,0x2f,0x41,0x12,0x12,0x13,0x1c,0x15,0x10,0x17,0x1b,0x1c,0x1f,0x30,0x35,0x32,0x35,0x35,0x36,0x36,0x36,0x3f,0x3a,0x39,0x3a,0x3c,0x6c,0x3d,0x3f,0x20,0x29,0x22,0x25,0x24,0x26,0x23,0x22,0x28,0x2d,0x2a,0x23,0x2d,0x2e,0x2e,0x2e,0x17,0x12,0x11,0x12,0x14,0x44,0x15,0x17,0x18,0x11,0x1a,0x36,0x31,0x31,0x36,0x31,0x35,0x32,0x37,0x3f,0x38,0x39,0x3b,0x3d,0x3a,0x3d,0x3c,0x21,0x21,0x73,0x20,0x24,0x25,0x2e,0x27,0x2e,0x29,0x29,0x2e,0x29,0x2d,0x2a,0x2f,0x41,0x10,0x11,0x13,0x15,0x12,0x15,0x14,0x19,0x19,0x4b,0x33,0x31,0x32,0x3b,0x34,0x33,0x36,0x34,0x3d,0x3c,0x3a,0x3f,0x3c,0x6f,0x3f,0x3c,0x20,0x20,0x25,0x20,0x27,0x24,0x26,0x76,0x2b,0x29,0x2a,0x23,0x2c,0x2b,0x2e,0x2c,0x15,0x14,0x12,0x17,0x14,0x16,0x17,0x14,0x18,0x18,0x1d,0x33,0x32,0x32,0x32,0x61,0x34,0x31,0x37,0x6c,0x3a,0x38,0x38,0x3d,0x3e,0x3e,0x3c,0x25,0x22,0x23,0x20,0x27,0x26,0x26,0x24,0x2a,0x2a,0x2b,0x28,0x25,0x2e,0x2d,0x2c,0x10,0x14,0x43,0x12,0x13,0x15,0x42,0x14,0x1c,0x1a,0x1c,0x33,0x31,0x31,0x36,0x37,0x35,0x35,0x30,0x3b,0x39,0x39,0x39,0x3f,0x3c,0x3d,0x36,0x23,0x22,0x21,0x23,0x21,0x74,0x25,0x27,0x2c,0x21,0x29,0x2a,0x2c,0x7c,0x2d,0x2f,0x10,0x19,0x12,0x15,0x14,0x16,0x13,0x12,0x18,0x1d,0x1a,0x36,0x30,0x31,0x33,0x35,0x32,0x35,0x34,0x39,0x39,0x6b,0x38,0x3c,0x3d,0x36,0x3f,0x26,0x21,0x21,0x26,0x21,0x25,0x22,0x27,0x20,0x28,0x29,0x2b,0x2d,0x2a,0x2d,0x2c,0x11,0x11,0x43,0x10,0x14,0x15,0x1e,0x17,0x1e,0x19,0x19,0x35,0x34,0x32,0x37,0x34,0x32,0x37,0x34,0x38,0x38,0x3d,0x38,0x3f,0x3c,0x3e,0x6e,0x23,0x21,0x22,0x2b,0x24,0x23,0x26,0x24,0x2d,0x2c,0x2a,0x2f,0x2c,0x7c,0x2f,0x2c,0x10,0x10,0x15,0x10,0x17,0x14,0x16,0x46,0x1b,0x19,0x1a,0x38,0x31,0x34,0x33,0x37,0x30,0x33,0x37,0x3c,0x39,0x68,0x3a,0x3f,0x3d,0x3f,0x38,0x23,0x22,0x23,0x23,0x75,0x26,0x26,0x27,0x20,0x29,0x2c,0x2b,0x2f,0x28,0x2b,0x2f,0x14,0x11,0x11,0x12,0x17,0x15,0x17,0x10,0x1b,0x1a,0x1a,0x38,0x33,0x32,0x32,0x36,0x37,0x35,0x37,0x38,0x6d,0x3a,0x3d,0x3c,0x34,0x3c,0x6e,0x28,0x27,0x26,0x2b,0x2c,0x23,0x70,0x20,0x28,0x7d,0x2a,0x2a,0x2c,0x2c,0x2e,0x2e,0x10,0x14,0x12,0x13,0x14,0x16,0x1e,0x15,0x18,0x18,0x1a,0x66,0x31,0x32,0x30,0x34,0x3d,0x34,0x37,0x39,0x39,0x6b,0x3b,0x3e,0x35,0x3c,0x3f,0x21,0x21,0x23,0x23,0x24,0x2d,0x27,0x73,0x7b,0x7c,0x2a,0x2e,0x2a,0x2d,0x27,0x7a,0x17,0x44,0x12,0x47,0x14,0x16,0x13,0x1f,0x4b,0x1a,0x18,0x38,0x33,0x31,0x65,0x60,0x67,0x67,0x35,0x38,0x3e,0x39,0x39,0x39,0x3d,0x6f,0x39,0x27,0x77,0x71,0x71,0x2c,0x71,0x74,0x2f,0x21,0x7f,0x2f,0x79,0x28,0x7b,0x2c,0x79,0x41,0x47,0x1b,0x13,0x42,0x16,0x14,0x13,0x19,0x10,0x48,0x37,0x31,0x3a,0x30,0x62,0x30,0x30,0x36,0x31,0x6c,0x6c,0x39,0x3e,0x39,0x3d,0x69,0x22,0x25,0x2a,0x2a,0x71,0x23,0x2f,0x26,0x21,0x2b,0x2b,0x2c,0x7e,0x25,0x2c,0x7d,0x46,0x10,0x15,0x15,0x10,0x47,0x42,0x1e,0x4c,0x11,0x18,0x39,0x63,0x36,0x36,0x34,0x34,0x31,0x66,0x6a,0x3e,0x32,0x68,0x6a,0x3e,0x6c,0x3b,0x29,0x23,0x24,0x70,0x23,0x70,0x72,0x75,0x7e,0x2c,0x7e,0x2f,0x2b,0x29,0x29,0x29,0x41,0x13,0x16,0x45,0x15,0x47,0x1e,0x17,0x4b,0x11,0x1c,0x65,0x30,0x37,0x34,0x32,0x37,0x32,0x64,0x6c,0x6f,0x6b,0x39,0x6f,0x3a,0x3b,0x3b,0x23,0x25,0x73,0x22,0x20,0x2d,0x26,0x75,0x2e,0x2d,0x28,0x29,0x2b,0x29,0x2e,0x2a,0x16,0x44,0x43,0x41,0x15,0x41,0x42,0x44,0x19,0x4f,0x13,0x61,0x31,0x31,0x36,0x33,0x34,0x32,0x64,0x6c,0x3d,0x33,0x6e,0x6e,0x3b,0x3e,0x3a,0x27,0x26,0x24,0x25,0x70,0x70,0x72,0x23,0x2b,0x2c,0x7e,0x2d,0x25,0x7f,0x2d,0x7c,0x44,0x16,0x10,0x17,0x47,0x12,0x1f,0x1f,0x1b,0x4c,0x18,0x38,0x38,0x63,0x32,0x31,0x64,0x35,0x33,0x3c,0x3b,0x39,0x6e,0x6d,0x3f,0x3b,0x69,0x76,0x20,0x2a,0x23,0x75,0x77,0x24,0x23,0x2d,0x7f,0x28,0x7a,0x2a,0x2b,0x2f,0x7d,0x18,0x18,0x41,0x47,0x10,0x11,0x16,0x1e,0x1f,0x4c,0x19,0x64,0x36,0x30,0x61,0x60,0x34,0x60,0x31,0x30,0x6a,0x3a,0x33,0x38,0x6c,0x3d,0x6e,0x26,0x28,0x71,0x21,0x2d,0x76,0x2f,0x73,0x29,0x2b,0x78,0x7d,0x7f,0x7e,0x27,0x79,0x11,0x17,0x12,0x17,0x15,0x43,0x13,0x13,0x18,0x4c,0x18,0x39,0x30,0x61,0x65,0x30,0x30,0x60,0x64,0x31,0x38,0x3d,0x6f,0x3c,0x6b,0x6b,0x3e,0x21,0x21,0x23,0x22,0x2d,0x73,0x20,0x20,0x7e,0x7d,0x2c,0x79,0x2d,0x2e,0x28,0x2d,0x41,0x19,0x40,0x13,0x45,0x12,0x15,0x17,0x11,0x4d,0x49,0x34,0x32,0x34,0x34,0x3d,0x35,0x63,0x33,0x3e,0x6c,0x3c,0x3c,0x6f,0x3f,0x3d,0x3d,0x27,0x70,0x77,0x20,0x26,0x23,0x72,0x74,0x2c,0x21,0x7b,0x23,0x29,0x2d,0x7f,0x2e,0x12,0x13,0x16,0x16,0x47,0x43,0x1f,0x1f,0x4a,0x1c,0x1b,0x36,0x32,0x34,0x36,0x34,0x60,0x30,0x64,0x6a,0x31,0x33,0x69,0x38,0x3e,0x3a,0x3e,0x27,0x73,0x25,0x20,0x70,0x23,0x26,0x27,0x2c,0x2d,0x2e,0x2d,0x7f,0x2f,0x26,0x7a,0x18,0x17,0x47,0x47,0x13,0x11,0x47,0x10,0x10,0x1a,0x48,0x64,0x62,0x67,0x66,0x3d,0x64,0x34,0x3e,0x3e,0x39,0x38,0x3f,0x34,0x3e,0x3a,0x39,0x73,0x26,0x20,0x76,0x71,0x70,0x73,0x74,0x7d,0x2a,0x23,0x2b,0x79,0x7b,0x29,0x26,0x13,0x19,0x46,0x46,0x41,0x1d,0x11,0x17,0x1e,0x4a,0x48,0x34,0x31,0x33,0x60,0x67,0x32,0x33,0x32,0x3a,0x3e,0x3d,0x3d,0x3c,0x39,0x6d,0x39,0x27,0x21,0x20,0x23,0x27,0x25,0x27,0x27,0x28,0x29,0x2b,0x7a,0x2f,0x2f,0x2f,0x2c,0x10,0x10]sign =[]for i in range(1023):    sign.append(signByte[i]^(i%43))data = []for i in range(len(enc)):    data.append(enc[i]^sign[i])key =0x20222022for j in range(0,80,8):    left = data[j] << 24 | data[j + 1] << 16 | data[j + 2] << 8 | data[j + 3]    right = data[j + 4] << 24 | data[j + 5] << 16 | data[j + 6] << 8 | data[j + 7]     right = (right ^ left)&0xffffffff    left = (left ^ key)&0xffffffff      data[j] = (left >> 24) & 0xff    data[j + 1] = (left >> 16) & 0xff    data[j + 2] = (left >> 8) & 0xff    data[j + 3] = left & 0xff    data[j + 4] = (right >> 24) & 0xff    data[j + 5] = (right >> 16) & 0xff    data[j + 6] = (right >> 8) & 0xff    data[j + 7] = right & 0xffdata = [chr(i) for i in data if i !=0]flag = []for i in range(0,len(data),2):    if data[i]!=0:        flag.append(int(data[i]+data[i+1],16))for i in range(len(flag)-2,0,-1):    flag[i] = flag[i] ^ flag[i+1] ^iflag = [chr(i) for i in flag if i !=0]print(''.join(flag))
    
    函數調用data
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    由于該研究是在一年前完成的,所以截止本文發布時,華為不僅解決了本文提到的漏洞(CVE-2021-22337),而且現在已經將他們的許多設備從 Android 升級到了鴻蒙操作系統。因此,不要期望在你最新的華為設備上找到完全相同的漏洞利用細節。
    概述在windows系統上,涉及到內核對象的功能函數,都需要從應用層權限轉換到內核層權限,然后再執行想要的內核函數,最終將函數結果返回給應用層。本文就是用OpenProcess函數來觀察函數從應用層到內核層的整體調用流程。OpenProcess函數,根據指定的進程ID,返回進程句柄。NTSTATUS Status; //保存函數執行狀態。OBJECT_ATTRIBUTES Obja; //待打開對象的對象屬性。HANDLE Handle; //存儲打開的句柄。CLIENT_ID ClientId; //進程、線程ID. dwDesiredAccess, //預打開進程并獲取對應的權限。ObjectNamePresent = ARGUMENT_PRESENT ; //判斷對象名稱是否為空
    1 賽題回顧 2 最終排名(部分) 3 啟發與思路 4 算法與模型 函數名(CG圖) 復賽模型融合 Section信息 字符匹配 Yara匹配 Opcode 4. 其他布爾信息 灰度圖 直方圖 PE靜態特征模型 特征工程 5 結果與改進 復...
    EXP編寫學習之繞過GS
    2023-02-20 09:58:16
    棧中的守護天使 :GSGS原理向棧內壓入一個隨機的DWORD值,這個隨機數被稱為canary ,IDA稱為 Security Cookie。Security Cookie 放入 ebp前,并且data節中存放一個 Security Cookie的副本。棧中發生溢出時,Security Cookie首先被淹沒,之后才是ebp和返回地址。函數返回之前,會添加一個Security Cookie驗證操作,稱為Security Check。檢測到溢出時,系統將進入異常處理流程,函數不會正常返回,ret也不會被執行。函數使用無保護的關鍵字標記。緩沖區不是8字節類型 且 大小不大于4個字節。可以為函數強制啟用GS。
    反射式DLL注入實現
    2022-05-13 15:59:21
    反射式dll注入與常規dll注入類似,而不同的地方在于反射式dll注入技術自己實現了一個reflective loader()函數來代替LoadLibaryA()函數去加載dll,示意圖如下圖所示。藍色的線表示與用常規dll注入相同的步驟,紅框中的是reflective loader()函數行為,也是下面重點描述的地方。
    在所有函數調用發生時,向棧幀內壓入一個額外的隨機 DWORD,隨機數標注為“SecurityCookie”。在函數返回之前,系統將執行一個額外的安全驗證操作,被稱做 Security check。
    ASLR程序加載到內存后不使用默認的加載地址,將加載基址進行隨機化,依賴重定位表進行地址修復。地址隨機化之后,shellcode中固定的地址值將失效。圖-程序地址未隨機化處理開啟/關閉軟件地址隨機化。每個頁目錄表和頁表項都存在 基址與屬性控制位,通過修改這些控制位,達到當前內存是否有執行、讀、寫等權限。圖-表項構成windows 系統上可以調用 VirtualProtect 函數完成內存屬性的修改操作。DWORD flNewProtect, // 請求的保護方式。大小超過 8 個字節且不包含指針的數據結構。
    可是當我們開啟了smap保護之后,內核態就沒有辦法訪問用戶態的數據,此時當我們再hijack tty_operation到我們的用戶態時,我們的kernel就會panic,更別說劫持執行流到用戶態上執行rop了。當我們調用msgsnd時,在linux內核中會調用do_msgsnd。
    目前的處理方法對于語句間的控制依賴處理過于粗糙,且并未指明語句對應的路徑。并且在代碼片重組的過程中存在暴力堆疊的問題,使不在同一控制范圍內的語句彼此直接相鄰,從而導致了路徑不敏感。Design of SEVulDet下圖展示了SEVulDet的訓練階段與檢測階段,訓練階段相較于檢測階段多了打標簽這一環節。因此作者通過為PDG添加相應的葉子節點使其能夠確定控制范圍,避免了語義的缺失。
    uds診斷協議-逆向題 WP
    2022-08-14 16:17:02
    介紹這是一道uds診斷協議的逆向題。比賽的時候時間太短沒做出來,又花時間研究了一下拿出來分享。UdsRoutineControlService這個函數從getflag這看起來就像目標函數,要求的條件很多。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类