h0lad/j2l_tool
GitHub: h0lad/j2l_tool
该工具用于移除或重新设置《Jazz Jackrabbit 2》.j2l 地图文件的密码保护,基于对文件格式和密码哈希机制的逆向分析。
Stars: 0 | Forks: 0
# j2l_tool - Jazz Jackrabbit 2 .j2l 地图密码保护移除工具
## j2l_tool.py
```
j2l_tool - Jazz Jackrabbit 2 .j2l password tool.
j2l_tool.py info password status
j2l_tool.py strip [out] remove password (use - for stdout)
j2l_tool.py set [out] set password
j2l_tool.py hash compute hash
j2l_tool.py coll find colliding password
j2l_tool.py pass show stored hash hex
```
## 描述
### 文件格式
262 字节的头部,随后跟着 4 个 zlib 压缩块 (Data1-4)。
```
offset size field
0x000 180 copyright (ignored)
0x0B4 4 magic "LEVL"
0x0B8 3 password hash (big-endian)
0x0BB 1 hide level (bool)
0x0BC 32 level name (null-terminated)
0x0DC 2 version (0x0202 = 1.23, 0x0203 = TSF)
0x0DE 4 file size
0x0E2 4 crc32 of compressed blocks
0x0E6 4 CData1
0x0EA 4 UData1
0x0EE 4 CData2
0x0F2 4 UData2
0x0F6 4 CData3
0x0FA 4 UData3
0x0FE 4 CData4
0x102 4 UData4
0x106 var Data1 (zlib)
```
### Data1 安全标记
```
offset size field passworded
0x00 2 JCSHorizOffset (unchanged)
0x02 2 Security1 0xBA00
0x04 2 JCSVertOffset (unchanged)
0x06 2 Security2 0xBE00
0x08 1 SecAndLayer upper nibble != 0
0x09 1 MinLight
0x0A 1 StartLight
```
### 密码哈希
得益于 CRC-32 的特性,寻找碰撞非常容易……因此无需暴力破解原始密码。
该表 (RVA 0x4AF9C0) 使用多项式 `0xEDB88320` 构建。
```
hash = crc32(password, seed=0) & 0x00FFFFFF
```
以大端序存储在头部 0xB8 处:
```
byte[0xB8] = (hash >> 16) & 0xFF
byte[0xB9] = (hash >> 8) & 0xFF
byte[0xBA] = hash & 0xFF
```
模式 `0x00BABE` (字节 `BE BA 00`) = 无密码。
### 参考
```
RVA description
0x40C57C cmp [ebx+0x1387a8], 0xBABE
0x40CE79 and eax,0xff; shl eax,8; or eax,edx; shl eax,8; or eax,ecx
0x40CED2 cmp edx, eax
0x429090 crc32(seed, *data, len)
0x4290A8 crc table init
0x474010 case-insensitive strncmp
0x46375E EM_SETPASSWORDCHAR
```
### 密码校验流程
1. 以大端序 24 位整数形式读取 3 字节头部 header[0xB8..0xBA]。
2. 如果 == 0x00BABE:无密码 -> 加载关卡。
3. 解压 Data1,检查 Security1==0xBA00, Security2==0xBE00, SecAndLayer[7:4]!=0。
4. 如果缺少标记:“security envelope damaged” (安全信封已损坏)。
5. 对输入的密码进行哈希处理:`crc32(pw_bytes, 0) & 0xFFFFFF`。
6. 比对:不匹配 -> “password incorrect” (密码错误)。
### 移除保护
1. Header[0xB8..0xBA] = `BE BA 00`。
2. Data1[2:4] = `00 00`。
3. Data1[6:8] = `00 00`。
4. Data1[8] &= 0x0F。
5. 重新压缩 Data1,更新 CData1,重新计算 0xE2 处的 CRC32,更新 0xDE 处的 FileSize。
标签:DOS头擦除, Jazz Jackrabbit 2, Python, 哈希碰撞, 密码破解, 文件解析, 无后门, 游戏工具, 逆向工具