嘿,我有一个非常耗时的问题,我想我可能会在这里找到比我经验更好的人来帮助我。
我正在对一个应用程序进行逆向工程,该应用程序在某些时候使用NdrClientCall2 api 来使用其他服务的远程过程(我不知道是哪个服务)
现在摆在我听到没有尝试任何我自己的意见有一些真正好的应用程序来完成我想要什么样NtTrace,strace的和大致oSpy可以达到同样的效果藏汉最终。但是我的应用程序有一些非常困难的反调试技术,这迫使我手动完成所有操作。
最终我想要实现的是知道正在调用什么程序以及在什么服务\进程上。
这是 MSDN 的 NdrClientCall2 Decleration
CLIENT_CALL_RETURN RPC_VAR_ENTRY NdrClientCall2(
__in PMIDL_STUB_DESC pStubDescriptor,
__in PFORMAT_STRING pFormat,
__in_out ...
);
所以它使用PMIDL_STUB_DESC结构,其定义如下:
typedef struct _MIDL_STUB_DESC {
void *RpcInterfaceInformation;
void* (__RPC_API *pfnAllocate)(size_t);
void (__RPC_API *pfnFree)(void*);
union {
handle_t *pAutoHandle;
handle_t *pPrimitiveHandle;
PGENERIC_BINDING_INFO pGenericBindingInfo;
} IMPLICIT_HANDLE_INFO;
const NDR_RUNDOWN *apfnNdrRundownRoutines;
const GENERIC_BINDING_ROUTINE_PAIR *aGenericBindingRoutinePairs;
const EXPR_EVAL *apfnExprEval;
const XMIT_ROUTINE_QUINTUPLE *aXmitQuintuple;
const unsigned char *pFormatTypes;
int fCheckBounds;
unsigned long Version;
MALLOC_FREE_STRUCT *pMallocFreeStruct;
long MIDLVersion;
const COMM_FAULT_OFFSETS *CommFaultOffsets;
const USER_MARSHAL_ROUTINE_QUADRUPLE *aUserMarshalQuadruple;
const NDR_NOTIFY_ROUTINE *NotifyRoutineTable;
ULONG_PTR mFlags;
const NDR_CS_ROUTINES *CsRoutineTables;
void *Reserved4;
ULONG_PTR Reserved5;
} MIDL_STUB_DESC, *PMIDL_STUB_DESC;
这是在windbg中的样子,当我在NdrClientCall2函数中放置一个断点时
0:006> .echo "Arguments:"; dds esp+4 L5
Arguments:
06d9ece4 74cc2158 SspiCli!sspirpc_StubDesc
06d9ece8 74cc2322 SspiCli!sspirpc__MIDL_ProcFormatString+0x17a
06d9ecec 06d9ed00
06d9ecf0 91640000
06d9ecf4 91640000
0:006> .echo "PMIDL_STUB_DESC:"; dds poi(esp+4) L20
PMIDL_STUB_DESC:
74cc2158 74cc2690 SspiCli!sspirpc_ServerInfo+0x24
74cc215c 74cca1cd SspiCli!MIDL_user_allocate
74cc2160 74cca1e6 SspiCli!MIDL_user_free
74cc2164 74ce0590 SspiCli!SecpCheckSignatureRoutineRefCount+0x4
74cc2168 00000000
74cc216c 00000000
74cc2170 00000000
74cc2174 00000000
74cc2178 74cc1c52 SspiCli!sspirpc__MIDL_TypeFormatString+0x2
74cc217c 00000001
74cc2180 00060001
74cc2184 00000000
74cc2188 0700022b
74cc218c 00000000
74cc2190 00000000
74cc2194 00000000
74cc2198 00000001
74cc219c 00000000
74cc21a0 00000000
74cc21a4 00000000
74cc21a8 48000000
74cc21ac 00000000
74cc21b0 001c0000
74cc21b4 00000032
74cc21b8 00780008
74cc21bc 41080646
74cc21c0 00000000
74cc21c4 000b0000
74cc21c8 00020004
74cc21cc 00080048
74cc21d0 21500008
74cc21d4 0008000c
0:006> .echo "PFORMAT_STRING:"; db poi(esp+8)
PFORMAT_STRING:
74cc2322 00 48 00 00 00 00 06 00-4c 00 30 40 00 00 00 00 .H......L.0@....
74cc2332 ec 00 bc 00 47 13 08 47-01 00 01 00 00 00 08 00 ....G..G........
74cc2342 00 00 14 01 0a 01 04 00-6e 00 58 01 08 00 08 00 ........n.X.....
74cc2352 0b 00 0c 00 20 01 0a 01-10 00 f6 00 0a 01 14 00 .... ...........
74cc2362 f6 00 48 00 18 00 08 00-48 00 1c 00 08 00 0b 00 ..H.....H.......
74cc2372 20 00 2c 01 0b 01 24 00-a2 01 0b 00 28 00 b8 01 .,...$.....(...
74cc2382 13 41 2c 00 a2 01 13 20-30 00 f8 01 13 41 34 00 .A,.... 0....A4.
74cc2392 60 01 12 41 38 00 f6 00-50 21 3c 00 08 00 12 21 `..A8...P!<....!
那么我究竟如何确定它要与之通信的远程进程是什么,或者它使用什么管道进行通信?
据我从 MSDN 了解到,它应该调用远程过程。如果我理解正确,这意味着它应该调用远程函数,就好像它是导出的 dll 函数一样。如何在那里设置断点?
PS:
提出这个函数的主要原因是 NdrClientCall2 看起来非常庞大。