任意语言从外部创建c++类实例

总所周知我们一般调用c++开发的dll 都是使用导出c接口来调用,所以呢我想直接在外部去创建dll导出类的实例,一般我们有任何想法都会先去搜索引擎看看有没有人有相同的想法看看有没有现成的代码可以参考,可惜并没有,所以我们只好自己琢磨。

想外部创建并调用一个c++类我们首先看看c++是怎么创建并调用的

首先创建一个简单的类,一个析构函数和一个函数返回字符串

CC::CC()
{
    memset(m_Text, 0, sizeof(m_Text));
    strcpy(m_Text, "这里是卢本伟广场");
}

char* CC::GetLastUsedFunc()
{
    return m_Text;
}

然后我们调用这个类看看

#include <iostream>
#include "test.h"


int main()
{
    CC* cc = new CC;
    std::cout << cc->GetLastUsedFunc() << "\n";
}

接下来我们看下他new一个类的过程

通过vs自带的反汇编我们可以看到 先是调用了new运算符传入一个260长度 然后返回一个地址然后把返回地址拷贝到ecx寄存器又调用了CC::CC 这个构造函数,这里260就是十进制的104.

这里我们需要了解两个问题,这个260代表什么和new返回的地址代表了什么,接下来我们单步调试看下

我们进去发现new运算符是传进来一个长度然后malloc申请一块内存 这个和网上说法是一致的

1)通过operator new申请内存
2)使用placement new调用构造函数(简单类型忽略此步)
3)返回内存指针

我们的问题解决了,那说明size就是类的大小,我们来验证下

1)通过operator new申请内存
{
    这一步我们可以自己申请内存
}
调用类成员上面汇编指令已经看到了,实际上是吧类指针实例(内存块指针)传到ecx寄存器然后调用函数指针

整个逻辑分析完毕我们来写个写个demo来验证下是否可行,是否可以从外部创建一个类指针 我们把这个类编译成dll然后查看导出函数 是不是很明显是c++的导出类 我们来使用外部创建类的方法来测试一下

int main()
{
	HMODULE hMod = LoadLibraryA("Test.dll");

	//构造函数
	FARPROC CC = GetProcAddress(hMod,"??0CC@@QAE@XZ");
	//GetLastUsedFunc函数成员地址
	FARPROC Func = GetProcAddress(hMod, "?GetLastUsedFunc@CC@@QAEPADXZ");

	//申请一块内存模拟new
	void* CCptr = malloc(260);
	memset(CCptr, 0, sizeof(CCptr));

	//调用构造函数
	__asm {
		mov ecx, CCptr
		call CC
	}
	//调用函数
	char* ret;
	__asm {
		mov ecx, CCptr
		call Func
		mov ret,eax
	}
	std::cout << "函数返回值:" << ret << "\n";
}

上面我们简单模拟一下类被创建到被调用

好了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章