The problem is that those arguments may, and will in most cases, be calculated, not constants, so you don't really have one single instruction that gives you the parameter. Consider this test program:
#include <stdio.h>
int a, b, c, d, e, f, g, h, i, j;
void func(int a1, int a2, int a3, int a4, int a5) {
printf("%d %d %d %d %d\n", a1, a2, a3, a4, a5);
}
int main(void) {
int x, y;
x=g+c;
y=d*e+i;
func(1, a, b+c, 7, j);
printf("blarfl\n");
func(e, j*c, 3, x, y);
}
After compiling it (with -O0 and without symbols) and loading it in IDA, the main functions looks like this:
push rbp
mov rbp, rsp
sub rsp, 10h
mov edx, cs:g
mov eax, cs:c
add eax, edx
mov [rbp+var_8], eax
mov edx, cs:d
mov eax, cs:e
imul edx, eax
mov eax, cs:i
add eax, edx
mov [rbp+var_4], eax
mov ecx, cs:j
mov edx, cs:b
mov eax, cs:c
add edx, eax
mov eax, cs:a
mov r8d, ecx
mov ecx, 7
mov esi, eax
mov edi, 1
call func
mov edi, offset s ; "blarfl"
call _puts
mov edx, cs:j
mov eax, cs:c
mov esi, edx
imul esi, eax
mov eax, cs:e
mov ecx, [rbp+var_4]
mov edx, [rbp+var_8]
mov r8d, ecx
mov ecx, edx
mov edx, 3
mov edi, eax
call func
leave
Once you define your function
; __int64 __cdecl func(int XYZ1, int XYZ2, int XYZ3, int XYZ4, int XYZ5)
the disassembly of main turns into
push rbp
mov rbp, rsp
sub rsp, 10h
mov edx, cs:g
mov eax, cs:c
add eax, edx
mov [rbp+XYZ4], eax
mov edx, cs:d
mov eax, cs:e
imul edx, eax
mov eax, cs:i
add eax, edx
mov [rbp+XYZ5], eax
mov ecx, cs:j
mov edx, cs:b
mov eax, cs:c
add edx, eax ; XYZ3
mov eax, cs:a
mov r8d, ecx ; XYZ5
mov ecx, 7 ; XYZ4
mov esi, eax ; XYZ2
mov edi, 1 ; XYZ1
call func
mov edi, offset s ; "blarfl"
call _puts
mov edx, cs:j
mov eax, cs:c
mov esi, edx
imul esi, eax ; XYZ2
mov eax, cs:e
mov ecx, [rbp+XYZ5]
mov edx, [rbp+XYZ4]
mov r8d, ecx ; XYZ5
mov ecx, edx ; XYZ4
mov edx, 3 ; XYZ3
mov edi, eax ; XYZ1
call func
leave
retn
so you see ida auto-generates comments where the parameters are assigned. You can probably scan backwards 10 or 20 instructions from each xref using PrevNotTail, and check the comments for your parameter strings. If you make your parameter names sufficiently unique, this should identify the instructions quite well (that's why i used XYZ1 instead of a1).
Of course,
imul esi, eax ; XYZ2
won't really help you that much. But your results may be better if most parameters to your func are constants.
__stdcalland__cdeclcalling conventions, and the parameters would most likely be pushed to the stack. – RoraΖ Jan 05 '15 at 13:33push <reg>instructions if you look for the comments, so those instructions are even more unusable than the above examples. – Guntram Blohm Jan 05 '15 at 14:19func(1, (a<b ? 2 : 3), 4)will probably compile to apush 4, two branches that push 2 or 3 respectively, and apush 1. But how do you want to display this in your list of parameter-annotated xrefs anyway, unless you're trying to re-implement the Hex Rays Decompiler? Spending the time to process the 5% edge cases manually is probably much more efficient than trying to get everything handled in your helper program, especially if that program is intended for one specific task. – Guntram Blohm Jan 05 '15 at 14:27cmovand other forms of branch-less conditionals. – DarthGizka Jan 05 '15 at 15:14