[已解决]如何从PID获取进程基址?
本帖最后由 lzmyst 于 2011-9-13 20:38 编辑我已经通过搜索“基址”查找,没有找到获取进程基址的相关资料
但在http://www.autoitx.com/forum.php?mod=viewthread&tid=27307找到了获取模块基址的方法
还请各位大侠指教获取进程基址的方法!谢谢。 $pid = ProcessExists("notepad.exe")
$addr = _MemoryModuleGetBaseAddress($pid,"notepad.exe")
MsgBox(0,0,$addr) 首先感谢楼上的兄台的回复!
我已经试过你的代码,在实际使用中不起效。
我是想用XueTrCmd卸载某个进程中的特定DLL模块
XueTrCmd在使用时需用到“进程对象地址”,按以上方法取得的基址,和XueTrCmd自身列出的不相同,从而无法使用XueTrCmd卸载指定模块。
PS:XueTrCmd的回显也无法取得,否则直接取XueTrCmd的回显就可以了。 创建远程线程。
#include <Thread.au3>
$pGetModuleHandleW = _RTGetProcAddress("Kernel32.dll", "GetModuleHandleW")
$hProcess = _RTOpenProcess("notepad.exe")
$hThread = _RTCreateRemoteThread($hProcess, $pGetModuleHandleW, 0)
_RTWaitForObject($hThread)
$pBaseAddress = DllCall("Kernel32.dll", "bool", "GetExitCodeThread", "handle", $hThread, "ptr*", 0)
$pBaseAddress = $pBaseAddress
_RTCloseHandle($hThread)
_RTCloseHandle($hProcess)
MsgBox(0, "Image Base", $pBaseAddress)
直接读取PE文件。
#include <PeShellX.au3>
$sImagePath = @WindowsDir & "\notepad.exe"
$pFileView = _PeMapFileView($sImagePath, $PE_FILE_READ)
$pBaseAddress = _PeGetImageBase($pFileView)
_PeUnmapFileView($pFileView)
MsgBox(0, "Image Base", $pBaseAddress)
第3种方法,如顶楼链接中说的,先枚举所有模块,然后比较模块名称。 这个问题我前几天也问了,你通过我的用户名查一下吧。 还有,找某个软件的基址还可能用到一个叫cheat engine的软件,网上有简单的教程,我也是刚开始研究,祝你好运! 本帖最后由 lzmyst 于 2011-9-5 20:57 编辑
感谢P版(偶的仰慕者)及yd111070 的回复!
能请P版提供PeShellX.au3吗?谢谢!
已经试过P说的创建远程线程的方法,取得的地址和取模块基址得到的相同,不是进程对象地址,而模块的基址,XueTrCmd卸载模块时需用到两个地址,一个是进程地址,一个是模块地址
模块地址已经取到,并且和XueTrCmd回显的相同
但进程地址还取不到。
我的本意是想利用XueTrCmd卸载某个模块,如果AU3能直接实现更好,否则我只能用XueTrCmd实现,但XueTrCmd要取得“进程对象地址”才可以卸载,这个难住了我。
以下XueTrCmd列出的EPROCESS:0x894F1020才是需要用到的,而且采用获取模块基址的方法得到的和这个不相同,因此无法使用。T_tools.exe:
PID:5120 Parent Pid:3440 EPROCESS:0x894F1020
Path:E:\AU3\autoit3\T_tools.exe
File Corporation:- #include <Thread.au3>
Func _UnloadDllEx($sDllName, $iProcessID = @AutoItPid)
If ($iProcessID = -1) Then $iProcessID = @AutoItPid
$iProcessID = ProcessExists($iProcessID)
If ($iProcessID < 1) Then Return SetError(2, 0, 0) ; ERROR_NOT_FOUND
Local $hProcess = _RTOpenProcess($iProcessID)
If ($hProcess < 1) Then Return SetError(@error, 0, 0)
Local $pStartAddr = _RTVirtualAllocEx($hProcess, 1024)
If ($pStartAddr = 0) Then Return SetError(@error, _RTCloseHandle($hProcess), 0)
Local $pDllName = $pStartAddr + 512
Local $tBuffer = DllStructCreate("ubyte ShellX;wchar wzDllName")
Local $pBuffer = DllStructGetPtr($tBuffer)
DllStructSetData($tBuffer, "ShellX", __UnloadDllEx_ShellX())
DllStructSetData($tBuffer, "wzDllName", $sDllName)
If _RTWriteProcessMemory($hProcess, $pStartAddr, $pBuffer, 1024) = 0 Then
Return SetError(@error, __UnloadDllEx_Cleanup($hProcess, $pStartAddr), 0)
EndIf
Local $hThread = _RTCreateRemoteThread($hProcess, $pStartAddr + 16, $pDllName)
If ($hThread = 0) Then Return SetError(@error, __UnloadDllEx_Cleanup($hProcess, $pStartAddr), 0)
_RTWaitForObject($hThread)
Local $iStatus = DllCall("Kernel32.dll", "bool", "GetExitCodeThread", "handle", $hThread, "long*", 0)
$iStatus = $iStatus
__UnloadDllEx_Cleanup($hProcess, $pStartAddr, $hThread)
Return SetError($iStatus, 1, $iStatus = 0)
EndFunc ;==>_UnloadDllEx
Func __UnloadDllEx_ShellX()
Local $bBinary = "0x558BEC8B450885C0742B53E8000000005B83EB2050FF1385C0740F50FF530485C0740733C05B5DC2040064A1180000008B4034EBF06A5758EBECCCCC"
Local $tBuffer = DllStructCreate("ptr Functions;ubyte ShellX")
DllStructSetData($tBuffer, "Functions", _RTGetProcAddress("Kernel32.dll", "GetModuleHandleW"), 1)
DllStructSetData($tBuffer, "Functions", _RTGetProcAddress("Kernel32.dll", "FreeLibrary"), 2)
DllStructSetData($tBuffer, "ShellX", Binary($bBinary))
Local $tBinary = DllStructCreate("ubyte ShellX", DllStructGetPtr($tbuffer))
Return DllStructGetData($tBinary, "ShellX")
EndFunc ;==>__UnloadDllEx_ShellX
Func __UnloadDllEx_Cleanup($hProcess, $pStartAddr = 0, $hThread = 0, $iReturn = 0)
If $pStartAddr Then _RTVirtualFreeEx($hProcess, $pStartAddr, 1024)
If $hThread Then _RTCloseHandle($hThread)
If $hProcess Then _RTCloseHandle($hProcess)
Return $iReturn
EndFunc ;==>__UnloadDllEx_Cleanup
操作系统会为每个模块维护一个引用计数,模块每加载一次,引用计数加1;每卸载一次,引用计数减1,直到计数达到0时,模块才真正从目标进程空间中删除。
_UnloadDllEx函数 调用示例:
; 卸载notepad.exe进程 加载的hook.dll。
While _UnloadDllEx("hook.dll", "notepad.exe")
WEnd
If @error = 126 Then
MsgBox(48, "OK", "Done.")
Else
MsgBox(48, "Error", "Failed with: " & @error)
EndIf
不要卸载 类似Ntdll.dll、Kernel32.dll、AdvApi32.dll 这样的核心模块,否则这段示例代码将会产生一个死循环。
汇编代码:
019B0010 55 push ebp
019B0011 8BEC mov ebp, esp
019B0013 8B45 08 mov eax, dword ptr
019B0016 85C0 test eax, eax
019B0018 74 2B je short 019B0045
019B001A 53 push ebx
019B001B E8 00000000 call 019B0020
019B0020 5B pop ebx
019B0021 83EB 20 sub ebx, 20
019B0024 50 push eax
019B0025 FF13 call dword ptr
019B0027 85C0 test eax, eax
019B0029 74 0F je short 019B003A
019B002B 50 push eax
019B002C FF53 04 call dword ptr
019B002F 85C0 test eax, eax
019B0031 74 07 je short 019B003A
019B0033 33C0 xor eax, eax
019B0035 5B pop ebx
019B0036 5D pop ebp
019B0037 C2 0400 retn 4
019B003A 64:A1 18000000 mov eax, dword ptr fs:
019B0040 8B40 34 mov eax, dword ptr
019B0043 ^ EB F0 jmp short 019B0035
019B0045 6A 57 push 57
019B0047 58 pop eax
019B0048 ^ EB EC jmp short 019B0036
019B004A CC int3
019B004B CC int3 在卸载如全局钩子或其他的DLL时,会出现目标进程崩溃。。。。
页:
[1]