这绝对是一个初学者问题,我正在对某些 dll 文件进行静态和动态分析,WinDbg 给了我调用堆栈,例如
SERVER+0x78123
当我返回 IDA 通过从 IDA 顶部列表中获取 0x78123+10001000“这是 dll 起始地址”来查看函数内部的代码时,我看不到该函数。感谢您的帮助
这绝对是一个初学者问题,我正在对某些 dll 文件进行静态和动态分析,WinDbg 给了我调用堆栈,例如
SERVER+0x78123
当我返回 IDA 通过从 IDA 顶部列表中获取 0x78123+10001000“这是 dll 起始地址”来查看函数内部的代码时,我看不到该函数。感谢您的帮助
当您在windbg 中看到大偏移量时,通常怀疑
windbg 根据最近的符号解析偏移量,
在大多数情况下,看到大的偏移量符号可能无法正确使用,
并且windbg 使用最近的符号可能不正确
优化的二进制文件也有分块的函数,但 pdbs 通常具有 Windbg 使用的未分块的偏移量,并且可能返回不正确的大偏移量
您应该使用地址而不是符号+偏移量,并使用地址而不是符号+偏移量值进行计算
例如在下面的堆栈中注意 vc__filt+0x12f3 和该行上方的警告
vc__filt+0x12f3 是栈上的返回地址,解析为
00 0012ff38 004012f3 msvcrt!_controlfp
你应该主要使用这样的解析地址而不是符号+偏移
0:000> k
# ChildEBP RetAddr
00 0012ff38 004012f3 msvcrt!_controlfp
WARNING: Stack unwind information not available. Following frames may be wrong.
01 0012ff88 76faed6c vc__filt+0x12f3
02 0012ff94 77c537eb kernel32!BaseThreadInitThunk+0xe
03 0012ffd4 77c537be ntdll!__RtlUserThreadStart+0x70
04 0012ffec 00000000 ntdll!_RtlUserThreadStart+0x1b
如果您无法手动解析,您可以要求 windbg 覆盖本地上下文并使用 PseudoRegister @$ra 访问每个帧的返回地址
见下面每个帧的解析返回地址
0:000> .cxr
0:000> .frame /c /r 0 ; ? @$ra
00 0012ff38 004012f3 msvcrt!_controlfp
msvcrt!_controlfp:
778de1e1 8bff mov edi,edi
Evaluate expression: 4199155 = 004012f3 <<<<<<<<<<<<<<<<
0:000> .frame /c /r 1 ; ? @$ra
01 0012ff44 00401237 vc__filt+0x12f3
vc__filt+0x12f3:
004012f3 59 pop ecx
Evaluate expression: 4198967 = 00401237 <<<<<<<<<<
0:000> .frame /c /r 2 ; ? @$ra
02 0012ff88 76faed6c vc__filt+0x1237
vc__filt+0x1237:
00401237 680c304000 push offset vc__filt+0x300c (0040300c)
Evaluate expression: 1996156268 = 76faed6c<<<<<<<
0:000> k
*** Stack trace for last set context - .thread/.cxr resets it
# ChildEBP RetAddr
WARNING: Stack unwind information not available. Following frames may be wrong.
02 0012ff88 76faed6c vc__filt+0x1237 <<<<<<<<< return address of last set context
03 0012ff94 77c537eb kernel32!BaseThreadInitThunk+0xe
04 0012ffd4 77c537be ntdll!__RtlUserThreadStart+0x70
05 0012ffec 00000000 ntdll!_RtlUserThreadStart+0x1b