|
远程进程就是要被你注入代码的进程,也可以理解为你注入代码的宿主,远程注入可以简单可以理解为你把一段代码植入到别的进程中去然后运行它,实现这个过程用到的主要工具就是:CreateRemoteThread,注入过程一般分为下面几步:打开远程进程--分配空间--植入代码--运行代码。CreateRemoteThread的原型如下:
函数原型
HANDLE CreateRemoteThread(
HANDLE hProcess, // handle to process
LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
SIZE_T dwStackSize, // initial stack size
LPTHREAD_START_ROUTINE lpStartAddress, // thread function
LPVOID lpParameter, // thread argument
DWORD dwCreationFlags, // creation option
LPDWORD lpThreadId // thread identifier
);
参数说明:
hProcess
[输入] 进程句柄
lpThreadAttributes
[输入] 线程安全描述字,指向SECURITY_ATTRIBUTES结构的指针
dwStackSize
[输入] 线程栈大小,以字节表示
lpStartAddress
[输入] 一个LPTHREAD_START_ROUTINE类型的指针,指向在远程进程中执行的函数地址
lpParameter
[输入] 传入参数
dwCreationFlags
[输入] 创建线程的其它标志
lpThreadId
[输出] 线程身份标志,如果为NULL,则不返回
返回值
成功返回新线程句柄,失败返回NULL,并且可调用GetLastError获得错误值。
VFP下调用格式如下:
DECLARE Integer CreateRemoteThread IN kernel32 ;
Integer hProcess , ;
Integer lpThreadAttributes , ;
Integer dwStackSize , ;
Integer lpStartAddress , ;
Integer lpParameter , ;
Integer dwCreationFlags , ;
Integer @lpThreadId
现在我们实现一个在其它进程注入MessageBoxA这个API的简单示例,在写代码前先简单介绍下这个函数,MessageBoxA的原型如下:
int MessageBoxA(
HWND hWnd, // handle to owner window
LPCTSTR lpText, // text in message box
LPCTSTR lpCaption, // message box title
UINT uType // message box style
);
那么ASM就可以简单写为:
push uType
push lpCaption
push lpText
push hWnd
move eax ,AdrMessageBox
call eax
ret 4
好了,我们现在就可以写代码了:
**API声明
DECLARE Long CloseHandle IN kernel32;
Long hObject
DECLARE Long OpenProcess IN kernel32;
Long dwDesiredAccessas,;
Long bInheritHandle,;
Long dwProcId
DECLARE Long CreateRemoteThread IN kernel32 ;
Long hProcess , ;
Long lpThreadAttributes , ;
Long dwStackSize , ;
Long lpStartAddress , ;
Long lpParameter , ;
Long dwCreationFlags , ;
Long @lpThreadId
DECLARE Long VirtualAllocEx IN WIN32API ;
Long hProcess, Long @ lpAddress, Long dwSize, ;
Long flAllocationType, Long flProtect
DECLARE Long VirtualFreeEx IN WIN32API ;
Long hProcess, Long lpAddress, Long dwSize, Long dwFreeType
DECLARE Long WriteProcessMemory IN WIN32API ;
Long hProcess, Long lpBaseAddress, string @lpBuffer, ;
Long nSize, Long @ lpNumberOfBytesWritten
DECLARE Long LoadLibrary IN WIN32API String
DECLARE Long FreeLibrary IN WIN32API Long
DECLARE Long GetProcAddress IN WIN32API Long,String
DECLARE Long WaitForSingleObject IN WIN32API Long hHandle,Long dwMilliseconds
PROCESS_ALL_ACCESS=0x1F0FFF
MEM_COMMIT=0x1000
PAGE_EXECUTE_READWRITE=0x40
hModule = LoadLibrary("user32")
AdrMessageBox=GetProcAddress(hModule,"MessageBoxA")
FreeLibrary(hModule)
sCaption="行者示例--VFP远程注入"+0h00 &&提示框的标题
sLabel='这是在VFP下实现的一个简单的远程线程注入示例'+0h00 &&提示框的内容
sStr=sCaption+sLabel+REPLICATE(0h00,24) &&这里多写入24字节是为机器码sCode先保留下位置
AcPid=3860 &&这里是要你注入目标进程的PID,打开任务管理器找个进程测试下,由于进程权限的问题并不是所有都能成功。
hProcess = OpenProcess(PROCESS_ALL_ACCESS,0,AcPid)&&以查询 读和写的权限打开
sAddr=VirtualAllocEx(hProcess,0,LEN(sStr),MEM_COMMIT,PAGE_EXECUTE_READWRITE) &&申请变量存放空间
Ret=0
sCode=""
sCode = sCode+sCaption+sLabel &&申请的空间前先放入提示框要显示的两个变量
sCode = sCode+0h6A+0h00 && push 0 这里开始写入代码了,就是上面的ASM部分
sCode = sCode+0h68+BINTOC(sAddr,"4rs") && push the string sCaption
sCode = sCode+0h68 + BINTOC(sAddr+LEN(sCaption),"4rs")&& push the string sLabel
sCode = sCode+0h6A+0h00 && push the hWnd
sCode = sCode+0hB8+BINTOC(AdrMessageBox,"4rs") && move eax, AdrMessageBox
sCode = sCode+0hFF+0hD0 && call eax
sCode = sCode+0hC2+0h0400 && ret 4
WriteProcessMemory(hProcess,sAddr,@sCode,LEN(sCode),@Ret) &&把要注入的内容写入到目标进程申请的空间里
thread=0
IF ret=LEN(sCode) &&确定写入成功
CreateRemoteThread(hProcess,0,0,sAddr+LEN(sCaption)+LEN(sLabel),0,0,@thread) &&运行远程线程
ENDI
CloseHandle(hProcess)
运行后效果图如下:
我这里最后并没有释放申请的进程空间,在实际应用的时候需要注意的几点:
用WaitForSingleObject等待线程结束,用GetExitCodeThread获取返回值,最后关闭句柄并释放空间。
|
|