WinDbg - 当前指令的 RVA

逆向工程 拆卸 视窗 调试 调试器 风袋
2021-06-14 21:40:38

有人知道一个windbg命令来显示它的模块中某个指令的RVA吗?

现在,如果我想找到当前指令的 RVA,比方说,它的 RVA test eax, eax

16237915 8b4e0c          mov     ecx,dword ptr [esi+0Ch]
16237918 e8633ff0ff      call    NPSWF32!BrokerMainW+0x1b0a4 (1613b880)
1623791d 85c0            test    eax,eax
1623791f 7507            jne     NPSWF32!BrokerMainW+0x11714c (16237928)
16237921 8bce            mov     ecx,esi
16237923 e80838fdff      call    NPSWF32!BrokerMainW+0xea954 (1620b130)
16237928 8b4810          mov     ecx,dword ptr [eax+10h]

我必须先找到模块的基地址:

0:000> lm a 1623791d 
Browse full module list
start    end        module name
15c70000 16b53000   NPSWF32    (export symbols)     

并自己计算 RVA: 1623791d - 15c70000 = 5C791D

我的问题是,是否有一个windbg 命令可以立即给我这个结果。

提前致谢!

1个回答

把这是一些 txt 文件并将其保存在类似c:\myrva.txt 的地方

.foreach ( place { lm1ma ${$arg1} } ){ .printf "Rva for input is %x\n", ${$arg1}-${place} }

并像使用它一样

0:000> $$>a< c:\\rva.txt @edx
Rva for input is 470b4
0:000> ? edx
Evaluate expression: 1997238452 = 770b70b4
0:000> $$>a< c:\\rva.txt .
Rva for input is a04fa
0:000> ? .
Evaluate expression: 1997604090 = 771104fa
0:000> $$>a< c:\\rva.txt 7711050a
Rva for input is a050a

好吧,如果您认为这应该是一个常规的 windbg 命令,您可以编写自己的扩展

使用 engextcpp 框架执行 !rva这应该不超过 5 行代码,如下所示

#include <engextcpp.cpp>
class EXT_CLASS : public ExtExtension {
public:
    EXT_COMMAND_METHOD(rva);
};
EXT_DECLARE_GLOBALS();
EXT_COMMAND( rva, "rva", "{;e,d=@$ip;!rva;}" ) {
    ULONG64 inaddr = GetUnnamedArgU64 (0);
    ULONG ModIndex = NULL;
    ULONG64 Modbase = NULL;
    m_Symbols->GetModuleByOffset(inaddr,0,&ModIndex,&Modbase);
    Out("Rva For Inaddress %I64x is %I64X\n" ,inaddr ,(inaddr - Modbase));    
}

编译并链接到

cl /LD /nologo /W4 /Ox  /Zi /EHsc rva.cpp /link /EXPORT:DebugExtensionInitialize /Export:rva /Export:help /RELEASE %linklibs%

并愉快地执行它接受一个参数一个表达式,默认情况下表达式是当前指令指针即 $ip

会话开始时自动加载扩展

windbg -c ".load rva" calc

永远快乐地旅行

0:000> !rva
Rva For Inaddress 776e04f6 is A04F6
0:000> !rva @edx
Rva For Inaddress 776870b4 is 470B4
0:000> !rva ntdll
Rva For Inaddress 77640000 is 0
0:000> !rva calc
Rva For Inaddress 440000 is 0
0:000> !rva calc!WinMain
Rva For Inaddress 441635 is 1635

even some obscure unrealistic expression will work
0:000> !rva @@c++( ( @$proc )->Ldr)
Rva For Inaddress 77717880 is D7880