【问题标题】:Why is a wchar_t* variable being clobbered?为什么 wchar_t* 变量被破坏?
【发布时间】:2020-01-08 16:29:27
【问题描述】:

我正在使用以下代码。 DLLName 的类型为wchar_t*,并且它在我的程序的早期设置。在我的代码中达到这一点之前,DLLName 是 DLL 的有效路径,例如 L"C:\\Windows\\System32\\advapi32.dll"

wprintf(L"Location: %s\n", DLLName);
HMODULE hDLL = LoadLibraryW(DLLName);

当我的代码到达wprintf 时会发生什么?不打印 DLLName 的值。事实上,DLLName 现在是一个空字符串,L""!这会导致对LoadLibraryW() 的调用失败。

很奇怪。我注释掉wprintf。当调试器到达LoadLibraryW() 时,DLLName 是正确的宽字符串,其中包含指向我的 DLL 的路径。在LoadLibraryW()之后,DLLName的值为L"\x4",调用失败。

这里发生了什么?我对如何调试它一无所知。

编辑:我的所有代码

BOOL FindOriginalCOMServer(wchar_t* GUID, wchar_t** DLLName)
{
    HKEY hKey;
    HKEY hCLSIDKey;
    wchar_t name[MAX_PATH];
    DWORD nameLength = MAX_PATH;

    wprintf(L"[*] Beginning search for GUID %s\n", GUID);

    LONG lResult = RegOpenKeyExW(HKEY_LOCAL_MACHINE, (LPCWSTR)L"SOFTWARE\\Classes\\CLSID", 0, KEY_READ, &hKey);
    if (lResult != ERROR_SUCCESS) {
        wprintf(L"[-] Error getting CLSID path\n");
        return FALSE;
    }

    // Make sure HKLM\Software\Classes\CLSID\{GUID} exists
    lResult = RegOpenKeyExW(hKey, GUID, 0, KEY_READ, &hCLSIDKey);
    if (lResult != ERROR_SUCCESS) {
        wprintf(L"[-] Error getting GUID path\n");
        RegCloseKey(hKey);
        return FALSE;
    }

    // Read the value of HKLM's InProcServer32
    lResult = RegGetValueW(hCLSIDKey, (LPCWSTR)L"InProcServer32", NULL, RRF_RT_ANY, NULL, (PVOID)&name, &nameLength);
    if (lResult != ERROR_SUCCESS) {
        wprintf(L"[-] Error getting InProcServer32 value: %d\n", lResult);
        RegCloseKey(hKey);
        RegCloseKey(hCLSIDKey);
        return FALSE;
    }

    *DLLName = name;
    return TRUE;
}

然后:

wchar_t* DLLName = new wchar_t[MAX_PATH];

if (!FindOriginalCOMServer((wchar_t*)lplpsz, &DLLName))
{
    wprintf(L"[-] Couldn't find original COM server\n");
    return S_FALSE;
}
wprintf("[+] Found original COM server: %s\n", DLLName);
HMODULE hDLL = LoadLibraryW(DLLName);

【问题讨论】:

  • *DLLName = name。在这里,您泄漏了您分配的内存并返回了一个指向本地分配数组的指针,该数组在函数返回后立即被销毁。

标签: c++ visual-studio winapi com


【解决方案1】:

DLLName 将指向FindOriginalCOMServer 中的本地字符数组,一旦该函数返回,该数组将不再存在。

您应该将DLLName 传递给FindOriginalCOMServer() 作为wchar_t*(一个指针,而不是两个),然后摆脱name 并直接使用DLLName。或者,您可以使用wcscpy_s() 将字符串从name 复制到DLLName

【讨论】:

  • 谢谢!那么如果在 FindOriginalCOMServer 返回后该值被销毁,为什么我能够在返回后在调试器中正确查看 DLLName 的值?
  • @david 因为内存还没有被覆盖,但是在技术上它已经被释放并且可以随时被覆盖,这正是后来发生的事情
猜你喜欢
  • 1970-01-01
  • 2012-07-24
  • 2019-02-08
  • 2011-12-05
  • 1970-01-01
  • 1970-01-01
  • 2015-02-06
  • 1970-01-01
  • 2022-11-18
相关资源
最近更新 更多