# How do I stop IDA from turning function into variadic without a cleanup?

**URL:** <https://community.hex-rays.com/t/how-do-i-stop-ida-from-turning-function-into-variadic-without-a-cleanup/331>\
**Category:** IDA General\
**Created:** [May 21, 2025, 8:22am UTC](https://community.hex-rays.com/t/how-do-i-stop-ida-from-turning-function-into-variadic-without-a-cleanup/331 "2025-05-21T08:22:43Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![NooneAtAll](https://avatars.discourse-cdn.com/v4/letter/n/e9c0ed/32.png) [@NooneAtAll](https://community.hex-rays.com/u/NooneAtAll)\
**Post date:** [May 21, 2025, 8:22am UTC](https://community.hex-rays.com/t/how-do-i-stop-ida-from-turning-function-into-variadic-without-a-cleanup/331/1 "2025-05-21T08:22:43Z")

</div>

It’s my first day ever trying decomilation and IDA, so I don’t really understand what’s happening.

I have a following function in my disassembly:

> **IDA View**
>
> ```auto
> ; =============== S U B R O U T I N E =======================================
> CODE:004040FC
> CODE:004040FC
> CODE:004040FC ; int __usercall sub_4040FC@<eax>(int result@<eax>, char@<dl>, char)
> CODE:004040FC sub_4040FC proc near ; CODE XREF: sub_403D94+7↑p
> CODE:004040FC ; sub_40D984+A↓p ...
> CODE:004040FC
> CODE:004040FC arg_0 = byte ptr 4
> CODE:004040FC
> CODE:004040FC push edx
> CODE:004040FD push ecx
> CODE:004040FE push ebx
> CODE:004040FF test dl, dl
> CODE:00404101 jl short loc_404106
> CODE:00404103 call dword ptr [eax-0Ch]
> CODE:00404106
> CODE:00404106 loc_404106: ; CODE XREF: sub_4040FC+5↑j
> CODE:00404106 xor edx, edx
> CODE:00404108 lea ecx, [esp+0Ch+arg_0]
> CODE:0040410C mov ebx, fs:[edx]
> CODE:0040410F mov [ecx], ebx
> CODE:00404111 mov [ecx+8], ebp
> CODE:00404114 mov dword ptr [ecx+4], offset sub_404125
> CODE:0040411B mov [ecx+0Ch], eax
> CODE:0040411E mov fs:[edx], ecx
> CODE:00404121 pop ebx
> CODE:00404122 pop ecx
> CODE:00404123 pop edx
> CODE:00404124 retn
> CODE:00404124 sub_4040FC endp
> 
> ```

> **Pseudocode**
>
> ```auto
> int __usercall sub_4040FC@<eax>(int result@<eax>, char a2@<dl>, char a3)
> {
> if ( a2 >= 0 )
> result = (*(int (**)(void))(result - 12))();
> __writefsdword(0, (unsigned int)&a3);
> return result;
> }
> 
> ```

Seeing that negative offset in `result-12`, I tried using \_\_shifted

> **I created new struct**
>
> 00000000 struct s20 // sizeof=0x10  
> 00000000 {  
> 00000000 void (\*foo)(void);  
> 00000004 \_BYTE gap[8];  
> 0000000C int i;  
> 00000010 };

and then changed type of `result` to `int *__shifted(s20,0xC)`

> **My function turns into variadic**
>
> ```auto
> int *__shifted(s20,0xC)__usercall sub_4040FC@<eax>(int *__shifted(s20,0xC) result@<eax>, char a2@<dl>, ...)
> {
> va_list va; // [esp+4h] [ebp+4h] BYREF
> 
> va_start(va, a2);
> if ( a2 >= 0 )
> result = (int *__shifted(s20,0xC))((int (*)(void))ADJ(result)->foo)();
> __writefsdword(0, (unsigned int)va);
> return result;
> }
> 
> ```

Notice that it has va\_list and va\_begin - but no va\_end.

> **Ctrl+Z reverts type, but not it turning into variadic**
>
> ```auto
> int __usercall sub_4040FC@<eax>(int result@<eax>, char a2@<dl>, ...)
> {
> va_list va; // [esp+4h] [ebp+4h] BYREF
> 
> va_start(va, a2);
> if ( a2 >= 0 )
> result = (*(int (**)(void))(result - 12))();
> __writefsdword(0, (unsigned int)va);
> return result;
> }
> 
> ```

I feel stuck

---

<div class="post-metadata">

**Author:** ![igor](https://sea2.discourse-cdn.com/flex002/user_avatar/community.hex-rays.com/igor/32/35_2.png) [@igor](https://community.hex-rays.com/u/igor)\
**Post date:** [May 21, 2025, 8:49am UTC](https://community.hex-rays.com/t/how-do-i-stop-ida-from-turning-function-into-variadic-without-a-cleanup/331/2 "2025-05-21T08:49:02Z")

</div>

We’ll check what’s wrong with Undo, but in the meantime I would suggest applying Lumina or one of the Delphi signatures - this looks like a standard Delphi function, probably `ClassCreate`.

---

<div class="post-metadata">

**Author:** ![Milanek](https://avatars.discourse-cdn.com/v4/letter/m/d07c76/32.png) [@Milanek](https://community.hex-rays.com/u/Milanek)\
**Post date:** [May 21, 2025, 12:48pm UTC](https://community.hex-rays.com/t/how-do-i-stop-ida-from-turning-function-into-variadic-without-a-cleanup/331/3 "2025-05-21T12:48:59Z")

</div>

Yeah, that’s Delphi. It has class methods at negative offsets in the vftable.
