理论:
什么是进程,什么是线程
进程就是4GB的空间,线程就是EIP
想在别的进程中执行自己的代码
- 进程空间中必须要有我的代码
- 进程空间中必须有一个线程执行我的代码
- 方法:(原来的线程JMP到我的代码,或者开辟一个新的线程)
原来的线程Jmp到我的代码,称之为HOOK,改变原来线程的执行轨迹
如何将代码放入目标进程空间:
- 代码整理成一个模块,直接插入到目标的进程空间中(容易被发现)
- 只把函数体放入对方的进程空间【硬编码】
如果直接使用硬编码的方式,会造成问题:
- 使用全局变量的地址会发生改变
- 使用API函数会导致IAT的地址找不到
使用ShellCode - 一种可变的硬编码
ShellCode是研究病毒必须要掌握的一种技能:将硬编码ShellCode化
ShellCode(代码注入)
- 不使用全局变量
- 需要什么API函数自己去获取
-
缺点:比较麻烦 - 如果代码量过多
-
优点:无法被检测到
特征码就是程序核心的硬编码
在程序的核心部分做记号,根据这个记号去找到对应的程序或者基址
无痕HOOK 就是Jmp
Inline HOOK 就是 Call
模块注入
优点:写起来非常方便
缺点:特征明显
实践:
LoadLibrary
将指定的模块加载到调用进程的地址空间中。 指定的模块可能会导致加载其他模块。
HMODULE LoadLibraryA(
[in] LPCSTR lpLibFileName
);
[in] lpLibFileName
模块的名称。 可以是库模块 (.dll 文件) ,也可以是可执行模块 (.exe 文件) 。 如果指定的模块是可执行模块,则不会加载静态导入;
LoadLibrary 可用于将库模块加载到进程的地址空间中,并返回一个句柄,该句柄可用于 在 GetProcAddress 中 获取 DLL 函数的地址。
如果指定的模块是尚未为调用进程加载的 DLL,则系统会使用DLL_PROCESS_ATTACH值调用 DLL 的 DllMain 函数。 如果 DllMain 返回 TRUE, 则 LoadLibrary 将返回模块的句柄。 如果 DllMain 返回 FALSE,则系统会从进程地址空间中卸载 DLL, 而 LoadLibrary 返回 NULL。 从 DllMain 调用 LoadLibrary 是不安全的。
返回值
如果函数成功,则返回值是模块的句柄。
如果函数失败,则返回值为 NULL。 要获得更多的错误信息,请调用 GetLastError。