概述
工欲善其事,必先利其器!
我们在逆向调试二进制代码的时候一般会静态分析和动态分析等多种方法:
- 静态分析:IDA、Ghidra等工具。可以添加注释,从汇编生成C代码等,在一次分析完成后,后续偏移的地址、基地址则不会发生变化。
- 动态分析:GDB、Windbg、ebpf等工具。程序加载进系统时候地址(也称基地址,简称基址或者base)多是随机的,虽然函数偏移(简称偏移或者offset)相对基址不会发生变化,但因基址发生变化,函数最终的位置也会发生变化(func_dst_addr = base_addr + func_offset)。
拿到这个目标函数地址(func_dst_addr)后,我们就可以在gdb、windbg中对程序添加断点,进而单步分析程序行为、查看内存数据、校验关键环节等。
我们往往无法在一次动态分析中准确理解程序行为。当重新进行动态分析时,基址会发生变化,这时候我们需要对所有目标函数地址进行一个个的重新计算。如果只是一次两次的动态调试还好,当分析的函数逐渐增多,需要重新动态分析的次数增加时,这个工作就显得枯燥且耗时。
于是,我们需要一个小工具来简化这项工作,我想到了下面这些方法:
- Python版本:我们可以实现一个Python代码,读取指定文件A,文件A中存放了函数和偏移,给定基址就可以计算得到想要的目标地址。
- Excel版本:我们可以使用excel做这一切,可视化效果好。
于是皮蛋熊两个都实现了一遍,使用过程中发现还是excel好用些:可视化效果好,自动计算,所见即所得,这里分享给各位小伙伴。
方法一(内置函数)
注意:这个方法没有办法做大数计算,excel中限制了只能计算10位长度的整数,对于64bit的数,这里就会无法计算。
这里可以使用EXCEL表的形式来自动计算,这里计算都是16进制的,

最终计算函数如下:
="0x" & TEXT(DEC2HEX(HEX2DEC(SUBSTITUTE($C$3, "0x", "")) + HEX2DEC(SUBSTITUTE(C5, "0x", ""))), "00")
分别解释一下:
- 输出的时候补上
0x头表示十六进制:="0x" & TEXT( DEC2HEX(B2), "00") - 输入的时候拆掉
0x头用十进制运算:HEX2DEC(SUBSTITUTE($C$3, "0x", "")) - 固定
base选择:$C$3,这里基址的表格是C3,这样子拖动推理的时候这个值就不会发生变化了
这样子只要一修改BASE地址,就可以直接计算出最终地址了,稍微美化一下:

方法二(VBA)
上面的方法一不能用大数(64位),所以这里用VBA实现了一版,可以进行大数计算了,所以这也是我现在使用的版本:

附件表格文件(VBA函数引入):调试地址表.xlsm
注意:使用时候需要注意excel中需要打开VBA函数的支持:
文件-》选项-》信任中心-》信任中心设置

附代码
vba实现的脚本如下(AI辅助),有兴趣的可以自行创建excel表格,参考上面提供的表格附件,添加下面vba代码进行计算。
Function HexAdd(ByVal hex1 As String, ByVal hex2 As String) As String
' 移除输入字符串中的"0x"或"0X"前缀并转换为大写
If Left(UCase(hex1), 2) = "0X" Then hex1 = Mid(hex1, 3)
If Left(UCase(hex2), 2) = "0X" Then hex2 = Mid(hex2, 3)
hex1 = UCase(hex1)
hex2 = UCase(hex2)
' 确保两个字符串长度相同(通过在左侧补0)
Dim maxLen As Integer
maxLen = IIf(Len(hex1) > Len(hex2), Len(hex1), Len(hex2))
hex1 = String(maxLen - Len(hex1), "0") & hex1
hex2 = String(maxLen - Len(hex2), "0") & hex2
' 初始化结果和进位
Dim result As String
Dim carry As Integer
carry = 0
' 从最低有效位开始逐位相加
Dim i As Integer
For i = maxLen To 1 Step -1
' 获取当前位的数值
Dim digit1 As Integer, digit2 As Integer
digit1 = HexCharToValue(Mid(hex1, i, 1))
digit2 = HexCharToValue(Mid(hex2, i, 1))
' 计算当前位的和
Dim total As Integer
total = digit1 + digit2 + carry
' 确定当前位的结果和进位
Dim currentDigit As String
currentDigit = ValueToHexChar(total Mod 16)
carry = total \ 16
' 构建结果字符串
result = currentDigit & result
Next i
' 处理最后可能的进位
If carry > 0 Then
result = ValueToHexChar(carry) & result
End If
' 移除结果中多余的前导零
Dim j As Integer
For j = 1 To Len(result)
If Mid(result, j, 1) <> "0" Then
result = Mid(result, j)
Exit For
End If
Next j
' 如果结果为空(全零),则结果为0
If result = "" Then result = "0"
' 添加"0x"前缀
HexAdd = "0x" & result
End Function
' 辅助函数:将十六进制字符转换为数值
Private Function HexCharToValue(ByVal c As String) As Integer
Select Case c
Case "0" To "9": HexCharToValue = Val(c)
Case "A": HexCharToValue = 10
Case "B": HexCharToValue = 11
Case "C": HexCharToValue = 12
Case "D": HexCharToValue = 13
Case "E": HexCharToValue = 14
Case "F": HexCharToValue = 15
Case Else: HexCharToValue = 0 ' 错误处理
End Select
End Function
' 辅助函数:将数值转换为十六进制字符
Private Function ValueToHexChar(ByVal v As Integer) As String
Select Case v
Case 0 To 9: ValueToHexChar = CStr(v)
Case 10: ValueToHexChar = "A"
Case 11: ValueToHexChar = "B"
Case 12: ValueToHexChar = "C"
Case 13: ValueToHexChar = "D"
Case 14: ValueToHexChar = "E"
Case 15: ValueToHexChar = "F"
Case Else: ValueToHexChar = "0" ' 错误处理
End Select
End Function


评论区