应用程序的 DIY__(给程序加上新功能)
2015-09-04 16:14
295 查看
原始排版:应用程序的 DIY__(给程序加上新功能)
标签(空格分隔): R3 窗口编程
这是 Windows Xp 下的计算器的窗口资源
我在其中添加了一个
在最新版本的
菜单资源的话也是同样的道理。
这个时候怎么办?
最简单的方法 莫过于 调用 CreateWidowsEx 来创建一个按钮出来。
不过后来我发现创建按钮的话由于种种原因并不可靠。
不过也有应对的方法就是添加
当然这个过程并不是由本地调用,而是由应用程序去调用
一、 远程线程注入
二、 导入表注入
两种各有优劣,自行斟酌。
从远程线程注入说起,也就是从动说起:
这个代码的 健壮性很差,代码中并没有
接下来说静:
这个说起来就很简单了,
使用
这里需要注意的是,这个
DllMain如下:
需要多创建一条线程出来,等待窗口创建完成。
使用
标签(空格分隔): R3 窗口编程
开篇
之前的考试中最后一个实操题就是要在记事本上加入一个功能。(通过 按钮 或者 菜单项来实现)动还是静
从静开始
这个问题的由来是 这个控件本身到底应该动态创建还是静态创建,本身是取决于原有应用程序的资源, 如果原本的应用程序是存在有窗口资源或者是菜单资源,那么我们静态创建也是无妨的,通过
ResHacker等工具可以轻易做到,过程比较简单,找到窗口的资源后,写入一个控件资源即可。
这是 Windows Xp 下的计算器的窗口资源
CONTROL "1/x", 107, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE, 140, 85, 24, 18 CONTROL "sqt", 103, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE, 140, 45, 24, 18 CONTROL "%", 109, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE, 142, 64, 20, 18 CONTROL "help", 333, BUTTON, BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE, 148, 23, 20, 19 CONTROL "", 1000, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 0, 127, 1, 1
我在其中添加了一个
Caption为 “help” 的按钮,资源ID为
333。
在最新版本的
ResHacker也支持可视化的资源编辑器,可以直接右键 “Insert control”。
菜单资源的话也是同样的道理。
到动结束
换一个例子,当我们去读取 Win7 的计算器时就会发现,其静态资源区是找不到 窗口资源和菜单资源的,反正我是没找到。这个时候怎么办?
最简单的方法 莫过于 调用 CreateWidowsEx 来创建一个按钮出来。
不过后来我发现创建按钮的话由于种种原因并不可靠。
不过也有应对的方法就是添加
菜单项,这个就我目前测试来说比较可靠。
HWND hWnd = FindWindow(L"SciCalc", L"计算器"); AppendMenu(GetMenu(hWnd), MF_STRING, 123, L"Hello");
当然这个过程并不是由本地调用,而是由应用程序去调用
驻进目标应用程序___dll注入
动还是静
驻进也分为动静两种:一、 远程线程注入
二、 导入表注入
两种各有优劣,自行斟酌。
从远程线程注入说起,也就是从动说起:
bool InjectDll(DWORD dwPid, char *pszLibFileName) { HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | // Required by Alpha PROCESS_CREATE_THREAD | // For CreateRemoteThread PROCESS_VM_OPERATION | // For VirtualAllocEx/VirtualFreeEx PROCESS_VM_WRITE, // For WriteProcessMemory //, PROCESS_VM_READ , // For CreateRemoteThread /* PROCESS_ALL_ACCESS,*/ FALSE, dwPid); PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(L"Kernel32"), "LoadLibraryA"); //计算DLL路径名需要的内存空间 int cb = (1 + lstrlenA(pszLibFileName)) * sizeof(char); //使用VirtualAllocEx函数在远程进程的内存地址空间分配DLL文件名缓冲区 char *pszLibFileRemote = (char *)VirtualAllocEx(hProcess, NULL, cb, MEM_COMMIT, PAGE_READWRITE); //使用WriteProcessMemory函数将DLL的路径名复制到远程进程的内存空间 bool iReturnCode = WriteProcessMemory(hProcess, pszLibFileRemote, (PVOID)pszLibFileName, cb, NULL); CreateRemoteThread(hProcess, NULL, 0, pfnStartAddr, pszLibFileRemote, 0, NULL); CloseHandle(hProcess); return true; }
这个代码的 健壮性很差,代码中并没有
return false的处理,是临时拼凑出来解释动这一情况的。
接下来说静:
这个说起来就很简单了,
使用
LoadPE这一类型的工具,直接将 DLL 添加到 原应用程序的导入表就行了。
这里需要注意的是,这个
dll的写法。
DWORD WINAPI ThreadProc( _In_ LPVOID lpParameter ) { // // 延时 500 毫秒 等待窗口创建完成 // Sleep(500); HWND hWnd = FindWindow(L"SciCalc", L"计算器"); // AppendMenu(GetMenu(hWnd), MF_STRING, 123, L"Hello"); g_uOldProc = GetWindowLong(hWnd, GWL_WNDPROC); SetWindowLong(hWnd, GWL_WNDPROC, (LONG)MyWindowProc); return 0; }
DllMain如下:
switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: { // // 延时几秒 等待窗口创建成功 // CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL); } case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; }
需要多创建一条线程出来,等待窗口创建完成。
尾声,消息的拦截
这里消息拦截是 使用的SetWindowLong这个API。 这个API 可以用来替换掉原来的消息回调函数地址,我们就可以实现一个中间过滤的功能。
GetWindowLong是用来获取 消息回调函数地址,把老的地址记录,替换上新的地址,
使用
CallWindowProc继续下发消息,看起来是不是有点像是 SSDT Inline HOOK呢?
LONG g_uOldProc; LRESULT CALLBACK MyWindowProc( _In_ HWND hwnd, _In_ UINT uMsg, _In_ WPARAM wParam, _In_ LPARAM lParam ) { if (uMsg == WM_COMMAND && LOWORD(wParam) == 333) { MessageBox(0, 0, 0, 0); } return CallWindowProc((WNDPROC)g_uOldProc, hwnd, uMsg, wParam, lParam); }
后话
实现方法远远不止上面列举的几种,例如还可以设置全局消息钩子等,各种各样的方法,不应该局限于眼前。相关文章推荐
- 剑指offer整理归纳(1/2)
- 1053. Path of Equal Weight (30)
- HTML5 Canvas绘图API
- PAT 1083. List Grades (25)
- Clothes
- Effective Java 英文 第二版 读书笔记 Item 4:Attempting to enforce noninstantiability by making a class abstract does not work.
- C++基础---纯虚函数
- Active Defense Harbinger Distribution
- 修改mysql主键的值为自增
- 整理阅读的论文(六)
- Hibernate案例-------基于xml配置,使用Hibernate实现对员工表的增、删、改、查功能
- 集合心得
- 19.模板方法模式
- 修改:类shell程序的简化实现,尝试消除ctrl+c,结果处理完信号后挑出了while循环
- Python List Merge for game 2048 (part1)
- Softmax回归
- Linux学习:Linux基础命令集(4)
- java基础经典问题String str=new String("abc")和String str="abc"
- 1052. Linked List Sorting (25)
- Warning: Multiple build commands for output file /xxx