本来想写个内存监视器的,但是现在遇到了点小麻烦。
这段代码我放在控制台里执行,很好,很健壮。
但是如果封装成了DLL封装进XX程序就出问题了。
搞了一上午 现在精神一点都不好,所以拿到论坛来问问
故障模块名称: memory_monitor1.dll_unloaded
dll_unloaded这是啥?我以前没听过,编程经验太少了。。
主要帮我看看 HookIat 这个函数。
#include <WinSock2.h>
#pragma comment (lib, "ws2_32.lib")
#define DATA_BUFFER_MAX 1024
#define DELAY_TIME 100
SOCKET sClient={0};
int s = 0; //状态 0 = 停止 1 = 开始
CRITICAL_SECTION sec;
typedef BOOL (WINAPI *WriteProcessMemory_UnHook)(
HANDLE hProcess,
LPVOID lpBaseAddress,
LPVOID lpBuffer,
DWORD nSize,
LPDWORD lpNumberOfBytesWritten
);
BOOL WINAPI WriteProcessMemory_MyHook(
HANDLE hProcess,
LPVOID lpBaseAddress,
LPVOID lpBuffer,
DWORD nSize,
LPDWORD lpNumberOfBytesWritten
);
int Socket_init();
DWORD WINAPI Recv_thread(LPVOID lpParameter);
void FreeMe();
void Hooker();
void Socket_Send(char *SendData,int sendSize);
bool HookIat(char *LibraryName,PVOID Hook,PVOID NewFunctionAddress);
WriteProcessMemory_UnHook WriteProcessMemory_addr = NULL;
void FreeMe()
{
HMODULE hModule= GetModuleHandleA("memory_monitor.dll");
//FreeLibrary(hModule);
}
int Socket_init() // 进程通信!
{
WSADATA wsadata;
int port = 1447;
struct sockaddr_in ser;//服务器端地址
DWORD ThreadId;
HANDLE ThreadHandle=NULL;
if(WSAStartup(MAKEWORD(2,2),&wsadata)!=0)
{
MessageBoxA(0,"初始化通信组建失败!","错误!",MB_OK);
return 0;
}
ser.sin_family = AF_INET;
ser.sin_port = htons(port);
//inet_addr()将命令行中输入的点分IP地址转换为二进制表示的网络字节序IP地址
ser.sin_addr.s_addr = inet_addr("127.0.0.1");
sClient = socket(AF_INET,SOCK_STREAM,0);
if(sClient == INVALID_SOCKET)
{
MessageBoxA(0,"初始化通信组建失败! 创建套接字失败!","错误!",MB_OK);
return 0;
}
if(connect(sClient,(struct sockaddr *)&ser,sizeof(ser)) == INVALID_SOCKET)
{
MessageBoxA(0,"初始化通信组建失败! 连接主程序失败!!","错误!",MB_OK);
return 0;
}
ThreadHandle = CreateThread(NULL,NULL,Recv_thread,NULL,0,&ThreadId);
if (ThreadHandle == INVALID_HANDLE_VALUE)
{
MessageBoxA(0,"接收消息线程启动失败!\n","错误!",MB_OK);
return 0;
}else
{
CloseHandle(ThreadHandle);
}
return 1;
}
void Socket_Send(char *SendData,int sendSize)
{
send(sClient,SendData,sendSize,0);
}
DWORD WINAPI Recv_thread(LPVOID lpParameter)
{
while (true)
{
int recv_len = 0;
char Recvbuf[DATA_BUFFER_MAX]={0};
memset(Recvbuf,0,DATA_BUFFER_MAX);
recv_len = recv(sClient,Recvbuf,sizeof(Recvbuf),0);
if (recv_len==-1)
{
MessageBoxA(0,"与服务器断开连接!\n","错误!",MB_OK);
FreeMe();
}
if (Recvbuf[1]='S')
{
s = 1;
}else
{
s=0;
}
Sleep(200);
}
}
void Hooker()
{
HMODULE hModule = GetModuleHandleA("kernel32.dll");
WriteProcessMemory_addr = (WriteProcessMemory_UnHook)GetProcAddress(hModule,"WriteProcessMemory");
if(HookIat("kernel32.dll",(PVOID)WriteProcessMemory_addr,WriteProcessMemory_MyHook)==false)
{
MessageBoxA(0,"Hook 目标进程XX函数失败!","错误",MB_OK);
FreeMe();
}
InitializeCriticalSection(&sec);
}
bool HookIat(char *LibraryName,PVOID Hook,PVOID NewFunctionAddress)
{
PIMAGE_DOS_HEADER pDosHead =NULL;
PIMAGE_NT_HEADERS pNtHead = NULL;
DWORD ImportLibNum = 0; // 导入表的库个数
PIMAGE_IMPORT_DESCRIPTOR lib = NULL;
if (LibraryName==NULL ||Hook==NULL||NewFunctionAddress==NULL)
{
return false;
}
pDosHead = (PIMAGE_DOS_HEADER)GetModuleHandleA(NULL);
if (pDosHead==NULL)
{
return false;
}
pNtHead = (PIMAGE_NT_HEADERS)((DWORD)pDosHead + (DWORD)pDosHead->e_lfanew);
pNtHead->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
// 计算导入库的个数
ImportLibNum = pNtHead->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size / sizeof(IMAGE_IMPORT_DESCRIPTOR);
ImportLibNum--;
if (ImportLibNum<1)
{
return false;
}
// 定位到 导入表
lib = (PIMAGE_IMPORT_DESCRIPTOR)((int)pDosHead+(int)(pNtHead->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));
while (lib)
{
char *name = NULL;
name = (char * )((char*)pDosHead +(DWORD)lib->Name);
if (lstrcmpiA(LibraryName,name)==0)
{
IMAGE_THUNK_DATA* ThunkData = (IMAGE_THUNK_DATA*)((BYTE*)pDosHead+lib->FirstThunk);
while (ThunkData)
{
if (IsBadWritePtr(&ThunkData->u1.Function,sizeof(DWORD))!=0)
{
ThunkData++;
}
if (ThunkData->u1.Function == (DWORD)Hook)
{
VirtualProtect(&ThunkData->u1.Function,4,PAGE_READWRITE,NULL);
WriteProcessMemory(GetCurrentProcess(),&(ThunkData->u1.Function),&NewFunctionAddress,sizeof(DWORD),NULL);
return true;
}
ThunkData++;
}
break;
}
lib++;
}
return false;
}
BOOL WINAPI WriteProcessMemory_MyHook(
HANDLE hProcess,
LPVOID lpBaseAddress,
LPVOID lpBuffer,
DWORD nSize,
LPDWORD lpNumberOfBytesWritten
)
{
char *start = "addr";
char *size_s = "size";
char *data ="data";
char addr[4] = {0};
if (1==s)
{
*((int *)&addr) = (int)lpBaseAddress;
//Socket_Send(start,strlen(start)+1);
//Sleep(200);
EnterCriticalSection(&sec);
Sleep(DELAY_TIME);
Socket_Send("Start!Start!",strlen("Start!Start!")+1);
Sleep(DELAY_TIME);
Socket_Send(addr,4); //地址
Sleep(DELAY_TIME);
*((int *)addr) = nSize;
Socket_Send(addr,4); //大小
Sleep(DELAY_TIME);
Socket_Send((char *)lpBuffer,nSize); //数据
LeaveCriticalSection(&sec);
}
return WriteProcessMemory_addr(hProcess,lpBaseAddress,lpBuffer,nSize,lpNumberOfBytesWritten);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
if(Socket_init())
{
Hooker();
}else
{
FreeMe();
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)