You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何挂钩并调用返回对象的成员函数?封装无源码DLL类遇崩溃

封装无源码DLL类的运算符调用问题

我想开发一个封装类,用来包装无源码DLL中的MyString类。最初计划用大量内联汇编调用真实函数,后来花了几小时研究尝试通过地址直接调用成员函数。目前已经成功调用构造函数,但调用+运算符时程序崩溃,不确定当前的方法定义与调用逻辑是否正确。


MyStringWrapper.h

#pragma once

#include <string>

class MyStringWrapper
{
public:
   static void InitializeAddresses();

   static MyStringWrapper* CastFrom(
      const uintptr_t address);

   MyStringWrapper(
      const std::wstring& original);

   MyStringWrapper operator+(
      const MyStringWrapper& other);

private:
   uintptr_t m_string_address;
   int m_u1;
   int m_u2;
   // Still need to figure out how to determine the correct size of a class, but hopefully this is big enough.
   char mData[2900];

   static struct FunctionDefinitions
   {
      typedef void(__thiscall* Create_FromArray)(void* pThis, wchar_t const* original);
      Create_FromArray CreateFromArray;

      // I think my issue is here, should I be returning/providing MyStringWrapper objects or the original MyString objects (that I do not have the source for).
      // and... if I should be using MyString objects, how can I do this without the compiler being upset about incomplete types?
      // Original symbol "public: class MyString __thiscall MyString::operator+(class MyString const &)"
      typedef MyStringWrapper(__thiscall* Combine_MyString)(void* pThis, const MyStringWrapper& other);
      Combine_MyString CombineMyString;
   } CustomFunctions;
};

MyStringWrapper.cpp

#include "MyStringWrapper.h"
#include "GlobalDLLBases.h"

MyStringWrapper::FunctionDefinitions MyStringWrapper::CustomFunctions;

void MyStringWrapper::InitializeAddresses()
{
   CustomFunctions.CreateFromArray = FunctionDefinitions::Create_FromArray((DWORD_PTR)DLLBase + 0x2c40);

   CustomFunctions.CombineMyString = FunctionDefinitions::Combine_MyString((DWORD_PTR)DLLBase + 0x3740);
}
   
MyStringWrapper* MyStringWrapper::CastFrom(
   const uintptr_t address)
{
   return reinterpret_cast<MyStringWrapper*>(address);
}

MyStringWrapper::MyStringWrapper(
   const std::wstring& original) :
   m_string_address(0),
   m_u1(0),
   m_u2(0)
{
   CustomFunctions.CreateFromArray(this, original.data());
}

MyStringWrapper MyStringWrapper::operator+(
   const MyStringWrapper& other)
{
   return CustomFunctions.CombineMyString(this, other);
}

Main.cpp

MyStringWrapper* obj1 = MyStringWrapper::CastFrom(address_to_existing_mystring);
MyStringWrapper* obj2 = MyStringWrapper::CastFrom(address_to_another_existing_mystring);
if(obj1 && obj2)
{
    // It crashes calling this, I expected ECX to hold the address of obj1, but the compiler seems to push both obj1 and obj2 addresses on to the stack and moves some other address into ecx.
    // It should only be pushing obj2's address, and moving obj1's address into ecx.
    MyStringWrapper final_product = *obj1 + *obj2;
}

核心问题

  1. 调用*obj1 + *obj2时程序崩溃:我预期ECX寄存器存储obj1的地址,但实际编译器将obj1和obj2的地址都压入栈,还把其他地址移入ECX。正确逻辑应该是仅将obj2的地址压栈,把obj1的地址存入ECX。
  2. 函数定义的类型困惑:
    • 运算符函数的定义应该返回/传入MyStringWrapper对象,还是原始的MyString对象(无源码)?
    • 如果必须使用原始MyString对象,如何避免编译器因不完整类型报错?

内容的提问来源于stack exchange,提问作者Rick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 12:02:15