首页
社区
课程
招聘
同一个函数stdcall和cdecl可以合用?

最近在反汇编的时候发现一个函数,有四个参数,函数结尾是retn 4,调用者调用完函数有add esp,0ch,这就让我有点懵了,请问什么调用约定会是这样的情况?可以确定这个函数有两个及以上参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
……
LOAD:014B46E4 loc_14B46E4:
LOAD:014B46E4                 sub     esp, 0Ch
LOAD:014B46E7                 push    eax
LOAD:014B46E8                 call    sub_14A9726
LOAD:014B46ED                 add     esp, 10h
LOAD:014B46F0                 mov     edi, eax
LOAD:014B46F2                 test    edi, edi
LOAD:014B46F4                 jnz     short loc_14B46FB
LOAD:014B46F6                 call    sub_415FAD8
LOAD:014B46FB loc_14B46FB:
LOAD:014B46FB                 push    0
LOAD:014B46FD                 push    1
LOAD:014B46FF                 push    edi
LOAD:014B4700                 push    esi
LOAD:014B4701                 call    sub_ED54D6   <---这个函数
LOAD:014B4706                 add     esp, 0Ch
LOAD:014B4709
LOAD:014B4709 loc_14B4709:
LOAD:014B4709                 mov     eax, esi
LOAD:014B470B                 pop     esi
LOAD:014B470C                 pop     edi
LOAD:014B470D                 pop     ebx
……
1
2
3
4
5
6
7
8
9
10
11
12
13
LOAD:00ED54D6                 push    ebp
LOAD:00ED54D7                 push    ebx
LOAD:00ED54D8                 push    edi
LOAD:00ED54D9                 push    esi
……
LOAD:00ED5593                 sub     esp, 4
LOAD:00ED5596                 mov     eax, esi
LOAD:00ED5598                 add     esp, 2Ch
LOAD:00ED559B                 pop     esi
LOAD:00ED559C                 pop     edi
LOAD:00ED559D                 pop     ebx
LOAD:00ED559E                 pop     ebp
LOAD:00ED559F                 retn    4
收藏
4条回答
higherlin 2022-4-23 2022-4-23编辑

用Clang显式地声明attribute((thiscall))可以有类似的效果,不过像这种情况的话被调用者是清理三个参数,调用者清理一个参数。哪位前辈能回答一下这是怎么回事?是不是还有其它调约定?

回复
tfrist 2022-4-27

这跟编译器有关!能否提供源代码?和用的什么编译器。
能否列一下在sub_ED54D6中其他参数被使用的情况的ASM指令?

回复
higherlin: 这是反汇编第三方的安卓文件,这是一个类的成品函数,正常情况下,第一个函数是this指针,有点奇怪的是,  这个函数第二个参数才是this指针,返回时出栈的应该是第一个参数,这一类函数还蛮多的,但是大部分函数又是正常调用约定。
应该是和编译器有关的特殊调用编写,就目前我接触过的VC,CLang,GCC好像是没有这类调用约定,可能是我接触得不够深。
以下是汇编代码:
```
LOAD:00ED54D6  sub_ED54D6            proc  near                              ;  CODE  XREF:  sub_BAB56B+105↑p
LOAD:00ED54D6                                                                                  ;  sub_BAB56B+302↑p  ...
LOAD:00ED54D6
LOAD:00ED54D6  var_3C                    =  dword  ptr  -3Ch
LOAD:00ED54D6  var_38                    =  dword  ptr  -38h
LOAD:00ED54D6  var_34                    =  qword  ptr  -34h
LOAD:00ED54D6  var_2C                    =  qword  ptr  -2Ch
LOAD:00ED54D6  var_24                    =  qword  ptr  -24h
LOAD:00ED54D6  var_1C                    =  qword  ptr  -1Ch
LOAD:00ED54D6  var_14                    =  dword  ptr  -14h
LOAD:00ED54D6  arg_0                      =  dword  ptr    4
LOAD:00ED54D6  arg_4                      =  dword  ptr    8
LOAD:00ED54D6  arg_8                      =  dword  ptr    0Ch
LOAD:00ED54D6
LOAD:00ED54D6                                  push        ebp
LOAD:00ED54D7                                  push        ebx
LOAD:00ED54D8                                  push        edi
LOAD:00ED54D9                                  push        esi
LOAD:00ED54DA                                  sub          esp,  2Ch
LOAD:00ED54DD                                  call        $+5
LOAD:00ED54E2                                  pop          ebx
LOAD:00ED54E3                                  add          ebx,  5F637BAh
LOAD:00ED54E9                                  mov          esi,  [esp+3Ch+arg_0]
LOAD:00ED54ED                                  mov          ecx,  [esp+3Ch+arg_8]
LOAD:00ED54F1                                  mov          eax,  [esp+3Ch+arg_4]
LOAD:00ED54F5                                  xor          edx,  edx
LOAD:00ED54F7                                  inc          edx
LOAD:00ED54F8                                  mov          edi,  edx
LOAD:00ED54FA                                  mov          ebp,  ecx
LOAD:00ED54FC                                  shl          edi,  cl
LOAD:00ED54FE                                  mov          ecx,  edi
LOAD:00ED5500                                  sar          ecx,  1Fh
LOAD:00ED5503                                  and          ecx,  [eax+30h]
LOAD:00ED5506                                  and          edi,  [eax+2Ch]
LOAD:00ED5509                                  cmp          edi,  edx
LOAD:00ED550B                                  sbb          ecx,  0
LOAD:00ED550E                                  jl            short  loc_ED5522
LOAD:00ED5510                                  mov          dword  ptr  [esp+3Ch+var_34],  ebp
LOAD:00ED5514                                  mov          [esp+3Ch+var_38],  eax
LOAD:00ED5518                                  mov          [esp+3Ch+var_3C],  esi
LOAD:00ED551B                                  call        sub_ED63F3
LOAD:00ED5520                                  jmp          short  loc_ED5593
LOAD:00ED5522  ;  ---------------------------------------------------------------------------
LOAD:00ED5522
LOAD:00ED5522  loc_ED5522:                                                          ;  CODE  XREF:  sub_ED54D6+38↑j
LOAD:00ED5522                                  mov          edi,  [eax+28h]
LOAD:00ED5525                                  test        edi,  edi
LOAD:00ED5527                                  jnz          short  loc_ED552E
LOAD:00ED5529                                  call        sub_415FAD8
LOAD:00ED552E  ;  ---------------------------------------------------------------------------
LOAD:00ED552E
LOAD:00ED552E  loc_ED552E:                                                          ;  CODE  XREF:  sub_ED54D6+51↑j
LOAD:00ED552E                                  mov          ecx,  ebp
LOAD:00ED5530                                  cmp          [edi+0Ch],  ecx
LOAD:00ED5533                                  ja            short  loc_ED554E
LOAD:00ED5535                                  mov          ebp,  ecx
LOAD:00ED5537                                  call        sub_4160752
LOAD:00ED553C                                  mov          [esp+3Ch+var_3C],  eax
LOAD:00ED553F                                  mov          [esp+3Ch+var_38],  0
LOAD:00ED5547                                  call        sub_415F99C
LOAD:00ED554C  ;  ---------------------------------------------------------------------------
LOAD:00ED554C                                  mov          ecx,  ebp
LOAD:00ED554E
LOAD:00ED554E  loc_ED554E:                                                          ;  CODE  XREF:  sub_ED54D6+5D↑j
LOAD:00ED554E                                  shl          ecx,  5
LOAD:00ED5551                                  xor          eax,  eax
LOAD:00ED5553                                  mov          [esp+3Ch+var_14],  eax
LOAD:00ED5557                                  mov          [esp+3Ch+var_38],  eax
LOAD:00ED555B                                  mov          [esp+3Ch+var_3C],  esi
LOAD:00ED555E                                  movsd      xmm0,  qword  ptr  [edi+ecx+28h]
LOAD:00ED5564                                  movsd      [esp+3Ch+var_1C],  xmm0
LOAD:00ED556A                                  movsd      xmm0,  qword  ptr  [edi+ecx+20h]
LOAD:00ED5570                                  movsd      [esp+3Ch+var_24],  xmm0
LOAD:00ED5576                                  movsd      xmm0,  qword  ptr  [edi+ecx+10h]
LOAD:00ED557C                                  movsd      xmm1,  qword  ptr  [edi+ecx+18h]
LOAD:00ED5582                                  movsd      [esp+3Ch+var_2C],  xmm1
LOAD:00ED5588                                  movsd      [esp+3Ch+var_34],  xmm0
LOAD:00ED558E                                  call        ObscuredFP_op_Implicit
LOAD:00ED5593
LOAD:00ED5593  loc_ED5593:                                                          ;  CODE  XREF:  sub_ED54D6+4A↑j
LOAD:00ED5593                                  sub          esp,  4
LOAD:00ED5596                                  mov          eax,  esi
LOAD:00ED5598                                  add          esp,  2Ch
LOAD:00ED559B                                  pop          esi
LOAD:00ED559C                                  pop          edi
LOAD:00ED559D                                  pop          ebx
LOAD:00ED559E                                  pop          ebp
LOAD:00ED559F                                  retn        4
```

以下是反编译代码:
```
int  __userpurge  sub_ED54D6@<eax>(int  a1,  _DWORD  *a2,  unsigned  int  a3)
{
    int  v3;  //  ecx
    unsigned  int  v4;  //  edi
    unsigned  __int8  v5;  //  of
    int  v6;  //  ecx
    int  v7;  //  edi
    int  v8;  //  eax
    __int64  v9;  //  ST24_8
    __int64  v10;  //  ST1C_8
    __int128  v11;  //  xmm0
    __int64  v12;  //  ST14_8

    v3  =  a2[12]  &  (1  <<  a3  >>  31);
    v4  =  a2[11]  &  (1  <<  a3);
    v5  =  __OFSUB__(v3,  v4  <  1);
    v6  =  v3  -  (v4  <  1);
    if  (  (v6  <  0)  ^  v5  )
    {
        v7  =  a2[10];
        if  (  !v7  )
            sub_415FAD8(v6);
        if  (  *(_DWORD  *)(v7  +  12)  <=  a3  )
        {
            v8  =  sub_4160752();
            sub_415F99C(v8,  0);
        }
        v9  =  *(_QWORD  *)(v7  +  32  *  a3  +  40);
        v10  =  *(_QWORD  *)(v7  +  32  *  a3  +  32);
        v11  =  *(unsigned  __int64  *)(v7  +  32  *  a3  +  16);
        v12  =  *(_QWORD  *)(v7  +  32  *  a3  +  24);
        ObscuredFP_op_Implicit(a1);
    }
    else
    {
        sub_ED63F3(a1);
    }
    return  a1;
}
```
回复 2022-4-30
higherlin 2022-4-30

@tfrist
这是反汇编第三方的安卓文件,这是一个类的成品函数,正常情况下,第一个函数是this指针,有点奇怪的是, 这个函数第二个参数才是this指针,返回时出栈的应该是第一个参数,这一类函数还蛮多的,但是大部分函数又是正常调用约定。
应该是和编译器有关的特殊调用编写,就目前我接触过的VC,CLang,GCC好像是没有这类调用约定,可能是我接触得不够深。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
LOAD:00ED54D6 sub_ED54D6      proc near               ; CODE XREF: sub_BAB56B+105↑p
LOAD:00ED54D6                                         ; sub_BAB56B+302↑p ...
LOAD:00ED54D6
LOAD:00ED54D6 var_3C          = dword ptr -3Ch
LOAD:00ED54D6 var_38          = dword ptr -38h
LOAD:00ED54D6 var_34          = qword ptr -34h
LOAD:00ED54D6 var_2C          = qword ptr -2Ch
LOAD:00ED54D6 var_24          = qword ptr -24h
LOAD:00ED54D6 var_1C          = qword ptr -1Ch
LOAD:00ED54D6 var_14          = dword ptr -14h
LOAD:00ED54D6 arg_0           = dword ptr  4
LOAD:00ED54D6 arg_4           = dword ptr  8
LOAD:00ED54D6 arg_8           = dword ptr  0Ch
LOAD:00ED54D6
LOAD:00ED54D6                 push    ebp
LOAD:00ED54D7                 push    ebx
LOAD:00ED54D8                 push    edi
LOAD:00ED54D9                 push    esi
LOAD:00ED54DA                 sub     esp, 2Ch
LOAD:00ED54DD                 call    $+5
LOAD:00ED54E2                 pop     ebx
LOAD:00ED54E3                 add     ebx, 5F637BAh
LOAD:00ED54E9                 mov     esi, [esp+3Ch+arg_0]
LOAD:00ED54ED                 mov     ecx, [esp+3Ch+arg_8]
LOAD:00ED54F1                 mov     eax, [esp+3Ch+arg_4]
LOAD:00ED54F5                 xor     edx, edx
LOAD:00ED54F7                 inc     edx
LOAD:00ED54F8                 mov     edi, edx
LOAD:00ED54FA                 mov     ebp, ecx
LOAD:00ED54FC                 shl     edi, cl
LOAD:00ED54FE                 mov     ecx, edi
LOAD:00ED5500                 sar     ecx, 1Fh
LOAD:00ED5503                 and     ecx, [eax+30h]
LOAD:00ED5506                 and     edi, [eax+2Ch]
LOAD:00ED5509                 cmp     edi, edx
LOAD:00ED550B                 sbb     ecx, 0
LOAD:00ED550E                 jl      short loc_ED5522
LOAD:00ED5510                 mov     dword ptr [esp+3Ch+var_34], ebp
LOAD:00ED5514                 mov     [esp+3Ch+var_38], eax
LOAD:00ED5518                 mov     [esp+3Ch+var_3C], esi
LOAD:00ED551B                 call    sub_ED63F3
LOAD:00ED5520                 jmp     short loc_ED5593
LOAD:00ED5522 ; ---------------------------------------------------------------------------
LOAD:00ED5522
LOAD:00ED5522 loc_ED5522:                             ; CODE XREF: sub_ED54D6+38↑j
LOAD:00ED5522                 mov     edi, [eax+28h]
LOAD:00ED5525                 test    edi, edi
LOAD:00ED5527                 jnz     short loc_ED552E
LOAD:00ED5529                 call    sub_415FAD8
LOAD:00ED552E ; ---------------------------------------------------------------------------
LOAD:00ED552E
LOAD:00ED552E loc_ED552E:                             ; CODE XREF: sub_ED54D6+51↑j
LOAD:00ED552E                 mov     ecx, ebp
LOAD:00ED5530                 cmp     [edi+0Ch], ecx
LOAD:00ED5533                 ja      short loc_ED554E
LOAD:00ED5535                 mov     ebp, ecx
LOAD:00ED5537                 call    sub_4160752
LOAD:00ED553C                 mov     [esp+3Ch+var_3C], eax
LOAD:00ED553F                 mov     [esp+3Ch+var_38], 0
LOAD:00ED5547                 call    sub_415F99C
LOAD:00ED554C ; ---------------------------------------------------------------------------
LOAD:00ED554C                 mov     ecx, ebp
LOAD:00ED554E
LOAD:00ED554E loc_ED554E:                             ; CODE XREF: sub_ED54D6+5D↑j
LOAD:00ED554E                 shl     ecx, 5
LOAD:00ED5551                 xor     eax, eax
LOAD:00ED5553                 mov     [esp+3Ch+var_14], eax
LOAD:00ED5557                 mov     [esp+3Ch+var_38], eax
LOAD:00ED555B                 mov     [esp+3Ch+var_3C], esi
LOAD:00ED555E                 movsd   xmm0, qword ptr [edi+ecx+28h]
LOAD:00ED5564                 movsd   [esp+3Ch+var_1C], xmm0
LOAD:00ED556A                 movsd   xmm0, qword ptr [edi+ecx+20h]
LOAD:00ED5570                 movsd   [esp+3Ch+var_24], xmm0
LOAD:00ED5576                 movsd   xmm0, qword ptr [edi+ecx+10h]
LOAD:00ED557C                 movsd   xmm1, qword ptr [edi+ecx+18h]
LOAD:00ED5582                 movsd   [esp+3Ch+var_2C], xmm1
LOAD:00ED5588                 movsd   [esp+3Ch+var_34], xmm0
LOAD:00ED558E                 call    ObscuredFP_op_Implicit
LOAD:00ED5593
LOAD:00ED5593 loc_ED5593:                             ; CODE XREF: sub_ED54D6+4A↑j
LOAD:00ED5593                 sub     esp, 4
LOAD:00ED5596                 mov     eax, esi
LOAD:00ED5598                 add     esp, 2Ch
LOAD:00ED559B                 pop     esi
LOAD:00ED559C                 pop     edi
LOAD:00ED559D                 pop     ebx
LOAD:00ED559E                 pop     ebp
LOAD:00ED559F                 retn    4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
int __userpurge sub_ED54D6@<eax>(int a1, _DWORD *a2, unsigned int a3)
{
  int v3; // ecx
  unsigned int v4; // edi
  unsigned __int8 v5; // of
  int v6; // ecx
  int v7; // edi
  int v8; // eax
  __int64 v9; // ST24_8
  __int64 v10; // ST1C_8
  __int128 v11; // xmm0
  __int64 v12; // ST14_8
 
  v3 = a2[12] & (1 << a3 >> 31);
  v4 = a2[11] & (1 << a3);
  v5 = __OFSUB__(v3, v4 < 1);
  v6 = v3 - (v4 < 1);
  if ( (v6 < 0) ^ v5 )
  {
    v7 = a2[10];
    if ( !v7 )
      sub_415FAD8(v6);
    if ( *(_DWORD *)(v7 + 12) <= a3 )
    {
      v8 = sub_4160752();
      sub_415F99C(v8, 0);
    }
    v9 = *(_QWORD *)(v7 + 32 * a3 + 40);
    v10 = *(_QWORD *)(v7 + 32 * a3 + 32);
    v11 = *(unsigned __int64 *)(v7 + 32 * a3 + 16);
    v12 = *(_QWORD *)(v7 + 32 * a3 + 24);
    ObscuredFP_op_Implicit(a1);
  }
  else
  {
    sub_ED63F3(a1);
  }
  return a1;
}
回复
不会用Python 2022-5-1

我不明白为什么我提问的问题一直显示内容违规??我看来看去都对的啊!!!

回复