专栏名称: 吾爱破解论坛
吾爱破解论坛致力于软件安全与病毒分析的前沿,丰富的技术版块交相辉映,由无数热衷于软件加密解密及反病毒爱好者共同维护,留给世界一抹值得百年回眸的惊艳,沉淀百年来计算机应用之精华与优雅,任岁月流转,低调而奢华的技术交流与探索却
目录
相关文章推荐
地球资源与地质活动  ·  中国科学院:王春琴-中国空间站舱外辐射剂量实测结果 ·  12 小时前  
地球资源与地质活动  ·  中国科学院:王春琴-中国空间站舱外辐射剂量实测结果 ·  12 小时前  
惠济发布  ·  零费用!零门槛!最高可赔2万 ·  2 天前  
惠济发布  ·  零费用!零门槛!最高可赔2万 ·  2 天前  
陕西发展改革  ·  何钟参加迎峰度夏负荷管理演练 ·  3 天前  
陕西发展改革  ·  何钟参加迎峰度夏负荷管理演练 ·  3 天前  
51好读  ›  专栏  ›  吾爱破解论坛

2025騰訊遊戲安全大賽(安卓決賽)

吾爱破解论坛  · 公众号  · 互联网安全  · 2025-04-18 09:25

正文

请到「今天看啥」查看全文


), 0x224 );
//    LOGD("crc_val: 0x%llx", crc_val);
return crc_val != 0x49d5c836 ;
}

在線程中不斷調用 is_sub_6711A54_modify 來檢測是否被修改,當 libGame.so 注入後,成功檢測。

當然更通用的做法可能是對整個 .text 段進行crc32,或者對一些重要的函數分別進行crc32,這裡針對單一函數的做法只是作為一個演示。

注:不知為何我用Xiaomi8 Lite( Magisk環境 )在測試時發現有時雖然 libGame.so 成功注入,但卻修改失敗?有時卻能修改成功,有點玄學。而在另一部非Magisk環境的手機手動注入 libGame.so 時卻能100%修改成功,有點神奇。

cheat分析

elf可執行文件的起始執行函數是 start ,如下。

一開始以為 br x16 那裡會跳到具體邏輯,但嘗試用frida stalker hook那處地址時並沒有觸發。


用frida stalker簡單trace後發現, __libc_init 會跳到 0x241d90

 复制代码 隐藏代码
0x241b04: bl #0x5f6bc47440
0x2b0440: adrp x16, #0x5f6bc4b000
0x2b0444: ldr x17, [x16, #0xfb0]
0x2b0448: add x16, x16, #0xfb0
0x2b044c: br x17
0x241d90: sub sp, sp, #0x70

注:後來用IDA9看才發現原來之前是因為沒有正確解析 __libc_init 的參數,導致看不到 sub_241d90


0x241d90 start_process ,這裡會通過am start來啟動APP,啟動成功後會調用 usleep 等待APP加載so,然後調用 sub_241BF0 實現外掛邏輯。


sub_241BF0 如下,一開始先初始化了ImGui,然後循環調用 MainLoopStep


對比ImGui源碼,以此手動還原 MainLoopStep 中的一些符號。


可以看到點擊「初始化輔助」按鈕後,會調用 init_cheat 進行初始化,看看它的實現。


「初始化輔助」分析

init_cheat 初始化流程大致如下。

/proc/ pidof com.ACE2025.Game /maps 獲取 libUE4.so 的基址,保存到全局變量。


通過 process_vm_readv 系統調用來跨內存訪問訪問 libUE4.so 中的一些值,保存到全局變量。


遍歷獲取 MyProjectCharacter 對象( 暫時未知是基於libUE4的哪個全局變量來獲取的 ),然後保存其中的 PlayerCameraManager 屬性到全局變量。


將上述遍歷過程用frida實現,如下:

 复制代码 隐藏代码
function test_cheat_init() {

    let unknow1 = base.add(0xAF75B08).readPointer();
    let unknow2 = base.add(0xAF75B08).add(8).readU32();
    console.log("unknow1: "hexdump(unknow1));
    console.log("FirstPersonCharacter_C: ", All_Objects["FirstPersonCharacter_C"]);
    for(let i = 0; i < unknow2; i++) {
        let uobj = unknow1.add(i * 24).readPointer();
        console.log(`${i}: ${uobj}`);
        printName(uobj);
    }

}

由此可以看出 0xAF75B08 指向的位置保存著 Character 對象數組, 0xAF75B08 + 8 指向的位置保存著數組大小。


最後調用 get_ThirdPerson 遍歷獲取 & 保存 TP_ThirdPersonCharacter 對象( 同上 ),後面還進行了一些操作,但應該不太重要,先不看了。




透視繪制分析

init_cheat 初始化後, inited 會置為true,然後會調用 process_cheat_options 處理勾選的外掛功能。


process_cheat_options 是個巨大的函數,一開始會遍歷所有 TP_ThirdPersonCharacter 對象,收集它們的信息( 同樣利用 process_vm_readv 系統調用 ),用來計算繪制的參數。


中間一大片類似如下結構的代碼,應該是在獲取 & 處理UE4角色的骨骼信息。


最後根據勾選的參數來繪制。








请到「今天看啥」查看全文