数据库逆向工程(三)
字数 1799 2025-08-18 11:36:53
数据库逆向工程(三):代码复用与图像解压技术详解
1. 数据库逆向工程回顾
在第二部分中,我们研究了Microcat Ford USA数据库的内部机制,重点分析了代表车辆和车辆部件的通用数据结构。本部分将聚焦于零件图的逆向分析,这是该数据库研究的最后一个关键组件。
1.1 数据结构依赖关系
- MCData.idx:代表零件树的索引文件
- MCData.dat:包含车辆零件数据
- MCImage[2].dat:包含车辆零件图,通过
image_offset和image_size字段与索引关联
2. 图像存储格式分析
2.1 图像文件初步检查
- 图像开头部分显示非标准格式特征
- 没有明显的幻数(magic numbers)
- 存在大量零值和重复字节,表明可能是压缩格式
- 每个图像都有独特的标题结构
2.2 图像格式特性
- 标题结构:每个图像都有独特的标题部分
- 压缩特征:中间部分显示明显的压缩特征
- 无标准标识:缺乏常见的图像格式标识符
3. 逆向工程方法
3.1 调试工具选择
由于目标程序是16位NE格式,调试工具选择至关重要:
| 调试工具 | 适用性评估 |
|---|---|
| WinDbg | 最佳选择,支持NE模块调试 |
| OllyDbg 1/2 | 通过NTVDM间接调试,16位代码断点会异常 |
| x64dbg | 不支持NE格式 |
| Open Watcom/Insight Debugger | 因自加载功能无法启动目标程序 |
3.2 调试策略
-
WinAPI断点设置:重点关注以下BMP相关函数:
CreateBitmapCreateBitmapIndirectCreateCompatibleBitmapCreateDIBitmapCreateDIBSectionLoadBitmap
-
内存布局分析:
- 16位模块加载在0x10000到0xA0000地址范围
- 类似于实模式内存布局
-
函数定位技术:
- 通过函数前导字节序列搜索目标函数
- 示例搜索模式:
8b F8 83 3e 08 1f 00 74 2c 83 7e fa 00 74 15 ff
3.3 关键发现
- 图像处理主要发生在两个库中:
- VBRUN300.dll:Visual Basic运行时库
- FNAUTIL2.dll:包含核心图像处理函数
4. 图像解压算法分析
4.1 解压流程
- 读取压缩数据:从MCImage.dat中读取指定偏移和大小的数据
- 调用解压函数:
READ_AND_UNPACK_IMAGE(内部实现仍为黑盒) - 尺寸调整:根据
screen_height和screen_width调整解压后图像 - 调色板处理:通过
get_palette_handle创建调色板 - 位图创建:使用
CreateDIBitmap创建最终位图 - 资源释放:释放解压使用的临时内存
4.2 函数接口
HBITMAP decrypt_image(char* mcimage_path,
unsigned long enc_image_offset,
unsigned long enc_image_size)
5. 代码复用实现
5.1 开发环境
- 编译器:Open Watcom C(16位兼容)
- 目标平台:16位Windows环境
5.2 核心数据结构
typedef struct {
long unk_1;
long unk_2;
int unk_3;
int mcimage;
} ImageFileData;
5.3 位图保存实现
int save_bitmap(HBITMAP bitmap, char* dec_image_path)
{
// 1. 获取设备上下文
HDC dc = GetDC(NULL);
// 2. 分配BITMAPINFO结构内存
unsigned lpbi_size = 256*4 + sizeof(BITMAPINFOHEADER);
BITMAPINFO* lpbi = (BITMAPINFO*)calloc(1, lpbi_size);
// 3. 初始化BITMAPINFOHEADER
lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lpbi->bmiHeader.biPlanes = 1;
// 4. 获取位图信息
ret_val = GetDIBits(dc, bitmap, 0, 0, NULL, lpbi, DIB_RGB_COLORS);
// 5. 分配位图数据内存
void __huge* bits = halloc(lpbi->bmiHeader.biSizeImage, 1);
// 6. 获取位图数据
ret_val = GetDIBits(dc, bitmap, 0, (WORD)lpbi->bmiHeader.biHeight,
bits, lpbi, DIB_RGB_COLORS);
// 7. 创建输出文件
int dec_image;
_dos_creat(dec_image_path, _A_NORMAL, &dec_image);
// 8. 写入文件头
BITMAPFILEHEADER file_header = {0};
file_header.bfType = 0x4D42; // "BM"
file_header.bfSize = sizeof(BITMAPFILEHEADER) + lpbi_size +
lpbi->bmiHeader.biSizeImage;
file_header.bfOffBits = sizeof(BITMAPFILEHEADER) + lpbi_size;
_dos_write(dec_image, &file_header, sizeof(BITMAPFILEHEADER), &bytes_written);
// 9. 分块写入位图数据(处理>64KB情况)
DWORD i = 0;
while(i < lpbi->bmiHeader.biSizeImage) {
WORD block_size = 0x8000;
if(lpbi->bmiHeader.biSizeImage - i < 0x8000) {
block_size = (WORD)(lpbi->bmiHeader.biSizeImage - i);
}
_dos_write(dec_image, (BYTE __huge*)bits + i, block_size, &bytes_written);
i += block_size;
}
// 10. 释放资源
_dos_close(dec_image);
hfree(bits);
free(lpbi);
return 1;
}
6. 未来研究方向
-
自动化逆向分析工具:
- 实现启发式算法重构表、记录和字段
- 交互式界面允许用户修正和补充数据结构
- 正反馈系统,基于已知结构推断其他结构
-
交叉引用研究自动化:
- 开发启发式算法识别偏移量指针
- 自动扩展数据库文件格式知识库
-
方法论扩展:
- 探索更多数据库逆向工程方法
- 建立标准化逆向工程流程
-
公共资源建设:
- 贡献逆向工程文件格式描述
- 参与维护格式库(如Kaitai Struct格式库)
7. 关键知识点总结
-
16位调试技术:
- NE格式模块的特殊性
- 自加载功能的影响
- 实模式内存布局
-
图像处理逆向:
- 通过API调用追踪定位关键函数
- 压缩图像格式的特征识别
- 调色板处理机制
-
代码复用策略:
- 16位兼容代码编写
- 大内存处理技术(halloc/huge指针)
- DOS文件操作限制的规避
-
逆向工程方法论:
- 从黑盒到白盒的渐进分析
- 通过行为分析推断内部实现
- 最小化假设验证技术
8. 参考资料
- Bitmap Functions - MSDN
- Reversing a 16-bit NE File Part 1
- Kaitai Struct格式库