首页
社区
课程
招聘
[原创]2023腾讯游戏安全竞赛初赛题解(安卓)
发表于: 2023-4-22 01:03 40248

[原创]2023腾讯游戏安全竞赛初赛题解(安卓)

2023-4-22 01:03
40248

虽然这次很不走运没拿名次,但是既然都花了这么长时间,还是得好好复现总结总结所学,尤其是才接触安卓两三个月,基础有点不牢固,于是准备重做一遍并记录下过程,分享出来与各逆向大佬共勉

拿到题目首先用 WinRAR 打开,看lib

说明这个是一个 unity il2cpp 框架下的 题目,那么立马就想到 il2cppdumpper

提取文件夹下的 assets\bin\Data\Managed\Metadata\global-metadata.dat

不出所料失败了

尝试使用Zygisk-Il2CppDumper,也失败了,那么到此只能使用终极 dump 方案

adb install apk 之后用 gg 在内存中 dump 解密之后的 libil2cpp.so

dump 过程如下,选择起始

以及结尾,然后保存就可以了

这时候用 il2cppdumper 选择 dump 下来的二进制文件,填上 so 在内存中的基址,直接 dump 下来了,甚至不需要手动找CodeRegistration 和 MetadataRegistration, global-metadata.dat 文件也没有被修改,如果被修改了也可以从内存中 dump 下来

到此拿到了

但是还没结束,dump的文件没有导入导出函数的符号,而 il2cpp 符号的脚本又是针对于 dump 文件的,所以可以顺手修复一下 dump 的文件头之类的,具体如下操作

首先可以看见 SECTION_HEADER 处一片空白,暂且不管

将 program_table 的每一个的 p_offset 改成 p_vaddr,以及 p_filesz 改成 p_memsz

值得注意的是第十一个表,这个表的结尾地址,正是之前 SECTION_HEADER 的开头处,也就是说 SECTION_HEADER 本来应该是移动到 0x13BC000+63352 = 0x13CB778,虽然这个地方是空的,但是暂且不管,把这个地址填到 SECTION_HEADER 处再说

修改完按 program_table 按一下 F5 就会重新分析了,也可以看到一片空白的 section_header

直接十六进制复制粘贴,即 Ctrl+shift+C Ctrl+shift+V,再 F5 刷新

可以看见字符还是对应不上,这其实是由 elf_header 中的 e_shtrndx 指定的,e_shtrndx 为26,意思是第 26 个指定了字符串的位置

索引一下就可以发现问题所在,是因为这个地方被重定位了

而在第 26 个表中 s_addr 为 0,说明这个 Section 是不会存在于运行的文件内的,然而往上翻发现了有趣的事情

没错,第 25 个表的 s_offset 与第 26 个的一样,但是他有 s_addr,所以可以确定第 26 个表的 s_addr 与第 25 个的一样,顺手把第 25个 s_offset 覆盖成 s_addr

不幸的是又出现了空白,不过没关系,直接二进制复制粘贴

除此之外,把其他的所有 section 中的 s_offset 覆盖成 s_addr,最后再按一次 F5 重载模板,就可以看见心心念念的符号了

最后记得保存,不然白忙活一场

将 dump 文件载入 ida 之后,最好是 Rebase 一下,因为是运行态文件,可能有些内存值已经被重定位,因此 Rebase 之后可能得到更多符号, Rebase 的值就是 dump 文件的载入地址,文件名上就有,比如我的是 0x7ad74c3000

等待 ida 初轮分析完之后,加载两次 il2cppdumper 的 ida_with_struct_py3.py 脚本,选择 script.json 和 il2cpp.h, 第二次的 json 选择 stringliteral.json,一阵分析之后,基于 il2cpp 能拿到的符号就全拿到了

经过尝试,发现直接挂 frida 服务上游戏,会直接弹窗,但是后开 frida 服务不会弹

后来发现 hook libsec2023.so 会弹窗,但是有一定延时才会弹出来,猜测调用 sleep, 尝试 hook 一下 sleep 发现真的不弹了,

包括 ida 附加的时候也不会闪退了

hook 的 frida 脚本如下,,既然是复现那就我自己来看

用 frida 上号直接可以看见打印 log

最后一个是弹出了一个什么权限我拒绝之后 hook 到的,应该是没用的,那么主要就是分析前面的 libsec2023.so 的函数

0x11f44 是函数 0x11f24 的一部分,这个函数看上去像是某种初始化,说明重点不在这,重点在下一步 call 的函数

0x220a8 是函数 0x22080 的一部分,这个 sleep 在函数的头部,但是这整个函数充斥着混淆,太难了不看

0x36794 是函数 0x36784 的一部分

看上去好像没什么异常的地方

0x36908 是 0x36818 的一部分,而这个函数...发现了很熟悉的操作

以我上一次做这个的经验,这里是一个字符串解密,解密函数 0x36f6c,修复去混淆之后重建函数,逻辑如下

解密之后

0x36818 剩下的逻辑也没啥好看的,其实是看不懂,用插件确实能找到 CRC 常数,不过却没有引用,算了算了,能跑就不管了,反反调试就到这吧

另外提一嘴,关于 ida 调试的事情

首先一定要新开 ida,不要用分析了 so 的 ida 附加,否则退出调试的时候会卡死,之前的分析就炸了,推荐是动静结合来分析

还有一件很重要的事情是关闭一些异常处理

Debugger Options...->Edit exceptions->

SIGPWR SIGXCPU 右键 edit,去掉挂起程序的勾,并勾上通过引用,report 选 log 或者 Silent 都行

这一点可能是因为 unity 的问题或者是 Android 的问题,调着调着就会弹这俩个异常,如果挂起程序,程序就会崩溃,程序崩溃又会导致 ida 崩溃,而设置完之后就不会出现这个情况了

还有一件事,程序暂停调试的时候不要点击屏幕,否则会出现和前面异常挂起一样的问题

按照说明,游戏内获得 1000 金币的时候,会出现 flag

那么肯定需要有个地方来判断金币数量,金币一般是用 coin 表示,在 dump.cs 中可以找到

同时发现 CollectCoin 函数

在有符号的 dump 中可以直接跳转到这个函数,也很容易发现相关逻辑

用 frida 改一下字节,比较1000改成比较0,这样随便捡一个金币就可以显示 flag 了

效果如下

这游戏自带外挂,但是必须输入 token 相对应的密码才能够使用,所以所谓注册机就是关于这个密码的逆向

注册机界面如下

本来没有什么下手点,但是从 dump.cs coin 往下随便翻翻,看到了 SmallKeyboard 相关的函数

甚至专门混淆了函数名,简直是此地无银三百两

直接看第一个函数就一步到位了

先看看后面那个oO0oOo0

很清晰就是生成随机 TOKEN 的逻辑,按照逻辑这个函数应该点进来会执行,enter 以后又会执行以刷新,看看引用果然如此

那么 SmallKeyboard__iI1Ii_527602715312 函数很显然就是 check 函数了

这个函数只有一个 int64的参数

往里走这个函数被 init_proc 搞得有点坏了

把 init_proc 函数 u 掉,再重新p就好了

而这个函数的庐山真面目其实是

然而 g_sec2023_p_array 是导入的

导入库中,只有 libsec2023.so 是非系统库

那么分析转到 libsec2023.so 中

可以看到 g_sec2023_p_array[9] 实际上就是 libsec2023.so + 0x31164

这个函数逻辑又是调用 g_sec2023_o_array,参数是类实例和 sub_3B8CC(input)

索引 g_sec2023_o_array 发现没有写入,那就说明是在其他 so 里写的,看一下 libil2cpp 里的调用果然找到了

最终这个函数调用到了 sub_7AD887BD64 (libil2cpp.so + 0x13b8d64)

可以猜测下大体逻辑,实际的话还是一边调试一边走比较好

索引一下最后比较成功他写的东西

虽然看的不是很懂,但是应该是开挂之类的,前面那个是无敌我还是看的明白的

所以到此,大体逻辑就已经看明白了,那么第一个用到 input 的函数是 sec2023 中的 sub_3b8cc,这里面有一点小混淆,掌握了规律还是很好去掉的

先拿 sub_3B8CC 里的函数 sub_3B9D4 举例

第一个X10,计算过程如下

0x3BA04 可以当作是小于的时候的执行,那么不小于的时候就要跳转到 0x3BB50

也就是 B.GE loc_3BB50

后面的一般都是这样的套路,手动计算跳转,然后满足原逻辑即可.当然 patch 完需要先 u c 下面的函数,然后按 u p 重建最上面的函数,才能恢复整个函数

直到 patch 到 ret,就说明这个函数已经去混淆完了,F5 可以看到清晰的逻辑

逆算法如下

我的 patch 点如下

patch 之后就看的很清楚了

0x3A054 像是个什么初始化的函数,不像在运算

0x3A924 用了 v9,也就是经过 0x3b9d4 加密后的翻转过的 input

这个函数中间解密了两次字符串,很明显是一个 java 层的函数,至于为什么这里有 JNIEnv 的函数自然是我盲猜之后转换的

不过把 apk 放到 jadx 里之后并没有找到这个函数,猜测是动态加载的

果然在内存中找到了,同样用 gg 把它 dump 下来

用 jadx 可以反编译这个 dex,果然找到了 encrypt 函数

混淆了控制流,不过整体不是很大,还是可以手动还原的,具体还原的时候可以通过和 Smali 代码一起看,因为反编译的字符串有些问题

具体还原的时候用在线 java 弄个 String 就可以取 hashCode 了

这一部分的正向逻辑如下..算了懒得再逆一遍了,直接放逆算法

到此,算法继续回到 libil2cpp 中

先把后面的 Tea 解决了,key 可以通过 hook InitializeArray 或者直接调试都可以拿到

看看最后剩下的

可以先稍微改一下 struct,在 Structures 里面就可以找到

例如这个结构体直接先改成 a1 到 a22,方便观察

ctor 一般是初始化的函数,那么下面那个函数应该就是计算函数

一眼望过去,可以感觉到非常抽象,不过简单梳理一下,把一些什么判断指针为不为空,什么长度有没有太长的删掉,就好看很多了

有点 vm 的意思,一个 while 循环,然后不断从表里拿东西,那么 aa5 就是 eip,aa1 就是 cmd

cmd 在初始化中来源于第二个参数

第二个参数来源于一个 199 的 array,验证了猜想,可以通过动调或者 hook 函数的方式 dump 下来

同时 eip 又是等于 aa7, aa7 是初始化的第 3 个参数,为0

vm 题型里有了指令,还需要解决 handler

ctor 中还有一个函数,似乎设置了一些函数

设置值来源于 OO0OoOOo_oO0OoOOo_TypeInfo.static_fields,通过索引可以看见,是设置为了 1~22

那就可以合理推测这里是设置了 1 ~ 22 对应的函数了

逐个分析,然后通过指令列表回推算法即可,偷懒直接把上次做的粘贴过来

具体推导算法过程我也偷个懒不重复推导了,到此所有算法都出来了,直接贴计算脚本

决赛的放下一篇明天再写

lib\arm64-v8a\libil2cpp.so
lib\arm64-v8a\libil2cpp.so.merged.result
lib\arm64-v8a\libmain.so
lib\arm64-v8a\libsec2023.so
lib\arm64-v8a\libunity.so
lib\arm64-v8a\libil2cpp.so
lib\arm64-v8a\libil2cpp.so.merged.result
lib\arm64-v8a\libmain.so
lib\arm64-v8a\libsec2023.so
lib\arm64-v8a\libunity.so
 
 
Initializing metadata...
Metadata Version: 29
Initializing il2cpp file...
Applying relocations...
WARNING: find .init_proc
ERROR: This file may be protected.
Il2Cpp Version: 29
Detected this may be a dump file.
Input il2cpp dump address or input 0 to force continue:
0
Searching...
CodeRegistration : 0
MetadataRegistration : 0
ERROR: No symbol is detected
ERROR: Can't use auto mode to process file, try manual mode.
Input CodeRegistration:
Initializing metadata...
Metadata Version: 29
Initializing il2cpp file...
Applying relocations...
WARNING: find .init_proc
ERROR: This file may be protected.
Il2Cpp Version: 29
Detected this may be a dump file.
Input il2cpp dump address or input 0 to force continue:
0
Searching...
CodeRegistration : 0
MetadataRegistration : 0
ERROR: No symbol is detected
ERROR: Can't use auto mode to process file, try manual mode.
Input CodeRegistration:
 
 
 
 
 
 
Initializing metadata...
Metadata Version: 29
Initializing il2cpp file...
Applying relocations...
Il2Cpp Version: 29
Detected this may be a dump file.
Input il2cpp dump address or input 0 to force continue:
7ad74c3000
Searching...
CodeRegistration : 7ad85254d0
MetadataRegistration : 7ad856ff38
Dumping...
Done!
Generate struct...
Done!
Generate dummy dll...
Done!
Press any key to exit...
Initializing metadata...
Metadata Version: 29
Initializing il2cpp file...
Applying relocations...
Il2Cpp Version: 29
Detected this may be a dump file.
Input il2cpp dump address or input 0 to force continue:
7ad74c3000
Searching...
CodeRegistration : 7ad85254d0
MetadataRegistration : 7ad856ff38
Dumping...
Done!
Generate struct...
Done!
Generate dummy dll...
Done!
Press any key to exit...
DummyDll
dump.cs
il2cpp.h
script.json
stringliteral.json
DummyDll
dump.cs
il2cpp.h
script.json
stringliteral.json
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
//frida -U -f com.com.sec2023.rocketmouse.mouse -l ./desktop/antidebug.js
function AntiDebug()
{
    var sleep_addr = Module.findExportByName(null, "sleep");
    var sleep = new NativeFunction(sleep_addr, "void",["int"]);
    Interceptor.attach(sleep,
    {
        onEnter: function (args)
        {
            args[0] = ptr(1000000);
            console.log("hooked sleep");
            console.log('sleep called from:\n' + Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n');
        },
        onLeave: function (returnValue)
        {
        }
    })
}AntiDebug();
//frida -U -f com.com.sec2023.rocketmouse.mouse -l ./desktop/antidebug.js
function AntiDebug()
{
    var sleep_addr = Module.findExportByName(null, "sleep");
    var sleep = new NativeFunction(sleep_addr, "void",["int"]);
    Interceptor.attach(sleep,
    {
        onEnter: function (args)
        {
            args[0] = ptr(1000000);
            console.log("hooked sleep");
            console.log('sleep called from:\n' + Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n');
        },
        onLeave: function (returnValue)
        {
        }
    })
}AntiDebug();
hooked sleep
hooked sleep
hooked sleep
sleep called from:
0x7b3c2bc908 libsec2023.so!0x36908
0x7b3c2bc7f8 libsec2023.so!0x367f8
0x7b3c2be708 libsec2023.so!0x38708
0x7b3c2be5a0 libsec2023.so!0x385a0
0x7b3c2bc278 libsec2023.so!0x36278
0x7b3c297f44 libsec2023.so!0x11f44
0x7bd4bd350c libc.so!_ZL15__pthread_startPv+0x44
0x7bd4b73b10 libc.so!__start_thread+0x44
 
sleep called from:
0x7b3c2bc794 libsec2023.so!0x36794
0x7b3c297f44 libsec2023.so!0x11f44
0x7bd4bd350c libc.so!_ZL15__pthread_startPv+0x44
0x7bd4b73b10 libc.so!__start_thread+0x44
 
sleep called from:
0x7b3c2a80a8 libsec2023.so!0x220a8
0x7b3c297f44 libsec2023.so!0x11f44
0x7bd4bd350c libc.so!_ZL15__pthread_startPv+0x44
0x7bd4b73b10 libc.so!__start_thread+0x44
 
hooked sleep
sleep called from:
0x7bd3e16b24 libEGL.so!0x13b24
0x7bd4bd350c libc.so!_ZL15__pthread_startPv+0x44
0x7bd4b73b10 libc.so!__start_thread+0x44
hooked sleep
hooked sleep
hooked sleep
sleep called from:
0x7b3c2bc908 libsec2023.so!0x36908
0x7b3c2bc7f8 libsec2023.so!0x367f8
0x7b3c2be708 libsec2023.so!0x38708
0x7b3c2be5a0 libsec2023.so!0x385a0
0x7b3c2bc278 libsec2023.so!0x36278
0x7b3c297f44 libsec2023.so!0x11f44
0x7bd4bd350c libc.so!_ZL15__pthread_startPv+0x44
0x7bd4b73b10 libc.so!__start_thread+0x44
 
sleep called from:
0x7b3c2bc794 libsec2023.so!0x36794
0x7b3c297f44 libsec2023.so!0x11f44
0x7bd4bd350c libc.so!_ZL15__pthread_startPv+0x44
0x7bd4b73b10 libc.so!__start_thread+0x44
 
sleep called from:
0x7b3c2a80a8 libsec2023.so!0x220a8
0x7b3c297f44 libsec2023.so!0x11f44
0x7bd4bd350c libc.so!_ZL15__pthread_startPv+0x44
0x7bd4b73b10 libc.so!__start_thread+0x44
 
hooked sleep
sleep called from:
0x7bd3e16b24 libEGL.so!0x13b24
0x7bd4bd350c libc.so!_ZL15__pthread_startPv+0x44
0x7bd4b73b10 libc.so!__start_thread+0x44
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
// RVA: 0x4652E4 Offset: 0x4652E4 VA: 0x7AD79282E4
private void CollectCoin(Collider2D coinCollider) { }
// RVA: 0x4652E4 Offset: 0x4652E4 VA: 0x7AD79282E4
private void CollectCoin(Collider2D coinCollider) { }
 
 
function main()
{
    var g_libil2cpp_addr = Module.findBaseAddress("libil2cpp.so");
    var coin_cmp = g_libil2cpp_addr.add(0x4653cc);
    Memory.protect(coin_cmp, 4, "rwx");
    Memory.writeInt(coin_cmp, 0x7100001f);//cmp w0,0
    Memory.protect(coin_cmp, 4, "rx");
}main();
function main()
{
    var g_libil2cpp_addr = Module.findBaseAddress("libil2cpp.so");
    var coin_cmp = g_libil2cpp_addr.add(0x4653cc);
    Memory.protect(coin_cmp, 4, "rwx");
    Memory.writeInt(coin_cmp, 0x7100001f);//cmp w0,0
    Memory.protect(coin_cmp, 4, "rx");
}main();
 
 
 
 
 
public enum SmallKeyboard.KeyboardType // TypeDefIndex: 3310
{
    // Fields
    public int value__; // 0x0
    public const SmallKeyboard.KeyboardType Number = 0;
    public const SmallKeyboard.KeyboardType Character = 1;
    public const SmallKeyboard.KeyboardType EnterKey = 2;
    public const SmallKeyboard.KeyboardType BackSpace = 3;
}
 
public class SmallKeyboard : MonoBehaviour // TypeDefIndex: 3313
{
    // Fields
    public static int KeyboardNum; // 0x0
    public string strInput; // 0x18
    public GameObject inputObj; // 0x20
    public List<SmallKeyboard.iII1i> list; // 0x28
    public GameObject IDObj; // 0x30
    public string oO0o0o0; // 0x38
    public string iIIIi; // 0x40
 
    // Methods
 
    // RVA: 0x465880 Offset: 0x465880 VA: 0x7AD7928880
    private void iI1Ii(SmallKeyboard.iII1i _info) { }
 
    // RVA: 0x465FDC Offset: 0x465FDC VA: 0x7AD7928FDC
    private void iI1Ii(GameObject go) { }
 
    // RVA: 0x465AB0 Offset: 0x465AB0 VA: 0x7AD7928AB0
    private void iI1Ii(ulong i1I) { }
 
    // RVA: 0x465E90 Offset: 0x465E90 VA: 0x7AD7928E90
    private void oO0oOo0() { }
 
    // RVA: 0x466184 Offset: 0x466184 VA: 0x7AD7929184
    private string oO0oOoO() { }
 
    // RVA: 0x46618C Offset: 0x46618C VA: 0x7AD792918C
    private void Start() { }
 
    // RVA: 0x466300 Offset: 0x466300 VA: 0x7AD7929300
    public void .ctor() { }
}
public enum SmallKeyboard.KeyboardType // TypeDefIndex: 3310
{
    // Fields
    public int value__; // 0x0
    public const SmallKeyboard.KeyboardType Number = 0;
    public const SmallKeyboard.KeyboardType Character = 1;
    public const SmallKeyboard.KeyboardType EnterKey = 2;
    public const SmallKeyboard.KeyboardType BackSpace = 3;
}
 
public class SmallKeyboard : MonoBehaviour // TypeDefIndex: 3313
{
    // Fields
    public static int KeyboardNum; // 0x0
    public string strInput; // 0x18
    public GameObject inputObj; // 0x20
    public List<SmallKeyboard.iII1i> list; // 0x28
    public GameObject IDObj; // 0x30
    public string oO0o0o0; // 0x38
    public string iIIIi; // 0x40
 
    // Methods
 
    // RVA: 0x465880 Offset: 0x465880 VA: 0x7AD7928880
    private void iI1Ii(SmallKeyboard.iII1i _info) { }
 
    // RVA: 0x465FDC Offset: 0x465FDC VA: 0x7AD7928FDC
    private void iI1Ii(GameObject go) { }
 
    // RVA: 0x465AB0 Offset: 0x465AB0 VA: 0x7AD7928AB0
    private void iI1Ii(ulong i1I) { }
 
    // RVA: 0x465E90 Offset: 0x465E90 VA: 0x7AD7928E90
    private void oO0oOo0() { }
 
    // RVA: 0x466184 Offset: 0x466184 VA: 0x7AD7929184
    private string oO0oOoO() { }
 
    // RVA: 0x46618C Offset: 0x46618C VA: 0x7AD792918C
    private void Start() { }
 
    // RVA: 0x466300 Offset: 0x466300 VA: 0x7AD7929300
    public void .ctor() { }
}
 
 
 
 
 
 
// RVA: 0x465AB0 Offset: 0x465AB0 VA: 0x7AD7928AB0 = 527602715312
private void iI1Ii(ulong i1I) { }
// RVA: 0x465AB0 Offset: 0x465AB0 VA: 0x7AD7928AB0 = 527602715312
private void iI1Ii(ulong i1I) { }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
if(0<2)
    b10 = off_72C40[0]
else
    b10 = off_72C40[5]
b10 += 0x740078FC;
 
.data:0000000000072C40 08 41 03 8C FF FF FF FF       off_72C40 DCQ 0xFFFFFFFF8C034108
.data:0000000000072C48 30 42 03 8C FF FF FF FF       DCQ 0xFFFFFFFF8C034230
.data:0000000000072C50 38 41 03 8C FF FF FF FF       DCQ 0xFFFFFFFF8C034138
.data:0000000000072C58 78 41 03 8C FF FF FF FF       DCQ 0xFFFFFFFF8C034178
.data:0000000000072C60 E4 41 03 8C FF FF FF FF       DCQ 0xFFFFFFFF8C0341E4
.data:0000000000072C68 54 42 03 8C FF FF FF FF       DCQ 0xFFFFFFFF8C034254
 
0:0xFFFFFFFF8C034108 + 0x740078FC = 0x3BA04
8:0x3BB2C
10:0x3BA34
18:0x3BA74
20:0x3BAE0
28:0x3BB50
if(0<2)
    b10 = off_72C40[0]
else
    b10 = off_72C40[5]
b10 += 0x740078FC;
 
.data:0000000000072C40 08 41 03 8C FF FF FF FF       off_72C40 DCQ 0xFFFFFFFF8C034108
.data:0000000000072C48 30 42 03 8C FF FF FF FF       DCQ 0xFFFFFFFF8C034230
.data:0000000000072C50 38 41 03 8C FF FF FF FF       DCQ 0xFFFFFFFF8C034138
.data:0000000000072C58 78 41 03 8C FF FF FF FF       DCQ 0xFFFFFFFF8C034178
.data:0000000000072C60 E4 41 03 8C FF FF FF FF       DCQ 0xFFFFFFFF8C0341E4
.data:0000000000072C68 54 42 03 8C FF FF FF FF       DCQ 0xFFFFFFFF8C034254
 
0:0xFFFFFFFF8C034108 + 0x740078FC = 0x3BA04
8:0x3BB2C
10:0x3BA34
18:0x3BA74
20:0x3BAE0
28:0x3BB50
 
 
 
 
 
 
void Decode1(unsigned int* flag)
{
    for(int j = 0; j < 2; ++j)
    {
        unsigned int v7 = flag[j];
        //v7 += 0x18100800;
        ((unsigned char *)&v7)[0] += 0x00;
        ((unsigned char *)&v7)[1] += 0x08;
        ((unsigned char *)&v7)[2] += 0x10;
        ((unsigned char *)&v7)[3] += 0x18;
 
        ((unsigned char *)&v7)[3] ^= 0x86;
        ((unsigned char *)&v7)[2] += 94;
        ((unsigned char *)&v7)[1] ^= 0xD3;
        ((unsigned char *)&v7)[0] += 28;
 
        for(int i = 3; i >= 0; --i)
        {
            ((unsigned char*)flag)[j * 4 + i] = (unsigned char)(v7 >> (i * 8)) ^ i;
        }
    }
}

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2023-4-22 20:49 被|_|sher编辑 ,原因:
收藏
免费 11
支持
分享
最新回复 (8)
雪    币: 1360
活跃值: (4473)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
2
前排支持
2023-4-22 01:18
0
雪    币: 116
活跃值: (1012)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
牛逼
2023-4-22 18:34
0
雪    币: 342
活跃值: (440)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
r0k
4
NB 学到了
2023-4-26 09:55
0
雪    币: 377
活跃值: (432)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
5
楼主你好,请教一下,有一个地方我看了很久实在是没有看懂。
“直接十六进制复制粘贴,即 Ctrl+shift+C Ctrl+shift+V,再 F5 刷新”

这里的源数据是从哪里来的呢?要从哪里复制数据到section_header去呢?期待答复,谢谢!
2023-5-24 17:52
0
雪    币: 377
活跃值: (432)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
6
哦,我知道了,从原来的libil2cpp.so里复制section_header到dump出来的bin里。
2023-5-24 19:06
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
师傅我完全不懂so结构,但是通过so_fixer项目是否可行
2023-8-31 15:03
0
雪    币: 6148
活跃值: (4892)
能力值: ( LV10,RANK:160 )
在线值:
发帖
回帖
粉丝
8
mark
2023-9-7 12:27
0
雪    币: 741
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
请问这里,调用到了 sub_7AD887BD64 (libil2cpp.so + 0x13b8d64)是如何找到的呢,索引跟进就可以找到吗
5天前
0
游客
登录 | 注册 方可回帖
返回
//