hack ¤Î¤¿¤á¤Î¥Í¥¿Ä¢, etc,,,

Ruby ¤«¤é Win32 API ᤯¤¿¤á¤Î¥¯¥é¥¹
źÉե饤¥Ö¥é¥ê¤Ë´Þ¤Þ¤ì¤ë

¥µ¥ó¥×¥ë

PSAPI ¤È kernel32 ¤Ë¤è¤ë¥×¥í¥»¥¹°ìÍ÷¤È¤«¥×¥í¥»¥¹¤Î½ªÎ»¤È¤« (2011-02-06)

#!/usr/bin/ruby
require 'Win32API'

class String
  def to_DWORD x = 0
    self.to_DWORDS[x]
  end
  def to_DWORDS
    self.unpack("L*")
  end
end

class Win32API
  SIZEOF_DWORD = 4
  SIZEOF_TCHAR = 1
  
  # @reference winnt.h
  SYNCHRONIZE               = 0x100000
  STANDARD_RIGHTS_REQUIRED  = 0xF0000
  PROCESS_TERMINATE         =    1
  PROCESS_CREATE_THREAD     =    2
  PROCESS_SET_SESSIONID     =    4
  PROCESS_VM_OPERATION      =    8
  PROCESS_VM_READ           =   16
  PROCESS_VM_WRITE          =   32
  PROCESS_DUP_HANDLE        =   64
  PROCESS_CREATE_PROCESS    =  128
  PROCESS_SET_QUOTA         =  256
  PROCESS_SUSPEND_RESUME    = 0x0800
  PROCESS_SET_INFORMATION   =  512
  PROCESS_QUERY_INFORMATION = 1024
  PROCESS_ALL_ACCESS        = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF)
  
  ############################################################################
  # kernel32.dll
  
  # @reference http://msdn.microsoft.com/ja-jp/library/cc429278.aspx
  def Win32API.OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId)
    openprocess = Win32API.new('kernel32.dll', 'OpenProcess', 'lll', 'l')
    bInheritHandle = bInheritHandle ? 1 : 0
    hProcess = openprocess.call(dwDesiredAccess, bInheritHandle, dwProcessId)
  end
  
  # @reference http://msdn.microsoft.com/ja-jp/library/cc429605.aspx
  def Win32API.CloseHandle(hObject)
    closehandle = Win32API.new('kernel32.dll', 'CloseHandle', 'l', 'l')
    closehandle.call(hObject) ? true : false
  end
  
  # @reference http://msdn.microsoft.com/ja-jp/library/cc429376.aspx
  def Win32API.TerminateProcess(hProcess, uExitCode)
    terminateprocess = Win32API.new('kernel32.dll', 'TerminateProcess', 'll', 'l')
    terminateprocess.call(hProcess, uExitCode) ? true : false
  end
  
  ############################################################################
  # psapi.dll
  
  # @reference http://msdn.microsoft.com/ja-jp/library/cc429383.aspx
  def Win32API.EnumProcesses
    enumprocesses = Win32API.new('psapi.dll', 'EnumProcesses', 'plp', 'i')
    lpidProcess = [0].pack("L") * 1024
    cbNeeded    = [0].pack("L")
    while true
      enumprocesses.call(lpidProcess, lpidProcess.length, cbNeeded)
      break if cbNeeded.to_DWORD < lpidProcess.length
      lpidProcess *= 2
    end
    lpidProcess.slice(0, cbNeeded.to_DWORD).to_DWORDS
  end
  
  # @reference http://msdn.microsoft.com/ja-jp/library/cc429387.aspx
  def Win32API.EnumProcessModules(hProcess)
    enumprocessmodules = Win32API.new('psapi.dll', 'EnumProcessModules', 'lplp', 'l')
    lphModule  = ""
    lpcbNeeded = [0].pack("L")
    while true do
      result = enumprocessmodules.call(hProcess, lphModule, lphModule.length, lpcbNeeded)
      return [] if result == 0
      break if lpcbNeeded.to_DWORD <= lphModule.length
      lphModule = "\0" * lpcbNeeded.to_DWORD
    end
    lphModule.slice(0, lpcbNeeded.to_DWORD).to_DWORDS
  end
  
  # @reference http://msdn.microsoft.com/ja-jp/library/cc429400.aspx
  def Win32API.GetModuleBaseName(hProcess, hModule)
    getmodulebasename = Win32API.new("psapi.dll", "GetModuleBaseName", "llpl", "l")
    lpBaseName = "\0" * 1024
    while true do
      len = getmodulebasename.call(hProcess, hModule, lpBaseName, lpBaseName.length / SIZEOF_TCHAR)
      break if len < lpBaseName.length / SIZEOF_TCHAR
      lpBaseName *= 2
    end
    lpBaseName.slice(0, len * SIZEOF_TCHAR)
  end
  
  # @reference http://msdn.microsoft.com/ja-jp/library/cc429403.aspx
  def Win32API.GetModuleFileNameEx(hProcess, hModule)
    getmodulefilenameex = Win32API.new("psapi.dll", "GetModuleFileNameEx", "llpl", "l")
    lpFilename = "\0" * 1024
    while true do
      len = getmodulefilenameex.call(hProcess, hModule, lpFilename, lpFilename.length / SIZEOF_TCHAR)
      break if len < lpFilename.length / SIZEOF_TCHAR
      lpFilename *= 2
    end
    lpFilename.slice(0, len * SIZEOF_TCHAR)
  end
end



def putProcessList bShowModules = false
  Win32API.EnumProcesses.sort.each do |pidProcess|
    hProcess = Win32API.OpenProcess(Win32API::PROCESS_QUERY_INFORMATION | Win32API::PROCESS_VM_READ, FALSE, pidProcess)
    hModules = Win32API.EnumProcessModules(hProcess)
    indent = sprintf("%d ", pidProcess)
    hModules.each do |hModule|
      printf("%s%s\n", indent, Win32API.GetModuleFileNameEx(hProcess, hModule))
      indent = "\t"
      break if !bShowModules
    end
    Win32API.CloseHandle hProcess
  end
end

def KillProcess pid
  hProcess = Win32API.OpenProcess(Win32API::PROCESS_TERMINATE, FALSE, pid)
  Win32API.TerminateProcess hProcess, 0
  Win32API.CloseHandle hProcess
end

¤Á¤ç¤Ã¤È±ø¤¤¤±¤É¤³¤ó¤Ê´¶¤¸¤Ç¹Ô¤±¤½¤¦
Î㤨¤Ð¾åµ­¤Î¥¹¥¯¥ê¥×¥È¤ò PSAPItest.rb ¤È¤·¤ÆÊݸ¤·¤Æ¤ª¤¯¤È°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ»È¤¨¤ë
$ ruby -r PSAPItest.rb -e "putProcessList"
kill ¤·¤¿¤¤¥×¥í¥»¥¹¤Î pid ¤¬ 12345 ¤Ê¤é°Ê²¼¤Î¤è¤¦¤Ë¤¹¤ì¤Ð kill ¤Ç¤­¤ë
$ ruby -r PSAPItest.rb -e "KillProcess 12345"

¥Ý¥¤¥ó¥¿ÅϤ·¤Î°ú¿ô¤ËÌá¤êÃͤ¬Æþ¤ë¾ì¹ç¤È¤«¤ò¤É¤¦°·¤¦¤«¤¬Çº¤ß¤É¤³¤í¤Êµ¤¤¬¤¹¤ë
wrapper ¤ËÅ°¤¹¤ë¤Ù¤­¤«¡¢Ruby ¤é¤·¤¤´Ø¿ô¤ä¥¯¥é¥¹¤Ë»ÅΩ¤Æ¤ë¤Ù¤­¤«Çº¤Þ¤·¤¤

Ruby ¤«¤é sizeof() ¤ÎÃÍÃΤëÊýË¡¤¬¤Ê¤¤¤Î¤Ç¤Á¤ç¤Ã¤Èº¤¤ë¡£
Î㤨¤Ð
GetModuleFileNameEx() ¤Î
nSize ¤Ã¤Æ sizeof(lpFilename)/sizeof(TCHAR) ¤Î¤Ï¤º¤Ê¤ó¤À¤±¤É
sizeof(TCHAR) ¤È¤«¤É¤¦¤ä¤Ã¤Æ¤È¤ì¤ÐÎɤ¤¤ó¤À¡©

32bit ´Ä¶­¤È 64bit ´Ä¶­¤Ç¥Ý¥¤¥ó¥¿¥µ¥¤¥º¤¬°ã¤¦¤Î¤Ç¥Ï¥Þ¤ê¤½¤¦¤Êͽ´¶
¤È¤ê¤¢¤¨¤º´Ä¶­¤ÎȽÊ̤ϰʲ¼¤ÎÊýË¡¤Ç²Äǽ¤ÊÌÏÍÍ
Answers: Determining XP 32 or 64Bit by calling IsWow64Process():

´ØÏ¢

¥¿¥°

¥³¥á¥ó¥È¤ò¤«¤¯


¡Öhttp://¡×¤ò´Þ¤àÅê¹Æ¤Ï¶Ø»ß¤µ¤ì¤Æ¤¤¤Þ¤¹¡£

ÍøÍѵ¬Ìó¤ò¤´³Îǧ¤Î¤¦¤¨¤´µ­Æþ²¼¤µ¤¤

WikiÆ⸡º÷

¥Õ¥ê¡¼¥¨¥ê¥¢

´ÉÍý¿Í/Éû´ÉÍý¿Í¤Î¤ßÊÔ½¸¤Ç¤­¤Þ¤¹