C22、插入DLL和挂接API
来源:互联网 发布:fc2手机破解版域名设置 编辑:程序博客网 时间:2024/05/29 15:48
将DLL插入到另一个进程的地址空间,对他做任何事。
一、插入DLL:
SetWindowLongPtr(hwnd, GWLP_WNDPROC, MySubclassProc);
二、使用注册表来插入DLL:
A. 注册表位置:HKEY_LOCAL_MACHINE/Software/Microsoft/Windows NT/CurrentVersion/Windows/AppInit_DLLs
三、使用Windows挂钩来插入DLL:
HHOOK hHook = SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, hinstDll, 0);
BOOL UnhookWindowsHookEx(HHOOK hhook); // 卸载
四、使用远程线程来插入DLL(win98不支持):
A. 进入时:
// 1、准备pfnStartAddr 参数,使用GetProcAddress获取LoadLibraryA(W)的实地址:
PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
GetProcAddress(GetModuleHandle(TEXT(“kernel32.dll”)), “LoadLibraryA”);
// 2、分配远程进程的地址空间中的内存
PVOID pvRemote = VirtualAllocEx(hProcessRemote,NULL,MAX_PATH,MEM_COMMIT,PAGE_READWRITE);
// 3、写入我们进程的路径
WirteProcessMemory(hProcessRemote,pvRemote,PVOID(“C://MyLib.dll”),MAX_PATH, NULL);
// 4、在远程进程中创建线程
HANDLE hThread = CreateRemoteThread(hProcessRemote, NULL, 0, pfnThreadRtn,
pvRemote, 0, NULL);
B. 退出时:
// 5、使用VirtualFreeEx释放pvRemote的内存
// 6、使用GetProcAddress获得FreeLibrary函数的实地址(在Kernel32.dll中),同步骤1
// 7、使用CreateRemoteThread,调用FreeLibrary,传递远程DLL的HINSTANCE。
说明:
u 在另一个进程中创建线程:
HANDLE CreateRemoteThread( // 类似于CreateThread。不能用于WIN98。
HANDLE hProcess, // 指明拥有新创建线程的进程
PSECURITY_ATTRIBUTES psa,
DWORD dwStackSize,
PTHREAD_START_ROUTINE pfnStartAddr, // 与远程进程相关线程函数的内存地址,使用GetProcAddress
PVOID pvParam, // 必须为远程进程的地址空间,使用VirtualAllocEx,WirteProcessMemory
DWORD fdwCreate,
PDWORD pdwThreadId);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// WIN2000中,CreateThread的内部形式如下:
// 而WIN98中GetLastError=ERROR_CALL_NOT_IMPLEMENTED,不能用于WIN98!
HANDLE CreateThread(PSECURITY_ATTRIBUTES psa, DWORD dwStackSize, PTHREAD_START_ROUTINE pfnStartAddr, PVOID pvParam, DWORD fdwCreate, PDWORD pdwThreadId){
return(CreateRemoteThread(GetCurrentProcess(), psa, dwStackSize, pfnStarAddr, pvParam, fdwCreate, pdwThreadID));
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
u 让线程加载我们的DLL:HINSTANCE LoadLibrary(PCTSTR pszLibFile);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 获取 LoadLibraryA 或 LoadLibraryW在Kernel32.dll 中的实地址:
// 因为Kernel32.dll在系统启动时就已经加载。
PTHREAD_START_ROUTINE pfnThreadRtn = (PTHREAD_START_ROUTINE)
GetProcAddress(GetModuleHandle(TEXT(“kernel32.dll”)), “LoadLibraryA”);
HANDLE hThread = CreateRemoteThread(hProcessRemote, NULL, 0, pfnThreadRtn,
“C://MyLib.dll”, 0, NULL);
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
u 分配(释放)远程进程的地址空间中的内存:
PVOID VirtualAllocEx( // 与非Ex版本类似
HANDLE hProcess, PVOID pvAddress, SIZE_T dwSize, DWORD flAllocationType, DWORD flProtect);
BOOL VirtualFreeEx( HANDLE hProcess, PVOID pvAddress, SIZE_T dwSize,
DWORD dwFreeType);
u 把字符串拷贝到远程进程的地址空间(或读取):
BOOL ReadProcessMemory( HANDLE hProcess, PVOID pvAddressRemote,
PVOID pvBufferLocal, DWORD dwSize, PDWORD pdwNumBytesRead);
BOOL WirteProcessMemory( HANDLE hProcess, PVOID pvAddressRemote,
PVOID pvBufferLocal, DWORD dwSize, PDWORD pdwNumBytesWritten);
u 获得远程进程的句柄:OpenProcess.
hProcess = OpenProcess(
PROCESS_CREATE_THREAD | // For CreateRemoteThread
PROCESS_VM_OPERATION | // For VirtualAllocEx / VirtualFreeEx
PROCESS_VM_WRITE, // For WriteProcessMemory
FALSE, dwProcessId // 可以使用任务管理器查看
);
五、使用特洛伊DLL来插入DLL:
u 创建你自己的DLL,赋予你想取代的DLL的文件名(把原有的DLL文件名改掉)。
u 必须输出原来DLL的全部输出符号(使用函数转发器,C20)。
u 如果仅操作单个应用程序:改变其.exe模块的输入节,使其加载你的DLL。
六、将DLL作为调试程序插入:
u 被调试程序加载时(未执行任何代码前),系统通知调试程序。这时,可以强制插入代码(如用WriteProcessMemory),然后被调试进程的主线程开始执行代码。
u 但需要对被调试程序的CONTEXT结构进行操作(针对特定的CPU)。
七、使用Windows98的内存映射文件插入代码:
Windows98上运行的32位程序共享最上面的2GB地址空间(内存映射文件的地址范围内)。但如何让远程进程来执行内存映射文件中的代码却很难做到。
八、使用CreateProcess插入代码:
u 必须从你的进程开始运行,创建暂停运行的子进程,修改.EXE模块起始内存地址的指令(调用LoadLibrary加载DLL)。然后继续运行子进程(将原始指令重新放入起始地址),从起始地址开始运行。
u 你的代码必须是父进程,不能跨CPU。
九、挂接API:
A. 通过改写代码来挂接API(建议避免使用:对CPU的依赖性大,不同的CPU JUMP指令的机器码是不同的;在抢占式多线程环境中不起作用。):
1. 找到想挂接函数在内存中的地址(比如Kernel32.dll的LoadLibraryA);
2. 将该函数的头几个字节保存在你自己的内存中;
3. 用JUMP CPU指令(的机器码)改写该函数的头几个字节。使其转移到你的替换函数的内存地址(替换函数的标记与原函数完全相同,即:所有的参数,返回值,调用规则必须一样!);
4. 挂接成功后,当其他线程调用被挂接的函数时,JUMP指令实际上将转移到你的替换函数。这时,你能够执行任何代码;
5. 取消函数的挂接状态。复原挂接函数的头几个字节(把第二步保存的字节放回);
6. 调用被挂接函数(此时已不再被挂接),执行原来函数的功能;
7. 当原始函数返回时,再次执行第二、三步。
B. 通过操作模块的输入节来挂接API:
模块的输入节包含一组该模块运行时需要的DLL及从DLL输入的符号(即调用函数)列表。当模块调用一个输入函数时,线程首先要获取输入函数的地址,然后转移到该地址(执行)。所以,要挂接某个函数,只需改变模块的输入节中的地址!(不依赖于CPU,及线程同步问题)。
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ReplaceIATEntryInOneMod(PCSTR pszModName, PROC pfnOrg,
PROC pfnNew, HMODULE hmod){
ULONG ulSize;
PIMAGE_IMPORT_DESCRIPTOR
}
- C22、插入DLL和挂接API
- 插入DLL和挂接API
- Windows编程那些事----插入dll和挂接API
- 第22章插入DLL和挂接API
- 插入DLL和挂接API——Windows核心编程学习手札之二十二
- HOOK API——Windows核心编程 第22章 插入DLL和挂接API学习笔记
- sdk,api和dll
- SDK和API DLL
- DLL注入和API 拦截
- DLL注入和API拦截
- DLL注入和API拦截
- DLL注入和API拦截
- Windows DLL注入和API拦截简介
- SDK,API和DLL的概念
- 第二十一章 DLL注入和API拦截
- MFC和SDK,API,DLL的关系
- SDK和MFC,API,DLL的关系
- SDK和MFC,API,DLL的关系
- speech codec (G.711, G.723, G.726, G.729, iLBC)
- oracle 如何导出数据字典
- C23、结束处理程序
- 应一个朋友要求转:MyEclipse-7.5.0版注册码破解及激活操作
- 用visual web pack写个程序
- C22、插入DLL和挂接API
- awk学习笔记
- Linux 关机指令
- 求救啊
- 开博,早安CSDN
- C24、异常处理程序和软件异常
- Windows7中7种不同关机模式介绍
- VC 字体
- [双语阅读]研究:青少年睡觉充足不易患抑郁