找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
查看: 6568|回复: 2

[求助] 这段代码看不懂

[复制链接]

76

主题

375

回帖

0

精华

铜牌会员

积分
231
发表于 2009-11-26 00:16:18 | 显示全部楼层 |阅读模式
获取进程命令行的代码
  1. Private Type CLIENT_ID
  2.     UniqueProcess As Long
  3.     UniqueThread  As Long
  4. End Type

  5. Private Const SYNCHRONIZE As Long = &H100000

  6. Private Const STANDARD_RIGHTS_REQUIRED As Long = &HF0000

  7. Private Declare Function NtOpenProcess Lib "NTDLL.DLL" (ByRef ProcessHandle As Long, _
  8.                                 ByVal AccessMask As Long, _
  9.                                 ByRef ObjectAttributes As OBJECT_ATTRIBUTES, _
  10.                                 ByRef ClientID As CLIENT_ID) As Long

  11. Private Type OBJECT_ATTRIBUTES
  12.     Length As Long
  13.     RootDirectory As Long
  14.     ObjectName As Long
  15.     Attributes As Long
  16.     SecurityDescriptor As Long
  17.     SecurityQualityOfService As Long
  18. End Type

  19. Private Const PROCESS_VM_READ = &H10
  20. Private Const PROCESS_CREATE_THREAD = &H2
  21. Private Const PROCESS_VM_OPERATION = &H8
  22. Private Const PROCESS_QUERY_INFORMATION As Long = (&H400)

  23. Private Const PROCESS_ALL_ACCESS As Long = (STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &HFFF)

  24. Private Const PROCESS_DUP_HANDLE As Long = (&H40)
  25. Private Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
  26. Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long
  27. Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long
  28. Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long
  29. Private Declare Function NtClose Lib "NTDLL.DLL" (ByVal ObjectHandle As Long) As Long
  30. Private Declare Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, _
  31.                                       ByRef Source As Any, _
  32.                                       ByVal Length As Long)
  33. Private Function GetProcessCommandLine(ByVal dwProcessId As Long) As String
  34.     Dim objCid As CLIENT_ID
  35.     Dim objOa As OBJECT_ATTRIBUTES
  36.     Dim ntStatus As Long, hKernel As Long, strName As String
  37.     Dim hProcess As Long, dwAddr As Long, dwRead As Long
  38.     objOa.Length = Len(objOa)
  39.     objCid.UniqueProcess = dwProcessId
  40.     ntStatus = NtOpenProcess(hProcess, &H10, objOa, objCid)
  41.     If hProcess = 0 Then
  42.         GetProcessCommandLine = ""
  43.         Exit Function
  44.     End If
  45.     hKernel = LoadLibrary("kernel32")
  46.     dwAddr = GetProcAddress(hKernel, "GetCommandLineA")
  47.     CopyMemory dwAddr, ByVal dwAddr + 1, 4
  48.     If ReadProcessMemory(hProcess, ByVal dwAddr, dwAddr, 4, dwRead) Then
  49.         strName = String(260, Chr(0))
  50.         If ReadProcessMemory(hProcess, ByVal dwAddr, ByVal strName, 260, dwRead) Then
  51.             strName = Left(strName, InStr(strName, Chr(0)) - 1)
  52.             NtClose hProcess
  53.             GetProcessCommandLine = strName
  54.             Exit Function
  55.         End If
  56.     End If
  57.     NtClose hProcess
  58. End Function


  59. 本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/chenhui530/archive/2007/12/10/1928409.aspx
复制代码
dwAddr = GetProcAddress(hKernel, "GetCommandLineA")下面的代码就不懂了。
CopyMemory dwAddr, ByVal dwAddr + 1, 4  这句不懂,为什么要dwAddr + 1,为什么要复制4个字节
ReadProcessMemory为什么要调用2次,这2次分别是什么作用。

3

主题

50

回帖

0

精华

银牌会员

积分
444
发表于 2009-11-26 01:00:08 | 显示全部楼层
代码能正确运行吗?能得到正确结果吗?如果能的话,你跟踪一下 strName  的值不就明白了?

275

主题

3017

回帖

1

精华

管理员

嗷嗷叫的老马

积分
17064

论坛牛人贡献奖关注奖最佳版主进步奖人气王疯狂作品奖精英奖赞助论坛勋章乐于助人勋章

QQ
发表于 2009-11-26 02:05:54 | 显示全部楼层
dwAddr = GetProcAddress(hKernel, "GetCommandLineA")下面的代码就不懂了。
CopyMemory dwAddr, ByVal dwAddr + 1, 4  这句不懂,为什么要dwAddr + 1,为什么要复制4个字节
ReadProcessMemory为什么要调用2次,这2次分别是什么作用。

everyone 发表于 2009-11-26 00:16


GetProcAddress返回的是一个指针.这个指针存在于IAT表里,里面放的是另一个指针,指向什么地址不知道....需要了解PE格式才行.

所以把地址加1,再复制4字节,是为了得到这个指针.(CopyMemory dwAddr, ByVal dwAddr + 1, 4)

从代码来看,上面那个指针指向的地址里,又是一个指针........

所以,第一次ReadProcessMemory是为了读到这个指针.....

而这个指针指向的地址,正好就是命令行字符串的存放开始地址,因此,在得到了这个指针后,马上进行第二次ReadProcessMemory.

这次ReadProcessMemory,就是复制字符串了,复制回来就马上返回了.

有点晕......

总结一下.

GetProcAddress返回指针A------->指针A+1处,存放的是指针B--------->指针B指向地址C------->地址C存放的是命令行字符串

哎,晕.....要知道为什么要这样做,应该只有研究PE格式了吧.....陈辉那鸟人对PE格式非常熟.
我就是嗷嗷叫的老马了......

您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表