c#调用c++ dll提示 尝试读取或写入受保护的内存

meinv777 2012-11-22 02:45:11
查了n遍百度,都找不解决不了,只有上来求大牛帮帮忙了。。。。

直接上代码:

c++ dll代码

文件: HookApi.h

#include <windows.h>
#ifndef _HOOKAPI_H
#define _HOOKAPI_H

class HookApi {
public:
LPVOID pOldFunEntry, pNewFunEntry ; // 初始函数地址、HOOK后的函数地址
BYTE bOldByte[5], bNewByte[5] ; // 原始字节、目标字节

public:
HookApi () {}
~HookApi() {}
// 实现HOOK API
void Hook (PSTR szModuleName,PSTR szFunName,FARPROC pFun)
{
HMODULE hMod = ::GetModuleHandleA ( szModuleName ) ;
if (hMod != NULL)
{
pNewFunEntry = (LPVOID)pFun ;
pOldFunEntry = (LPVOID)GetProcAddress ( hMod, szFunName ) ;
bNewByte[0] = 0xE9 ;
*((PDWORD)(&(bNewByte[1]))) = (DWORD)pNewFunEntry -(DWORD)pOldFunEntry - 5 ;

DWORD dwProtect, dwWriteByte, dwReadByte ;
VirtualProtect ( (LPVOID)pOldFunEntry, 5, PAGE_READWRITE, &dwProtect );
ReadProcessMemory ( GetCurrentProcess(), (LPVOID)pOldFunEntry, bOldByte, 5, &dwReadByte ) ;
WriteProcessMemory ( GetCurrentProcess(), (LPVOID)pOldFunEntry, bNewByte, 5, &dwWriteByte ) ;
VirtualProtect ( (LPVOID)pOldFunEntry, 5, dwProtect, NULL ) ;
}
}
// 重新HOOK
void ReHook ()
{
DWORD dwProtect, dwWriteByte ;
VirtualProtect ( pOldFunEntry, 5, PAGE_READWRITE, &dwProtect );
WriteProcessMemory ( GetCurrentProcess(), pOldFunEntry, bNewByte, 5, &dwWriteByte ) ;
VirtualProtect ( pOldFunEntry, 5, dwProtect, NULL ) ;
}
// 撤消HOOK
void UnHook ()
{
DWORD dwProtect, dwWriteByte ;
VirtualProtect ( pOldFunEntry, 5, PAGE_READWRITE, &dwProtect );
WriteProcessMemory ( GetCurrentProcess(), pOldFunEntry, bOldByte, 5, &dwWriteByte ) ;
VirtualProtect ( pOldFunEntry, 5, dwProtect, NULL ) ;
}
} ;

#endif

文件 dllmain.cpp

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"

#include "HookApi.h";
HookApi HookItem;

// 定义MessageBoxA函数原型
typedef int (WINAPI* PFNMessageBoxA)( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType ) ;

// 自定义的MessageBoxA函数
// 实现对原始MessageBoxA的输入、输出参数的监控,甚至是取消调用
int WINAPI New_MessageBoxA( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType )
{
// 撤消HOOK
HookItem.UnHook () ;

PFNMessageBoxA pfnMessageBoxA = (PFNMessageBoxA)HookItem.pOldFunEntry ;

// 调用原函数,修改输入参数
int ret = pfnMessageBoxA ( hWnd, "这是HOOK函数过程的消息框", "[测试]", uType ) ;

HookItem.ReHook () ;

return ret ;
}

extern "C" __declspec(dllexport) void abc()
{
// HOOK API
MessageBoxA ( 0, "正常消息框", "测试", 0 ) ;
HookItem.Hook("USER32.dll","MessageBoxA",(FARPROC)New_MessageBoxA) ;
}

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;
}
上面代码编译成:CHook.dll

c#代码很简单

public partial class Form1 : Form
{
[DllImport("CHook.dll")]
public static extern void abc();
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
abc();//点这里开始调用c++ hook ,没报错,证明已经运行了
}

private void button2_Click(object sender, EventArgs e)
{
MessageBox.Show("aaa");//这里报错,尝试读取或写入受保护的内存
}
}


请问,那里错了,c++水平不怎么样,很郁闷。。。。

大牛们救救小弟。。。。。
...全文
164 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
meinv777 2012-11-23
  • 打赏
  • 举报
回复
自己继续顶顶顶,上面回答的,应该不是那个问题哦
meinv777 2012-11-23
  • 打赏
  • 举报
回复
鬼都没一个。。
杨友山 2012-11-22
  • 打赏
  • 举报
回复
仔细看下c++代码有没有指针指向空的,我之前用过一个c++的dll,读取文件头信息的,里面有指针为空也报过这个异常。你这段代码我也看不懂。
meinv777 2012-11-22
  • 打赏
  • 举报
回复
妈妈的呀,来个人啊。。。。。
meinv777 2012-11-22
  • 打赏
  • 举报
回复
人呢,来个人啊。。。。
meinv777 2012-11-22
  • 打赏
  • 举报
回复
自己顶顶顶顶

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧