今天可是个好日子啊~~就在这个好日子送给我们广大的程序大朋友们和小朋友们一个节日礼物,同时我也希望这份代码能给带来一些思路和技术上的提升,但是更希望大家能用到正途上不要搞歪门邪道。此代码的功能比较强悍,所以用到好的地方自然能发光,但是用到黑暗的地方可能会辱没了这份代码,希望大家认真对待这份珍贵的代码,我是专门花了一天时间写的,而且专门用VB语言写的,其实用C的话更简单更快,就是想在节日送给我们广大的VB爱好者一个节日礼物。在这里祝大家“节日快乐”~哈哈~~
想了很久也不知道怎么为这份代码(文章)取个好听的名字想来想去好像“移花接木”最适合。为什么这么说呢?这份代码可以完成远程调用,可以在远程进程中执行任何STDCALL声明的API函数,这样做到了“远程调用本地化”当然还没达到这种级别的效果,但是确实还是值得我们继续在这份代码上发展和研究。我在测试程序中写了三个典型的实例。首先是一个在远程进程中弹出一个消息框的测试(这里要保证目标进程已经加载了USER33.DLL才行)。第二个实例是演示了利用远程进程创建新进程的功能(在这里我想说点废话,我在我博客也发表了好几种创建SYSTEM进程的代码,当然有参考别人的代码和思路,以前也有人说过用远程注入的方式实现,但是好像是需要DLL的好了现在这份代码不再需要DLL而且你可以创建指定用户的进程,比如你可以创建SYSTEM用户甚至是LOAL SYSTEM用户等)。第三个实例是演示了NT系列函数的调用也是演示了参数带返回值的API函数在我的程序中的调用方法和取返回值的方法。其实还有很多很多的功能有待大家去研究琢磨我只是提供了一个小小的“平台”,希望大家在这个“平台”给你带来更多的精细也希望能使大家更深入的了解VB内嵌汇编的方法和需要注意些什么。我在这份代码上做了详细的注释,如果你在使用还有不明白的地方或者发现存在了某些BUG请于我一起探讨,谢谢。好了废话就不多说了大家等得都是代码。
窗体代码部分
Option Explicit
Private Type CLIENT_ID
UniqueProcess As Long
UniqueThread As Long
End Type
Private Type OBJECT_ATTRIBUTES
Length As Long
RootDirectory As Long
ObjectName As Long
Attributes As Long
SecurityDescriptor As Long
SecurityQualityOfService As Long
End Type
Private Type STARTUPINFO
cb As Long
lpReserved As String
lpDesktop As String
lpTitle As String
dwX As Long
dwY As Long
dwXSize As Long
dwYSize As Long
dwXCountChars As Long
dwYCountChars As Long
dwFillAttribute As Long
dwFlags As Long
wShowWindow As Integer
cbReserved2 As Integer
lpReserved2 As Long
hStdInput As Long
hStdOutput As Long
hStdError As Long
End Type
Private Type PROCESS_INFORMATION
hProcess As Long
hThread As Long
dwProcessId As Long
dwThreadId As Long
End Type
Private Function IsArrayIsEmpty(pData() As OUT_DAT) As Boolean
Dim i As Integer
On Error GoTo ErrLine
i = UBound(pData)
IsArrayIsEmpty = False
Exit Function
ErrLine:
IsArrayIsEmpty = True
End Function
'当API的参数有返回值的演示
Private Sub cmdKill_Click()
Dim dwFunAddress As Long
Dim objAttr As OBJECT_ATTRIBUTES
Dim dwAccessMask As Long
Dim objId As CLIENT_ID
Dim bytShellcode() As Byte
Dim pOutData() As OUT_DAT
Dim hProcess As Integer
Dim i As Integer
If Val(txtPid.Text) = 0 Then
MsgBox "请输入正确的PID"
txtPid.SetFocus
Exit Sub
End If
If Val(txtPid1.Text) = 0 Then
MsgBox "请输入正确的PID"
txtPid1.SetFocus
Exit Sub
End If
'获取函数地址
dwFunAddress = GetFunAddress("ntdll.dll", "NtOpenProcess")
If dwFunAddress = 0 Then
MsgBox "获取函数地址失败!!"
Exit Sub
End If
dwAccessMask = PROCESS_ALL_ACCESS
objId.UniqueProcess = Val(txtPid1.Text)
objAttr.Length = LenB(objAttr)
If GetShellCode(dwFunAddress, 4, bytShellcode) Then
'如果API参数有返回值的我们可以从pOutData数组结构中读取如果只有一个
'需要返回的并且返回的只是4个字节就可以直接从pOutData(0).dwDataSize
'中读取,如果大于4个字节在这里我们需要再次从目标进程中读取数据出来
'ReadProcessMemory hProcess, ByVal pOutData(i).dwAddress, bytBuffer(), pOutData(0).dwDataSize, ByVal 0&
If CallAsmFun(Val(txtPid.Text), pOutData, VarPtr(bytShellcode(0)), UBound(bytShellcode) + 1, 4, 1, 0, 4, 0, dwAccessMask, 4, 1, VarPtr(objAttr), LenB(objAttr), 1, VarPtr(objId), LenB(objId)) <> 0 Then
MsgBox "执行失败!!"
End If
If Not IsArrayIsEmpty(pOutData) Then
hProcess = pOutData(0).dwDataSize
If hProcess Then
Erase bytShellcode
Erase pOutData
dwFunAddress = GetFunAddress("ntdll.dll", "NtTerminateProcess")
If dwFunAddress > 0 And GetShellCode(dwFunAddress, 2, bytShellcode) Then
If CallAsmFun(Val(txtPid.Text), pOutData, VarPtr(bytShellcode(0)), UBound(bytShellcode) + 1, 2, 0, hProcess, 4, 0, 0, 4) <> 0 Then
MsgBox "执行失败!!"
End If
End If
End If
On Error Resume Next
hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, Val(txtPid.Text))
If hProcess Then
VirtualFreeEx hProcess, ByVal pOutData(0).dwAddress, 0, MEM_RELEASE
End If
CloseHandle hProcess
End If
End If
End Sub
'多个参数演示,演示在远