我正在阅读“实用恶意软件分析”一书,其中显示了以下示例代码:
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页。
答案 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
中返回的返回值只是这五个值中的一个:
返回的 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程序集是(不幸和令人困惑的)常见问题,如另一个问题所述: