免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2276 | 回复: 0
打印 上一主题 下一主题

插入DLL和挂接API [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-07-24 11:09 |只看该作者 |倒序浏览
每个进程都有它自己的私有地址空间。当使用指针来引用内存时,指针的值将引用你自己进程的地址空间中的一个内存地址,有些情况下,必须打破进程的界限,访问另一个进程的地址空间,这些情况包括:

• 当你想要为另一个进程创建的窗口建立子类时。

• 当你需要调试帮助时(例如,当你需要确定另一个进程正在使用哪个DLL时)。

• 当你想要挂接其他进程时

将DLL插入到另一个进程的地址空间中。一旦DLL进入另一个进程的地址空间,就可以对另一个进程为所欲为。Dll必须进入进程的空间否则就会出现地址访问的越界违规。这就是问什么不能直接用函数 SetWindowLongPtr(hwnd,GWLP_WNDPROC,Mysubclassproc);插入的方法有多种:

1:注册表插入

windows98不可以用!是在windows初始化的时候加载的!DLL只会映射到使用User 32.dll的进程中。所有基于GUI的应用程序均使用User32.dll,不过大多数基于CUI的应用程序并不使用它。很容易实现但很不安全,系统易崩溃!

2:用windows挂钩插入DLL

Microsoft Spy++就是安装了挂钩(wm_getmessage)查看系统各个窗口处理的消息!用下面的函数安装

HHOOK HhOOK = SetWindowsHookEx(WH_GETMESSAGE,GetMsgProc,hinstDll,0);

第一个参数WH_GETMESSAGE用于指定安装挂钩的类型,GetMsgProc用于指明窗口准备处理一个消息时系统应该调用的函数的地址。HinstDll指明包含GetMsgProc函数的DLL,DLL的hinstDll的值用于标识DLL被映射到的进程的地址空间中的虚拟内存地址;最后一个参数0用于指明要挂接的线程,对于一个线程来说,它可以调用SetWindowsHookEx函数,传递系统中的另一个线程的ID。通过为这个参数传递0,就告诉系统说,我们想要挂接系统中的所有GUI线程。现在让我们来看一看将会发生什么情况:

1) 进程B中的一个线程准备将一条消息发送到一个窗口。

2) 系统查看该线程上是否已经安装了WH_GETMESSAGE挂钩。

3) 系统查看包含GetMsgProc函数的DLL是否被映射到进程B的地址空间中。

4) 如果该DLL尚未被映射,系统将强制该DLL映射到进程B的地址空间,并且将进程B中的DLL映像的自动跟踪计数递增1

这个方法允许你在另一个进程的地址空间中不再需要DLL时删除该DLL的映像,方法是调用函数 BOOL UnhookWindowsHookEx(HHOOK hhook);

3: 使用远程线程来插入D L L

这个DLL插入法要求目标进程中的线程调用LoadLibrary函数来加载必要的DLL。但我们无法控制其它线程,因此要求我们可以在目标进程中创建一个新进程以便控制它。CreateRemoteThread函数可以做到这一点:

HANDLE CreateRemoteThread(
HANDLE hProcess, //指明拥有新创建线程的进程句柄

PSECURITY_ATTRIBUTES psa,

PTHREAD_START_ROUTINE pfnStartAddr, //线程函数的地址空间

PVOID pvParam,

DWORD fdwCreate,

PDWORD pdwThreadId);

使用实例:

HANDLE hThread=CreateRemoteThread(hProcessRemote,NULL,0,

LoadLibraryA,”C:\\mylib.dll”,0,NULL);

CreateRemoteThread的前提条件是Kernel32.dll已经被同事映射到了本地和远程进程的地址空间中,恰好每个程序都要用到Kernel32.dll。

PTHREAD_START_ROUTIME pfnThreadRtn = (PTHREAD_START_ROUTIME)

GetProcAddress(GetModuleHandle(TEXT(“Kernel32”),”LoadLibraryA”);

HANDLE hThread = CreateRemoteThread(hProcessRemote,NULL,0,

pfnThreadRtn,”c:\\mylib.dll”,0,NULL);

《WINDOWS核心编程》中的例子

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);
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP