I already described how you can extract address of GlobalRpcServer and offset to some RPC_SERVER_T fields. Lets do it for arm64 in declarative manner using FSM
Start again with I_RpcServerRegisterForwardFunction function - we can get address of RpcHasBeenInitialized (will be stored with index 1), GlobalRpcServer (with index 2) and RPC_SERVER_T.pRpcForwardFunction offset (with index 3):
section .data
func I_RpcServerRegisterForwardFunction
# 1 - RpcHasBeenInitialized
stg1 load
# 2 - GlobalRpcServer
stg2 load
# 3 - ForwardFunction offset
stg3 strx
section .data
fsection .text
# size of RPC_SERVER_T - 1st arg to AllocWrapper, stored with index 4
stg4 movx0
# AllocWrapper
call
# store to GlobalRpcServer
gstore 2
Next in function you can see call to RtlInitializeCriticalSectionAndSpinCount expecting pointer to CRITICAL_SECTION as first argument (passed in register x0) - store this offset under index 5:
# x0 - offset to critical section, stored with index 5
stg5 addx0
call_imp RtlInitializeCriticalSectionAndSpinCount
And now we must insert loading of our pseudo-GUID to be able to find function InitializeRpcServer:
guid 60 00 00 00 80 BD A8 AF 8A 7D C9 11 BE F4 08 00
call .text
Also we can find offset to stop event - from exported function RpcMgmtStopServerListening, where this offset passed as first argument to SetEvent:
# stop event offset - from RpcMgmtStopServerListening
section .data
func RpcMgmtStopServerListening
gload 1
gload 2
# 7 - offset to stop event, 1st arg to SetEvent
stg7 ldrx0
call_imp SetEvent
Run our rules on couple of files:
afsm.exe -a D:\src\armpatched\fsm\tmp.fsm d:\work\kernel\w10\18363\arm\rpcrt4.dll D:\work\kernel\w10\rtm\2004\arm\rpcrt4.dll
[0] d:\work\kernel\w10\18363\arm\rpcrt4.dll: found at 0 1 - 114D3C 2 - 114D28 3 - 178 4 - 1F0 5 - 60 7 - 108[1] D:\work\kernel\w10\rtm\2004\arm\rpcrt4.dll: found at 0 1 - 10ED44 2 - 10ED30 3 - 178 4 - 1F0 5 - 60 7 - 108
- address of RpcHasBeenInitialized - at index 1
- address of GlobalRpcServer - at index 2
- offset of RPC_SERVER_T.pRpcForwardFunction - at index 3
- size of RPC_SERVER - at index 4
- offset to some CRITICAL_SECTION in RPC_SERVER - at index 5
- offset to stop event in RPC_SERVER - at index 7
This data is enough to select right version of RPC_SERVER struct (or at least say that this is some new and unknown version)