最近一段时间由于使用MinHook的API挂钩不稳定,经常因为挂钩地址错误而导致宿主进程崩溃。听同事介绍了一款智能强大的挂钩引擎EasyHook。它比微软的detours好的一点是它的x64注入支持是免费开源的。不想微软的detours,想搞x64还得购买。

好了,闲话不多说,先下载EasyHook的开发库,当然有兴趣的同学可以下载源码进行学习。下载地址:http://easyhook.codeplex.com/releases/view/24401。我给的这个是2.6版本的。

EasyHook提供了两种模式的注入管理。一种是托管代码的注入,另一种是非托管代码的注入。我是学习C++的,所以直接学习了例子中的非托管项目UnmanagedHook。里面给了一个简单的挂钩MessageBeep API的示例。我需要将其改造成支持远程注入的。下面先给出钩子DLL代码:

  1. // dllmain.cpp : 定义 DLL 应用程序的入口点。
  2. #include "stdafx.h"
  3. #include "HookApi.h"
  4. #include "easyhook.h"
  5. #include "ntstatus.h"
  6. ptrCreateFileW realCreateFileW = NULL;
  7. ptrCreateFileA realCreateFileA = NULL;
  8. HMODULE                 hKernel32 = NULL;
  9. TRACED_HOOK_HANDLE      hHookCreateFileW = new HOOK_TRACE_INFO();
  10. TRACED_HOOK_HANDLE      hHookCreateFileA = new HOOK_TRACE_INFO();
  11. NTSTATUS                statue;
  12. ULONG                   HookCreateFileW_ACLEntries[1] = {0};
  13. ULONG                   HookCreateFileA_ACLEntries[1] = {0};
  14. int PrepareRealApiEntry()
  15. {
  16. OutputDebugString(L"PrepareRealApiEntry()\n");
  17. // 获取真实函数地址
  18. HMODULE hKernel32 = LoadLibrary(L"Kernel32.dll");
  19. if (hKernel32 == NULL)
  20. {
  21. OutputDebugString(L"LoadLibrary(L\"Kernel32.dll\") Error\n");
  22. return -6002;
  23. }
  24. OutputDebugString(L"LoadLibrary(L\"Kernel32.dll\") OK\n");
  25. realCreateFileW = (ptrCreateFileW)GetProcAddress(hKernel32, "CreateFileW");
  26. if (realCreateFileW == NULL)
  27. {
  28. OutputDebugString(L"(ptrCreateFileW)GetProcAddress(hKernel32, \"CreateFileW\") Error\n");
  29. return -6007;
  30. }
  31. OutputDebugString(L"(ptrCreateFileW)GetProcAddress(hKernel32, \"CreateFileW\") OK\n");
  32. realCreateFileA = (ptrCreateFileA)GetProcAddress(hKernel32, "CreateFileA");
  33. if (realCreateFileA == NULL)
  34. {
  35. OutputDebugString(L"(ptrCreateFileA)GetProcAddress(hKernel32, \"CreateFileA\") Error\n");
  36. return -6007;
  37. }
  38. OutputDebugString(L"(ptrCreateFileA)GetProcAddress(hKernel32, \"CreateFileA\") OK\n");
  39. return 0;
  40. }
  41. void DoHook()
  42. {
  43. OutputDebugString(L"DoHook()\n");
  44. statue = LhInstallHook(realCreateFileW,
  45. MyCreateFileW,
  46. /*(PVOID)0x12345678*/NULL,
  47. hHookCreateFileW);
  48. if(!SUCCEEDED(statue))
  49. {
  50. switch (statue)
  51. {
  52. case STATUS_NO_MEMORY:
  53. OutputDebugString(L"STATUS_NO_MEMORY\n");
  54. break;
  55. case STATUS_NOT_SUPPORTED:
  56. OutputDebugString(L"STATUS_NOT_SUPPORTED\n");
  57. break;
  58. case STATUS_INSUFFICIENT_RESOURCES:
  59. OutputDebugString(L"STATUS_INSUFFICIENT_RESOURCES\n");
  60. break;
  61. default:
  62. WCHAR dbgstr[512] = {0};
  63. wsprintf(dbgstr, L"%d\n", statue);
  64. OutputDebugString(dbgstr);
  65. }
  66. OutputDebugString(L"LhInstallHook(GetProcAddress(hKernel32, \"CreateFileW\"),MyCreateFileW,(PVOID)0x12345678,hHookCreateFileW); Error\n");
  67. return;
  68. }
  69. OutputDebugString(L"Hook CreateFileW OK\n");
  70. statue = LhInstallHook(realCreateFileA,
  71. MyCreateFileA,
  72. /*(PVOID)0x12345678*/NULL,
  73. hHookCreateFileA);
  74. if(!SUCCEEDED(statue))
  75. {
  76. switch (statue)
  77. {
  78. case STATUS_NO_MEMORY:
  79. OutputDebugString(L"STATUS_NO_MEMORY\n");
  80. break;
  81. case STATUS_NOT_SUPPORTED:
  82. OutputDebugString(L"STATUS_NOT_SUPPORTED\n");
  83. break;
  84. case STATUS_INSUFFICIENT_RESOURCES:
  85. OutputDebugString(L"STATUS_INSUFFICIENT_RESOURCES\n");
  86. break;
  87. default:
  88. WCHAR dbgstr[512] = {0};
  89. wsprintf(dbgstr, L"%d\n", statue);
  90. OutputDebugString(dbgstr);
  91. }
  92. OutputDebugString(L"LhInstallHook(GetProcAddress(hKernel32, \"CreateFileA\"),MyCreateFileA,(PVOID)0x12345678,hHookCreateFileA); Error\n");
  93. return;
  94. }
  95. OutputDebugString(L"Hook CreateFileA OK\n");
  96. // 一定要调用这个函数,否则注入的钩子无法正常运行。
  97. LhSetExclusiveACL(HookCreateFileA_ACLEntries, 1, hHookCreateFileA);
  98. LhSetExclusiveACL(HookCreateFileW_ACLEntries, 1, hHookCreateFileW);
  99. }
  100. void DoneHook()
  101. {
  102. OutputDebugString(L"DoneHook()\n");
  103. // this will also invalidate "hHook", because it is a traced handle...
  104. LhUninstallAllHooks();
  105. // this will do nothing because the hook is already removed...
  106. LhUninstallHook(hHookCreateFileA);
  107. LhUninstallHook(hHookCreateFileW);
  108. // now we can safely release the traced handle
  109. delete hHookCreateFileA;
  110. hHookCreateFileA = NULL;
  111. delete hHookCreateFileW;
  112. hHookCreateFileW = NULL;
  113. // even if the hook is removed, we need to wait for memory release
  114. LhWaitForPendingRemovals();
  115. }
  116. BOOL APIENTRY DllMain( HMODULE hModule,
  117. DWORD  ul_reason_for_call,
  118. LPVOID lpReserved
  119. )
  120. {
  121. switch (ul_reason_for_call)
  122. {
  123. case DLL_PROCESS_ATTACH:
  124. {
  125. OutputDebugString(L"DllMain::DLL_PROCESS_ATTACH\n");
  126. // 准备好原始地址与目的地址
  127. int errCode = PrepareRealApiEntry();
  128. if (errCode != 0)
  129. {
  130. OutputDebugString(L"PrepareRealApiEntry() Error\n");
  131. return FALSE;
  132. }
  133. // 开始挂钩
  134. DoHook();
  135. break;
  136. }
  137. case DLL_THREAD_ATTACH:
  138. {
  139. OutputDebugString(L"DllMain::DLL_THREAD_ATTACH\n");
  140. break;
  141. }
  142. case DLL_THREAD_DETACH:
  143. {
  144. OutputDebugString(L"DllMain::DLL_THREAD_DETACH\n");
  145. break;
  146. }
  147. case DLL_PROCESS_DETACH:
  148. {
  149. OutputDebugString(L"DllMain::DLL_PROCESS_DETACH\n");
  150. // 卸载钩子
  151. DoneHook();
  152. break;
  153. }
  154. }
  155. return TRUE;
  156. }
  1. <pre name="code" class="cpp">// HookSvr.cpp
  2. #include "stdafx.h"
  3. #include "HookApi.h"
  4. #include "easyhook.h"
  5. HANDLE WINAPI MyCreateFileW(
  6. __in     LPCWSTR lpFileName,
  7. __in     DWORD dwDesiredAccess,
  8. __in     DWORD dwShareMode,
  9. __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  10. __in     DWORD dwCreationDisposition,
  11. __in     DWORD dwFlagsAndAttributes,
  12. __in_opt HANDLE hTemplateFile
  13. )
  14. {
  15. HANDLE hHandle = NULL;
  16. // 执行钩子
  17. if (realCreateFileW == NULL)
  18. {
  19. OutputDebugString(L"realCreateFileW is NULL\n");
  20. return INVALID_HANDLE_VALUE;
  21. }
  22. else
  23. {
  24. OutputDebugString(L"realCreateFileW is not NULL\n");
  25. hHandle = (realCreateFileW)(lpFileName, dwDesiredAccess, dwShareMode,
  26. lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
  27. OutputDebugString(L"MyCreateFileW : ");
  28. OutputDebugString(lpFileName);
  29. OutputDebugString(L"\n");
  30. }
  31. return hHandle;
  32. }
  33. HANDLE WINAPI MyCreateFileA(
  34. __in     LPCSTR lpFileName,
  35. __in     DWORD dwDesiredAccess,
  36. __in     DWORD dwShareMode,
  37. __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  38. __in     DWORD dwCreationDisposition,
  39. __in     DWORD dwFlagsAndAttributes,
  40. __in_opt HANDLE hTemplateFile
  41. )
  42. {
  43. HANDLE hHandle = NULL;
  44. // 执行钩子
  45. if (realCreateFileA == NULL)
  46. {
  47. OutputDebugString(L"realCreateFileA is NULL\n");
  48. return INVALID_HANDLE_VALUE;
  49. }
  50. else
  51. {
  52. OutputDebugString(L"realCreateFileA is not NULL\n");
  53. hHandle = (realCreateFileA)(lpFileName, dwDesiredAccess, dwShareMode,
  54. lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
  55. OutputDebugString(L"MyCreateFileW : ");
  56. OutputDebugStringA(lpFileName);
  57. OutputDebugString(L"\n");
  58. }
  59. return hHandle;
  60. }</pre><br>
  61. 钩子这一部分我弄了比较久,主要是API不熟悉,不过好在弄好了。
  62. <pre></pre>
  63. <p><br>
  64. </p>
  65. <p></p><pre name="code" class="cpp">// HookSvr.h
  66. #pragma once
  67. #include <Windows.h>
  68. #ifndef _M_X64
  69. #pragma comment(lib, "EasyHook32.lib")
  70. #else
  71. #pragma comment(lib, "EasyHook64.lib")
  72. #endif
  73. HANDLE WINAPI MyCreateFileW(
  74. __in     LPCWSTR lpFileName,
  75. __in     DWORD dwDesiredAccess,
  76. __in     DWORD dwShareMode,
  77. __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  78. __in     DWORD dwCreationDisposition,
  79. __in     DWORD dwFlagsAndAttributes,
  80. __in_opt HANDLE hTemplateFile
  81. );
  82. typedef HANDLE (WINAPI *ptrCreateFileW)(
  83. __in     LPCWSTR lpFileName,
  84. __in     DWORD dwDesiredAccess,
  85. __in     DWORD dwShareMode,
  86. __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  87. __in     DWORD dwCreationDisposition,
  88. __in     DWORD dwFlagsAndAttributes,
  89. __in_opt HANDLE hTemplateFile
  90. );
  91. extern ptrCreateFileW realCreateFileW;
  92. HANDLE WINAPI MyCreateFileA(
  93. __in     LPCSTR lpFileName,
  94. __in     DWORD dwDesiredAccess,
  95. __in     DWORD dwShareMode,
  96. __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  97. __in     DWORD dwCreationDisposition,
  98. __in     DWORD dwFlagsAndAttributes,
  99. __in_opt HANDLE hTemplateFile
  100. );
  101. typedef HANDLE (WINAPI *ptrCreateFileA)(
  102. __in     LPCSTR lpFileName,
  103. __in     DWORD dwDesiredAccess,
  104. __in     DWORD dwShareMode,
  105. __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  106. __in     DWORD dwCreationDisposition,
  107. __in     DWORD dwFlagsAndAttributes,
  108. __in_opt HANDLE hTemplateFile
  109. );
  110. extern ptrCreateFileA realCreateFileA;</pre><br>
  111. <br>
  112. <p></p>
  113. <p>接下来是注入工具,这里指提供核心代码。本来EasyHook还提供了一个叫<span style="color:black">Rh</span>InjectLibrary()方法直接注入,这种方法相当稳定,推荐使用。我本来也用它,但是发现注入会失败,所以就采用了比较通用的远程注入代码,如下:</p>
  114. <pre name="code" class="cpp">BOOL RtlFileExists(WCHAR* InPath)
  115. {
  116. HANDLE          hFile;
  117. if((hFile = CreateFileW(InPath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
  118. return FALSE;
  119. CloseHandle(hFile);
  120. return TRUE;
  121. }
  122. BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege)
  123. {
  124. TOKEN_PRIVILEGES tp;
  125. HANDLE hToken;
  126. LUID luid;
  127. if( !OpenProcessToken(GetCurrentProcess(),
  128. TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  129. &hToken) )
  130. {
  131. return FALSE;
  132. }
  133. if( !LookupPrivilegeValue(NULL,             // lookup privilege on local system
  134. lpszPrivilege,    // privilege to lookup
  135. &luid) )          // receives LUID of privilege
  136. {
  137. return FALSE;
  138. }
  139. tp.PrivilegeCount = 1;
  140. tp.Privileges[0].Luid = luid;
  141. if( bEnablePrivilege )
  142. tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  143. else
  144. tp.Privileges[0].Attributes = 0;
  145. // Enable the privilege or disable all privileges.
  146. if( !AdjustTokenPrivileges(hToken,
  147. FALSE,
  148. &tp,
  149. sizeof(TOKEN_PRIVILEGES),
  150. (PTOKEN_PRIVILEGES) NULL,
  151. (PDWORD) NULL) )
  152. {
  153. return FALSE;
  154. }
  155. if( GetLastError() == ERROR_NOT_ALL_ASSIGNED )
  156. {
  157. //The token does not have the specified privilege.
  158. return FALSE;
  159. }
  160. return TRUE;
  161. }
  162. typedef DWORD (WINAPI *PFNTCREATETHREADEX)
  163. (
  164. PHANDLE                 ThreadHandle,
  165. ACCESS_MASK             DesiredAccess,
  166. LPVOID                  ObjectAttributes,
  167. HANDLE                  ProcessHandle,
  168. LPTHREAD_START_ROUTINE  lpStartAddress,
  169. LPVOID                  lpParameter,
  170. BOOL                   CreateSuspended,
  171. DWORD                   dwStackSize,
  172. DWORD                   dw1,
  173. DWORD                   dw2,
  174. LPVOID                  Unknown
  175. );
  176. BOOL MyCreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE pThreadProc, LPVOID pRemoteBuf)
  177. {
  178. HANDLE      hThread = NULL;
  179. FARPROC     pFunc = NULL;
  180. BOOL bHook;
  181. // 判断系统版本
  182. OSVERSIONINFO osvi;
  183. //BOOL bIsWindowsXPorLater;
  184. ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
  185. osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  186. GetVersionEx(&osvi);
  187. if (osvi.dwMajorVersion == 6)
  188. {
  189. bHook = TRUE;
  190. }
  191. else
  192. {
  193. bHook = FALSE;
  194. }
  195. if(bHook)    // Vista, 7, Server2008
  196. {
  197. pFunc = GetProcAddress(GetModuleHandle(L"ntdll.dll"), "NtCreateThreadEx");
  198. if( pFunc == NULL )
  199. {
  200. //GetLastError());
  201. return FALSE;
  202. }
  203. OutputDebugString(L"MyCreateRemoteThread");
  204. ((PFNTCREATETHREADEX)pFunc)(&hThread,
  205. 0x1FFFFF,
  206. NULL,
  207. hProcess,
  208. pThreadProc,
  209. pRemoteBuf,
  210. FALSE,
  211. NULL,
  212. NULL,
  213. NULL,
  214. NULL);
  215. if( hThread == NULL )
  216. {
  217. return FALSE;
  218. }
  219. }
  220. else                    // 2000, XP, Server2003
  221. {
  222. hThread = CreateRemoteThread(hProcess,
  223. NULL,
  224. 0,
  225. pThreadProc,
  226. pRemoteBuf,
  227. 0,
  228. NULL);
  229. if( hThread == NULL )
  230. {
  231. return FALSE;
  232. }
  233. }
  234. if( WAIT_FAILED == WaitForSingleObject(hThread, INFINITE) )
  235. {
  236. return FALSE;
  237. }
  238. return TRUE;
  239. }
  240. BOOL InjectDll(DWORD dwPID, const wchar_t *szDllName)
  241. {
  242. HANDLE hProcess = NULL;
  243. LPVOID pRemoteBuf = NULL;
  244. FARPROC pThreadProc = NULL;
  245. DWORD dwBufSize = wcslen(szDllName)*sizeof(wchar_t)+2;
  246. if ( !(hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPID)) )
  247. {
  248. return FALSE;
  249. }
  250. pRemoteBuf = VirtualAllocEx(hProcess, NULL, dwBufSize,
  251. MEM_COMMIT, PAGE_READWRITE);
  252. WriteProcessMemory(hProcess, pRemoteBuf, (LPVOID)szDllName,
  253. dwBufSize, NULL);
  254. pThreadProc = GetProcAddress(GetModuleHandle(L"kernel32.dll"),
  255. "LoadLibraryW");
  256. if( !MyCreateRemoteThread(hProcess, (LPTHREAD_START_ROUTINE)pThreadProc, pRemoteBuf) )
  257. {
  258. return FALSE;
  259. }
  260. VirtualFreeEx(hProcess, pRemoteBuf, dwBufSize, MEM_RELEASE);
  261. CloseHandle(hProcess);
  262. return TRUE;
  263. }
  264. int DoInject(DWORD aPid, const WCHAR *aFullpath)
  265. {
  266. if (wcslen(aFullpath) <= 0)
  267. {
  268. return -1;
  269. }
  270. //判断dll是否存在
  271. HANDLE hFile = CreateFile(aFullpath, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
  272. if(hFile != INVALID_HANDLE_VALUE)
  273. {
  274. DWORD dwsize = GetFileSize(hFile, NULL);
  275. CloseHandle(hFile);
  276. if (dwsize < 10)
  277. {
  278. return -2;
  279. }
  280. }
  281. else
  282. {
  283. return -3;
  284. }
  285. BOOL bSuc=SetPrivilege(SE_DEBUG_NAME, TRUE);
  286. bSuc=InjectDll((DWORD)aPid, aFullpath);
  287. if (bSuc)
  288. {
  289. return -4;
  290. }
  291. return 0;
  292. }
  293. // 真实注入的时候应该这样调用
  294. DoInject(m_processId, L"E:\\src\\easyhook\\trunk\\Debug\\x86\\HookSvr.dll");
  295. </pre><br>
  296. 这样就能保证注入的钩子能正常工作了。
分享到: 
 
 

查看评论
4楼 SpiritMFC 2013-03-26 15:43发表 [回复]
你好~ 能提供能运行的源码嘛?
我用你的方法正常exe可以hook成功,
但是DLL注入后钩子无法工作。
困扰数天的问题了。
求帮助!
还有 C++的话这个库能实现全局钩子嘛?
Re: baggiowangyu 2013-03-29 09:24发表 [回复]
回复SpiritMFC:我给的例子就是源代码了哇,那时候研究到那里就没有继续往下了。应该是你注入之后挂钩写的不对导致的。

你指的全局钩子是什么概念?全局消息钩子么?目前我知道的是这个可以实现指定进程的挂钩。

3楼 lsssml1990 2012-10-26 12:22发表 [回复]
这个代码可以直接用不?
2楼 baggiowangyu 2012-06-23 14:02发表 [回复]
一同学习,一同学习
1楼 Wentasy 2012-06-19 11:46发表 [回复]
不错,学习了。

转:EasyHook远程代码注入的更多相关文章

  1. EasyHook远程进程注入并hook api的实现

    EasyHook远程进程注入并hook api的实现 http://blog.csdn.net/v6543210/article/details/44276155

  2. C语言实现远程代码注入

    #include <windows.h> #include <iostream> #define STRLEN 20 typedef struct _DATA { DWORD ...

  3. windows:shellcode 代码远程APC注入和加载

    https://www.cnblogs.com/theseventhson/p/13197776.html  上一章介绍了通用的shellcode加载器,这个加载器自己调用virtualAlloc分配 ...

  4. Windows下的代码注入

    木马和病毒的好坏很大程度上取决于它的隐蔽性,木马和病毒本质上也是在执行程序代码,如果采用独立进程的方式需要考虑隐藏进程否则很容易被发现,在编写这类程序的时候可以考虑将代码注入到其他进程中,借用其他进程 ...

  5. ecshop 全系列版本网站漏洞 远程代码执行sql注入漏洞

    ecshop漏洞于2018年9月12日被某安全组织披露爆出,该漏洞受影响范围较广,ecshop2.73版本以及目前最新的3.0.3.6.4.0版本都受此次ecshop漏洞的影响,主要漏洞是利用远程代码 ...

  6. 注入攻击-SQL注入和代码注入

    注入攻击 OWASP将注入攻击和跨站脚本攻击(XSS)列入网络应用程序十大常见安全风险.实际上,它们会一起出现,因为 XSS 攻击依赖于注入攻击的成功.虽然这是最明显的组合关系,但是注入攻击带来的不仅 ...

  7. MongoDB ‘conn’Mongo 对象远程代码执行漏洞

    漏洞名称: MongoDB ‘conn’Mongo 对象远程代码执行漏洞 CNNVD编号: CNNVD-201307-497 发布时间: 2013-07-25 更新时间: 2013-07-25 危害等 ...

  8. 使用VC++通过远程进程注入来实现HOOK指定进程的某个API

    前阵子读到一篇关于<HOOK API入门之Hook自己程序的MessageBoxW>的博客,博客地址:http://blog.csdn.net/friendan/article/detai ...

  9. 远程线程注入方法CreateRemoteThread

    最近在整理学习Windows注入方面的知识,这个远程注入前面早写过,现在看看人家博客的理解整理,整理, 需要源码的可以到我的github上下载. 链接是  https://github.com/Ars ...

随机推荐

  1. POJ 3274 Gold Balanced Lineup

    Gold Balanced Lineup Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10924 Accepted: 3244 ...

  2. POJ 3041 Asteroids

     最小点覆盖数==最大匹配数 Asteroids Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12678 Accepted:  ...

  3. HDU 4858 项目管理(邻接表 暴力模拟)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4858 我们建造了一个大项目!这个项目有n个节点,用很多边连接起来,并且这个项目是连通的! 两个节点间可 ...

  4. 快速诊断Linux性能

    导读 当你为了解决一个性能问题登录到一台 Linux 服务器:在第一分钟你应该检查些什么? 通过运行下面十个命令,你就能在六十秒内粗略地了解系统正在运行的进程及资源使用情况.通过查看这些命令输出的错误 ...

  5. sql注入学习小结

    /* 转载请注明出处,By:珍惜少年时 小知识,只是放在博客吃饭时无聊看看,大牛勿喷. */ 珍惜少年时博客,专注网络安全 web渗透测试 00x1爆所有库: mysql> select sch ...

  6. 用sed删除空行

    用sed删除空行 我的代码如下:class Song def initialize(name)        @name = name    end def tell        puts @nam ...

  7. android 自定义Dialog背景透明及显示位置设置

    先贴一下显示效果图,仅作参考: 代码如下: 1.自定义Dialog public class SelectDialog extends AlertDialog{ public SelectDialog ...

  8. 【Django】如何自定义manage.py命令? 达到启动后台进程的目的?

    代码: #-*- coding:utf- -*- """ The handle active user mail send """ from ...

  9. 【SpringMVC】SpringMVC系列10之视图与视图解析器

    10.视图与视图解析器 10.1.概述     请求处理方法执行完成后,最终返回一个 ModelAndView处理方法,Spring MVC 也会在内部将它们装配成一个ModelAndView 对象, ...

  10. HashMap实现原理分析(详解)

    1. HashMap的数据结构 http://blog.csdn.net/gaopu12345/article/details/50831631   ??看一下 数据结构中有数组和链表来实现对数据的存 ...