外挂框架开发(1)HOOKAPI
来源:互联网 发布:熟女交友软件 编辑:程序博客网 时间:2024/05/16 07:22
这一篇是外挂开发的基础。可能对初学者而言听起来很麻烦,其实不然。因为这方面的技术也已很成熟了,源码都是公开的,剩下来就是怎么用了。在多线程环境下,理论上有两种方法实现挂截API,一是Jeffery的修改IAT算法,二是用detours开发包。我建议大家用detours。因为只需要少量几行代码就可实现挂截。以1.5版本为例:
typedef int (WINAPI *PFN_TCP)(SOCKET s,const char FAR *buf,int len,int nflag);
PFN_TCP _send = NULL;
int WINAPI mysend(SOCKET s,const char FAR *buf,int len,int nflag)
{
//your code goes here:
//...
return ((PFN_TCP)_send)(s,buf,len,nflag);
}
这样实现挂截
PBYTE pfn = (PBYTE)GetProcAddress( hwsock32,"send");
_send = (PFN_TCP)DetourFunction(pfn,(PBYTE)mysend);
这样清除挂截
DetourRemove((PBYTE)_send,(PBYTE)mysend);
到这里,如果通过别的什么工具知道send函数的buf里传输的是什么含义后,在mysend中加入你的补丁代码,已经完成核心功能了。恭喜你。
可是,以上代码用什么方法组织起来呢?答案是DLL。写法如下:
extern BOOL SpyInit();
extern BOOL SpyInit();
BOOL APIENTRY DllMain( HANDLE hModule, DWORD r, LPVOID lpReserved )
{
if( r==DLL_PROCESS_ATTACH )
{
return SpyInit();
}
else if( r==DLL_PROCESS_DETACH )
{
SpyExit();
}
return TRUE;
}
其中,SpyInit()就是DetourFunction包装后的样子;
接下来,我们得考虑怎么把以上代码“安装”到目标进程中去。好在算法Jerffrey早就为我们准备好了(见《windows核心编程》),用这个算法写个工具,专门用来装/卸动态库。这样做的好处是,当我们的DLL成功安装到指定进程后,这个工具就可以关掉了。
#include "stdafx.h"
#include "Injectlib.h"
//#include "tlhelp32.h"
//#include "string.h"
///////////////////////////////////////////////////////////////////////////////
BOOL WINAPI InjectLibW(DWORD dwProcessId, PCWSTR pszLibFile) {
BOOL fOk = FALSE; // Assume that the function fails
HANDLE hProcess = NULL, hThread = NULL;
PWSTR pszLibFileRemote = NULL;
__try {
// Get a handle for the target process.
hProcess = OpenProcess(
PROCESS_QUERY_INFORMATION | // Required by Alpha
PROCESS_CREATE_THREAD | // For CreateRemoteThread
PROCESS_VM_OPERATION | // For VirtualAllocEx/VirtualFreeEx
PROCESS_VM_WRITE, // For WriteProcessMemory
FALSE, dwProcessId);
if (hProcess == NULL) __leave;
// Calculate the number of bytes needed for the DLL's pathname
int cch = 1 + lstrlenW(pszLibFile);
int cb = cch * sizeof(WCHAR);
// Allocate space in the remote process for the pathname
pszLibFileRemote = (PWSTR)
VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE);
if (pszLibFileRemote == NULL) __leave;
// Copy the DLL's pathname to the remote process's address space
if (!WriteProcessMemory(hProcess, pszLibFileRemote,
(PVOID) pszLibFile, cb, NULL)) __leave;
// Get the real address of LoadLibraryW in Kernel32.dll
PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "LoadLibraryW");
if (pfnThreadRtn == NULL) __leave;
// Create a remote thread that calls LoadLibraryW(DLLPathname)
hThread = CreateRemoteThread(hProcess, NULL, 0,
pfnThreadRtn, pszLibFileRemote, 0, NULL);
if (hThread == NULL) __leave;
// Wait for the remote thread to terminate
WaitForSingleObject(hThread, INFINITE);
fOk = TRUE; // Everything executed successfully
}
__finally { // Now, we can clean everthing up
// Free the remote memory that contained the DLL's pathname
if (pszLibFileRemote != NULL)
VirtualFreeEx(hProcess, pszLibFileRemote, 0, MEM_RELEASE);
if (hThread != NULL)
CloseHandle(hThread);
if (hProcess != NULL)
CloseHandle(hProcess);
}
return(fOk);
}
///////////////////////////////////////////////////////////////////////////////
BOOL WINAPI InjectLibA(DWORD dwProcessId, PCSTR pszLibFile) {
// Allocate a (stack) buffer for the Unicode version of the pathname
PWSTR pszLibFileW = (PWSTR)
_alloca((lstrlenA(pszLibFile) + 1) * sizeof(WCHAR));
// Convert the ANSI pathname to its Unicode equivalent
wsprintfW(pszLibFileW, L"%S", pszLibFile);
// Call the Unicode version of the function to actually do the work.
return(InjectLibW(dwProcessId, pszLibFileW));
}
///////////////////////////////////////////////////////////////////////////////
BOOL WINAPI EjectLibW(DWORD dwProcessId, PCWSTR pszLibFile) {
BOOL fOk = FALSE; // Assume that the function fails
HANDLE hthSnapshot = NULL;
HANDLE hProcess = NULL, hThread = NULL;
__try {
// Grab a new snapshot of the process
hthSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
if (hthSnapshot == NULL) __leave;
// Get the HMODULE of the desired library
MODULEENTRY32W me = { sizeof(me) };
BOOL fFound = FALSE;
BOOL fMoreMods = Module32FirstW(hthSnapshot, &me);
for (; fMoreMods; fMoreMods = Module32NextW(hthSnapshot, &me)) {
fFound = (lstrcmpiW(me.szModule, pszLibFile) == 0) ||
(lstrcmpiW(me.szExePath, pszLibFile) == 0);
if (fFound) break;
}
if (!fFound) __leave;
// Get a handle for the target process.
hProcess = OpenProcess(
PROCESS_QUERY_INFORMATION | // Required by Alpha
PROCESS_CREATE_THREAD |
PROCESS_VM_OPERATION, // For CreateRemoteThread
FALSE, dwProcessId);
if (hProcess == NULL) __leave;
// Get the real address of LoadLibraryW in Kernel32.dll
PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
GetProcAddress(GetModuleHandle(TEXT("Kernel32")), "FreeLibrary");
if (pfnThreadRtn == NULL) __leave;
// Create a remote thread that calls LoadLibraryW(DLLPathname)
hThread = CreateRemoteThread(hProcess, NULL, 0,
pfnThreadRtn, me.modBaseAddr, 0, NULL);
if (hThread == NULL) __leave;
// Wait for the remote thread to terminate
WaitForSingleObject(hThread, INFINITE);
fOk = TRUE; // Everything executed successfully
}
__finally { // Now we can clean everything up
if (hthSnapshot != NULL)
CloseHandle(hthSnapshot);
if (hThread != NULL)
CloseHandle(hThread);
if (hProcess != NULL)
CloseHandle(hProcess);
}
return(fOk);
}
///////////////////////////////////////////////////////////////////////////////
BOOL WINAPI EjectLibA(DWORD dwProcessId, PCSTR pszLibFile) {
// Allocate a (stack) buffer for the Unicode version of the pathname
PWSTR pszLibFileW = (PWSTR)
_alloca((lstrlenA(pszLibFile) + 1) * sizeof(WCHAR));
// Convert the ANSI pathname to its Unicode equivalent
wsprintfW(pszLibFileW, L"%S", pszLibFile);
// Call the Unicode version of the function to actually do the work.
return(EjectLibW(dwProcessId, pszLibFileW));
}
///////////////////////////////////////////////////////////////////////////////
好,我们的初级外挂准备好了。进程dwProcessId可以先在任务管理器中查查,填写进去。大家按着上面试试,体会一下,有缺点不怕,咱们慢慢改进。
(如有意交流,请发EMAIL至hotmail的cg328信箱交流)
- 外挂框架开发(1)HOOKAPI
- 挂机型外挂开发-框架设计
- 外挂开发
- HookAPI函数
- C#hookapi
- HookAPI函数
- HOOKAPI--初步
- HookAPI通信
- 外挂开发开篇
- 扫雷外挂程序开发
- 开发的辅助外挂
- 开发外挂的一些原理
- 外挂开发中的封包技术
- Delphi如何开发游戏外挂
- Delphi如何开发游戏外挂
- Delphi如何开发游戏外挂
- 开心网外挂开发手记
- QQ农场外挂开发实践
- Server.Transfer和Response.Redirect的区别
- 位图
- 用个循环链表解决约瑟夫环问题
- 迟到的正义以牺牲另一种正义的代价来到——今天从法院领了被拖欠3年多的工资。
- vi下的十六进制显示
- 外挂框架开发(1)HOOKAPI
- happy work, happy life
- 有感于"盖茨北大演讲遭遇开源人士抗议"
- DLINQ基础知识
- System.Environment.GetFolderPath函数中未开放的枚举参数
- 网站
- 最佳css控制打印方法
- 也谈"正方形不是长方形"
- UML类图详解