VB变态应用之“移花接木”

来源:互联网 发布:myeclipse python 编辑:程序博客网 时间:2024/04/29 16:57

今天可是个好日子啊~~就在这个好日子送给我们广大的程序大朋友们和小朋友们一个节日礼物,同时我也希望这份代码能给带来一些思路和技术上的提升,但是更希望大家能用到正途上不要搞歪门邪道。此代码的功能比较强悍,所以用到好的地方自然能发光,但是用到黑暗的地方可能会辱没了这份代码,希望大家认真对待这份珍贵的代码,我是专门花了一天时间写的,而且专门用VB语言写的,其实用C的话更简单更快,就是想在节日送给我们广大的VB爱好者一个节日礼物。在这里祝大家“节日快乐”~哈哈~~

想了很久也不知道怎么为这份代码(文章)取个好听的名字想来想去好像“移花接木”最适合。为什么这么说呢?这份代码可以完成远程调用,可以在远程进程中执行任何STDCALL声明的API函数,这样做到了“远程调用本地化”当然还没达到这种级别的效果,但是确实还是值得我们继续在这份代码上发展和研究。我在测试程序中写了三个典型的实例。首先是一个在远程进程中弹出一个消息框的测试(这里要保证目标进程已经加载了USER33.DLL才行)。第二个实例是演示了利用远程进程创建新进程的功能(在这里我想说点废话,我在我博客也发表了好几种创建SYSTEM进程的代码,当然有参考别人的代码和思路,以前也有人说过用远程注入的方式实现,但是好像是需要DLL的好了现在这份代码不再需要DLL而且你可以创建指定用户的进程,比如你可以创建SYSTEM用户甚至是LOAL SYSTEM用户等)。第三个实例是演示了NT系列函数的调用也是演示了参数带返回值的API函数在我的程序中的调用方法和取返回值的方法。其实还有很多很多的功能有待大家去研究琢磨我只是提供了一个小小的“平台”,希望大家在这个“平台”给你带来更多的精细也希望能使大家更深入的了解VB内嵌汇编的方法和需要注意些什么。我在这份代码上做了详细的注释,如果你在使用还有不明白的地方或者发现存在了某些BUG请于我一起探讨,谢谢。好了废话就不多说了大家等得都是代码。

窗体代码部分Option ExplicitPrivate Type CLIENT_ID    UniqueProcess As Long    UniqueThread  As LongEnd TypePrivate Type OBJECT_ATTRIBUTES    Length As Long    RootDirectory As Long    ObjectName As Long    Attributes As Long    SecurityDescriptor As Long    SecurityQualityOfService As LongEnd TypePrivate 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 LongEnd TypePrivate Type PROCESS_INFORMATION    hProcess As Long    hThread As Long    dwProcessId As Long    dwThreadId As LongEnd TypePrivate Function IsArrayIsEmpty(pData() As OUT_DAT) As Boolean    Dim i As Integer    On Error GoTo ErrLine    i = UBound(pData)    IsArrayIsEmpty = False    Exit FunctionErrLine:    IsArrayIsEmpty = TrueEnd 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 IfEnd Sub'多个参数演示,演示在远程进程中创建进程的功能Private Sub cmdRun_Click()    Dim dwFunAddress As Long    Dim bytAgs() As Byte    Dim dwAgs As Long    Dim bytShellcode() As Byte    Dim pOutData() As OUT_DAT    Dim pStartInfo As STARTUPINFO    Dim pProcInfo As PROCESS_INFORMATION    If Val(txtPid.Text) = 0 Then        MsgBox "请输入正确的PID"        txtPid.SetFocus        Exit Sub    End If    If Dir(txtPath.Text, 1 Or 2 Or 4) = "" Then        MsgBox "请输入正确的文件路径"        txtPath.SetFocus        Exit Sub    End If    '获取函数地址    dwFunAddress = GetFunAddress("kernel32.dll", "CreateProcessA")    If dwFunAddress = 0 Then        MsgBox "获取函数地址失败!!"        Exit Sub    End If    pStartInfo.cb = LenB(pStartInfo)    '构造ShellCode    If GetShellCode(dwFunAddress, 10, bytShellcode) Then        '构造执行进程路径的Buffer        bytAgs = StrConv(txtPath.Text, vbFromUnicode)        '获取进程路径Buffer所在本进程空间的地址因为我们需要传给CallAsmFun        dwAgs = VarPtr(bytAgs(0))        '远程执行我们的函数        '其实下面函数功能相当于C里面的下面的代码,和我们直接调用API稍微有点区别,因为编译器会给我们优化        '比如 push 0我们为了处理方便都是4个字节对齐是用&H68 0x00000000是占用4个字节的,但是编译器可能就        '是&H6a 0x只占用2个字节        '__asm        '{        '   push pStartInfo        '   push pProcInfo        '   push 0        '   push 0        '   push 0        '   push 0        '   push 0        '   push 0        '   push dwAgs        '   push 0        '   call CreateProcessA        '}        '调用方法是:        '第一个参数是进程PID(可以是自己),第二个参数是本进程SHELLCODE的地址,第三个参数是API函数的参数个数        '从第4个参数起就是API函数的参数结构了输入顺序和我们平时调用API的参数顺序一样,但是需要增加两个额外的        '参数方便我在CallAsmFun中解析,这样API的一个参数就变成3个了,其中第一个是这个API传进去的参数是否是一        '个定值(不需要寻址的),如果是就传0,否则传1表示需要在目标进程空间申请一段内存把我们需要的传进去的        '数据(一般是字符串或者是结构)拷贝进去,第二个参数是需要传的值(这里需要注意一下,这个值跟前一个参数        '息息相关,如果前一个参数是1的话这个参数就是我们本进程中数据的地址),第三个参数是我们需要写入值的长度        '(以字节计算,这个值也跟第一个参数息息相关,如果第一个参数为0这个参数永远是4因为我们是4个字节对齐的        '如果第一个参数为1那么就是表明我们需要传进去的数据(字符串和结构)的长度)        If CallAsmFun(Val(txtPid.Text), pOutData, VarPtr(bytShellcode(0)), UBound(bytShellcode) + 1, 10, 0, 0, 4, 1, dwAgs, UBound(bytAgs) + 2, 0, 0, 4, 0, 0, 4, 0, 0, 4, 0, 0, 4, 0, 0, 4, 0, 0, 4, 1, VarPtr(pStartInfo), LenB(pStartInfo), 1, VarPtr(pProcInfo), LenB(pProcInfo)) = 0 Then            MsgBox "执行失败!!"        End If    End IfEnd Sub'显示消息框的演示Private Sub cmdShow_Click()    Dim dwFunAddress As Long    Dim bytAgs1() As Byte    Dim bytAgs2() As Byte    Dim dwAgs1 As Long, dwAgs2 As Long    Dim bytShellcode() As Byte    Dim pOutData() As OUT_DAT    If Val(txtPid.Text) = 0 Then        MsgBox "请输入正确的PID"        txtPid.SetFocus        Exit Sub    End If    dwFunAddress = GetFunAddress("user32.dll", "MessageBoxA")    If GetShellCode(dwFunAddress, 4, bytShellcode) Then        bytAgs1 = StrConv(txtNote.Text, vbFromUnicode)        dwAgs1 = VarPtr(bytAgs1(0))        bytAgs2 = StrConv(txtCaption.Text, vbFromUnicode)        dwAgs2 = VarPtr(bytAgs2(0))        If CallAsmFun(Val(txtPid.Text), pOutData, VarPtr(bytShellcode(0)), UBound(bytShellcode) + 1, 4, 0, 0, 4, 1, dwAgs1, UBound(bytAgs1) + 2, 1, dwAgs2, UBound(bytAgs2) + 2, 0, 0, 4) <= 0 Then            MsgBox "执行失败!!"        End If    End IfEnd SubPrivate Sub Form_Load()    '提升进程权限    If Not EnablePrivilege(SE_DEBUG_PRIVILEGE, True) Then        MsgBox "提升进程权限失败"        EnablePrivilege SE_DEBUG_PRIVILEGE, False    End IfEnd SubPrivate Sub Form_Unload(Cancel As Integer)    EnablePrivilege SE_DEBUG_PRIVILEGE, FalseEnd SubPrivate Sub txtPid1_GotFocus()    If txtPid1.Text = "请输入需要结束的进程PID" Then        txtPid1.Text = ""    End IfEnd SubPrivate Sub txtPid_GotFocus()    If txtPid.Text = "请输入目标进程PID" Then        txtPid.Text = ""    End IfEnd SubPrivate Sub txtNote_GotFocus()    If txtNote.Text = "请输入需要显示的信息" Then        txtNote.Text = ""    End IfEnd SubPrivate Sub txtCaption_GotFocus()    If txtCaption.Text = "请输入标题" Then        txtCaption.Text = ""    End IfEnd SubPrivate Sub txtPath_GotFocus()    If txtPath.Text = "请输入需要创建进程的路径" Then        txtPath.Text = ""    End IfEnd Sub
提权模块代码部分Option Explicit'提权相关常数Public Const SE_MIN_WELL_KNOWN_PRIVILEGE = 2Public Const SE_CREATE_TOKEN_PRIVILEGE = 2Public Const SE_ASSIGNPRIMARYTOKEN_PRIVILEGE = 3Public Const SE_LOCK_MEMORY_PRIVILEGE = 4Public Const SE_INCREASE_QUOTA_PRIVILEGE = 5' end_wdm'' Unsolicited Input is obsolete and unused.'Public Const SE_UNSOLICITED_INPUT_PRIVILEGE = 6' begin_wdmPublic Const SE_MACHINE_ACCOUNT_PRIVILEGE = 6Public Const SE_TCB_PRIVILEGE = 7Public Const SE_SECURITY_PRIVILEGE = 8Public Const SE_TAKE_OWNERSHIP_PRIVILEGE = 9Public Const SE_LOAD_DRIVER_PRIVILEGE = 10Public Const SE_SYSTEM_PROFILE_PRIVILEGE = 11Public Const SE_SYSTEMTIME_PRIVILEGE = 12Public Const SE_PROF_SINGLE_PROCESS_PRIVILEGE = 13Public Const SE_INC_BASE_PRIORITY_PRIVILEGE = 14Public Const SE_CREATE_PAGEFILE_PRIVILEGE = 15Public Const SE_CREATE_PERMANENT_PRIVILEGE = 16Public Const SE_BACKUP_PRIVILEGE = 17Public Const SE_RESTORE_PRIVILEGE = 18Public Const SE_SHUTDOWN_PRIVILEGE = 19Public Const SE_DEBUG_PRIVILEGE = 20Public Const SE_AUDIT_PRIVILEGE = 21Public Const SE_SYSTEM_ENVIRONMENT_PRIVILEGE = 22Public Const SE_CHANGE_NOTIFY_PRIVILEGE = 23Public Const SE_REMOTE_SHUTDOWN_PRIVILEGE = 24Public Const SE_UNDOCK_PRIVILEGE = 25Public Const SE_SYNC_AGENT_PRIVILEGE = 26Public Const SE_ENABLE_DELEGATION_PRIVILEGE = 27Public Const SE_MANAGE_VOLUME_PRIVILEGE = 28Public Const SE_IMPERSONATE_PRIVILEGE = 29Public Const SE_CREATE_GLOBAL_PRIVILEGE = 30Public Const SE_MAX_WELL_KNOWN_PRIVILEGE = SE_CREATE_GLOBAL_PRIVILEGEPublic Const STATUS_NO_TOKEN = &HC000007CPrivate Declare Function RtlAdjustPrivilege Lib "ntdll.dll" (ByVal Privilege As Long, ByVal Enable As Boolean, ByVal Client As Boolean, WasEnabled As Long) As LongPublic Function EnablePrivilege(ByVal Privilege As Long, Enable As Boolean) As Boolean    Dim ntStatus As Long    Dim WasEnabled As Long    ntStatus = RtlAdjustPrivilege(Privilege, Enable, True, WasEnabled)    If ntStatus = STATUS_NO_TOKEN Then        ntStatus = RtlAdjustPrivilege(Privilege, Enable, False, WasEnabled)    End If    If ntStatus = 0 Then        EnablePrivilege = True    Else        EnablePrivilege = False    End IfEnd Function
核心内嵌汇编部分(主要是完成API调用的汇编码)Option ExplicitPrivate Declare Function VirtualAllocEx Lib "kernel32" (ByVal hProcess As Long, lpAddress As Any, ByVal dwSize As Long, ByVal flAllocationType As Long, ByVal flProtect As Long) As LongPublic Declare Function VirtualFreeEx Lib "kernel32" (ByVal hProcess As Long, lpAddress As Any, ByVal dwSize As Long, ByVal dwFreeType As Long) As LongPrivate Declare Function CreateRemoteThread Lib "kernel32" (ByVal hProcess As Long, lpThreadAttributes As Any, ByVal dwStackSize As Long, lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadId As Long) As LongPrivate Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As LongPublic Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As LongPublic Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As LongPrivate Declare Function GetCurrentProcessId Lib "kernel32" () As LongPrivate Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As LongPrivate Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As LongPrivate Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" (ByVal lpPrevWndFunc As Long, ByVal hwnd As Long, ByVal Msg As Long, ByVal wParam As Long, ByVal lParam As Long) As LongPrivate Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As LongPrivate Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As LongPrivate Declare Function GetExitCodeThread Lib "kernel32" (ByVal hThread As Long, lpExitCode As Long) As LongPublic Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As LongPrivate Const INFINITE = &HFFFFFFFFPrivate Const MEM_COMMIT = &H1000Public Const MEM_RELEASE = &H8000Private Const PAGE_EXECUTE_READWRITE = &H40Private Const PAGE_READWRITE = &H4Private Const SYNCHRONIZE As Long = &H100000Private Const STANDARD_RIGHTS_REQUIRED As Long = &HF0000Public Const PROCESS_ALL_ACCESS As Long = (STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &HFFF)Public Type OUT_DAT    dwAddress As Long    dwDataSize As LongEnd Type'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''参数Params是可变参数其中第一个参数为你写的SHELLCODE Buffer的地址,第二个参数是这个'SHELLCODE Buffer的长度,第三个参数是API参数个数,从第四个参数起每3个参数形成API函'数中的一个参数,其中第一个参数表明是否需要申请内存,第二个参数是值(这里如果需要申'请内存的话这个值将是你需要)写入目标进程的Buffer所在你的进程空间的地址,第三个参数'是Buffer长度(如果不需要申请内存的这个值可以填0因为默认是以&H68来Push参数的都是4个'字节对齐,以后的API参数都是一样依次类推下去。直到API参数都完了后就是CALL的机器码E8'接着是CallValue这个需要计算(我的程序会自动计算),后面紧接着是return 10h,然后再'填个0好让CPU不要识别错了,因为可能你写到的地方最后一个字节不为0这样return值就会出错'造成栈不平,参数pOutData为后加上去的主要是用来返回有些API的参数需要返回值的情况下,用'发很简单传个数组进来即可然后返回的只是一个4个字节数据就保存在它的dwDataSize中,如果'大于4个字节那么dwAddress是目标进程的数据所在地址dwDataSize是数据的长度,如果我们需要'把这部分数据读出来只需要再次用ReadProcessMemory读取一次,如果有多个参数就遍历下数组''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''Public Function CallAsmFun(ByVal dwProcessId As Long, pOutData() As OUT_DAT, ParamArray Params()) As Long    'lplpRemoteAddress 是在目标进程为ShellCode申请的内存块地址,lpRemoteAddresses()是一些参数申请的内存快地址    '一般只有传结构或者是字符串的时候才需要    Dim lpRemoteAddress As Long, lpRemoteAddresses() As Long, intCount As Integer '在目标进程申请的内存计数    Dim hProcess As Long '进程句柄    Dim lngRet As Long '返回的结果    Dim hThread As Long, dwThreadId As Long '创建的选择线程句柄和TID    Dim i As Integer, j As Integer    Dim dwValue As Long, dwAddress As Long '值和地址    Dim intAgsCount As Integer '参数个数    Dim intOutCount As Integer    Dim blnIsFind As Boolean    '打开目标进程    hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, dwProcessId)    If hProcess Then        '在目标进程申请一块内存,长度是SHELLCODE的长度,好把SHELLCODE写进去        lpRemoteAddress = VirtualAllocEx(hProcess, ByVal 0&, CLng(Params(1)), MEM_COMMIT, PAGE_EXECUTE_READWRITE)        If lpRemoteAddress Then            dwAddress = CLng(Params(0)) '我们进程中SHELLCODE的地址            '把我们生成的SHELLCODE写入目标进程中            If WriteProcessMemory(hProcess, ByVal lpRemoteAddress, ByVal dwAddress, CLng(Params(i + 1)), ByVal 0) Then                '获取需要申请内存的参数计数                For i = Val(Params(2)) * 3 To 3 Step -3                    If Val(Params(i)) = 1 Then                        intCount = intCount + 1                    End If                Next                If intCount > 0 Then                    ReDim lpRemoteAddresses(intCount - 1) '申请保存参数申请内存的地址方便后面释放                End If                intCount = 0                intAgsCount = CLng(Params(2)) '我们传进来的第二个参数是API函数的参数个数                For i = intAgsCount * 3 To 3 Step -3 '从最后一个API参数开始取                    If Val(Params(i)) = 1 Then                        '如果是需要申请内存的参数(比如字符串或者结构等)我们就再申请一块内存                        lpRemoteAddresses(intCount) = VirtualAllocEx(hProcess, ByVal 0&, CLng(Params(i + 2)), MEM_COMMIT, PAGE_READWRITE)                        '把我们进程空间的才参数内存写入目标进程我们申请的内存块中                        If CLng(Params(i + 1)) <> 0 Then                            lngRet = WriteProcessMemory(hProcess, ByVal lpRemoteAddresses(intCount), ByVal CLng(Params(i + 1)), CLng(Params(i + 2)), ByVal 0)                            If lngRet = 0 Then GoTo RET                        Else                            ReDim Preserve pOutData(0 To intOutCount)                            pOutData(intOutCount).dwAddress = lpRemoteAddresses(intCount)                            pOutData(intOutCount).dwDataSize = CLng(Params(i + 2))                            intOutCount = intOutCount + 1                        End If                        '因为是__stdcall所以最前面的参数应该是在最后面相反最前面的在最后面                        dwAddress = lpRemoteAddress + 4 + 5 * (intAgsCount - (i / 3)) + 1                        '更改SHELLCODE里的push值,因为开始我们传进来的是我们的进程空间的地址,现在我们要替换成目标进程空间的地址                        lngRet = WriteProcessMemory(hProcess, ByVal dwAddress, lpRemoteAddresses(intCount), 4, ByVal 0)                        If lngRet = 0 Then GoTo RET                        intCount = intCount + 1                    Else                        '如果参数不需要申请内存就直接写入值即可                        dwAddress = lpRemoteAddress + 4 + 5 * (intAgsCount - (i / 3)) + 1                        dwValue = Params(i + 1)                        lngRet = WriteProcessMemory(hProcess, ByVal dwAddress, dwValue, 4, ByVal 0)                        If lngRet = 0 Then GoTo RET                    End If                Next            End If            '计算E8 XXXXXXXX中的XXXXXXXX所在目标进程空间中的地址            dwAddress = lpRemoteAddress + intAgsCount * 5 + 4 + 1            '获取函数的真正地址            CopyMemory dwValue, ByVal CLng(Params(0)), 4            '计算 XXXXXXXX的地址            dwValue = dwValue - (lpRemoteAddress + intAgsCount * 5 + 4) - 5            '更新E8后的XXXXXXXX值这样才能正确执行函数            lngRet = WriteProcessMemory(hProcess, ByVal dwAddress, dwValue, 4, ByVal 0)            If lngRet = 0 Then GoTo RET            '创建远程线程执行我们的SHELLCODE,这里我们可以换成Debug的Api比如SetThreadContext和QueueAPC之类的函数也行            hThread = CreateRemoteThread(hProcess, ByVal 0, 0, ByVal lpRemoteAddress + 4, ByVal 0, 0, dwThreadId)            If hThread Then                '等待线程执行结束                WaitForSingleObject hThread, INFINITE                For i = 0 To intOutCount - 1                    If pOutData(i).dwDataSize = 4 Then                        ReadProcessMemory hProcess, ByVal pOutData(i).dwAddress, pOutData(i).dwDataSize, 4, ByVal 0&                    End If                Next                '获取返回值                GetExitCodeThread hThread, lngRet            End If        End If    End IfRET:    '清理我们申请的内存和关闭相关句柄    If hProcess Then        For i = 0 To intCount - 1            If intOutCount = 0 Then                VirtualFreeEx hProcess, ByVal lpRemoteAddresses(i), 0, MEM_RELEASE            Else                For j = 0 To intOutCount - 1                    If lpRemoteAddresses(i) = pOutData(j).dwAddress Then                        blnIsFind = True                        Exit For                    End If                Next                If Not blnIsFind Then VirtualFreeEx hProcess, ByVal lpRemoteAddresses(i), 0, MEM_RELEASE            End If        Next        If lpRemoteAddress Then VirtualFreeEx hProcess, ByVal lpRemoteAddress, 0, MEM_RELEASE    End If    If hProcess Then CloseHandle hProcess    If hThread Then CloseHandle hThread    CallAsmFun = lngRetEnd Function'获取API函数的地址Public Function GetFunAddress(ByVal strLibName As String, ByVal strFunName As String) As Long    Dim hMod As Long, dwFunAddress As Long    hMod = LoadLibrary(strLibName)    If hMod Then        dwFunAddress = GetProcAddress(hMod, strFunName)    End If    FreeLibrary hMod    GetFunAddress = dwFunAddressEnd Function'Public Function SetAgsValue(ByVal dwRemoteShellCodeAddress As Long, ByVal intAgsIndex As Integer, ByVal dwValue As Long) As Long''End Function'构造SHELLCODE,以&H68 4个字节对齐方式构造Public Function GetShellCode(ByVal dwFunAddress As Long, ByVal intAgsCount As Integer, bytShellcode() As Byte) As Boolean    Dim i As IntegerOn Error GoTo ErrLine    ReDim bytShellcode(intAgsCount * 5 + 4 + 8 - 1)    CopyMemory bytShellcode(0), dwFunAddress, 4    For i = 4 To intAgsCount * 5 Step 5        bytShellcode(i) = &H68        CopyMemory bytShellcode(i + 1), 0, 4    Next    bytShellcode(i) = &HE8    CopyMemory bytShellcode(i + 1), 0, 4    bytShellcode(i + 5) = &HC2    bytShellcode(i + 6) = &H10    bytShellcode(i + 7) = 0    GetShellCode = True    Exit FunctionErrLine:    GetShellCode = FalseEnd Function
原创粉丝点击