吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 6890|回复: 46
收起左侧

[原创] 某单机游戏脱壳过程

[复制链接]
少年持剑 发表于 2023-10-25 13:40
本帖最后由 少年持剑 于 2023-10-25 13:44 编辑

网上看到一款单机游戏,发现加了一个未知壳,拿来练练手。
一. 简单分析
PE Tools 查看Sections,可以看到3个.text代码段,第一个.text RawSize和Offset都为0,代码可能被压缩,后两个段可能为外壳代码 负责解压真实代码。

sections

sections


x64 DBG 打开程序在OEP断下,OPE位于第三个.text段,查看第一个.text段,发现数据已经被写入到.text段。说明外壳程序在 TLS回调 时已经解压了第一个 .text段的数据并写入,OEP位于第三个.text段可能后续会对程序进行crc 之类的校验以及反调试。
image.png

二.寻找OEP
使用ESP定律,在rsp-8的位置下断,一直按F9运行。

rsp

rsp

最后真实OEP在第一个.text段位置断下。

OEP

OEP



三.修复IAT 表
使用Scylla 自动搜索IAT。

dump

dump

image.png




发现很多无效的地址,并且都位于外壳程序的.text段,说明外壳程序硬编码了大部分的iat 地址(使用外壳程序函数地址代替导入函数地址,外壳程序函数内会计算得到导入函数地址 进行间接跳转)。


我们已经确定了IAT的位置,可以尝试使用Unicorn 跑出真实的导入函数地址。
[C++] 纯文本查看 复制代码
DWORD64 runAndGetAddr(uc_engine* uc, DWORD64 beginAddr)
{
    DWORD64 r_rip;
    uc_emu_start(uc, beginAddr, 0, 0, 0);
    uc_reg_read(uc, UC_X86_REG_RIP, &r_rip);
    return r_rip;
}


void dealIat(HANDLE hProc, LPVOID exeMem)
{
    if (g_uc)
    {
        DWORD64 startIatAddr = 0x000000141489000;
        DWORD64 endIatAddr = 0x0000000141489840;

        DWORD64 tempRead;
        while (startIatAddr < endIatAddr )
        {
            ReadProcessMemory(hProc, (LPVOID)startIatAddr , &tempRead, 8, NULL);
            if (tempRead)
                tempRead = runAndGetAddr(g_uc, tempRead);

            printf("%p:%p\n", startIatAddr , tempRead);

            if (tempRead)
            {
                WriteProcessMemory(hProc, (LPVOID)startIatAddr , &tempRead, 8, NULL);
            }

startIatAddr += 8;
        }

    }
}


当从外壳程序执行到导入函数时,因为导入函数没有在unicorn 中map,所以会异常退出,得到导入函数地址。

DealIat

DealIat


此时在使用Scylla 自动搜索IAT,可以得到完整的IAT。

IAT

IAT


四. dump 镜像
获取iat之后在Dump和Fix Dump 就可以得到脱壳后的程序了。




免费评分

参与人数 16威望 +1 吾爱币 +36 热心值 +15 收起 理由
笙若 + 1 + 1 谢谢@Thanks!
ohssr + 1 + 1 谢谢@Thanks!
wheatmaizi + 1 + 1 热心回复!
ManaCola + 1 + 1 热心回复!
Hmily + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Hcj665766 + 1 + 1 谢谢@Thanks!
plasd + 1 + 1 用心讨论,共获提升!
SysEntry + 1 + 1 用心讨论,共获提升!
walt666 + 1 + 1 我很赞同!
16316 + 1 谢谢@Thanks!
chinawolf2000 + 1 + 1 热心回复!
董督秀 + 2 + 1 谢谢@Thanks!
156608225 + 1 + 1 用心讨论,共获提升!
朱朱你堕落了 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
limit7 + 1 + 1 用心讨论,共获提升!
杨辣子 + 1 + 1 谢谢@Thanks!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Hmily 发表于 2023-10-25 17:54
期待补充一下Unicorn的实现过程~
lies2014 发表于 2023-11-2 17:49
jiangjobs 发表于 2023-10-30 18:58
"可以尝试使用Unicorn 跑出真实的导入函数地址。"  针对这段话下面的代码, 我尝试运行了一下, 有很多报错,  ...

你直接运行肯定出错啊,要先运行游戏,并根据内存中 IAT 的地址修改 startIatAddr 和 endIatAddr 才能跑起来的。不过看样子楼主不想公布游戏名称,你可以找类似的壳练练手,或先学习思路,修复一些被壳改掉的 IAT 也会用得着的。
朱朱你堕落了 发表于 2023-10-25 16:46
我们已经确定了IAT的位置,可以尝试使用Unicorn 跑出真实的导入函数地址。

弱弱的问下楼主,Unicorn是个什么东西?
dgw1022 发表于 2023-10-25 18:15
大神太6了
slslsl 发表于 2023-10-25 18:17
搜了一下,大概是UnicornVM模拟执行框架?
 楼主| 少年持剑 发表于 2023-10-25 18:50
朱朱你堕落了 发表于 2023-10-25 16:46
我们已经确定了IAT的位置,可以尝试使用Unicorn 跑出真实的导入函数地址。

弱弱的问下楼主,Unicorn是个 ...

unicorn 是一个模拟执行软件,给一段汇编可以模拟执行得到输出结果。
https://github.com/unicorn-engine/unicorn
migntu997 发表于 2023-10-25 19:37

大牛了 大神
大白菜明媚太阳 发表于 2023-10-25 20:13
好久没有学习了,我连ESP定律都忘记了。感谢大牛分析的思路
hhw1999 发表于 2023-10-25 20:40
不懂就问,我连脱壳后和脱壳前有什么区别都不知道
gksj 发表于 2023-10-25 21:24
hhw1999 发表于 2023-10-25 20:40
不懂就问,我连脱壳后和脱壳前有什么区别都不知道

这就像一个女人,穿着衣服和没穿衣服的区别
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-22 16:32

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表