参看
《RpcView简介》
http://scz.617.cn:8/windows/202110270957.txt
就此,颜涛提到可以试试IDA插件findrpc。
https://github.com/lucasg/findrpc
这是个IDAPython插件,直接在IDA中Alt-F7加载,从binary中静态分析RPC相关数据结构。若在Windows上用,依赖一个外部PE还可以得到IDL文件,此时findrpc可以当成曾经的IDA插件mIDA的替代品。
RpcView已经非常优秀,为什么需要findrpc呢?findrpc作者提到,某些进程受PPL机制(Protected Processes Light)保护,RpcView可能无法获取其RPC接口信息,此时findrpc就派上用场了。另有一些进程可能不是后台驻留的,执行完就结束了,这种无法用RpcView看。内核中也有RPC接口,RpcView无法用于内核。这几种场景都可以静态分析二进制获取RPC接口信息。
findrpc与RpcView互为补充。
关于PPL,参看
The Evolution of Protected Processes Part 1: Pass-the-Hash Mitigations in Windows 8.1 – Alex Ionescu [2013-11-05]
假设IDA分析来自LTSB Win10中的usermgr.dll(10.0.14393.4169)。下面举例说明findrpc的使用。
Alt-F7加载findrpc.py,若顺利,会在三个窗口中显示逆向分析获取的信息。
1) Output窗口
Output窗口以文本形式输出找到的RPC相关数据结构,比如这种
可以看到IID、各远程过程地址,可以点击地址跳转过去查看。
2) “detected rpc structures”窗口
“detected rpc structures”窗口将Output窗口的输出换个形式展现,给出具体结构名及相应地址,比如
无法从此点击地址跳过去,只有Output窗口中的地址可以点击。右键选中某个结构,右键菜单里有4种操作
Apply type
相当于跳到结构所在地址,Alt-Q应用结构
Clear applied type
Renamed applied type
在结构所在地址处出现名字,形如
_findrpc_b18fbab6_56f8_4702_84e041053293a869_rpc_dispatch_table
中间是IID,后缀表明结构是啥
Renamed proc handlers
类似”Renamed applied type”的操作
显然,若有PDB文件加持,就别用那两个Renamed操作,”Apply type”倒是可以用。
3) “FindRpc results”窗口
“FindRpc results”窗口将Output窗口的输出换个形式展现,重点展现远程过程所在地址。无法从此点击地址跳过去,只有Output窗口中的地址可以点击。
右键选中某个IID,右键菜单里有3种操作
Generate stub (beta)
产生RPC所用桩码,比如
usermgr_b18fbab6-56f8-4702-84e041053293a869.h
usermgr_b18fbab6-56f8-4702-84e041053293a869_s.c
看了一下,这些.h、.c没啥用,果然是beta功能
Generate json summary
将插件识别出的RPC信息以json形式导出,比如
usermgr_b18fbab6-56f8-4702-84e041053293a869.json
Decomplie interface (only for Windows)
调用”decompile\DecompileInterface.exe”,解析上述json格式的数据,生成IDL文件。相当于
“decompile\DecompileInterface.exe” usermgr_b18fbab6-56f8-4702-84e041053293a869.json
“Decomplie interface”功能只在Windows上有,因为要调外部PE文件。usermgr.dll中某接口的IDL确实生成了,但findrpc作者在github上提供的三个示例,无一成功生成IDL文件。findrpc作者提供的IDL示例中远程过程名应该是利用了PDB文件,我测试没看到这效果,还是Proc*这种名字。用Process Monitor看,会找dbghelp.dll,一般System32目录有,但没有symsrv.dll。从windbg中复制dbghelp.dll、symsrv.dll到DecompileInterface.exe所在目录,会优先加载。DecompileInterface.exe是32位PE,起初复制32位dbghelp.dll、symsrv.dll过去,发现虽然优先加载了,但转头又去加载System32下的dbghelp.dll;后来复制64位dbghelp.dll过去,优先加载后不再去找System32下的dbghelp.dll。但无论怎么穷折腾,IDL中仍然是Proc*,没有用上符号信息,诡异。
github上的findrpc是2019年8月的,作者用的可能是”IDA 7.3+Python 2″,findrpc无法直接用于”IDA 7.6.x+Python 3.9.x”。若非要在后一种环境中用,需要做两种移植工作,首先是Python2到Python3的移植,其次是IDAPython 7.3到IDAPython 7.4及更高版本的移植,都是有例可循的。
findrpc项目自带DecompileInterface.exe,作者有段介绍
DecompileInterface.exe is a custom loader for Forshaw’s NdrParser.ReadFromRpcServerInterface which uses a json file exported from IDA instead of reading a remote process’s memory.
findrpc作者没有提供DecompileInterface.exe源码,2021.5.23有人在github上问作者能不能提供DecompileInterface.exe源码,作者未回答。简单说一下这事。
https://github.com/0xd4d/dnSpy
dnSpy是款强大的.NET反编译器,可以无源码调试.NET程序,可以从.NET PE导出VS 2019工程。若只是看看DecompileInterface.exe代码逻辑,dnSpy看看即可。若想与最新版NtApiDotNet、Newtonsoft.Json的源码适配,就有些费劲。
用dnSpy看旧版NtApiDotNet.dll,原来有
public interface NtApiDotNet.Ndr.IMemoryReader
public class NtApiDotNet.Win32.DbgHelpSymbolResolver
最新版里它们变了
internal interface NtApiDotNet.Utilities.Memory.IMemoryReader
internal sealed partial class NtApiDotNet.Win32.Debugger.DbgHelpSymbolResolver
再比如,旧版NtApiDotNet.dll中RPC_SERVER_INTERFACE是public的,新版源码中它是internal的。我能想到的办法是改NtApiDotNet源码,把internal改回public,不知正经办法是啥?对现在的C#一窍不通,不深究了。
最后是
public DbgHelpSymbolResolver(NtProcess process, string dbghelp_path, string symbol_path)
public DbgHelpSymbolResolver(NtProcess process, string dbghelp_path, string symbol_path, SymbolResolverFlags flags, TextWriter trace_writer)
旧版DbgHelpSymbolResolver构造函数只有3个形参,新版新增了2个形参。
除非确有刚需,否则没必要折腾DecompileInterface.exe可编译源码,findrpc自带的那个就能用。
版权声明
本站“技术博客”所有内容的版权持有者为绿盟科技集团股份有限公司(“绿盟科技”)。作为分享技术资讯的平台,绿盟科技期待与广大用户互动交流,并欢迎在标明出处(绿盟科技-技术博客)及网址的情形下,全文转发。
上述情形之外的任何使用形式,均需提前向绿盟科技(010-68438880-5462)申请版权授权。如擅自使用,绿盟科技保留追责权利。同时,如因擅自使用博客内容引发法律纠纷,由使用者自行承担全部法律责任,与绿盟科技无关。