ss22219 发表于 2018-2-12 07:45

记一次FGO逆向过程 chapter3

本帖最后由 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难度有点大,到这里我已经花了不少时间,已经没有耐心跟他玩了

一切加壳和加密在Dump面前都是纸老虎
                                        ——鲁迅



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

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

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

adb shell
ps

cp /proc/2420/map_files/* ./

其中2420就是fgo的进程id,把这些文件拿出来

如何在内存中查找一个dll文件?

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

找到了好几个dll文件,这里用dnSpy一个个试,发现有一个识别不了

emm...
https://www.perfare.net/1010.html
大香蕉这篇文章中提到如何还原文件

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


程序源代码下面会给出




执行后成功用dnSpy打开

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





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

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

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


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

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

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;
    fread_s(pFileBuffer, length, 1, length, fp);
    char* ppe = pFileBuffer;
    int image_length = 0;
    int buffer_length = length;
    while (true)
    {
      char f;
      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结构被破坏了还是解密完就释放了?
页: [1] 2 3 4 5 6
查看完整版本: 记一次FGO逆向过程 chapter3