Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 对于使用dllexport导出的函数,GetProcAddress失败_C++_Dll_Hook_Messagebox_Loadlibrary - Fatal编程技术网

C++ 对于使用dllexport导出的函数,GetProcAddress失败

C++ 对于使用dllexport导出的函数,GetProcAddress失败,c++,dll,hook,messagebox,loadlibrary,C++,Dll,Hook,Messagebox,Loadlibrary,首先,我不熟悉挂钩方法和dll操作。我的任务是首先创建一个简单的程序,使用MessageBoxA打开一个消息框。守则: #include <windows.h> #include <iostream> #include <string> using namespace std; int main() { LPCSTR text = "Hello World!"; LPCSTR caption = "My Message Box"; M

首先,我不熟悉挂钩方法和dll操作。我的任务是首先创建一个简单的程序,使用MessageBoxA打开一个消息框。守则:

#include <windows.h>
#include <iostream>
#include <string>
using namespace std;

int main() {
    LPCSTR text = "Hello World!";
    LPCSTR caption = "My Message Box";
    MessageBoxA(NULL, text, caption, MB_OK);
    return 0;
}
#包括
#包括
#包括
使用名称空间std;
int main(){
LPCSTR text=“你好,世界!”;
LPCSTR caption=“我的消息框”;
MessageBoxA(空、文本、标题、MB_OK);
返回0;
}
之后,我需要创建一个DLL,该DLL与上面的程序挂钩,并打开一个不同的消息框。我写的代码是:

#include "stdafx.h"
#include <windows.h>
#define SIZE 6

typedef int (WINAPI* pMessageBox)(HWND, LPCSTR, LPCSTR, UINT);              //MessageBox function pointer
int WINAPI newMessageBoxA(HWND, LPCSTR, LPCSTR, UINT);            // my detour
void redirect(LPVOID);

pMessageBox pOrigAddress = NULL;
DWORD oldProtect, newProtect = PAGE_EXECUTE_READWRITE;
BYTE origBytes[SIZE];
BYTE jmp[SIZE];

void __declspec(dllexport) myMessageBox() {
    pOrigAddress = (pMessageBox)GetProcAddress(GetModuleHandleA("user32.dll"), "MessageBoxA");      //get MessageBoxA address
    if (pOrigAddress != NULL) {
        redirect(newMessageBoxA);
    }
}
/* Detour */
void redirect(LPVOID newFunc) {
    BYTE tmpJmp[SIZE] = { 0xE9, 0x90, 0x90,  0x90,  0x90, 0xC3 };               //initiate hook (0xE9 = jmp, 0xC3 = ret, 0x90 = nop)
    memcpy(jmp, tmpJmp, SIZE);
    DWORD jmpSize = (DWORD)newFunc - (DWORD)pOrigAddress - 5;                   //jump distance
    VirtualProtect(pOrigAddress, SIZE, PAGE_EXECUTE_READWRITE, &oldProtect);    //change protection to read-write and save previous protection value
    memcpy(origBytes, pOrigAddress, SIZE);                                      //save original value of function address
    memcpy(&jmp[1], &jmpSize, 4);                                               //fill the nops in tmpJmp with the address of the new function
    memcpy(pOrigAddress, jmp, SIZE);                                            //replace jump instruction of old function with new function
    VirtualProtect(pOrigAddress, SIZE, oldProtect, NULL);                       //reset protection value
}

int WINAPI newMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uiType) {
    VirtualProtect((LPVOID)pOrigAddress, SIZE, newProtect, NULL);                                                               // assign read write protection
    memcpy(pOrigAddress, origBytes, SIZE);                                                                                      // restore backup
    int retValue = MessageBoxA(hWnd, (LPCSTR)"This Message Box has been hijacked!", (LPCSTR)"Message Box Hijacked", uiType);    // get return value of original function
    memcpy(pOrigAddress, jmp, SIZE);                                                                                            // set the jump instruction again
    VirtualProtect((LPVOID)pOrigAddress, SIZE, oldProtect, NULL);                                                               // reset protection
    return retValue;                                                                                                            // return original return value
}
#包括“stdafx.h”
#包括
#定义尺寸6
typedef int(WINAPI*pMessageBox)(HWND、LPCSTR、LPCSTR、UINT)//MessageBox函数指针
int WINAPI newMessageBoxA(HWND、LPCSTR、LPCSTR、UINT);//我的绕道
无效重定向(LPVOID);
pMessageBox pOrigAddress=NULL;
DWORD oldProtect,newProtect=PAGE\u EXECUTE\u READWRITE;
字节或字节[大小];
字节jmp[SIZE];
void uu declspec(dllexport)myMessageBox(){
pOrigAddress=(pMessageBox)GetProcAddress(GetModuleHandleA(“user32.dll”),“MessageBoxA”);//获取MessageBoxA地址
if(pOrigAddress!=NULL){
重定向(newMessageBoxA);
}
}
/*绕道*/
无效重定向(LPVOID newFunc){
字节tmpJmp[SIZE]={0xE9,0x90,0x90,0x90,0xC3};//启动钩子(0xE9=jmp,0xC3=ret,0x90=nop)
memcpy(jmp、tmpJmp、SIZE);
DWORD jmpSize=(DWORD)newFunc-(DWORD)pOrigAddress-5;//跳转距离
VirtualProtect(pOrigAddress、SIZE、PAGE_EXECUTE_READWRITE和oldProtect);//将保护更改为读写并保存以前的保护值
memcpy(origBytes,pOrigAddress,SIZE);//保存函数地址的原始值
memcpy(&jmp[1],&jmpSize,4);//用新函数的地址填充tmpJmp中的nop
memcpy(pOrigAddress,jmp,SIZE);//用新函数替换旧函数的跳转指令
VirtualProtect(pOrigAddress,SIZE,oldProtect,NULL);//重置保护值
}
int WINAPI newMessageBoxA(HWND-HWND、LPCSTR-lpText、LPCSTR-lpCaption、UINT-uiType){
VirtualProtect((LPVOID)pOrigAddress,SIZE,newProtect,NULL);//分配读写保护
memcpy(pOrigAddress,origBytes,SIZE);//恢复备份
int retValue=MessageBoxA(hWnd,(LPCSTR)“此消息框已被劫持!”,(LPCSTR)“消息框被劫持”,uiType);//获取原始函数的返回值
memcpy(pOrigAddress,jmp,SIZE);//再次设置跳转指令
VirtualProtect((LPVOID)pOrigAddress,SIZE,oldProtect,NULL);//重置保护
return retValue;//返回原始返回值
}
之后,我更改了第一段代码,以使用LoadLibrary加载DLL:

#include <windows.h>
#include <iostream>
#include <string>
using namespace std;

typedef void(__stdcall *FNPTR)();

int main() {

    HINSTANCE hInst = LoadLibrary(L"C:\\Users\\yuvalnissan\\Desktop\\Workspaces\\VS Workspace\\morphisecAssignment\\x64\\Debug\\dllinject.dll");

    if (hInst == NULL) {
        cout << "\nCould not load dll" << endl;
        return 0;
    }

    FNPTR function = (FNPTR)GetProcAddress(hInst, "myMessageBox");
    if (function == NULL) {
        cout << "\nCould not locate function in dll" << endl;
        return 0;
    }

    function();

    FreeLibrary(hInst);

    LPCSTR text = "Hello World!";
    LPCSTR caption = "My Message Box";
    MessageBoxA(NULL, text, caption, MB_OK);

    return 0;
}
#包括
#包括
#包括
使用名称空间std;
typedef void(u stdcall*FNPTR)();
int main(){
HINSTANCE hInst=LoadLibrary(L“C:\\Users\\yuvalnissan\\Desktop\\Workspace\\VS Workspace\\morphisecAssignment\\x64\\Debug\\dllinject.dll);
if(hInst==NULL){

这与DLL挂接无关。您的问题是无法
GetProcAddress
DLL中的函数。看起来您是在导出已修饰的函数(通过
dllexport
),但您正试图以未修饰的方式访问它。请选择修饰或未修饰的方式。(我建议整个过程都取消装饰。)使用DEF文件取消装饰导出。应该是
extern“C”void\uu declspec(dllexport)myMessageBox()
谢谢@RaymondChen!成功了。可能的重复与DLL挂接无关。您的问题是无法
GetProcAddress
DLL中的函数。看起来您正在导出已修饰的函数(通过
dllexport
)但您正在尝试不修饰地访问它。修饰整个或不修饰整个。(我建议不修饰整个。)使用DEF文件来取消修饰导出。应该是
extern“C”void\uu declspec(dllexport)myMessageBox()
Thank you@RaymondChen!这就成功了。可能是