I have decompiled a DLL and IDA Pro came up with the following code:
signed int __thiscall sub_10029900(void *a1, int a2)
{
int v2; // esi@1
int v3; // ebx@1
int v4; // eax@1
int v5; // edx@3
int v6; // eax@5
signed int v7; // esi@5
bool v8; // cf@7
signed int v9; // eax@8
int v11; // [sp+10h] [bp-20h]@1
v2 = 0;
v3 = EnumFirstValidChild(a1, &v11);
..........
return v2;
}
Where EnumFirstValidChild
is defined as:
int __userpurge EnumFirstValidChild<eax>(int a1<eax>, int a2, int a3);
I modified the code above to call the userpurge function as follows:
int *v12 = &v11;
__asm
{
push v12
push a1
call sub_10029800
mov v3, eax
}
The problem I am having is that the call to this function is causing a stack a Run-Time Check Failure #2 - Stack around v11
variable.
v11
is 4 bytes long and I see that more than 16 bytes are wtitten to that pointer.
What could it be wrong?
Thanks!
EDIT:
Disassembled code listing of sub_10029900
.text:10029900 ; =============== S U B R O U T I N E ===========
.text:10029900
.text:10029900 ; Attributes: bp-based frame
.text:10029900
.text:10029900 sub_10029900 proc near ; CODE XREF: sub_1000F400+F1p
.text:10029900 ; sub_10010870+135p ...
.text:10029900
.text:10029900 var_20 = dword ptr -20h
.text:10029900 arg_0 = dword ptr 8
.text:10029900
.text:10029900 mov edi, edi
.text:10029902 push ebp
.text:10029903 mov ebp, esp
.text:10029905 and esp, 0FFFFFFF8h
.text:10029908 sub esp, 24h
.text:1002990B lea eax, [esp+24h+var_20]
.text:1002990F push ebx
.text:10029910 push esi
.text:10029911 push edi
.text:10029912 push eax
.text:10029913 push ecx
.text:10029914 xor esi, esi
.text:10029916 call ds:EnumFirstValidChild
.text:1002991C mov ebx, eax
.text:1002991E lea eax, [esi+1]
.text:10029921 test ebx, ebx
.text:10029923 jz short loc_10029985
.text:10029925 mov edi, [ebp+arg_0]
.text:10029928
.text:10029928 loc_10029928: ; CODE XREF: sub_10029900+6Aj
.text:10029928 test eax, eax
.text:1002992A jz short loc_10029983
.text:1002992C mov edx, [esp+30h+var_20]
.text:10029930 test edx, edx
.text:10029932 jz short loc_1002995E
.text:10029934 test edi, edi
.text:10029936 jz short loc_1002995E
.text:10029938 mov eax, edi
.text:1002993A mov esi, 0Ch
.text:1002993F nop
.text:10029940
.text:10029940 loc_10029940: ; CODE XREF: sub_10029900+4Fj
.text:10029940 mov ecx, [edx]
.text:10029942 cmp ecx, [eax]
.text:10029944 jnz short loc_10029958
.text:10029946 add edx, 4
.text:10029949 add eax, 4
.text:1002994C sub esi, 4
.text:1002994F jnb short loc_10029940
.text:10029951 mov eax, 1
.text:10029956 jmp short loc_1002995A
.text:10029958 ; ---------------------------------------------------------------------------
.text:10029958
.text:10029958 loc_10029958: ; CODE XREF: sub_10029900+44j
.text:10029958 xor eax, eax
.text:1002995A
.text:1002995A loc_1002995A: ; CODE XREF: sub_10029900+56j
.text:1002995A test eax, eax
.text:1002995C jnz short loc_1002996C
.text:1002995E
.text:1002995E loc_1002995E: ; CODE XREF: sub_10029900+32j
.text:1002995E ; sub_10029900+36j
.text:1002995E lea eax, [esp+30h+var_20]
.text:10029962 push eax
.text:10029963 push ebx
.text:10029964 call ds:EnumNextValidChild
.text:1002996A jmp short loc_10029928
.text:1002996C ; ---------------------------------------------------------------------------
.text:1002996C
.text:1002996C loc_1002996C: ; CODE XREF: sub_10029900+5Cj
.text:1002996C push ebx
.text:1002996D mov esi, 1
.text:10029972 call ds:EndEnumValidChild
.text:10029978 mov eax, esi
.text:1002997A pop edi
.text:1002997B pop esi
.text:1002997C pop ebx
.text:1002997D mov esp, ebp
.text:1002997F pop ebp
.text:10029980 retn 4
.text:10029983 ; ---------------------------------------------------------------------------
Disassembled code listing of EnumFirstValidChild
.
.text:1000B710 ; Exported entry 4. EnumFirstValidChild
.text:1000B710
.text:1000B710 ; =============== S U B R O U T I N E ==============
.text:1000B710
.text:1000B710 ; Attributes: bp-based frame
.text:1000B710
.text:1000B710 public EnumFirstValidChild
.text:1000B710 EnumFirstValidChild proc near ; DATA XREF: .text:off_10027368o
.text:1000B710
.text:1000B710 var_28 = dword ptr -28h
.text:1000B710 var_24 = dword ptr -24h
.text:1000B710 var_20 = dword ptr -20h
.text:1000B710 var_1C = dword ptr -1Ch
.text:1000B710 var_18 = byte ptr -18h
.text:1000B710 var_C = dword ptr -0Ch
.text:1000B710 var_4 = dword ptr -4
.text:1000B710 arg_0 = dword ptr 8
.text:1000B710 arg_4 = dword ptr 0Ch
.text:1000B710
.text:1000B710 mov edi, edi
.text:1000B712 push ebp
.text:1000B713 mov ebp, esp
.text:1000B715 and esp, 0FFFFFFF8h
.text:1000B718 mov eax, large fs:0
.text:1000B71E push 0FFFFFFFFh
.text:1000B720 push offset SEH_1001DAD0
.text:1000B725 push eax
.text:1000B726 mov large fs:0, esp
.text:1000B72D sub esp, 20h
.text:1000B730 mov ecx, dword_1002ACE8
.text:1000B736 push ebx
.text:1000B737 push esi
.text:1000B738 push edi
.text:1000B739 xor edi, edi
.text:1000B73B test ecx, ecx
.text:1000B73D jnz short loc_1000B77D
.text:1000B73F push dword_1002ACE4
.text:1000B745 lea eax, [esp+3Ch+var_28]
.text:1000B749 push eax
.text:1000B74A push 7Ch
.text:1000B74C push 1
.text:1000B74E call ds:api_func_107
.text:1000B754 mov ecx, [esp+38h+var_28]
.text:1000B758 mov [esp+38h+var_24], ecx
.text:1000B75C mov [esp+38h+var_4], edi
.text:1000B760 test ecx, ecx
.text:1000B762 jz short loc_1000B76D
.text:1000B764 call sub_10005440
.text:1000B769 mov ecx, eax
.text:1000B76B jmp short loc_1000B76F
.text:1000B76D ; ---------------------------------------------------------------------------
.text:1000B76D
.text:1000B76D loc_1000B76D: ; CODE XREF: EnumFirstValidChild+52j
.text:1000B76D xor ecx, ecx
.text:1000B76F
.text:1000B76F loc_1000B76F: ; CODE XREF: EnumFirstValidChild+5Bj
.text:1000B76F mov [esp+38h+var_4], 0FFFFFFFFh
.text:1000B777 mov dword_1002ACE8, ecx
.text:1000B77D
.text:1000B77D loc_1000B77D: ; CODE XREF: EnumFirstValidChild+2Dj
.text:1000B77D mov eax, [ebp+arg_0]
.text:1000B780 lea esi, [ecx+34h]
.text:1000B783 mov [esp+38h+var_24], eax
.text:1000B787 mov ecx, esi
.text:1000B789 lea eax, [esp+38h+var_24]
.text:1000B78D push eax
.text:1000B78E lea eax, [esp+3Ch+var_18]
.text:1000B792 push eax
.text:1000B793 call sub_10008330
.text:1000B798 mov ecx, [eax]
.text:1000B79A mov ebx, [eax+4]
.text:1000B79D mov eax, [esi+4]
.text:1000B7A0 mov [esp+38h+var_20], ecx
.text:1000B7A4 mov [esp+38h+var_1C], ebx
.text:1000B7A8 mov [esp+38h+var_24], eax
.text:1000B7AC test ecx, ecx
.text:1000B7AE jz short loc_1000B7B4
.text:1000B7B0 cmp ecx, esi
.text:1000B7B2 jz short loc_1000B7BE
.text:1000B7B4
.text:1000B7B4 loc_1000B7B4: ; CODE XREF: EnumFirstValidChild+9Ej
.text:1000B7B4 call ds:_invalid_parameter_noinfo
.text:1000B7BA mov eax, [esp+38h+var_24]
.text:1000B7BE
.text:1000B7BE loc_1000B7BE: ; CODE XREF: EnumFirstValidChild+A2j
.text:1000B7BE mov esi, [ebp+arg_4]
.text:1000B7C1 cmp ebx, eax
.text:1000B7C3 jz short loc_1000B80B
.text:1000B7C5 lea ecx, [esp+38h+var_20]
.text:1000B7C9 call sub_10008390
.text:1000B7CE mov ebx, [eax+4]
.text:1000B7D1 test ebx, ebx
.text:1000B7D3 jz short loc_1000B80B
.text:1000B7D5 push esi
.text:1000B7D6 push 0
.text:1000B7D8 mov ecx, ebx
.text:1000B7DA call sub_1001D620
.text:1000B7DF test eax, eax
.text:1000B7E1 jz short loc_1000B80B
.text:1000B7E3 push dword_1002ACE4
.text:1000B7E9 lea eax, [esp+3Ch+var_24]
.text:1000B7ED push eax
.text:1000B7EE push 8
.text:1000B7F0 push 1
.text:1000B7F2 call ds:api_func_107
.text:1000B7F8 mov edi, [esp+38h+var_24]
.text:1000B7FC test edi, edi
.text:1000B7FE jz short loc_1000B80B
.text:1000B800 mov [edi], ebx
.text:1000B802 mov dword ptr [edi+4], 0
.text:1000B809 jmp short loc_1000B824
.text:1000B80B ; ---------------------------------------------------------------------------
.text:1000B80B
.text:1000B80B loc_1000B80B: ; CODE XREF: EnumFirstValidChild+B3j
.text:1000B80B ; EnumFirstValidChild+C3j ...
.text:1000B80B xor eax, eax
.text:1000B80D mov [esi], eax
.text:1000B80F mov [esi+4], eax
.text:1000B812 mov [esi+8], eax
.text:1000B815 mov [esi+0Ch], eax
.text:1000B818 mov [esi+10h], eax
.text:1000B81B mov [esi+14h], eax
.text:1000B81E mov [esi+18h], eax
.text:1000B821 mov [esi+1Ch], eax
.text:1000B824
.text:1000B824 loc_1000B824: ; CODE XREF: EnumFirstValidChild+F9j
.text:1000B824 mov ecx, [esp+38h+var_C]
.text:1000B828 mov eax, edi
.text:1000B82A pop edi
.text:1000B82B pop esi
.text:1000B82C mov large fs:0, ecx
.text:1000B833 pop ebx
.text:1000B834 mov esp, ebp
.text:1000B836 pop ebp
.text:1000B837 retn 8
.text:1000B837 EnumFirstValidChild endp
.text:1000B837
.text:1000B837 ; ---------------------------------------------------------------------------
Decompiled code of sub_10029900
.
signed int __thiscall sub_10029900(void *this, int a2) //note that I changed *this to *a1
{
int v2; // esi@1
int v3; // ebx@1
int v4; // eax@1
int v5; // edx@3
int v6; // eax@5
signed int v7; // esi@5
bool v8; // cf@7
signed int v9; // eax@8
int v11; // [sp+10h] [bp-20h]@1
v2 = 0;
v3 = EnumFirstValidChild(this, &v11);
v4 = 1;
if ( v3 )
{
while ( v4 )
{
v5 = v11;
if ( v11 && a2 )
{
v6 = a2;
v7 = 12;
while ( *(_DWORD *)v5 == *(_DWORD *)v6 )
{
v5 += 4;
v6 += 4;
v8 = (unsigned int)v7 < 4;
v7 -= 4;
if ( v8 )
{
v9 = 1;
goto LABEL_10;
}
}
v9 = 0;
LABEL_10:
if ( v9 )
{
EndEnumValidChild(v3);
return 1;
}
}
v4 = EnumNextValidChild(v3, &v11);
}
v2 = 0;
}
EndEnumValidChild(v3);
return v2;
}
Decompiled code of EnumFirstValidChild
.
int __userpurge EnumFirstValidChild<eax>(int a1<eax>, int a2, int a3)
{
int v3; // ecx@1
int v4; // edi@1
int v5; // esi@6
int v6; // eax@6
int v7; // ecx@6
int v8; // ebx@6
int v9; // eax@6
int v10; // ebx@10
int v12; // [sp+1Ch] [bp-28h]@2
int v13; // [sp+20h] [bp-24h]@2
int v14; // [sp+24h] [bp-20h]@6
int v15; // [sp+28h] [bp-1Ch]@6
char v16; // [sp+2Ch] [bp-18h]@6
int v17; // [sp+38h] [bp-Ch]@1
int (__cdecl *v18)(); // [sp+3Ch] [bp-8h]@1
int v19; // [sp+40h] [bp-4h]@1
v19 = -1;
v18 = SEH_1001DAD0;
v17 = a1;
v3 = dword_1002ACE8;
v4 = 0;
if ( !dword_1002ACE8 )
{
api_func_107(1, 124, &v12, dword_1002ACE4);
v13 = v12;
v19 = 0;
if ( v12 )
v3 = sub_10005440(v12);
else
v3 = 0;
v19 = -1;
dword_1002ACE8 = v3;
}
v5 = v3 + 52;
v13 = a2;
v6 = sub_10008330(v3 + 52, (int)&v16, (int)&v13);
v7 = *(_DWORD *)v6;
v8 = *(_DWORD *)(v6 + 4);
v9 = *(_DWORD *)(v5 + 4);
v14 = v7;
v15 = v8;
v13 = v9;
if ( !v7 || v7 != v5 )
{
invalid_parameter_noinfo(v7);
v9 = v13;
}
if ( v8 != v9
&& (v10 = *(_DWORD *)(sub_10008390(&v14) + 4)) != 0
&& sub_1001D620(v10, 0, a3)
&& (api_func_107(1, 8, &v13, dword_1002ACE4), (v4 = v13) != 0) )
{
*(_DWORD *)v13 = v10;
*(_DWORD *)(v4 + 4) = 0;
}
else
{
*(_DWORD *)a3 = 0;
*(_DWORD *)(a3 + 4) = 0;
*(_DWORD *)(a3 + 8) = 0;
*(_DWORD *)(a3 + 12) = 0;
*(_DWORD *)(a3 + 16) = 0;
*(_DWORD *)(a3 + 20) = 0;
*(_DWORD *)(a3 + 24) = 0;
*(_DWORD *)(a3 + 28) = 0;
}
return v4;
}