具有不匹配参数的函数签名

逆向工程 职能 吉德拉
2021-06-25 05:09:11

我有以下由 ghidra 反汇编的代码:

PUSH      EBX
PUSH      dword ptr [EBP + param_1]             wchar_t * _Format for swprintf
PUSH      u_%s\%s_0040eb88                      size_t _Count for swprintf
PUSH      dword ptr [EBP + param_3]             wchar_t * _String for swprintf
CALL      dword ptr [->MSVCRT.DLL::swprintf]

第二个参数是unicode string %s\%s,但是应该是size_t参数,因为swprintf函数需要count参数

这是另一个使用相同功能的代码:

LEA       EAX=>local_4dc,[0xfffffb28 + EBP]
PUSH      EAX                                        wchar_t * _Format for swprintf
LEA       EAX=>windowsDir,[0xfffffd30 + EBP]
PUSH      _Count_0040f40c                            size_t _Count for swprintf
PUSH      EAX                                        wchar_t * _String for swprintf
CALL      EDI=>MSVCRT.DLL::swprintf

再次,_Count_0040f40cunicode 字符串 %/Program Data 被检测为_Count

Ghidra 具有正确的函数签名:

int swprintf (wchar_t * _String, size_t _Count, wchar_t * _Format, ...)

正常计数参数总是缺失,Ghidra 检测到的不是数字类型变量。看起来如果所有函数都是在没有它的情况下编译的。ghidra 检测到的所有这些内存变量作为计数参数实际上都是格式参数。如果每次调用 swprintf 时都有实际的计数参数,一切都会看起来不错。

1个回答

似乎选择的原型不正确。的原始版本swprintf没有计数参数。来自 VS 9.0 (2008) CRT 来源:

#ifndef _COUNT_

int __cdecl _swprintf (
        wchar_t *string,
        const wchar_t *format,
        ...
        )
#else  /* _COUNT_ */

#ifndef _SWPRINTFS_ERROR_RETURN_FIX
/* Here we implement _snwprintf without the
return value bugfix */

int __cdecl _snwprintf (
        wchar_t *string,
        size_t count,
        const wchar_t *format,
        ...
        )
#else  /* _SWPRINTFS_ERROR_RETURN_FIX */
int __cdecl _swprintf_c (
        wchar_t *string,
        size_t count,
        const wchar_t *format,
        ...
        )
#endif  /* _SWPRINTFS_ERROR_RETURN_FIX */