michei69/waze-stuff
GitHub: michei69/waze-stuff
该项目通过逆向解析 Waze 的切片地图文件格式并搭建模拟服务器,使自定义地图数据(如 ETS2 游戏地图)能够在 Waze 应用中加载显示。
Stars: 1 | Forks: 0
# OwO 这是什么? :3
一个关于 [waze](https://www.waze.com/) 切片地图格式的逆向工程项目
更具体地说,是一些帮助使用 geojson 解析并为 waze 创建新切片的脚本(主要目标是将 Waze 引入 ETS2)
注意:对文件格式本身的理解基本已经完成。规范的解析仍在进行中(WIP),而新切片的创建甚至还没开始(因为我太懒了,而且缺乏所需的数据)
# 结w构 :P
- `/hexpats` 包含 hexpat 文件,用于在 [ImHex](https://imhex.werwolv.net/) 等应用中理解 waze 切片文件
- `/protos` 包含 waze 使用的 protobuf 文件(用于正确伪造服务器)
- `/scripts` 包含关于处理 waze 切片文件(WZM/MAP_PKG/RDM、WZDF、WZT)的 python 脚本
- `/src` 包含与服务器相关的 TS 代码。还包含一些测试和中间脚本
- `/lib` 包含一些为了速度而用 C 重写的实用 python 脚本
# 我该怎么用这个? >w<
- 使用 [truckermudgeon 出色的地图解析器/生成器](https://github.com/truckermudgeon/maps) 生成一个 geojson 文件
- 将其放入 `/src/scaleGeoJSON.ts` 中进行缩小比例(ETS2 使用的是 1:19 比例的地图)
- 运行 `/src/parseGeoJSON.ts`(或 `/lib/build/geojson-parser`)来生成一个表示要转换为 waze 切片数据的 json 文件
- 然后你可以选择
- 运行 `/src/index.ts` 让它动态生成切片
- 运行 `/src/generate_tiles.py` 让它提前生成切片
- 运行 `/lib/build/json-to-wzdf` 让它快速提前生成切片
- 注意,切片在应用接收后通常会被缓存,所以动态生成并不慢
# 状态? :o
### waze 服务器
- [x] 提供初始登录服务
- [x] 提供切片
- [ ] 处理警报数据
- [ ] 处理信标数据
- [ ] 处理搜索
- [ ] 处理路线
- [ ] 处理更多功能
### waze 切片逆向进度
- [x] map packages 分离
- [x] 解压 waze 数据文件(WZDF)
- [x] 解析 wzt
- [x] 条目计数
- [x] 掩码位(部分?)
- [x] 偏移量
- [x] 字符串数组
- [x] 形状数据
- [x] 线段数据
- [x] 线段摘要
- [x] 断裂线段
- [x] 线段环岛
- [x] 点数据
- [x] 点 ID
- [x] 线段路线
- [x] from_flags(a_to_b)
- [x] to_flags(b_to_a)
- [x] from_turn_res(b_to_a_turn_restrictions)
- [x] to_turn_res(a_to_b_turn_restrictions)
- [x] 街道名称
- [x] 街道城市
- [x] 多边形头部
- [x] first_polygon_point_idx
- [x] polygon_point_count
- [x] 名称
- [x] cfcc
- [x] 北
- [x] 西
- [x] 东
- [x] 南
- [x] 多边形点
- [x] 线段引用
- [x] 线段平均速度
- [x] 线段速度 ID
- [x] 线段速度 ID small
- [x] 范围
- [x] 警报数据(部分?)
- [x] 正方形数据
- [x] 元数据属性
- [x] 场所头部(部分?)
- [x] 场所 ID
- [x] 线段扩展类型
- [x] 线段扩展 ID
- [x] 按线段划分的线段扩展级别
- [x] 线段扩展级别
- [x] 线段最大速度
- [x] 多边形扩展
- [ ] 线段属性
- [x] byte 0(flags)
- [ ] byte 1
- [ ] byte 2
- [ ] byte 3
- [x] 街道 ID
- [x] 信标位置(未使用)
- [x] 信标 ID(未使用)
- [x] 信标扩展位置(未使用)
- [x] 信标扩展 ID(未使用)
- [x] 信标扩展掩码(未使用)
- [x] 车道类型
- [x] 线段新类型
- [x] 扩展 protobuf 数据
- [x] 根据自有数据创建新切片(部分)
# 我有w问题!
### 为什么需要一个单独的脚本来解析 geojson?
- python 在解析 json 和遍历对象时慢得离谱
- 这个 C 程序可能甚至比 TS 版本还要快,也许吧
### 为什么使用 python、TS 和 C?
- python 足够简单,适合用于解析二进制文件本身(尽管我确实计划“最终”编写一个 rust 库,一旦我完全理解了该格式),但对于大多数操作来说太慢了
- typescript 是我已经非常熟悉的东西,但我不想处理 `Uint8Array`,相信我。
- C 很快,我可以直接访问原始内存。我也想要一点挑战,所以我选择了它而不是 c++
### 用 python 脚本手动生成切片看起来很慢!
- 只是因为我还没来得及创建服务器-客户端的方法,所以由 `parseGeoJSON.ts` 生成的巨大的 json 文件需要很长时间来处理,并且每个切片都要重新处理。将其乘以 20 倍(因为默认情况下一个 map_pkg 请求中就有这么多切片),就是这样
- 尝试使用 C 程序提前生成切片
### `AA_test.ts` 和 `redirector_test.ts` 到底是怎么回事???
- 我最初想使用 [ETS2LA 的](https://github.com/ETS2LA/Euro-Truck-Simulator-2-Lane-Assist) 导航 sockets,但由于某种原因它们在我的机器上无法运行,所以我直接修改了导航 sockets,改为使用 http posts 发送到硬编码的链接,哈哈
- `AA_test.ts` 使用 [Google 的 DHU](https://developer.android.com/training/cars/testing/dhu) 自动加载 android auto,(几乎)启用了所有传感器,并通过车机本身设置位置
- `redirector_test.ts` 使用了我花 2 分钟制作的一个自定义应用,它使用 TCP socket 发送位置数据,并直接在设备上模拟位置
### 我到底怎么把我的 waze 连到你的东西上
- 使用像 [httptoolkit](https://httptoolkit.com/) 这样的工具,将 `rt.waze.com`、`rt-xlb-row.waze.com`、`gapi.waze.com` 和 `ctilesgcs-row.waze.com` 重定向到你的服务器
- 在 root 和非 root 设备上都可以使用,因为你可以轻松地[将证书设置东西](https://httptoolkit.com/docs/guides/android/#intercepting-traffic-from-your-own-android-app)添加到 waze 中,幸好它不使用 pairip(谢天谢地 :pray:)
- 如果你愿意,你也可以直接在应用源代码中将 `rt.waze.com` 和其他 url 替换为你自己的服务器
### 我的 waze 这样做时崩溃了 / 说我没有网络连接
- 重启应用,直到它愿意工作为止
- 仍然不确定这是我的服务器实现(`index.ts`)还是 HTTPToolkit 的问题
- 你也可以尝试多清除几次存储,这确实有点随机
### 做 X 行得通吗??
- 查看[状态](#statuwus-o)
# 关于 WZT 的额外数据 UwU
形状数据真他妈奇怪。所以,它存在于一个类似这样的 struct 中:
```
struct shape {
ushort dx;
ushort dy;
}
```
问题在于,`shapes[line.shape_idx]` 实际上是一个“标记形状”(基本上,dx 总是为 0,而 dy 表示后续形状的数量)。
| id | data |
|----|------------------------------|
| 1 | freeway |
| 2 | major highway |
| 3 | minor highway / boulevard |
| 4 | ramp |
| 5 | primary street |
| 6 | passage way(?) |
| 7 | street |
| 8 | non-routable pedestrian path |
| 9 | dirt path |
| 10 | routable pedestrian path |
| 11 | stairway |
| 12 | railway |
| 13 | runway / taxiway |
| 14 | ferry |
| 15 | private road |
| 16 | parking lot road |
注意:由于某种莫名其妙的原因,编辑器 ID 与 waze 内部 ID 并不匹配,所以不要试图从 web 编辑器获取它们。用这些
| cfcc | polygon category |
|------|-------------------------------|
| 12 | land |
| 15 | building / venue |
| 16 | city / tile (the entire tile) |
| 20 | water |
注意:多边形类别可能不止这些
| offset | string usage |
|--------|--------------------|
| 0 | street type |
| 1 | street base name |
| 2 | |
| 3 | street prefix name |
| 4 | street suffix name |
| 5 | city name |
| 6 | metadata |
| 7 | venue name |
| id | alert type |
|----|-----------------|
| 2 | speed cam |
| 3 | dummy speed cam |
| 4 | red light cam |
| 5 | |
注意:这些警报类型是从旧代码中获取的,可能并不正确
一个切片的大小为 10000x10000,代表 0.01x0.01(纬度 x 经度)。它的 (0,0) 位置位于左下角
tile_id 是通过一个简单的公式根据纬度、经度和比例尺计算的。查看脚本来了解具体方法(我太懒了,不想复制粘贴)
不知道为什么街道在地图上看起来比平时更细,但这也可能是因为它们缺少大部分数据,哈哈
路由看起来光是想想要开始就让人头疼。查看 [UserDriveV2.proto](./protos/v2/UserDriveV2.proto)(StartNavigationInfo),试着去理解它吧,笑死。我的意思是,它并不难理解,但我的天,似乎需要大量的计算……我最终™ 会做的
ext protobuf 注册在 native code 中,所以不是那么容易提取,但它也“主要”基于 proto 文件。我见过的一个 ext protobuf 是:
```
{
3 = MapFeature {
1 = id (int64)
12 = { // some kind of polygon
1 = repeated Coordinate // polygon lonlat
2 = string // polygon text
3 = varint // cfcc
}
}
}
```
# 截图!


# 非常感谢 <3
- [waze](https://waze.com/) 首先感谢它的存在
- [truckermudgeon](https://github.com/truckermudgeon) 感谢他可爱的地图生成脚本
- [mkoloberdin](https://github.com/mkoloberdin) 感谢他保留了 waze 旧源代码的克隆
标签:GPS导航, 云资产清单, 协议分析, 地图解析, 地理信息系统, 客户端加密, 数据转换, 权限提升, 游戏Mod, 逆向工具, 逆向工程