吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 22395|回复: 51
收起左侧

[Android 原创] 记一次FGO逆向过程 chapter3

  [复制链接]
ss22219 发表于 2018-2-12 07:45
本帖最后由 ss22219 于 2018-3-5 16:43 编辑

上一篇中通过源代码对比获取到了mono_image_open_from_data_with_name的地址

但是事情并没有那么简单,mono_image_open_from_data_with_name函数处有大量的db代码
说明这一块代码是处理过的,还原难度很大,想要获取正确的流程,就一定要调试才行

问题又回来了,干掉反调试

通过分析,在dlopen libunity之后程序就退出了,于是分析libunity的init_array段
发现有好几十个函数地址。。。。

不过看到输出窗口处有一个线程被创建了,感觉很可疑
打开debug option,设置thread start/end
发现libNetHtProtect中启动了一个线程,libNetHtProtect什么时候加载的?

查看发现libmono引用了它,linker会在libmono加载前给他分析出来
很明显,这libNetHtProtect应该是反调试的关键了
libmono是个壳,这个壳的导入会先执行libNetHtProtect,这个Protect会创建一个线程去检查是否有调试器

把libNetHtProtect创建的线程全部暂停掉,libunity成功加载
但是分析libNetHtProtect难度有点大,到这里我已经花了不少时间,已经没有耐心跟他玩了

[C] 纯文本查看 复制代码
一切加壳和加密在Dump面前都是纸老虎
                                        ——鲁迅




===========================================================

只要是解密完成了,就一定会在内存中保存有对应的文件

android中/proc/pid/maps记录了进程内存的分布
在/proc/pid/map_files中可以以文件的方式操作这些内存区域

[Shell] 纯文本查看 复制代码
adb shell
ps

cp /proc/2420/map_files/* ./

ps.png
其中2420就是fgo的进程id,把这些文件拿出来
dump.png
如何在内存中查找一个dll文件?

dll文件有DOS头,是一个标准的Nt File,我们可以通过DOS头来搜索内存中的所有dll文件
https://bbs.pediy.com/thread-223649.htm
这篇文章中给出了对应的代码,很好Copy Paste,直接运行没问题

找到了好几个dll文件,这里用dnSpy一个个试,发现有一个识别不了
cannotopen.png
emm...
https://www.perfare.net/1010.html
大香蕉这篇文章中提到如何还原文件

这里我是自己编写了个程序进行还原
fixuotput.png

程序源代码下面会给出
fixheaptables.png
fixntfile.png
fixnumberofSteams.png

执行后成功用dnSpy打开

到这里就成功解密了程序文件
fixsucess.png




===========================================
FGO系列到这里还不会完结,之后还会有游戏代码的分析

这一章内容不多,但其实花了很多时间和精力,翻阅了很多文章与源码

感谢所有愿意分享的人,让我从一个逆向小白走到现在,你们的文章让我有动力继续学习下去


下一章:
https://www.52pojie.cn/thread-698513-1-1.html

上一章:
https://www.52pojie.cn/thread-697414-1-1.html

PE search.zip

3.67 KB, 下载次数: 234, 下载积分: 吾爱币 -1 CB

NET_PE_Fix.zip

229.59 KB, 下载次数: 282, 下载积分: 吾爱币 -1 CB

免费评分

参与人数 13吾爱币 +16 热心值 +13 收起 理由
qaz789a4 + 2 + 1 牛逼
lsz7575 + 1 + 1 谢谢@Thanks!
zycode + 1 + 1 我很赞同!
906790185 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
很快再相见123 + 1 + 1 我很赞同!
冥墨幽 + 1 + 1 你真厉害!
BBB老二 + 1 + 1 我很赞同!
qzr + 1 + 1 你这系列写的真棒
光之子 + 1 + 1 用心讨论,共获提升!
akria00 + 1 + 1 谢谢@Thanks!
jcily + 1 + 1 我很赞同!
我的爱是你 + 1 + 1 我很赞同!
NewsJai + 3 + 1 我很赞同!

查看全部评分

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

hjphy 发表于 2018-3-25 21:58
楼主,今天又出新版本了,原来的修复代码不灵了,有空看看哈
x425326908 发表于 2018-3-18 15:16
大佬,能不能把这个程序发我,谢谢。
https://bbs.pediy.com/thread-223649.htm
char * findDosHeader(char * buffer, int length, int *out_length) {
    char * pe = NULL;
    for (int i = 0; i < length - 0x200; i++) {
        WORD * p = (WORD *)(buffer + i);
        if (*p != IMAGE_DOS_SIGNATURE) {
            continue;
        }
        IMAGE_NT_HEADERS * ntheader = (IMAGE_NT_HEADERS *)(buffer + 0x80 + i);
        if (ntheader->Signature != IMAGE_NT_SIGNATURE){
            continue;
        }
        IMAGE_FILE_HEADER * fileheader = &ntheader->FileHeader;
        if (!(fileheader->Characteristics & IMAGE_FILE_DLL)){
            continue;
        }
        IMAGE_SECTION_HEADER * section = IMAGE_FIRST_SECTION(ntheader);
        int size = 0;
        for (int j = 0; j < fileheader->NumberOfSections; j++) {
            if ((section + j)->SizeOfRawData + (section + j)->PointerToRawData > size) {
                size = (section + j)->SizeOfRawData + (section + j)->PointerToRawData;
            }
        }
        *out_length = size;
        return (buffer + i);
    }
    return NULL;
}

void find(const char * fileName) {
    FILE *fp = NULL;
    fopen_s(&fp, fileName, "rb");
    if (fp == NULL) {
        return;
    }
    fseek(fp, 0L, SEEK_END);
    int length = ftell(fp);
    fseek(fp, 0L, SEEK_SET);

    char * pFileBuffer = new char[length];
    fread_s(pFileBuffer, length, 1, length, fp);
    char* ppe = pFileBuffer;
    int image_length = 0;
    int buffer_length = length;
    while (true)
    {
        char f[512];
        buffer_length -= image_length;
        ppe = findDosHeader(ppe + image_length, length - (ppe - pFileBuffer) - image_length, &image_length);
        if (ppe != NULL) {
            sprintf_s(f, "%s.%x-%x.dll", fileName, ppe, image_length);
            FILE* outfp = 0;
            fopen_s(&outfp, f, "wb+");
            fwrite(ppe, image_length, 1, outfp);
            fclose(outfp);
            printf("%x %x\n", ppe, image_length);
        }
        else{
            break;
        }
    }
     
    delete[] pFileBuffer;
    fclose(fp);
}
秋风君 发表于 2018-2-12 08:55
LightingZero 发表于 2018-2-12 09:52
前排膜拜、学习!不知不觉就到了第三章,个人感觉即使最后不放附件能学到那么多也是值得,感谢dalao分享!
ほむら 发表于 2018-2-12 09:58 来自手机
前来学习,占座
maomao1314 发表于 2018-2-12 11:14
可以,学习了
chenhwei 发表于 2018-2-12 11:57
学习,学习,虽然看不太懂
nohack 发表于 2018-2-12 14:29
我现在也是小白,跟着楼主学习
jzw00101 发表于 2018-2-12 14:29
鲁迅:我没说过这话
 楼主| ss22219 发表于 2018-2-12 14:31
LightingZero 发表于 2018-2-12 09:52
前排膜拜、学习!不知不觉就到了第三章,个人感觉即使最后不放附件能学到那么多也是值得,感谢dalao分享!

能把我的经验传递出去才是最重要的....
aopdnf 发表于 2018-2-12 18:58
问一下dalao dump了少前找不到解密后的assemblyCsharp是因为pe结构被破坏了还是解密完就释放了?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-15 17:21

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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