他人の空似自作物置場

cmd_logger.zip/injector/main.cpp


#include <vector>
#include <algorithm>

#include <windows.h>

#include <boost/filesystem.hpp>

boost::filesystem::path GetAppDir() {
  wchar_t buffer[MAX_PATH];
  if (0 == ::GetModuleFileNameW(::GetModuleHandleW(NULL), buffer, _countof(buffer))) {
    return boost::filesystem::path();
  }
  return boost::filesystem::path(buffer).remove_filename();
}

int main() {
  std::wstring wcmd = ::GetCommandLineW();
  for (unsigned int i = 0;; i++) {
    if (wcmd[i] == L'"') {
      std::wstring::iterator it = std::find(wcmd.begin() + i + 1, wcmd.end(), L'"');
      if (it != wcmd.end()) {
        it++;
      }
      wcmd.erase(wcmd.begin() + i, it);
      i--;
    }
    if (wcmd[i] == L' ' && (i + 1 == wcmd.size() || wcmd[i + 1] != L' ')) {
      wcmd.erase(wcmd.begin(), wcmd.begin() + i + 1);
      break;
    }
    if (i + 1 == wcmd.size()) {
      wcmd = L"";
      break;
    }
  }
  std::vector<wchar_t> wcmd_buffer(wcmd.begin(), wcmd.end());
  wcmd_buffer.resize(wcmd.size() + 1);
  wcmd_buffer.back() = L'\0';

  STARTUPINFOW startupinfo;
  startupinfo.cb = sizeof(startupinfo);
  startupinfo.lpReserved = NULL;
  startupinfo.lpDesktop = L"";
  startupinfo.lpTitle = NULL;
  startupinfo.dwFlags = 0;
  startupinfo.cbReserved2 = 0;
  startupinfo.lpReserved2 = NULL;
  PROCESS_INFORMATION info;
  if (FALSE == ::CreateProcessW(L"C:\\Windows\\System32\\cmd.exe", &wcmd_buffer.front(), NULL, NULL, FALSE,
    CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED | NORMAL_PRIORITY_CLASS,
    NULL, NULL, &startupinfo, &info))
  {
    return 1;
  }
  const boost::filesystem::path path = GetAppDir() / L"cmd_logger.dll";
  const unsigned int size = sizeof(wchar_t) * (path.wstring().size() + 1);
  void * const dllname_address = ::VirtualAllocEx(info.hProcess, NULL, size, MEM_COMMIT, PAGE_READWRITE);
  if (dllname_address == NULL) {
    ::ResumeThread(info.hThread);
    return 1;
  }
  ::SetLastError(0);
  DWORD write_size;
  if (::WriteProcessMemory(info.hProcess, dllname_address, path.c_str(), size, &write_size) == FALSE) {
    ::ResumeThread(info.hThread);
    return 1;
  }
  DWORD thread_id;
  const HANDLE remote_thread_handle = ::CreateRemoteThread(info.hProcess, NULL, 0,
    reinterpret_cast<LPTHREAD_START_ROUTINE>(::LoadLibraryW), dllname_address, 0, &thread_id);
  ::WaitForSingleObject(remote_thread_handle, INFINITE);
  ::CloseHandle(remote_thread_handle);
  ::VirtualFreeEx(info.hProcess, dllname_address, 0, MEM_RELEASE);
  ::ResumeThread(info.hThread);
  ::CloseHandle(info.hThread);
  ::CloseHandle(info.hProcess);
  return 0;
}