调用系统插件后从结构中获取信息 [英] Getting info from struct after calling system plugin

查看:45
本文介绍了调用系统插件后从结构中获取信息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过系统插件和 netapi32 库从 Windows 获取一些信息.

I am trying to get some info from windows via the System plugin and the netapi32 library.

在分配适合作为 WKSTA_INFO_100 的结构后,我尝试调用 NetWkstaGetInfo().

I try to call NetWkstaGetInfo() after allocating a struct suitable as a WKSTA_INFO_100.

MSDN 中的 NetWkstaGetInfo() 原型说明:

The NetWkstaGetInfo() prototype states in MSDN:

NET_API_STATUS NetWkstaGetInfo(
  _In_   LPWSTR servername,
  _In_   DWORD level,
  _Out_  LPBYTE *bufptr
);

虽然 WKSTA_INFO_100

typedef struct _WKSTA_INFO_100 {
  DWORD wki100_platform_id;
  LMSTR wki100_computername;
  LMSTR wki100_langroup;
  DWORD wki100_ver_major;
  DWORD wki100_ver_minor;
} WKSTA_INFO_100, *PWKSTA_INFO_100, *LPWKSTA_INFO_100;

为了初步测试,我尝试在消息框中显示结构成员.我首先用虚拟信息初始化结构,以检查 api 调用是否替换了我分配的块的内容.

For a preliminary test, I try to display the struct members in a messagebox. I first initialize the struct with dummy info to check if the api call replaces the content of my allocated block.

但是直到现在我在第一个结构体成员之后几乎什么也没有得到,我想结构体没有正确定义,或者我有结构体对齐问题.不幸的是,系统插件的奇怪文档让我发疯 对我没有多大帮助.

But until now I got barely nothing after the first struct member, I suppose that the struct is not correctly defined, or that I have a struct alignment issue. Unfortunately the weird documentation of the System plugin is driving me nuts does not help me much.

这是我的测试脚本:

outfile "hello.exe"

section

System::Call /NOUNLOAD "*(*i11,t 'some',t 'thing',i22,i44)i .r0"
Dumpstate::debug
System::Call /NOUNLOAD "netapi32::NetWkstaGetInfo(i0, i100, i r0) i.r6"
Dumpstate::debug
System::Call /NOUNLOAD "*$0(*i.r1, t.r2, t.r3, i.r4, i.r5)"
Dumpstate::debug
messagebox MB_OK "Hello, to $2 $3 domain (win $1 - $4.$5) !"
System::Free $0

sectionEnd

第一个检索到的值 (500) 是正确的.但其他成员保持其初始值.我缺少什么?

The first retrieved value (500) is correct. But the other members keep their initial value. What I am missing?

(编辑) 推论问题:

  • 似乎按照文档和 MSDN,结构的第一个成员应该是 i 而不是 *i 但我没有设法获得正确的返回值没有 *(Dumpstate 插件倾向于显示它作为地址返回)
  • 插件的 /NOUNLOAD 参数是强制性的吗?我找到了几个例子,但没有找到确切的原因.我担心分配的结构可能会在没有参数的情况下过早释放.你能确认/体弱多病吗?
  • it seems that following the documentation and MSDN, the first member of the struct should be i and not *i but I did not managed to get a correct returned value without the * (the Dumpstate plugin tends to show it is returned as an address)
  • is the /NOUNLOAD parameter for the plugin mandatory? I have found several examples with it but did not find a precise reason for it. I feared that the allocated struct could have been freed prematurely without the parameter. Could you confirm / infirm?

推荐答案

bufptr 仅输出,因此将 r0 作为输入传递给 NetWkstaGetInfo 毫无意义,该函数不需要输入数据.你不应该把*i和NetApiBufferFree一起用,i就够了($0已经有地址了,你不想让系统插件玩指针,直接传它直接到 API)

bufptr is out only so passing r0 as input to NetWkstaGetInfo is pointless, the function does not require input data. You should not use *i with NetApiBufferFree, i alone is enough ($0 already has the address, you don't want the system plugin to play with the pointer, just pass it straight to the API)

!include LogicLib.nsh

System::Call "netapi32::NetWkstaGetInfo(i0, i100, *i 0 r0) i.r1"
${If} 0 = $1
    System::Call "*$0(i.r1, w.r2, w.r3, i.r4, i.r5)"
    DetailPrint "Hello, to $2 $3 domain (win $1 - $4.$5) !"
${EndIf}
System::Call "netapi32::NetApiBufferFree(ir0)"

在前面的示例中,我使用 *i 0 r0 作为 bufptr 参数,以便在函数启动之前 $0 为 NULL(如果您不想使用此技巧,您可以执行 StrCpy $0 0 在系统调用之前).如果您不这样做,则不清楚如果函数失败会发生什么.文档没有指定当函数失败时 bufptr 会发生什么,希望它被设置为 NULL 但你不能确定.如果函数失败,我们最终将 NULL 传递给 NetApiBufferFree,这通常是传递给自由函数的安全事情,但文档并未将其称为 OK.为了超级安全,你应该只释放一个非空指针:

In the preceding example I used *i 0 r0 for the bufptr parameter so that $0 is NULL before the function starts (If you don't want to use this trick you can just do StrCpy $0 0 before the system call). If you don't do this then it is unclear what happens if the function fails. The documentation does not specify what happens to bufptr when the function fails, hopefully it is set to NULL but you cannot know for sure. If the function fails we end up passing NULL to NetApiBufferFree and that is usually a safe thing to pass to a free function but the documentation does not call this out as OK. To be on the super safe side you should only free a non-NULL pointer:

System::Call "netapi32::NetWkstaGetInfo(i0, i100, *i 0 r0) i.r1"
${If} 0 = $1
    System::Call "*$0(i.r1, w.r2, w.r3, i.r4, i.r5)"
    DetailPrint "Hello, to $2 $3 domain (win $1 - $4.$5) !"
${EndIf}
${IfThen} $0 <> 0 ${|} System::Call "netapi32::NetApiBufferFree(ir0)" ${|}
SectionEnd

<小时>使用系统插件时不再需要

/NOUNLOAD(自 v2.42 起)./NOUNLOAD 阻止 NSIS 卸载插件.如果插件具有内部状态,这很重要,但在您的情况下,唯一的状态是 Windows 分配的内存块.


/NOUNLOAD is no longer required when using the system plugin (Since v2.42). /NOUNLOAD prevents NSIS from unloading the plugin. That is important if the plugin has internal state but in your case the only state is a block of memory allocated by Windows.

这篇关于调用系统插件后从结构中获取信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆