这个x86 mov如何反向工作?

How does this x86 mov work in reverse?

我正在阅读《实用恶意软件分析》一书,其中出现了以下示例代码:

00401022 call ds:CoCreateInstance
00401028 mov eax, [esp+24h+ppv]

作者接着说:

The COM object returned will be stored on the stack in a variable that IDA Pro has labeled ppv, as shown.

我的问题是,这是为什么?因为我们做了一个 mov eax,[esp+24h+ppv],这不会是将 [esp+24h+ppv] 中的数据移动到 eax 中并 覆盖 return 值 而不是将 return 值存储在变量中?我认为在 Intel 格式中,mov operand1, operand 2 总是将第二个操作数放入第一个。

注意:顺便说一下,如果有人碰巧有这本书,它是第 558 页。

从作者对代码的描述中可以清楚地看出,这些操作数是按 AT&T 顺序排列的(首先是源,然后是目标)。作者之前是否指定代码是按英特尔顺序编写的,或者这只是您的假设?使用这两种风格编写 x86 程序集很常见(不幸且令人困惑),如另一个问题所述:

MOV src dest (or) MOV dest src?

我对 COM 的经验很少,但快速浏览 MSDNs CoCreateInstance function 就会发现这个签名

HRESULT CoCreateInstance(
  _In_  REFCLSID  rclsid,
  _In_  LPUNKNOWN pUnkOuter,
  _In_  DWORD     dwClsContext,
  _In_  REFIID    riid,
  _Out_ LPVOID    *ppv
);

所以 CoCreateInstance 做了 return 一个名为 ppvout 参数,它似乎很方便地由 提取IDA Pro 还有。

ppvout值定义为

Address of pointer variable that receives the interface pointer requested in riid. Upon successful return, *ppv contains the requested interface pointer. Upon failure, *ppv contains NULL.

据推测 return 编辑在 EAX 中的 return 值只是以下五个值之一:

  • S_OK: 成功创建了指定对象的实例class。
  • REGDB_E_CLASSNOTREG: 指定的class没有在注册数据库中注册。也可能表明您在 CLSCTX 枚举中请求的服务器类型未注册或注册表中服务器类型的值已损坏。
  • CLASS_E_NOAGGREGATION:此 class 无法创建为聚合的一部分。
  • E_NOINTERFACE: 指定的 class 没有实现请求的接口,或者控制 IUnknown 没有公开请求的接口。
  • E_POINTER: ppv参数为NULL。

returned ppv 值是指向 COM 对象 的真正指针,然后使用

mov eax, [esp+24h+ppv]

说明。因此,包含可能错误代码的 return 值(除 S_OK 以外的任何内容)都会立即被覆盖(因此它假定 COM 调用成功)。

DWORD PTR [esp+24h+ppv](以某种方式)指向 COM 对象的基地址,将其加载到 EAX.

但是我不能表示寻址方式。也许是IDA Pro的一种特殊语法显示。

从那里开始,EAX 中的这个指针用于访问 COM 对象,并且 - 更进一步 - 它的方法如评论中所述。

This CodeProject article 可能会让您有更深入的了解。