www.pudn.com > RmtDll.rar > RmtDll.cpp


 
#include 
#include 
#include 
#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:\n\t%s\n\n", 
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\n", 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\n\n", 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\n\n",pErrorMsg); 
    printf("\t\tRemote Process DLL by Shotgun\n"); 
    printf("\tThis program can inject a DLL into remote process\n"); 
    printf("Email:\n"); 
    printf("\tShotgun@Xici.Net\n"); 
    printf("HomePage:\n"); 
    printf("\thttp://It.Xici.Net\n"); 
    printf("\thttp://www.Patching.Net\n"); 
    printf("USAGE:\n"); 
    printf("\tRmtDLL.exe PID[|ProcessName] DLLFullPathName\n"); 
    printf("Example:\n"); 
    printf("\tRmtDLL.exe 1024 C:\\WINNT\\System32\\MyDLL.dll\n"); 
    printf("\tRmtDLL.exe Explorer.exe C:\\MyDLL.dll\n"); 
    exit(0); 
}//end of usage()