Ruby ¤«¤é Win32 API ᤯¤¿¤á¤Î¥¯¥é¥¹
źÉե饤¥Ö¥é¥ê¤Ë´Þ¤Þ¤ì¤ë
¤Á¤ç¤Ã¤È±ø¤¤¤±¤É¤³¤ó¤Ê´¶¤¸¤Ç¹Ô¤±¤½¤¦
Î㤨¤Ð¾åµ¤Î¥¹¥¯¥ê¥×¥È¤ò PSAPItest.rb ¤È¤·¤ÆÊݸ¤·¤Æ¤ª¤¯¤È°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ»È¤¨¤ë
¥Ý¥¤¥ó¥¿ÅϤ·¤Î°ú¿ô¤ËÌá¤êÃͤ¬Æþ¤ë¾ì¹ç¤È¤«¤ò¤É¤¦°·¤¦¤«¤¬Çº¤ß¤É¤³¤í¤Êµ¤¤¬¤¹¤ë
wrapper ¤ËÅ°¤¹¤ë¤Ù¤¤«¡¢Ruby ¤é¤·¤¤´Ø¿ô¤ä¥¯¥é¥¹¤Ë»ÅΩ¤Æ¤ë¤Ù¤¤«Çº¤Þ¤·¤¤
Ruby ¤«¤é sizeof() ¤ÎÃÍÃΤëÊýË¡¤¬¤Ê¤¤¤Î¤Ç¤Á¤ç¤Ã¤Èº¤¤ë¡£
Î㤨¤Ð
GetModuleFileNameEx() ¤Î
nSize ¤Ã¤Æ sizeof(lpFilename)/sizeof(TCHAR) ¤Î¤Ï¤º¤Ê¤ó¤À¤±¤É
sizeof(TCHAR) ¤È¤«¤É¤¦¤ä¤Ã¤Æ¤È¤ì¤ÐÎɤ¤¤ó¤À¡©
32bit ´Ä¶¤È 64bit ´Ä¶¤Ç¥Ý¥¤¥ó¥¿¥µ¥¤¥º¤¬°ã¤¦¤Î¤Ç¥Ï¥Þ¤ê¤½¤¦¤Êͽ´¶
¤È¤ê¤¢¤¨¤º´Ä¶¤ÎȽÊ̤ϰʲ¼¤ÎÊýË¡¤Ç²Äǽ¤ÊÌÏÍÍ
Answers: Determining XP 32 or 64Bit by calling IsWow64Process():
źÉե饤¥Ö¥é¥ê¤Ë´Þ¤Þ¤ì¤ë
#!/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():
- ¥«¥Æ¥´¥ê¡§
- ¥Ñ¥½¥³¥ó
- ¥×¥í¥°¥é¥ß¥ó¥°
¥¿¥°
¥³¥á¥ó¥È¤ò¤«¤¯