Hex-Rays decompiled (with the assistance of pdb symbols) a piece of code as such: XPerfAddIn::CFramesInfoSource::MatchEventDescriptor( (XPerfAddIn::CFramesInfoSource *)2

And by my following of the assembly, it is correct:

xor     r15d, r15d
test    rax, rax
jz      loc_1800224C7
lea     r13, [rax+20h]
cmp     [r13+0], r15
jz      loc_1800224C7
lea     r12, [r14+28h]
mov     rax, [rsp+260h+a3]
mov     rcx, [rax]
cmp     rcx, cs:qword_180044990
jnz     loc_1800224C7
mov     rax, [rax+8]
cmp     rax, cs:qword_180044998
jnz     loc_1800224C7
lea     ecx, [r15+2]
mov     r9d, ecx        ; a4
mov     rdx, r12        ; a2
call    ?MatchEventDescriptor@CFramesInfoSource@XPerfAddIn

MatchEventDescriptor does not use the 'this' parameter in rcx, so it doesn't really matter what gets passed in. So why would the compiler emit an extra lea instruction to pass in a constant 2 instead of just leaving it 0... or passing in the actual, correct this value?

  • add the call to the disassembly
    – Igor Skochinsky
    Commented May 26, 2018 at 9:50
  • @IgorSkochinsky edited it in
    – Zhentar
    Commented May 26, 2018 at 15:52

1 Answer 1


Apparently ecx is just used as a temporary for calculating the value 2 which is copied to r9d and is probably used later in the function.

When the decompiler does not have reliable information about function prototype, it has to resort to heuristics, or guessing. Since the demangled function name looks like a C++ method, it assumes that it’s a method of a class XPerfAddIn::CFramesInfoSource and since it’s not marked static, it probably takes in the class instance in rcx as common for the thiscall calling convention, thus the value in rcx (ecx) is assumed to be the this pointer.

If you analyzed the function and deduced that it does not actually use rcx/ecx, you can edit the function prototype, remove the this argument and __thiscall calling convention to get “proper” decompilation.

  • This is x86-64, so it's it's expecting the first argument to be in rcx whether or not it's this. I tried manually defining the registers ( bool __fastcall XPerfAddIn__CFramesInfoSource__MatchEventDescriptor(_EVENT_DESCRIPTOR *a2<rdx>, _EVENT_DESCRIPTOR *a3<r8>, EDVersionCheckType a4<r9>)) , but that just gave me the error "Argument location rdx is not allowed here"
    – Zhentar
    Commented May 27, 2018 at 0:00
  • explicit argument locations only work for __usercall
    – Igor Skochinsky
    Commented May 27, 2018 at 17:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.