吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 708|回复: 4
收起左侧

[讨论] IDR导出map 导入ida9.2 脚本修改。已修正脚本代码(Delphi)

[复制链接]
weiguang2345 发表于 2026-3-20 11:34
帖子idr导出map 导入ida9.1 脚本问题。已修正脚本代码 - 吾爱破解 - 52pojie.cn
分析 Delphi 编译的文件
其中 BASE_ADJUSTMENT 的注释有点问题,测试了正常使用的情况(即dump在ope),给出对 BASE_ADJUSTMENT 的新注释
已测试在IDA9.2中完美运行
非dump在ope的情况需要修改 BASE_ADJUSTMENT ,注释中也备注的比较清除

[Python] 纯文本查看 复制代码
import os
import sys
import random
from idautils import *
from idaapi import *
import idc
import ida_name
import ida_funcs
import ida_nalt

# ---------------------- 配置部分 ----------------------
MAP_FILE_PATH = r"D:\learning\ida9.2\loadmap\41f718bcac1fed649693943444547f7e975a869273f21c107ecc035f68dac275.map"  # 替换为你的.map文件路径
IMAGE_BASE = ida_nalt.get_imagebase()

# BASE_ADJUSTMENT: 将.map文件中的"段:偏移"地址转换为 IDA 实际地址的偏移量
# 比如对于 MAP 文件中的一行, parse_borland_symbol_line 函数修正地址
# 0001:00000060 system.kernel32.CloseHandle_00401060
# 由于存在 CloseHandle_00401060 ,会直接使用00401060地址,可以不用设置 BASE_ADJUSTMENT
# 如果不存在 CloseHandle_00401060 ,会使用0001:00000060计算地址 再加上 BASE_ADJUSTMENT
# 即 0001 << 4 + 00000060 = 00001060
# 但实际地址为 401060 ,所以此时 BASE_ADJUSTMENT 就是 IDA 的 IMAGE_BASE
# 大部分情况下设置为 IMAGE_BASE 即可

BASE_ADJUSTMENT = IMAGE_BASE  # 特殊情况手动设置
# ----------------------------------------------------


def parse_borland_symbol_line(line, symbols_addresses):
    """解析Borland格式的.map文件行(修正地址计算)"""
    line = line.strip()
    if (
        not line
        or ":" not in line
        or any(x in line for x in ["Start", "Address", "Program entry"])
    ):
        return symbols_addresses

    try:
        parts = line.split()
        seg_offset = parts[0]
        seg, offset = seg_offset.split(":")

        # 优先从符号名中提取完整地址(如 `Finalization_711A4A70` -> 0x711A4A70)
        if "_" in parts[-1]:
            full_addr_str = parts[-1].split("_")[-1]
            if (
                full_addr_str.isalnum() and len(full_addr_str) == 8
            ):  # 检查是否为8位十六进制
                linear_addr = int(full_addr_str, 16)
                symbol_name = parts[-1]
                symbols_addresses[linear_addr] = symbol_name
                print(f"[DEBUG] 直接映射符号: 0x{linear_addr:08X} -> {symbol_name}")
                return symbols_addresses

        # 回退到段:偏移计算(需确保BASE_ADJUSTMENT正确)
        linear_addr = (int(seg, 16) << 4) + int(offset, 16) + BASE_ADJUSTMENT
        symbol_name = parts[-1]
        symbols_addresses[linear_addr] = symbol_name
        print(f"[DEBUG] 计算映射符号: 0x{linear_addr:08X} -> {symbol_name}")

    except Exception as e:
        print(f"[WARN] 跳过无效行: {line} (错误: {str(e)})")

    return symbols_addresses


def is_name_used(name, exclude_ea=idc.BADADDR):
    """检查名称是否已被使用"""
    for ea, current_name in Names():
        if current_name == name and ea != exclude_ea:
            return True
    return False


def safe_rename(ea, new_name):
    """安全重命名函数(处理冲突和异常)"""
    try:
        # 清理旧名称(使用 SN_FORCE 而不是 SN_DELTAIL)
        ida_name.set_name(ea, "", ida_name.SN_FORCE | ida_name.SN_NOWARN)

        # 处理名称冲突
        final_name = new_name
        if is_name_used(new_name, ea):
            final_name = f"{new_name}_{ea:08X}"
            print(f"[NOTE] 名称冲突处理: {new_name} -> {final_name}")

        # 强制重命名
        if ida_name.set_name(ea, final_name, ida_name.SN_FORCE | ida_name.SN_NOWARN):
            print(f"[SUCCESS] 重命名 0x{ea:08X}: {final_name}")
            return True
        else:
            # 回退方案:添加随机后缀
            random_suffix = random.randint(0, 999)
            fallback_name = f"{final_name}_{random_suffix:03d}"
            if ida_name.set_name(
                ea, fallback_name, ida_name.SN_FORCE | ida_name.SN_NOWARN
            ):
                print(f"[RETRY] 重命名回退: 0x{ea:08X} -> {fallback_name}")
                return True
            else:
                print(f"[ERROR] 无法重命名 0x{ea:08X}(包括回退方案)")
                return False

    except Exception as e:
        print(f"[ERROR] 重命名失败 @ 0x{ea:08X}: {str(e)}")
        return False


# ---------------------- 主逻辑 ----------------------
print("=" * 60)
print(f"正在加载MAP文件: {MAP_FILE_PATH}")
print(f"IDA基址: 0x{IMAGE_BASE:08X}, 调整值: 0x{BASE_ADJUSTMENT:08X}")
print("=" * 60)

# 1. 加载MAP文件
all_symbols = {}
if not os.path.exists(MAP_FILE_PATH):
    print(f"[ERROR] 文件不存在: {MAP_FILE_PATH}")
    sys.exit(1)
else:
    try:
        with open(MAP_FILE_PATH, "r") as f:
            in_publics = False
            for line in f:
                if "Address Publics by Value" in line:
                    in_publics = True
                    continue
                if in_publics:
                    parse_borland_symbol_line(line, all_symbols)
        print(f"[INFO] 成功加载 {len(all_symbols)} 个符号")
    except Exception as e:
        print(f"[ERROR] 读取MAP文件失败: {str(e)}")
        sys.exit(1)

# 2. 应用符号到IDA函数
rename_count = 0
for seg_start in Segments():
    for func_ea in Functions(seg_start, idc.get_segm_end(seg_start)):
        if func_ea in all_symbols:
            if safe_rename(func_ea, all_symbols[func_ea]):
                rename_count += 1
            else:
                # 尝试匹配函数内的地址
                for insn_ea in FuncItems(func_ea):
                    if insn_ea in all_symbols:
                        print(
                            f"[HINT] 发现函数内符号匹配: 0x{func_ea:08X} 包含 0x{insn_ea:08X} -> {all_symbols[insn_ea]}"
                        )
                        if safe_rename(func_ea, all_symbols[insn_ea]):
                            rename_count += 1
                            break

# 3. 结果统计
print("=" * 60)
print(f"处理完成!")
print(f"MAP符号总数: {len(all_symbols)}")
print(f"成功重命名函数: {rename_count}")
print(f"未匹配的符号: {len(all_symbols) - rename_count}")
if rename_count == 0:
    print("\n[疑难解答]")
    print("1. 检查基址调整值是否正确:")
    print(f"   IDA基址: 0x{IMAGE_BASE:08X}")
    print(f"   当前调整值: 0x{BASE_ADJUSTMENT:08X}")
    print("2. 手动测试示例(在IDA Python命令行中执行):")
    if all_symbols:
        sample_addr = next(iter(all_symbols))
        print(
            f"   ida_name.set_name(0x{sample_addr:08X}, 'TEST_NAME', ida_name.SN_FORCE | ida_name.SN_NOWARN)"
        )
print("=" * 60)


部分日志,未匹配函数有两个但是不影响,应该问题不大,具体原因没太深究
[Python] 纯文本查看 复制代码
============================================================
正在加载MAP文件: D:\learning\ida9.2\loadmap\41f718bcac1fed649693943444547f7e975a869273f21c107ecc035f68dac275.map
IDA基址: 0x00400000, 调整值: 0x00400000
============================================================
[DEBUG] 直接映射符号: 0x00401060 -> system.kernel32.CloseHandle_00401060
......
[INFO] 成功加载 358 个符号
[SUCCESS] 重命名 0x00401060: system.kernel32.CloseHandle_00401060
......
============================================================
处理完成!
MAP符号总数: 358
成功重命名函数: 356
未匹配的符号: 2
============================================================

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
helian147 + 1 + 1 热心回复!

查看全部评分

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

 楼主| weiguang2345 发表于 2026-3-20 12:15
idr导出map  导入ida9.1 脚本问题。已修正脚本代码
https://www.52pojie.cn/thread-2043596-1-1.html
(出处: 吾爱破解论坛)
原文地址
m_h 发表于 2026-3-22 11:07
 楼主| weiguang2345 发表于 2026-3-22 13:28

原来的代码没改,只改了对BASE_ADJUSTMENT的注释。我用的时候看半天原本注释没看懂,整理了一下并修改了注释再发出来。对于DUMP在OEP的情况没有影响。
jy02236902 发表于 2026-4-12 04:25
谢谢分析,我下载看看。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2026-8-7 14:46

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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