我一直在开发一个使用 Win32 C++ 枚举 Windows 中共享的函数,但遇到了障碍。
net share
显示了所有带有默认共享的共享,这很好。但由于以下代码的某种原因,该程序因此没有返回任何份额。我尝试使用 _SHARE_INFO_1
、_SHARE_INFO_2
和 _SHARE_INFO_501
。
在 IDA Free 中,我看到
net.exe
调用 NetShareEnum()
并且它从 NetWkstaGetInfo()
获取我认为的服务器名称。 Ghidra 说进口就在那里,而且看起来没有任何其他进口,比如 GetComputerNameEx
等。
无论如何,我想知道我是否必须调用登录,或者我的 AV 是否阻止了我或其他什么?
这是代码。该功能以
ERROR_SUCCESS
结束。在调试中,函数调用后 totalEntries
和 entriesRead
为零。
std::list<String> FileSystem::listShares() {
std::list<String> shares;
_SHARE_INFO_502* buffer, p;
LPWKSTA_INFO_100 pBuf = NULL;
NET_API_STATUS nStatus;
// Retrieve workstation information at level 100
nStatus = NetWkstaGetInfo(NULL, 100, (LPBYTE*)&pBuf);
if (nStatus != NERR_Success) {
Util::printError(L"NetWkstaGetInfo");
}
LPWSTR serverName = pBuf->wki100_computername;
DWORD entriesRead;
DWORD totalEntries;
DWORD resumeHandle;
DWORD result = NetShareEnum(serverName, 502, (LPBYTE*)&buffer, MAX_PREFERRED_LENGTH, &entriesRead, &totalEntries, &resumeHandle);
std::wstringstream ss;
if (result == 0) {
for (DWORD i = 0; i < entriesRead; i++) {
p = buffer[i];
ss << L"Share Name: " << p.shi502_netname << L"\n\tShare Type: " << p.shi502_type << L"\n\tRemark: " << p.shi502_remark << std::endl;
shares.push_back(ss.str());
ss.str(L"");
}
}
else {
Util::printError(L"NetShareEnum");
}
return shares;
}
我做错了什么,如何解决?
正如@Luke在评论中提到的,你有未定义的行为,因为你没有正确初始化
resumeHandle
,所以NetShareEnum()
的结果是不可预测的。
NetShareEnum()
文档:
[输入,输出]resume_handle
指向包含恢复句柄的值的指针,该恢复句柄用于继续现有的共享搜索。 第一次调用时句柄应为零,并在后续调用中保持不变。如果resume_handle为NULL,则不存储恢复句柄。
此外,如果
NetWkstaGetInfo()
失败,你就有 UB,如果成功,你就会泄漏它的缓冲区。
您也泄漏了
NetShareEnum()
缓冲区。