当前位置:编程学习 > 网站相关 >>

编程思路突破语言限制——易语言远线程注入实现程序自删除

文/图 cby1990
对于程序的自删除,现在网上比较流行的做法一般是创建一个BAT文件来实现,这种方法虽然可行,但毕竟是基于脚本的技术。本文要讨论的是另外一种做法,即在其他进程创建代码以实现删除自身程序。
 
API说明
我的思路大致是这样的:打开一个目标进程->在目标进程内分配合适大小的内存->构建我们的机器代码->将代码写到目标进程->调用远程线程执行这段代码。涉及到的相关系统API如下。
.DLL命令 OpenProcess,整数型,"Kernel32.dll","OpenProcess",打开进程
         .参数 dwDesiredAccess,整数型,需要的进程权限
         .参数 bInheritHandle,逻辑型,是否可以继承
.参数 dwProcessId,整数型,目标进程的PID
.DLL命令 VirtualAllocEx,整数型,"Kernel32.dll","VirtualAllocEx",分配空间
    .参数 hProcess,整数型,进程句柄
    .参数 lpAddress,整数型,地址指针
    .参数 dwSize,整数型,大小
    .参数 flAllocationType,整数型
    .参数 flProtect,整数型,页面保护属性
.DLL命令WriteProcessMemory,整数型,"Kernel32.dll","WriteProcessMemory",写内存
    .参数 hProcess,整数型,进程句柄
    .参数 lpBaseAddress,整数型,地址
    .参数 lpBuffer,字节集,要写入的内容,这里用字节集
    .参数 nSize,整数型,大小
    .参数 lpNumberOfBytesWritten,整数型,传址,实际写入的大小
.DLL命令 CreateRemoteThread,整数型,"Kernel32.dll","CreateRemoteThread",公开
    .参数 hProcess,整数型,进程句柄
    .参数 lpThreadAttributes,整数型,NULL,线程安全属性
    .参数 dwStackSize,整数型,NULL,堆栈大小
    .参数 lpStartAddress,整数型,Pointer,过程地址
    .参数 lpParameter,整数型,NULL,参数
    .参数 dwCreationFlags,整数型,NULL,建立标志
    .参数 lpThreadId,整数型,传址,Thread identifier,线程表示符
 
小提示:易语言里面是没有NULL这个数据类型的,这一点和C++等其他高级语言不一样,
比如 LPSECURITY_ATTRIBUTES lpThreadAttributes本来的数据类型应该是
SECURITY_ATTRIBUTES的结构,但是我们这里并不需要使用,在C++里面我们可以直接传送NULL,
这个NULL就是空的意思。那么实质上就是0指针,也就是整数型的0。
另外SIZE_T* lpNumberOfBytesWritten,也就是写内存的最后一个参数实际上是一个输出参数,
也就是说函数返回以后,这个参数将返回一些信息,而不是只是调用参数。
 
代码分析
 
GetWindowThreadProcessId (GetShellWindow (), PID)
‘获取explorer的进程ID
.如果真 (PID = 0)
信息框 (“无法删除自身!!!”, 0, )
返回 ()
进程句柄 = OpenProcess (#_PROCESS_ALL_ACCESS, 假, PID)
‘打开目标进程
BaseAddress =VirtualAllocEx (进程句柄, 0, 1000, #_MEM_COMMIT, #_PAGE_EXECUTE_READWRITE)
‘在目标进程空间分配内存
.如果真 (BaseAddress = 0)
信息框 (“无法删除自身!!! Error on BaseAddress ”, 0, )
返回 ()
.如果真结束
写入数据 =构建汇编码 (BaseAddress)
WriteProcessMemory (进程句柄, BaseAddress, 写入数据, 取字节集长度 (写入数据), WrittenBytes)
.如果真 (取字节集长度 (写入数据) ≠ WrittenBytes)
信息框 (“警告:长度与原先的不符!程序可能出现异常”, 0, )
返回 ()
.如果真结束
.如果真 (CreateRemoteThread (进程句柄, 0, 0, BaseAddress, GetCurrentProcessId (), 0, ThreadId) < 0)
信息框 (“无法删除自身!!!”, 0, )
返回 ()
.如果真结束
结束 ()
 
这段代码涉及到了#_PROCESS_ALL_ACCESS和#_PAGE_EXECUTE_READWRITE,易语言本身是没有提供的,那么是怎么得来的呢?我们打开这个函数的MSDN,在其Requirements部分可以看到DLL这一栏的说明:Requires Kernel32.dll,表示这个函数在动态链接库Kernel32.dll中。我们用相关的编辑器Microsoft Platform SDKIncludeWInnt.h搜索对应的常量(这些头文件可以从Microsoft的网站上下载SDK得来,或者安装C++),我搜索到的结果为“#define PAGE_EXECUTE_READWRITE 0x40”,用计算器将0x40换算成十进制64写到我们的易语言IDE中即可,如图1所示。
图1
下面介绍我们的重点了:构建汇编码子程序!也是本文的核心所在。(需要读者有一定的汇编基础,如果没有,看看我的注释也应该知道大体在干什么了。)
删除文件的API是DeleteFile,在目标进程内执行结束后我们要释放内存,并结束线程。因此要用到VirtualFree和ExitThread。
 
DeleteFile = GetAddress (“Kernel32.dll”, “DeleteFileA”)
VirtualFree = GetAddress (“Kernel32.dll”, “VirtualFree”)
ExitThread = GetAddress (“Kernel32.dll”, “ExitThread”)
‘GetAddress函数是获取指定函数在指定动态链接库内的地址,这里有一个技巧,Microsoft出于效率考虑,在所有的应用程序中,核心动态链接库(如Kernel32.dll、User32.dll等)的地址在每一个进程中是一样的,所以我们可以在本进程内获取对应的函数地址。
 
汇编码 = 汇编码 + { 191 } + 到字节集 (DeleteFile)
‘mov edi,kernel32.DeleteFileA
汇编码 = 汇编码 + { 104, 51, 51, 51, 51 }
‘push XXXXXXXX暂时用51来表示,下面来替换成对应的代码
汇编码 = 汇编码 + { 255, 215, 131, 248, 0, 116, 244}
‘call edi、cmp eax,0、je short V2200611.7120CB27,调用目标API(考虑到系统延迟)并循环直到删除成功。
 
汇编码=汇编码+{191}+到字节集(VirtualFree)+{184}+到字节集(ExitThread)
‘mov edi,kernel32.VirtualFree为了避免计算相对地址(Call address的机器码要计算相对地址),采取通过寄存器来Call API的间接办法来实现。
‘mov eax,kernel32.ExitThread,把这两个API的地址写到指定的寄存器
汇编码=汇编码+{104,0, 64,0,0,104,0,16,0,0}
‘push 4000参数四:页面属性常量,push 1000参数三:分配的大小
汇编码=汇编码+{104,34,34,34,34}
‘要 Free的地址,这里后面计算后替换写入
汇编码=汇编码+{80,255,231}
‘push eax;jmp edi
汇编码 = 汇编码 + { 195 }
‘retn 这一句应该是多余的,因为永远也无法执行到,线程已经结束了。
 
注意上面的代码,我们为什么要“jmp edi”而不是“call edi”呢?为什么我们压的是四个参数,而不是三个呢?首先,edi在标准的WINAPI调用后的值不会变,我们不需要重新赋值。Call的本质是压入返回地址并jmp到目标地址,这里我们是模拟call!注意eax的地址,是ExitThread!也就是说当执行完 VirtualFree后,不返回到原来的地址中继续执行(也无法执行,因为已经Free掉了这段内存,如果返回将造成内存访问错误,从而引发异常!),而是返回到了kernel32.ExitThread,直接退出这个线程!
大家注意看了,下面的代码是计算字符串偏移,是嵌入机器码成功的关键之处。
 
偏移=取字节集长度(汇编码)
文件地址=取空白文本(255)
GetModuleFileName(0,文件地址,255)
‘获取当前的执行文件全名
汇编码=汇编码+到字节集(文件地址)+{0}
‘把我们的文件名的字符串(注意不是指针)全部写到机器码后面。
补充:综合编程 , 其他综合 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,