吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 16287|回复: 19
收起左侧

[调试逆向] tcj小分析1

[复制链接]
fyc132 发表于 2018-9-26 15:03
本帖最后由 fyc132 于 2018-9-26 18:49 编辑

0x1:   某反外挂一直在打开文件我们对ReadFile 下一个断点,很快就命中了
1.png
查看下调用者发现是在 tcj 读取的大小是PAGE_SIZE * 10
2.png
对读入的数据下一个硬件断点
3.png
看了栈实际上TCJ 读完文件就直接进来了IDA 分析下这个函数
4.png   
分析它的子函数可以很容易看到,这就是一个 MD5 的函数
5.png
看下 TCJ 循环READFILE 的逻辑
6.png
实际上就是循环读取文件内容,每次 PAGE_SIZE * 10 大小,得到最终的MD5 值放到参数中
7.png
8.png
9.png
我们接着看 TCJ得到了文件的MD5 后要继续做了什么如果成功得到了文件的MD5 ,那么就进入了第二个函数
10.png
11.png
该函数逻辑如下,其作用是获取整个文件的 murmur哈希值和文件大小
12.png
名单最终我们得到了 2 个值
13.png

  那么,程序已经获取了目标程序的 MD5 值,HASH值,和文件大小。接着
14.png
作为参数调用。 IDA 回顾下之前的逻辑值得一提的是,在以后操作都完成后,释放才会文件句柄
15.png
我们接着分析 HandleFileHash,对输入的MD5 参数下一个硬件断点
16.png
发现断在了这个地方。回溯往上
17.png       
  第二次中中断发现在比较 MD5 的值
18.png   
可以得出这段代码是先把 MD5 归类成一个ID ,然后在一个链表中查找相同ID 的数据这样做的目的是加速搜索
19.png       
观察它的结构,发现已经存在于数据库中了,看来这个数据库存放的都是 TCJ 扫描过的所有文件的信息。
20.png   
接着,我们回到上一个地方,发现它查找到对应的数据库后,就会判断数据库中的 + 0×11字段是否匹配,如果匹配就修改8 为当前的时间
21.png
     这里的英文查找到 MD5
22.png
而且有趣的的是,不止一个 MD5 数据库,还有一个hash数据库
23.png
24.png
从这 2 个不同的地方,我们就可以知道,有2 搜索方式1. 搜索方式为 md5 的时候先获取md5 的桶ID ,再(object+ 0x60)的一个数组索引对应桶ID 的链表 下面我们接着看搜索方式为 hash 和大小的时候,
25.png
MD5 搜索类似,给hash计算桶INDEX,再算表。不过是另外一个表,以下我简称这2 个表一个为HASH快查表,一个MD5 快查表。这个函数是搜索的对应的表,不过对应的表又指向相同的数据库。
MD5 快查表的一项
26.png
HASH查表快的一项
27.png
数据库
28.png
既然知道,这里放着的是 TCJ 扫描过后的缓存,那么如果数据库中没有我们的记录,肯定是会插入的,往上继续回溯
29.png
如果没有找到对应的数据库,那么就调用 add_cache_list 添加到2 个表中去。
30.png
通过调用参数,我们可以确定最终的数据库结构和对应的大小了0×28
31.png
分析了这么多,我们写一个程序 DUMP 一下这2 份表吧
   32.png
   33.png
34.png
35.png
[C++] 纯文本查看 复制代码
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <windows.h>
#include <cstdio>
 
#pragma pack(1)
struct SFileSig
{
  DWORD murmur_hash;
  DWORD file_size;
  DWORD64 time;
  BYTE level;
  BYTE id;
  DWORD md5[4];
};
#pragma pack()
 
 
struct SMd5Item
{
  SMd5Item* p1;
  SMd5Item* p2;
  DWORD md5[4];
  SFileSig* database;
};
 
struct SHashItem
{
  SHashItem* p1;
  SHashItem* p2;
  DWORD murmur_hash;
  DWORD file_size;
  SFileSig* database;
};
 
struct STableMd5
{
  DWORD p1;
  SMd5Item* list;
};
 
 
struct STableHash
{
  DWORD p1;
  SHashItem* list;
};
 
void DumpDatabase(const SFileSig* sig) {
  printf("----------------------------\n");
  printf("murmur_hash:%08X\n", sig->murmur_hash);
  printf("file_size:%08X\n", sig->file_size);
  printf("update-time:%lu\n", sig->time);
  printf("level:%02X\n", sig->level);
  printf("id:%02x\n", sig->id);
  printf("md5:%08X%08X%08X%08X\n", sig->md5[0], sig->md5[1], sig->md5[2], sig->md5[3]);
  printf("-------------------------\n");
}
 
int __stdcall DllMain(_In_ void* _DllHandle, _In_ unsigned long _Reason, _In_opt_ void* _Reserved) {
  if (_Reason == DLL_PROCESS_ATTACH) {
 
    const auto md5_fast_list = reinterpret_cast<STableMd5 *>(0x0C23BC60);
    for (int index = 0; index < 0x201; index++) {
      if (md5_fast_list[index].list) {
        for (auto iter = md5_fast_list[index].list; ; iter = iter->p1) {
          if (iter->database == nullptr || iter->md5[0] == 0)break;  
          printf("[FastMd5List]md5:%08X%08X%08X%08X\n", iter->md5[0], iter->md5[1], iter->md5[2],
                 iter->md5[3]);
          DumpDatabase(iter->database);
          if (iter->p1 == md5_fast_list[index].list) break;
        }
      }
    }
    const auto hash_fast_list = reinterpret_cast<STableHash *>(0x0C23E488);
    for (int index = 0; index < 0x201; index++) {
      if (hash_fast_list[index].list) {
        for (auto iter = hash_fast_list[index].list; ; iter = iter->p1) {
          if (iter->p1 == hash_fast_list[index].list)
            break;
          printf("[FastHashList]hash:%08X ,file size:%08x\n", iter->murmur_hash, iter->file_size);
          DumpDatabase(iter->database);
          
        }
      }
    }
  }
  return 0;
}

   那么tcj维护这个大表做什么呢
36.png
37.png
欲知后事如何

免费评分

参与人数 8威望 +1 吾爱币 +18 热心值 +8 收起 理由
L4Nce + 1 + 10 + 1 期待下文
姚小宝 + 1 + 1 热心回复!
wnnydgl + 1 + 1 新手表示不知道TCJ是什么。。。反外挂还能让OD下断点啊...
xinkui + 1 + 1 谢谢@Thanks!
demoscene + 2 + 1 你为何这么屌,连什么murmur,数据结构都逆出来了
lookerJ + 1 + 1 用心讨论,共获提升!
ycsyywl + 1 + 1 大佬教我们继续
Dispa1r + 1 + 1 谢谢@Thanks!

查看全部评分

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

azZL 发表于 2018-11-15 10:39
楼主,能不能详细些,我都不知道你IDA分析的是哪部分函数而且所分析的函数贴图还不全,看的摸不到头脑
头像被屏蔽
詠恒ぃ☆吣 发表于 2018-9-26 16:24
ycsyywl 发表于 2018-9-26 18:00
644100706 发表于 2018-9-26 18:25
腾讯微安全 对这个帖子表示非常感兴趣。
流水Zzz 发表于 2018-9-27 01:36
大佬啊 !!
头像被屏蔽
yangyuejia 发表于 2018-9-27 09:56
提示: 作者被禁止或删除 内容自动屏蔽
丿颠覆灬虎哥 发表于 2018-9-27 18:47
个个都是大牛,羡慕
gongyong728125 发表于 2018-9-28 09:57
看看学习下!
baby 发表于 2018-9-28 11:15
单行 你好 单行 再见
52896009 发表于 2018-9-28 12:44
这个有点意思~~~先回帖插个眼再仔细看看~~
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2025-4-12 10:48

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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