这个x86 mov如何反向工作?

时间:2017-03-04 03:43:04

标签: assembly com x86

我正在阅读“实用恶意软件分析”一书,其中显示了以下示例代码:

import XCTest
import CoreData

class RCCoreDataMigrationTests: XCTestCase {

    private let storeType = NSSQLiteStoreType
    private let modelName = "Model"
    private let modelNameVersionFormatString = "Model-%@"

    private func storeURL(_ version: String) -> URL? {
        let storeURL = URL(fileURLWithPath: "\(NSTemporaryDirectory())\(version).sqlite" )
        return storeURL
    }

    private func createObjectModel(_ version: String) -> NSManagedObjectModel? {
        let bundle = Bundle.main
        let managedObjectModelURL = bundle.url(forResource: modelName, withExtension: "momd")
        let managedObjectModelURLBundle = Bundle(url: managedObjectModelURL!)
        let modelVersionName = String(format: modelNameVersionFormatString, version)
        let managedObjectModelVersionURL = managedObjectModelURLBundle!.url(forResource: modelVersionName, withExtension: "mom")
        return NSManagedObjectModel(contentsOf: managedObjectModelVersionURL!)
    }

    private func createStore(_ version: String) -> NSPersistentStoreCoordinator {
        let model = createObjectModel(version)
        let storeCoordinator = NSPersistentStoreCoordinator(managedObjectModel: model!)
        try! storeCoordinator.addPersistentStore(ofType: storeType,
                                                 configurationName: nil,
                                                 at: storeURL(version),
                                                 options: nil)
        return storeCoordinator
    }

    private func migrateStore(fromVersionMOM: String, toVersionMOM: String) {
        let store = createStore(fromVersionMOM)
        let nextVersionObjectModel = createObjectModel(toVersionMOM)!
        let mappingModel = NSMappingModel(from: [Bundle.main], forSourceModel: store.managedObjectModel, destinationModel: nextVersionObjectModel)!
        let migrationManager = NSMigrationManager(sourceModel: store.managedObjectModel, destinationModel: nextVersionObjectModel)
        do {
            try migrationManager.migrateStore(from: store.persistentStores.first!.url!,
                                              sourceType: storeType,
                                              options: nil,
                                              with: mappingModel,
                                              toDestinationURL: storeURL(toVersionMOM)!,
                                              destinationType: NSSQLiteStoreType,
                                              destinationOptions: nil)
        } catch {
            print("Error: \(error)")
            XCTAssertNil(error)
        }
        try! FileManager.default.removeItem(at: storeURL(toVersionMOM)!)
        try! FileManager.default.removeItem(at: storeURL(fromVersionMOM)!)
    }

    func testMigratingStores() {
        migrateStore(fromVersionMOM: "1486", toVersionMOM: "1487")
    }
}

然后,作者说:

  

COM   返回的对象将以IDA Pro标记为ppv 的变量存储在堆栈中,如图所示。

我的问题是,这是为什么?由于我们执行了一个mov eax,[esp + 24h + ppv],这不会将[esp + 24h + ppv]内的数据移动到eax中并且覆盖返回值而不是存储变量中的返回值?我认为在英特尔格式中,mov operand1,操作数2总是将第二个操作数放在第一个操作数中。

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

2 个答案:

答案 0 :(得分:2)

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

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

所以CoCreateInstance确实会返回一个名为ppv out 参数,该参数似乎也很方便地由 IDA Pro 提取。

ppv out 值定义为

  

接收riid中请求的接口指针的指针变量的地址。成功返回后,* ppv包含请求的接口指针。失败时,* ppv包含NULL。

假设在EAX中返回的返回值只是这五个值中的一个:

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

返回的 ppv 值是指向 COM对象的真实指针,然后使用

进行访问
mov eax, [esp+24h+ppv]

指令。因此,包含可能的错误代码(除 S_OK 之外的任何内容)的返回值会立即被覆盖(因此它假定COM调用成功)。

DWORD PTR [esp+24h+ppv](不知何故)指向COM对象的基址,并将其加载到EAX

但我无法表示寻址模式。也许它是 IDA Pro 的特殊语法显示。

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

This CodeProject article可能会为您提供进一步的见解。

答案 1 :(得分:0)

从作者对代码的描述中可以清楚地看出,这些操作数处于AT& T顺序(首先是源,然后是目的地)。作者之前是否已指定代码是使用英特尔订购编写的,还是仅仅是您的假设?使用两种样式编写x86程序集是(不幸和令人困惑的)常见问题,如另一个问题所述:

MOV src dest (or) MOV dest src?