import os
import sys
import ctypes
import subprocess
class DEBUG_EVENT(ctypes.Structure):
_fields_ = [
("dwDebugEventCode", ctypes.c_ulong),
("dwProcessId", ctypes.c_ulong),
("dwThreadId", ctypes.c_ulong),
("u", ctypes.c_ulong * 1024)
]
def debug_main():
# 调试进程主函数
filename = sys.executable # 获取自身文件名
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
process_info = subprocess.STARTUPINFO()
process_info.dwFlags |= subprocess.CREATE_NEW_CONSOLE
while True:
try:
process = subprocess.Popen([filename], startupinfo=startupinfo, creationflags=subprocess.CREATE_NEW_CONSOLE)
except Exception as e:
return
debug_event = DEBUG_EVENT()
continue_debugging = ctypes.c_ulong()
while_do_flag = True
# 等待调试事件
ctypes.windll.kernel32.WaitForDebugEvent(ctypes.byref(debug_event), ctypes.c_ulong(-1))
# 处理调试事件
if debug_event.dwDebugEventCode == ctypes.c_ulong(1): # CREATE_PROCESS_DEBUG_EVENT
continue_debugging.value = 65536 # DBG_CONTINUE
elif debug_event.dwDebugEventCode == ctypes.c_ulong(5): # EXIT_PROCESS_DEBUG_EVENT
while_do_flag = False
elif debug_event.dwDebugEventCode == ctypes.c_ulong(3): # EXCEPTION_DEBUG_EVENT
if debug_event.u.Exception.ExceptionRecord.ExceptionCode == ctypes.c_ulong(80000003): # EXCEPTION_BREAKPOINT
continue_debugging.value = 65536 # DBG_CONTINUE
# 继续调试事件
ctypes.windll.kernel32.ContinueDebugEvent(debug_event.dwProcessId, debug_event.dwThreadId, continue_debugging)
if not while_do_flag:
break
ctypes.windll.kernel32.CloseHandle(process_info.hProcess)
ctypes.windll.kernel32.CloseHandle(process_info.hThread)
def main():
# 主函数
if not ctypes.windll.kernel32.IsDebuggerPresent(): # 区分调试进程与被调试进程
debug_main()
else:
while True:
# 被调试进程的主要逻辑
ctypes.windll.user32.MessageBoxW(None, "微信公众号蓝胖子之家--自我保护进程", "TraceMe", 0)
# 当被调试进程结束时,重新启动被调试进程
os.execl(sys.executable, sys.executable, *sys.argv)
if __name__ == "__main__":
main()
首先,这段代码用于实现一个调试进程的主函数。调试进程是指一个程序能够监视和控制另一个程序的执行过程,常用于调试和分析程序。
代码的第一部分是导入模块和库,包括os、sys、ctypes和subprocess。这些模块和库提供了操作系统相关的功能和对动态链接库中函数的调用。
接下来是定义调试事件结构体DEBUG_EVENT。这个结构体用于保存调试事件的相关信息,包括调试事件代码、进程ID、线程ID和其他信息。
然后是定义调试进程的主函数debug_main()。这个函数使用一个无限循环来创建子进程并等待调试事件的发生。
在循环开始时,获取当前脚本的文件名作为子进程的可执行文件。
然后设置子进程的启动信息,包括窗口显示标志和进程信息。
在一个无限循环中,尝试创建子进程。如果创建失败,说明无法继续调试,函数返回。
在循环内部,定义了调试事件和调试继续标志。调试事件使用ctypes.windll.kernel32.WaitForDebugEvent函数等待调试事件的发生。
根据不同的调试事件代码进行相应的处理:
在处理完调试事件后,使用ctypes.windll.kernel32.ContinueDebugEvent函数继续调试事件。
如果退出循环,则关闭进程和线程的句柄,结束调试。
接下来是定义主函数main()。这个函数是程序的入口函数。
首先通过ctypes.windll.kernel32.IsDebuggerPresent()函数判断当前进程是否处于调试状态。
如果不是调试进程,则调用debug_main()函数进入调试进程。
如果是调试进程,则进入一个无限循环:
最后,在__name__ == “__main__”的判断下,执行主函数main()。
运行效果:
具体来说,它创建了两个进程:一个是被调试进程,另一个是调试进程。被调试进程是要被保护的主要进程,而调试进程则用于监视和保护被调试进程的执行。
被调试进程的主要逻辑在main()函数中,它会在一个无限循环中执行。当被调试进程处于被调试状态时,会弹出一个消息框显示提示信息,并在被调试进程结束后使用os.execl()函数重新启动被调试进程。
调试进程的主要逻辑在debug_main()函数中,它也在一个无限循环中执行。调试进程会创建子进程,并等待调试事件的发生。根据不同的调试事件进行相应的处理,如创建进程事件、退出进程事件和异常事件。调试进程通过监视和控制被调试进程的执行,实现了对被调试进程的保护。
通过这种双进程的机制,被调试进程可以在被调试状态下正常运行,而调试进程可以监控和保护被调试进程的执行,提高了被调试进程的安全性和稳定性。
限时特惠:本站每日持续更新海量各大内部网赚创业教程,会员可以下载全站资源点击查看详情
站长微信:11082411