逆向2.添加插件DEMO

插件Demo

main

#include <vector>
#include <string>
#include <iostream>
#include <windows.h>
using namespace std;
​
// 1. 插件通常是以什么样的方式存在的
//  - 通常是以 dll 的方式存在的,但是后缀名可能会有变化
// 2. 应用程序如何找到所有的插件
//  - 所有的插件都应该被保存到具体的路径中
// 3. 应用程序怎样知道是否符合自己的要求
//  - 插件必须提供指定名称的函数说明自己的信息
//  - 插件还需要通过对应名称的函数提供具体的功能
struct PluginInfo
{
    HMODULE Handle;
    char name[20];
    char ver[20];
};
​
using queryInfo = bool(*)(char* name, char* ver);
using clearPlugin = void(*)();
using runPlugin = void(*)();
​
// 用于保存所有的插件信息
vector<PluginInfo> PluginVec;
​
​
// 加载插件,获取插件的基本信息,并且判断插件是否是有效的
void init()
{
​
    WIN32_FIND_DATA FileData = { 0 };
​
    // 1. 遍历当前指定的插件目录,获取插件
    HANDLE Handle = FindFirstFile("./plugins/*.plg", &FileData);
    if (Handle != INVALID_HANDLE_VALUE)
    {
        do {
            PluginInfo info = { 0 };
            string path("./plugins/");
            path = path + FileData.cFileName;
​
            // 2. 加载找到的对应格式的文件
            info.Handle = LoadLibraryA(path.c_str());
​
            // 3. 通过指定函数获取插件的信息
            queryInfo func = (queryInfo)GetProcAddress(info.Handle, "queryInfo");
​
            // 4. 获取信息
            bool b = func(info.name, info.ver);
​
            if (b == true)
            {
                PluginVec.push_back(info);
                printf("name: %s[%s]\n", info.name, info.ver);
            }
        } while (FindNextFile(Handle, &FileData));
    }
}
​
// 调用插件提供的函数,实现相应的功能
void running()
{
    for (auto& info : PluginVec)
    {
        // 调用插件的功能函数
        runPlugin func = (runPlugin)GetProcAddress(info.Handle, "runPlugin");
​
        if (func) func();
    }
}
​
// 卸载插件,执行清理
void exit()
{
    for (auto& info : PluginVec)
    {
        // 卸载之前,应该调用插件的函数,执行插件的清理
        clearPlugin func = (clearPlugin)GetProcAddress(info.Handle, "clearPlugin");
​
        if (func) func();
​
        FreeLibrary(info.Handle);
    }
}
​
int main()
{
    init();
​
    running();
​
    exit();
​
    return 0;
}

 

dllmain.cpp

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "framework.h"
#include <stdio.h>
​
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}
​
bool queryInfo(char* name, char* ver)
{
    memcpy(name, "plgin_one", 10);
    memcpy(ver, "0.0.0.0.1", 10);
​
    return true;
}
​
​
void clearPlugin()
{
    printf("plgin_one[0.0.0.0.1]正在清理插件\n");
}
​
void runPlugin()
{
    printf("plgin_one[0.0.0.0.1]正在运行插件\n");
}

 

framework.h

// header.h: 标准系统包含文件的包含文件,
// 或特定于项目的包含文件
//
#pragma once#define WIN32_LEAN_AND_MEAN             // 从 Windows 头文件中排除极少使用的内容
// Windows 头文件
#include <windows.h>extern "C" _declspec(dllexport)  bool queryInfo(char* name, char* ver);
extern "C" _declspec(dllexport)  void clearPlugin();
extern "C" _declspec(dllexport)  void runPlugin();

 

posted @ 2019-07-10 20:08  ltyandy  阅读(307)  评论(0编辑  收藏  举报