找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
查看: 4955|回复: 1

[交流] VB变态应用之“移花接木”

[复制链接]

1

主题

7

回帖

0

精华

初来乍到

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

想了很久也不知道怎么为这份代码(文章)取个好听的名字想来想去好像“移花接木”最适合。为什么这么说呢?这份代码可以完成远程调用,可以在远程进程中执行任何STDCALL声明的API函数,这样做到了“远程调用本地化”当然还没达到这种级别的效果,但是确实还是值得我们继续在这份代码上发展和研究。我在测试程序中写了三个典型的实例。首先是一个在远程进程中弹出一个消息框的测试(这里要保证目标进程已经加载了USER33.DLL才行)。第二个实例是演示了利用远程进程创建新进程的功能(在这里我想说点废话,我在我博客也发表了好几种创建SYSTEM进程的代码,当然有参考别人的代码和思路,以前也有人说过用远程注入的方式实现,但是好像是需要DLL的好了现在这份代码不再需要DLL而且你可以创建指定用户的进程,比如你可以创建SYSTEM用户甚至是LOAL SYSTEM用户等)。第三个实例是演示了NT系列函数的调用也是演示了参数带返回值的API函数在我的程序中的调用方法和取返回值的方法。其实还有很多很多的功能有待大家去研究琢磨我只是提供了一个小小的“平台”,希望大家在这个“平台”给你带来更多的精细也希望能使大家更深入的了解VB内嵌汇编的方法和需要注意些什么。我在这份代码上做了详细的注释,如果你在使用还有不明白的地方或者发现存在了某些BUG请于我一起探讨,谢谢。好了废话就不多说了大家等得都是代码。
  1. 窗体代码部分  
  2.   
  3. Option Explicit  
  4.   
  5. Private Type CLIENT_ID  
  6.     UniqueProcess As Long  
  7.     UniqueThread  As Long  
  8. End Type  
  9.   
  10. Private Type OBJECT_ATTRIBUTES  
  11.     Length As Long  
  12.     RootDirectory As Long  
  13.     ObjectName As Long  
  14.     Attributes As Long  
  15.     SecurityDescriptor As Long  
  16.     SecurityQualityOfService As Long  
  17. End Type  
  18.   
  19. Private Type STARTUPINFO  
  20.     cb As Long  
  21.     lpReserved As String  
  22.     lpDesktop As String  
  23.     lpTitle As String  
  24.     dwX As Long  
  25.     dwY As Long  
  26.     dwXSize As Long  
  27.     dwYSize As Long  
  28.     dwXCountChars As Long  
  29.     dwYCountChars As Long  
  30.     dwFillAttribute As Long  
  31.     dwFlags As Long  
  32.     wShowWindow As Integer  
  33.     cbReserved2 As Integer  
  34.     lpReserved2 As Long  
  35.     hStdInput As Long  
  36.     hStdOutput As Long  
  37.     hStdError As Long  
  38. End Type  
  39.   
  40. Private Type PROCESS_INFORMATION  
  41.     hProcess As Long  
  42.     hThread As Long  
  43.     dwProcessId As Long  
  44.     dwThreadId As Long  
  45. End Type  
  46.   
  47. Private Function IsArrayIsEmpty(pData() As OUT_DAT) As Boolean  
  48.     Dim i As Integer  
  49.     On Error GoTo ErrLine  
  50.     i = UBound(pData)  
  51.     IsArrayIsEmpty = False  
  52.     Exit Function  
  53. ErrLine:  
  54.     IsArrayIsEmpty = True  
  55. End Function  
  56.   
  57. '当API的参数有返回值的演示  
  58. Private Sub cmdKill_Click()  
  59.     Dim dwFunAddress As Long  
  60.     Dim objAttr As OBJECT_ATTRIBUTES  
  61.     Dim dwAccessMask As Long  
  62.     Dim objId As CLIENT_ID  
  63.     Dim bytShellcode() As Byte  
  64.     Dim pOutData() As OUT_DAT  
  65.     Dim hProcess As Integer  
  66.     Dim i As Integer  
  67.     If Val(txtPid.Text) = 0 Then  
  68.         MsgBox "请输入正确的PID"  
  69.         txtPid.SetFocus  
  70.         Exit Sub  
  71.     End If  
  72.     If Val(txtPid1.Text) = 0 Then  
  73.         MsgBox "请输入正确的PID"  
  74.         txtPid1.SetFocus  
  75.         Exit Sub  
  76.     End If  
  77.     '获取函数地址  
  78.     dwFunAddress = GetFunAddress("ntdll.dll", "NtOpenProcess")  
  79.     If dwFunAddress = 0 Then  
  80.         MsgBox "获取函数地址失败!!"  
  81.         Exit Sub  
  82.     End If  
  83.     dwAccessMask = PROCESS_ALL_ACCESS  
  84.     objId.UniqueProcess = Val(txtPid1.Text)  
  85.     objAttr.Length = LenB(objAttr)  
  86.     If GetShellCode(dwFunAddress, 4, bytShellcode) Then  
  87.         '如果API参数有返回值的我们可以从pOutData数组结构中读取如果只有一个  
  88.         '需要返回的并且返回的只是4个字节就可以直接从pOutData(0).dwDataSize  
  89.         '中读取,如果大于4个字节在这里我们需要再次从目标进程中读取数据出来  
  90.         'ReadProcessMemory hProcess, ByVal pOutData(i).dwAddress, bytBuffer(), pOutData(0).dwDataSize, ByVal 0&  
  91.         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  
  92.             MsgBox "执行失败!!"  
  93.         End If  
  94.         If Not IsArrayIsEmpty(pOutData) Then  
  95.             hProcess = pOutData(0).dwDataSize  
  96.             If hProcess Then  
  97.                 Erase bytShellcode  
  98.                 Erase pOutData  
  99.                 dwFunAddress = GetFunAddress("ntdll.dll", "NtTerminateProcess")  
  100.                 If dwFunAddress > 0 And GetShellCode(dwFunAddress, 2, bytShellcode) Then  
  101.                     If CallAsmFun(Val(txtPid.Text), pOutData, VarPtr(bytShellcode(0)), UBound(bytShellcode) + 1, 2, 0, hProcess, 4, 0, 0, 4) <> 0 Then  
  102.                         MsgBox "执行失败!!"  
  103.                     End If  
  104.                 End If  
  105.             End If  
  106.             On Error Resume Next  
  107.             hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, Val(txtPid.Text))  
  108.             If hProcess Then  
  109.                 VirtualFreeEx hProcess, ByVal pOutData(0).dwAddress, 0, MEM_RELEASE  
  110.             End If  
  111.             CloseHandle hProcess  
  112.         End If  
  113.     End If  
  114. End Sub  
  115.   
  116. '多个参数演示,演示在远程进程中创建进程的功能  
  117. Private Sub cmdRun_Click()  
  118.     Dim dwFunAddress As Long  
  119.     Dim bytAgs() As Byte  
  120.     Dim dwAgs As Long  
  121.     Dim bytShellcode() As Byte  
  122.     Dim pOutData() As OUT_DAT  
  123.     Dim pStartInfo As STARTUPINFO  
  124.     Dim pProcInfo As PROCESS_INFORMATION  
  125.     If Val(txtPid.Text) = 0 Then  
  126.         MsgBox "请输入正确的PID"  
  127.         txtPid.SetFocus  
  128.         Exit Sub  
  129.     End If  
  130.     If Dir(txtPath.Text, 1 Or 2 Or 4) = "" Then  
  131.         MsgBox "请输入正确的文件路径"  
  132.         txtPath.SetFocus  
  133.         Exit Sub  
  134.     End If  
  135.     '获取函数地址  
  136.     dwFunAddress = GetFunAddress("kernel32.dll", "CreateProcessA")  
  137.     If dwFunAddress = 0 Then  
  138.         MsgBox "获取函数地址失败!!"  
  139.         Exit Sub  
  140.     End If  
  141.     pStartInfo.cb = LenB(pStartInfo)  
  142.     '构造ShellCode  
  143.     If GetShellCode(dwFunAddress, 10, bytShellcode) Then  
  144.         '构造执行进程路径的Buffer  
  145.         bytAgs = StrConv(txtPath.Text, vbFromUnicode)  
  146.         '获取进程路径Buffer所在本进程空间的地址因为我们需要传给CallAsmFun  
  147.         dwAgs = VarPtr(bytAgs(0))  
  148.         '远程执行我们的函数  
  149.         '其实下面函数功能相当于C里面的下面的代码,和我们直接调用API稍微有点区别,因为编译器会给我们优化  
  150.         '比如 push 0我们为了处理方便都是4个字节对齐是用&H68 0x00000000是占用4个字节的,但是编译器可能就  
  151.         '是&H6a 0x只占用2个字节  
  152.         '__asm  
  153.         '{  
  154.         '   push pStartInfo  
  155.         '   push pProcInfo  
  156.         '   push 0  
  157.         '   push 0  
  158.         '   push 0  
  159.         '   push 0  
  160.         '   push 0  
  161.         '   push 0  
  162.         '   push dwAgs  
  163.         '   push 0  
  164.         '   call CreateProcessA  
  165.         '}  
  166.         '调用方法是:  
  167.         '第一个参数是进程PID(可以是自己),第二个参数是本进程SHELLCODE的地址,第三个参数是API函数的参数个数  
  168.         '从第4个参数起就是API函数的参数结构了输入顺序和我们平时调用API的参数顺序一样,但是需要增加两个额外的  
  169.         '参数方便我在CallAsmFun中解析,这样API的一个参数就变成3个了,其中第一个是这个API传进去的参数是否是一  
  170.         '个定值(不需要寻址的),如果是就传0,否则传1表示需要在目标进程空间申请一段内存把我们需要的传进去的  
  171.         '数据(一般是字符串或者是结构)拷贝进去,第二个参数是需要传的值(这里需要注意一下,这个值跟前一个参数  
  172.         '息息相关,如果前一个参数是1的话这个参数就是我们本进程中数据的地址),第三个参数是我们需要写入值的长度  
  173.         '(以字节计算,这个值也跟第一个参数息息相关,如果第一个参数为0这个参数永远是4因为我们是4个字节对齐的  
  174.         '如果第一个参数为1那么就是表明我们需要传进去的数据(字符串和结构)的长度)  
  175.         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  
  176.             MsgBox "执行失败!!"  
  177.         End If  
  178.     End If  
  179. End Sub  
  180.   
  181. '显示消息框的演示  
  182. Private Sub cmdShow_Click()  
  183.     Dim dwFunAddress As Long  
  184.     Dim bytAgs1() As Byte  
  185.     Dim bytAgs2() As Byte  
  186.     Dim dwAgs1 As Long, dwAgs2 As Long  
  187.     Dim bytShellcode() As Byte  
  188.     Dim pOutData() As OUT_DAT  
  189.     If Val(txtPid.Text) = 0 Then  
  190.         MsgBox "请输入正确的PID"  
  191.         txtPid.SetFocus  
  192.         Exit Sub  
  193.     End If  
  194.     dwFunAddress = GetFunAddress("user32.dll", "MessageBoxA")  
  195.     If GetShellCode(dwFunAddress, 4, bytShellcode) Then  
  196.         bytAgs1 = StrConv(txtNote.Text, vbFromUnicode)  
  197.         dwAgs1 = VarPtr(bytAgs1(0))  
  198.         bytAgs2 = StrConv(txtCaption.Text, vbFromUnicode)  
  199.         dwAgs2 = VarPtr(bytAgs2(0))  
  200.         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  
  201.             MsgBox "执行失败!!"  
  202.         End If  
  203.     End If  
  204. End Sub  
  205.   
  206.   
  207. Private Sub Form_Load()  
  208.     '提升进程权限  
  209.     If Not EnablePrivilege(SE_DEBUG_PRIVILEGE, True) Then  
  210.         MsgBox "提升进程权限失败"  
  211.         EnablePrivilege SE_DEBUG_PRIVILEGE, False  
  212.     End If  
  213. End Sub  
  214.   
  215. Private Sub Form_Unload(Cancel As Integer)  
  216.     EnablePrivilege SE_DEBUG_PRIVILEGE, False  
  217. End Sub  
  218.   
  219. Private Sub txtPid1_GotFocus()  
  220.     If txtPid1.Text = "请输入需要结束的进程PID" Then  
  221.         txtPid1.Text = ""  
  222.     End If  
  223. End Sub  
  224.   
  225. Private Sub txtPid_GotFocus()  
  226.     If txtPid.Text = "请输入目标进程PID" Then  
  227.         txtPid.Text = ""  
  228.     End If  
  229. End Sub  
  230.   
  231. Private Sub txtNote_GotFocus()  
  232.     If txtNote.Text = "请输入需要显示的信息" Then  
  233.         txtNote.Text = ""  
  234.     End If  
  235. End Sub  
  236.   
  237. Private Sub txtCaption_GotFocus()  
  238.     If txtCaption.Text = "请输入标题" Then  
  239.         txtCaption.Text = ""  
  240.     End If  
  241. End Sub  
  242.   
  243. Private Sub txtPath_GotFocus()  
  244.     If txtPath.Text = "请输入需要创建进程的路径" Then  
  245.         txtPath.Text = ""  
  246.     End If  
  247. End Sub  
  248. <pre class="vb.net" name="code">提权模块代码部分  
  249.   
  250. Option Explicit  
  251. '提权相关常数  
  252. Public Const SE_MIN_WELL_KNOWN_PRIVILEGE = 2  
  253. Public Const SE_CREATE_TOKEN_PRIVILEGE = 2  
  254. Public Const SE_ASSIGNPRIMARYTOKEN_PRIVILEGE = 3  
  255. Public Const SE_LOCK_MEMORY_PRIVILEGE = 4  
  256. Public Const SE_INCREASE_QUOTA_PRIVILEGE = 5  
  257.   
  258. ' end_wdm  
  259. '  
  260. ' Unsolicited Input is obsolete and unused.  
  261. '  
  262.   
  263. Public Const SE_UNSOLICITED_INPUT_PRIVILEGE = 6  
  264.   
  265. ' begin_wdm  
  266. Public Const SE_MACHINE_ACCOUNT_PRIVILEGE = 6  
  267. Public Const SE_TCB_PRIVILEGE = 7  
  268. Public Const SE_SECURITY_PRIVILEGE = 8  
  269. Public Const SE_TAKE_OWNERSHIP_PRIVILEGE = 9  
  270. Public Const SE_LOAD_DRIVER_PRIVILEGE = 10  
  271. Public Const SE_SYSTEM_PROFILE_PRIVILEGE = 11  
  272. Public Const SE_SYSTEMTIME_PRIVILEGE = 12  
  273. Public Const SE_PROF_SINGLE_PROCESS_PRIVILEGE = 13  
  274. Public Const SE_INC_BASE_PRIORITY_PRIVILEGE = 14  
  275. Public Const SE_CREATE_PAGEFILE_PRIVILEGE = 15  
  276. Public Const SE_CREATE_PERMANENT_PRIVILEGE = 16  
  277. Public Const SE_BACKUP_PRIVILEGE = 17  
  278. Public Const SE_RESTORE_PRIVILEGE = 18  
  279. Public Const SE_SHUTDOWN_PRIVILEGE = 19  
  280. Public Const SE_DEBUG_PRIVILEGE = 20  
  281. Public Const SE_AUDIT_PRIVILEGE = 21  
  282. Public Const SE_SYSTEM_ENVIRONMENT_PRIVILEGE = 22  
  283. Public Const SE_CHANGE_NOTIFY_PRIVILEGE = 23  
  284. Public Const SE_REMOTE_SHUTDOWN_PRIVILEGE = 24  
  285. Public Const SE_UNDOCK_PRIVILEGE = 25  
  286. Public Const SE_SYNC_AGENT_PRIVILEGE = 26  
  287. Public Const SE_ENABLE_DELEGATION_PRIVILEGE = 27  
  288. Public Const SE_MANAGE_VOLUME_PRIVILEGE = 28  
  289. Public Const SE_IMPERSONATE_PRIVILEGE = 29  
  290. Public Const SE_CREATE_GLOBAL_PRIVILEGE = 30  
  291. Public Const SE_MAX_WELL_KNOWN_PRIVILEGE = SE_CREATE_GLOBAL_PRIVILEGE  
  292. Public Const STATUS_NO_TOKEN = &HC000007C  
  293. Private Declare Function RtlAdjustPrivilege Lib "ntdll.dll" (ByVal Privilege As Long, ByVal Enable As Boolean, ByVal Client As Boolean, WasEnabled As Long) As Long  
  294.   
  295. Public Function EnablePrivilege(ByVal Privilege As Long, Enable As Boolean) As Boolean  
  296.     Dim ntStatus As Long  
  297.     Dim WasEnabled As Long  
  298.     ntStatus = RtlAdjustPrivilege(Privilege, Enable, True, WasEnabled)  
  299.     If ntStatus = STATUS_NO_TOKEN Then  
  300.         ntStatus = RtlAdjustPrivilege(Privilege, Enable, False, WasEnabled)  
  301.     End If  
  302.     If ntStatus = 0 Then  
  303.         EnablePrivilege = True  
  304.     Else  
  305.         EnablePrivilege = False  
  306.     End If  
  307. End Function  
  308. </pre>  
  309. <pre class="vb.net" name="code">核心内嵌汇编部分(主要是完成API调用的汇编码)  
  310.   
  311. Option Explicit  
  312. Private 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 Long  
  313. Public Declare Function VirtualFreeEx Lib "kernel32" (ByVal hProcess As Long, lpAddress As Any, ByVal dwSize As Long, ByVal dwFreeType As Long) As Long  
  314. Private 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 Long  
  315. Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)  
  316. Private Declare Function WriteProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long  
  317. Public Declare Function OpenProcess Lib "kernel32" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long  
  318. Public Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long  
  319. Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long  
  320. Private Declare Function LoadLibrary Lib "kernel32" Alias "LoadLibraryA" (ByVal lpLibFileName As String) As Long  
  321. Private Declare Function GetProcAddress Lib "kernel32" (ByVal hModule As Long, ByVal lpProcName As String) As Long  
  322. Private 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 Long  
  323. Private Declare Function FreeLibrary Lib "kernel32" (ByVal hLibModule As Long) As Long  
  324. Private Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long  
  325. Private Declare Function GetExitCodeThread Lib "kernel32" (ByVal hThread As Long, lpExitCode As Long) As Long  
  326. Public Declare Function ReadProcessMemory Lib "kernel32" (ByVal hProcess As Long, lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long  
  327.   
  328. Private Const INFINITE = &HFFFFFFFF  
  329. Private Const MEM_COMMIT = &H1000  
  330. Public Const MEM_RELEASE = &H8000  
  331. Private Const PAGE_EXECUTE_READWRITE = &H40  
  332. Private Const PAGE_READWRITE = &H4  
  333. Private Const SYNCHRONIZE As Long = &H100000  
  334. Private Const STANDARD_RIGHTS_REQUIRED As Long = &HF0000  
  335. Public Const PROCESS_ALL_ACCESS As Long = (STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &HFFF)  
  336.   
  337. Public Type OUT_DAT  
  338.     dwAddress As Long  
  339.     dwDataSize As Long  
  340. End Type  
  341.   
  342. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''  
  343. '参数Params是可变参数其中第一个参数为你写的SHELLCODE Buffer的地址,第二个参数是这个  
  344. 'SHELLCODE Buffer的长度,第三个参数是API参数个数,从第四个参数起每3个参数形成API函  
  345. '数中的一个参数,其中第一个参数表明是否需要申请内存,第二个参数是值(这里如果需要申  
  346. '请内存的话这个值将是你需要)写入目标进程的Buffer所在你的进程空间的地址,第三个参数  
  347. '是Buffer长度(如果不需要申请内存的这个值可以填0因为默认是以&H68来Push参数的都是4个  
  348. '字节对齐,以后的API参数都是一样依次类推下去。直到API参数都完了后就是CALL的机器码E8  
  349. '接着是CallValue这个需要计算(我的程序会自动计算),后面紧接着是return 10h,然后再  
  350. '填个0好让CPU不要识别错了,因为可能你写到的地方最后一个字节不为0这样return值就会出错  
  351. '造成栈不平,参数pOutData为后加上去的主要是用来返回有些API的参数需要返回值的情况下,用  
  352. '发很简单传个数组进来即可然后返回的只是一个4个字节数据就保存在它的dwDataSize中,如果  
  353. '大于4个字节那么dwAddress是目标进程的数据所在地址dwDataSize是数据的长度,如果我们需要  
  354. '把这部分数据读出来只需要再次用ReadProcessMemory读取一次,如果有多个参数就遍历下数组  
  355. ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''  
  356. Public Function CallAsmFun(ByVal dwProcessId As Long, pOutData() As OUT_DAT, ParamArray Params()) As Long  
  357.     'lplpRemoteAddress 是在目标进程为ShellCode申请的内存块地址,lpRemoteAddresses()是一些参数申请的内存快地址  
  358.     '一般只有传结构或者是字符串的时候才需要  
  359.     Dim lpRemoteAddress As Long, lpRemoteAddresses() As Long, intCount As Integer '在目标进程申请的内存计数  
  360.     Dim hProcess As Long '进程句柄  
  361.     Dim lngRet As Long '返回的结果  
  362.     Dim hThread As Long, dwThreadId As Long '创建的选择线程句柄和TID  
  363.     Dim i As Integer, j As Integer  
  364.     Dim dwValue As Long, dwAddress As Long '值和地址  
  365.     Dim intAgsCount As Integer '参数个数  
  366.     Dim intOutCount As Integer  
  367.     Dim blnIsFind As Boolean  
  368.     '打开目标进程  
  369.     hProcess = OpenProcess(PROCESS_ALL_ACCESS, 0, dwProcessId)  
  370.     If hProcess Then  
  371.         '在目标进程申请一块内存,长度是SHELLCODE的长度,好把SHELLCODE写进去  
  372.         lpRemoteAddress = VirtualAllocEx(hProcess, ByVal 0&, CLng(Params(1)), MEM_COMMIT, PAGE_EXECUTE_READWRITE)  
  373.         If lpRemoteAddress Then  
  374.             dwAddress = CLng(Params(0)) '我们进程中SHELLCODE的地址  
  375.             '把我们生成的SHELLCODE写入目标进程中  
  376.             If WriteProcessMemory(hProcess, ByVal lpRemoteAddress, ByVal dwAddress, CLng(Params(i + 1)), ByVal 0) Then  
  377.                 '获取需要申请内存的参数计数  
  378.                 For i = Val(Params(2)) * 3 To 3 Step -3  
  379.                     If Val(Params(i)) = 1 Then  
  380.                         intCount = intCount + 1  
  381.                     End If  
  382.                 Next  
  383.                 If intCount > 0 Then  
  384.                     ReDim lpRemoteAddresses(intCount - 1) '申请保存参数申请内存的地址方便后面释放  
  385.                 End If  
  386.                 intCount = 0  
  387.                 intAgsCount = CLng(Params(2)) '我们传进来的第二个参数是API函数的参数个数  
  388.                 For i = intAgsCount * 3 To 3 Step -3 '从最后一个API参数开始取  
  389.                     If Val(Params(i)) = 1 Then  
  390.                         '如果是需要申请内存的参数(比如字符串或者结构等)我们就再申请一块内存  
  391.                         lpRemoteAddresses(intCount) = VirtualAllocEx(hProcess, ByVal 0&, CLng(Params(i + 2)), MEM_COMMIT, PAGE_READWRITE)  
  392.                         '把我们进程空间的才参数内存写入目标进程我们申请的内存块中  
  393.                         If CLng(Params(i + 1)) <> 0 Then  
  394.                             lngRet = WriteProcessMemory(hProcess, ByVal lpRemoteAddresses(intCount), ByVal CLng(Params(i + 1)), CLng(Params(i + 2)), ByVal 0)  
  395.                             If lngRet = 0 Then GoTo RET  
  396.                         Else  
  397.                             ReDim Preserve pOutData(0 To intOutCount)  
  398.                             pOutData(intOutCount).dwAddress = lpRemoteAddresses(intCount)  
  399.                             pOutData(intOutCount).dwDataSize = CLng(Params(i + 2))  
  400.                             intOutCount = intOutCount + 1  
  401.                         End If  
  402.                         '因为是__stdcall所以最前面的参数应该是在最后面相反最前面的在最后面  
  403.                         dwAddress = lpRemoteAddress + 4 + 5 * (intAgsCount - (i / 3)) + 1  
  404.                         '更改SHELLCODE里的push值,因为开始我们传进来的是我们的进程空间的地址,现在我们要替换成目标进程空间的地址  
  405.                         lngRet = WriteProcessMemory(hProcess, ByVal dwAddress, lpRemoteAddresses(intCount), 4, ByVal 0)  
  406.                         If lngRet = 0 Then GoTo RET  
  407.                         intCount = intCount + 1  
  408.                     Else  
  409.                         '如果参数不需要申请内存就直接写入值即可  
  410.                         dwAddress = lpRemoteAddress + 4 + 5 * (intAgsCount - (i / 3)) + 1  
  411.                         dwValue = Params(i + 1)  
  412.                         lngRet = WriteProcessMemory(hProcess, ByVal dwAddress, dwValue, 4, ByVal 0)  
  413.                         If lngRet = 0 Then GoTo RET  
  414.                     End If  
  415.                 Next  
  416.             End If  
  417.             '计算E8 XXXXXXXX中的XXXXXXXX所在目标进程空间中的地址  
  418.             dwAddress = lpRemoteAddress + intAgsCount * 5 + 4 + 1  
  419.             '获取函数的真正地址  
  420.             CopyMemory dwValue, ByVal CLng(Params(0)), 4  
  421.             '计算 XXXXXXXX的地址  
  422.             dwValue = dwValue - (lpRemoteAddress + intAgsCount * 5 + 4) - 5  
  423.             '更新E8后的XXXXXXXX值这样才能正确执行函数  
  424.             lngRet = WriteProcessMemory(hProcess, ByVal dwAddress, dwValue, 4, ByVal 0)  
  425.             If lngRet = 0 Then GoTo RET  
  426.             '创建远程线程执行我们的SHELLCODE,这里我们可以换成Debug的Api比如SetThreadContext和QueueAPC之类的函数也行  
  427.             hThread = CreateRemoteThread(hProcess, ByVal 0, 0, ByVal lpRemoteAddress + 4, ByVal 0, 0, dwThreadId)  
  428.             If hThread Then  
  429.                 '等待线程执行结束  
  430.                 WaitForSingleObject hThread, INFINITE  
  431.                 For i = 0 To intOutCount - 1  
  432.                     If pOutData(i).dwDataSize = 4 Then  
  433.                         ReadProcessMemory hProcess, ByVal pOutData(i).dwAddress, pOutData(i).dwDataSize, 4, ByVal 0&  
  434.                     End If  
  435.                 Next  
  436.                 '获取返回值  
  437.                 GetExitCodeThread hThread, lngRet  
  438.             End If  
  439.         End If  
  440.     End If  
  441. RET:  
  442.     '清理我们申请的内存和关闭相关句柄  
  443.     If hProcess Then  
  444.         For i = 0 To intCount - 1  
  445.             If intOutCount = 0 Then  
  446.                 VirtualFreeEx hProcess, ByVal lpRemoteAddresses(i), 0, MEM_RELEASE  
  447.             Else  
  448.                 For j = 0 To intOutCount - 1  
  449.                     If lpRemoteAddresses(i) = pOutData(j).dwAddress Then  
  450.                         blnIsFind = True  
  451.                         Exit For  
  452.                     End If  
  453.                 Next  
  454.                 If Not blnIsFind Then VirtualFreeEx hProcess, ByVal lpRemoteAddresses(i), 0, MEM_RELEASE  
  455.             End If  
  456.         Next  
  457.         If lpRemoteAddress Then VirtualFreeEx hProcess, ByVal lpRemoteAddress, 0, MEM_RELEASE  
  458.     End If  
  459.     If hProcess Then CloseHandle hProcess  
  460.     If hThread Then CloseHandle hThread  
  461.     CallAsmFun = lngRet  
  462. End Function  
  463.   
  464. '获取API函数的地址  
  465. Public Function GetFunAddress(ByVal strLibName As String, ByVal strFunName As String) As Long  
  466.     Dim hMod As Long, dwFunAddress As Long  
  467.     hMod = LoadLibrary(strLibName)  
  468.     If hMod Then  
  469.         dwFunAddress = GetProcAddress(hMod, strFunName)  
  470.     End If  
  471.     FreeLibrary hMod  
  472.     GetFunAddress = dwFunAddress  
  473. End Function  
  474.   
  475. 'Public Function SetAgsValue(ByVal dwRemoteShellCodeAddress As Long, ByVal intAgsIndex As Integer, ByVal dwValue As Long) As Long  
  476. '  
  477. 'End Function  
  478.   
  479. '构造SHELLCODE,以&H68 4个字节对齐方式构造  
  480. Public Function GetShellCode(ByVal dwFunAddress As Long, ByVal intAgsCount As Integer, bytShellcode() As Byte) As Boolean  
  481.     Dim i As Integer  
  482. On Error GoTo ErrLine  
  483.     ReDim bytShellcode(intAgsCount * 5 + 4 + 8 - 1)  
  484.     CopyMemory bytShellcode(0), dwFunAddress, 4  
  485.     For i = 4 To intAgsCount * 5 Step 5  
  486.         bytShellcode(i) = &H68  
  487.         CopyMemory bytShellcode(i + 1), 0, 4  
  488.     Next  
  489.     bytShellcode(i) = &HE8  
  490.     CopyMemory bytShellcode(i + 1), 0, 4  
  491.     bytShellcode(i + 5) = &HC2  
  492.     bytShellcode(i + 6) = &H10  
  493.     bytShellcode(i + 7) = 0  
  494.     GetShellCode = True  
  495.     Exit Function  
  496. ErrLine:  
  497.     GetShellCode = False  
  498. End Function  
  499. </pre>  
复制代码

275

主题

3020

回帖

1

精华

管理员

嗷嗷叫的老马

积分
17067

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

QQ
发表于 2014-8-28 15:04:19 | 显示全部楼层
这不是陈辉的东西么,转载为什么不注明出处呢.
我就是嗷嗷叫的老马了......

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

本版积分规则

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