├── dbg_flash_vul_2.0 ├── dbg_flash_vul.v11.suo ├── dbg_flash_vul │ ├── dbg_flash_vul.aps │ ├── dbg_flash_vul.vcxproj.user │ ├── dbg_flash_vul.def │ ├── stdafx.cpp │ ├── targetver.h │ ├── resource.h │ ├── dllmain.cpp │ ├── stdafx.h │ ├── dbg_flash_vul.vcxproj.filters │ ├── ReadMe.txt │ ├── dbg_flash_vul.vcxproj │ └── dbg_flash_vul.cpp └── dbg_flash_vul.sln ├── Discover Flash Player Zero-day attacks in the wild from big data.pptx └── README.md /dbg_flash_vul_2.0/dbg_flash_vul.v11.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blaquee/DbgFlashVul/HEAD/dbg_flash_vul_2.0/dbg_flash_vul.v11.suo -------------------------------------------------------------------------------- /dbg_flash_vul_2.0/dbg_flash_vul/dbg_flash_vul.aps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blaquee/DbgFlashVul/HEAD/dbg_flash_vul_2.0/dbg_flash_vul/dbg_flash_vul.aps -------------------------------------------------------------------------------- /Discover Flash Player Zero-day attacks in the wild from big data.pptx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blaquee/DbgFlashVul/HEAD/Discover Flash Player Zero-day attacks in the wild from big data.pptx -------------------------------------------------------------------------------- /dbg_flash_vul_2.0/dbg_flash_vul/dbg_flash_vul.vcxproj.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FED 2 | DbgFlashVul 3 | 4 | A extension of Windbg, help to debug flash samples 5 | 6 | You need to insall VS2012 redist first. 7 | 8 | It is a tool for researchers not for users. May has some bugs in it. 9 | 10 | Detail information is in the PPT file. 11 | 12 | Wrote by @heisecode 13 | -------------------------------------------------------------------------------- /dbg_flash_vul_2.0/dbg_flash_vul/dbg_flash_vul.def: -------------------------------------------------------------------------------- 1 | LIBRARY "DbgFlashVul.DLL" 2 | 3 | EXPORTS 4 | WinDbgExtensionDllInit 5 | ExtensionApiVersion 6 | SetBaseAddress 7 | SetBpForJitCode 8 | EnableTraceJit 9 | EnableTraceJitEx 10 | SetIdBpForJitCode 11 | HandleHookId 12 | HandleHookName 13 | help -------------------------------------------------------------------------------- /dbg_flash_vul_2.0/dbg_flash_vul/stdafx.cpp: -------------------------------------------------------------------------------- 1 | // stdafx.cpp : source file that includes just the standard includes 2 | // my_windbg_ext.pch will be the pre-compiled header 3 | // stdafx.obj will contain the pre-compiled type information 4 | 5 | #include "stdafx.h" 6 | 7 | // TODO: reference any additional headers you need in STDAFX.H 8 | // and not in this file 9 | -------------------------------------------------------------------------------- /dbg_flash_vul_2.0/dbg_flash_vul/targetver.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Including SDKDDKVer.h defines the highest available Windows platform. 4 | 5 | // If you wish to build your application for a previous Windows platform, include WinSDKVer.h and 6 | // set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. 7 | 8 | #include 9 | -------------------------------------------------------------------------------- /dbg_flash_vul_2.0/dbg_flash_vul/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by my_windbg_ext.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /dbg_flash_vul_2.0/dbg_flash_vul/dllmain.cpp: -------------------------------------------------------------------------------- 1 | // dllmain.cpp : Defines the entry point for the DLL application. 2 | #include "stdafx.h" 3 | 4 | BOOL APIENTRY DllMain( HMODULE hModule, 5 | DWORD ul_reason_for_call, 6 | LPVOID lpReserved 7 | ) 8 | { 9 | switch (ul_reason_for_call) 10 | { 11 | case DLL_PROCESS_ATTACH: 12 | case DLL_THREAD_ATTACH: 13 | case DLL_THREAD_DETACH: 14 | case DLL_PROCESS_DETACH: 15 | break; 16 | } 17 | return TRUE; 18 | } 19 | 20 | -------------------------------------------------------------------------------- /dbg_flash_vul_2.0/dbg_flash_vul/stdafx.h: -------------------------------------------------------------------------------- 1 | // stdafx.h : include file for standard system include files, 2 | // or project specific include files that are used frequently, but 3 | // are changed infrequently 4 | // 5 | 6 | #pragma once 7 | 8 | #include "targetver.h" 9 | 10 | #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers 11 | // Windows Header Files: 12 | #include 13 | 14 | 15 | #define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit 16 | 17 | #include 18 | #include 19 | 20 | // TODO: reference additional headers your program requires here 21 | -------------------------------------------------------------------------------- /dbg_flash_vul_2.0/dbg_flash_vul.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dbg_flash_vul", "dbg_flash_vul\dbg_flash_vul.vcxproj", "{87965BB5-0C72-48C8-9848-763919DD025D}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Release|Win32 = Release|Win32 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {87965BB5-0C72-48C8-9848-763919DD025D}.Debug|Win32.ActiveCfg = Debug|Win32 13 | {87965BB5-0C72-48C8-9848-763919DD025D}.Debug|Win32.Build.0 = Debug|Win32 14 | {87965BB5-0C72-48C8-9848-763919DD025D}.Release|Win32.ActiveCfg = Release|Win32 15 | {87965BB5-0C72-48C8-9848-763919DD025D}.Release|Win32.Build.0 = Release|Win32 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /dbg_flash_vul_2.0/dbg_flash_vul/dbg_flash_vul.vcxproj.filters: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Header Files 23 | 24 | 25 | Header Files 26 | 27 | 28 | Header Files 29 | 30 | 31 | 32 | 33 | Source Files 34 | 35 | 36 | Source Files 37 | 38 | 39 | Source Files 40 | 41 | 42 | -------------------------------------------------------------------------------- /dbg_flash_vul_2.0/dbg_flash_vul/ReadMe.txt: -------------------------------------------------------------------------------- 1 | ======================================================================== 2 | DYNAMIC LINK LIBRARY : my_windbg_ext Project Overview 3 | ======================================================================== 4 | 5 | AppWizard has created this my_windbg_ext DLL for you. 6 | 7 | This file contains a summary of what you will find in each of the files that 8 | make up your my_windbg_ext application. 9 | 10 | 11 | my_windbg_ext.vcxproj 12 | This is the main project file for VC++ projects generated using an Application Wizard. 13 | It contains information about the version of Visual C++ that generated the file, and 14 | information about the platforms, configurations, and project features selected with the 15 | Application Wizard. 16 | 17 | my_windbg_ext.vcxproj.filters 18 | This is the filters file for VC++ projects generated using an Application Wizard. 19 | It contains information about the association between the files in your project 20 | and the filters. This association is used in the IDE to show grouping of files with 21 | similar extensions under a specific node (for e.g. ".cpp" files are associated with the 22 | "Source Files" filter). 23 | 24 | my_windbg_ext.cpp 25 | This is the main DLL source file. 26 | 27 | When created, this DLL does not export any symbols. As a result, it 28 | will not produce a .lib file when it is built. If you wish this project 29 | to be a project dependency of some other project, you will either need to 30 | add code to export some symbols from the DLL so that an export library 31 | will be produced, or you can set the Ignore Input Library property to Yes 32 | on the General propert page of the Linker folder in the project's Property 33 | Pages dialog box. 34 | 35 | ///////////////////////////////////////////////////////////////////////////// 36 | Other standard files: 37 | 38 | StdAfx.h, StdAfx.cpp 39 | These files are used to build a precompiled header (PCH) file 40 | named my_windbg_ext.pch and a precompiled types file named StdAfx.obj. 41 | 42 | ///////////////////////////////////////////////////////////////////////////// 43 | Other notes: 44 | 45 | AppWizard uses "TODO:" comments to indicate parts of the source code you 46 | should add to or customize. 47 | 48 | ///////////////////////////////////////////////////////////////////////////// 49 | -------------------------------------------------------------------------------- /dbg_flash_vul_2.0/dbg_flash_vul/dbg_flash_vul.vcxproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {87965BB5-0C72-48C8-9848-763919DD025D} 15 | Win32Proj 16 | dbg_flash_vul 17 | DbgFlashVul 18 | 19 | 20 | 21 | DynamicLibrary 22 | true 23 | v110 24 | Unicode 25 | Static 26 | 27 | 28 | DynamicLibrary 29 | false 30 | v110 31 | true 32 | Unicode 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | true 46 | 47 | 48 | false 49 | 50 | 51 | 52 | Use 53 | Level3 54 | Disabled 55 | WIN32;_DEBUG;_WINDOWS;_USRDLL;dbg_flash_vul_EXPORTS;%(PreprocessorDefinitions) 56 | true 57 | 58 | 59 | Windows 60 | true 61 | 62 | 63 | 64 | 65 | Level3 66 | Use 67 | MaxSpeed 68 | true 69 | true 70 | WIN32;NDEBUG;_WINDOWS;_USRDLL;dbg_flash_vul_EXPORTS;%(PreprocessorDefinitions) 71 | true 72 | 73 | 74 | Windows 75 | true 76 | true 77 | true 78 | dbg_flash_vul.def 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | false 92 | 93 | 94 | false 95 | 96 | 97 | 98 | 99 | 100 | Create 101 | Create 102 | 103 | 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /dbg_flash_vul_2.0/dbg_flash_vul/dbg_flash_vul.cpp: -------------------------------------------------------------------------------- 1 | //// my_windbg_ext.cpp : Defines the exported functions for the DLL application. 2 | //// 3 | // 4 | #include "stdafx.h" 5 | // 6 | #include 7 | #pragma comment (lib ,"dbgeng.lib") 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #define HOOKED_BYTES_SIZE 5 15 | IDebugAdvanced2* gAdvancedDebug2 = NULL; 16 | IDebugControl4* gDebugControl4 = NULL; 17 | IDebugControl* gExecuteCmd = NULL; 18 | IDebugClient* gDebugClient = NULL; 19 | 20 | ULONG64 g_hooked_function_address = 0; 21 | ULONG64 g_overwrite_address_in_hooked_func = 0; 22 | const ULONG64 g_overwrite_offset = 0xC; //0x2B; 23 | ULONG64 g_get_method_name_found_addr = 0; 24 | ULONG64 g_gabbage_func_found_addr = 0; 25 | ULONG_PTR g_base_address = 0x10000000; 26 | bool g_hooked = false; 27 | std::set g_method_ids_need_to_set_bp; 28 | std::set g_method_name_need_to_set_bp; 29 | std::set g_method_set; 30 | ULONG64 g_last_jit_method_id = 0; 31 | ULONG64 g_last_jit_code_addr = 0; 32 | bool g_dump_method_info_detail = false; 33 | bool g_dump_method_info_detail_ex = false; 34 | char g_save_hooked_bytes[HOOKED_BYTES_SIZE] = {0}; 35 | 36 | /*********************************************************** 37 | * Global Variable Needed For Versioning 38 | ***********************************************************/ 39 | EXT_API_VERSION g_ExtApiVersion = { 40 | 5 , 41 | 5 , 42 | EXT_API_VERSION_NUMBER , 43 | 0 44 | } ; 45 | /*********************************************************** 46 | * ExtensionApiVersion 47 | * 48 | * Purpose: WINDBG will call this function to get the version 49 | * of the API 50 | * 51 | * Parameters: 52 | * Void 53 | * 54 | * Return Values: 55 | * Pointer to a EXT_API_VERSION structure. 56 | * 57 | ***********************************************************/ 58 | LPEXT_API_VERSION WDBGAPI ExtensionApiVersion (void) 59 | { 60 | return &g_ExtApiVersion; 61 | } 62 | 63 | 64 | /*********************************************************** 65 | * WinDbgExtensionDllInit 66 | * 67 | * Purpose: WINDBG will call this function to initialize 68 | * the API 69 | * 70 | * Parameters: 71 | * Pointer to the API functions, Major Version, Minor Version 72 | * 73 | * Return Values: 74 | * Nothing 75 | * 76 | ***********************************************************/ 77 | VOID WDBGAPI WinDbgExtensionDllInit (PWINDBG_EXTENSION_APIS 78 | lpExtensionApis, USHORT usMajorVersion, 79 | USHORT usMinorVersion) 80 | { 81 | ExtensionApis = *lpExtensionApis; 82 | HRESULT hResult = S_FALSE; 83 | 84 | if (hResult = DebugCreate(__uuidof(IDebugClient), (void**) &gDebugClient) != S_OK) 85 | { 86 | dprintf("Acuqiring IDebugClient* Failled\n\n"); 87 | return; 88 | } 89 | 90 | if (hResult = gDebugClient->QueryInterface(__uuidof(IDebugControl), (void**) &gExecuteCmd) != S_OK) 91 | { 92 | dprintf("Acuqiring IDebugControl* Failled\n\n"); 93 | return; 94 | } 95 | 96 | if (hResult = gDebugClient->QueryInterface(__uuidof(IDebugAdvanced2), (void**) &gAdvancedDebug2) != S_OK) 97 | { 98 | dprintf("Acuqiring IDebugAdvanced2* Failled\n\n"); 99 | return; 100 | } 101 | 102 | if (hResult = gDebugClient->QueryInterface(__uuidof(IDebugControl4), (void**) &gDebugControl4) != S_OK) 103 | { 104 | dprintf("Acuqiring IDebugControl4* Failled\n\n"); 105 | return; 106 | } 107 | dprintf("load extension success, enter !help to get info. if need plz contact @heisecode\n"); 108 | } 109 | 110 | 111 | /*********************************************************** 112 | * Global Variable Needed For Functions 113 | ***********************************************************/ 114 | WINDBG_EXTENSION_APIS ExtensionApis = {0}; 115 | 116 | /*********************************************************** 117 | * !help 118 | * 119 | * Purpose: WINDBG will call this API when the user types !help 120 | * 121 | * 122 | * Parameters: 123 | * N/A 124 | * 125 | * Return Values: 126 | * N/A 127 | * 128 | ***********************************************************/ 129 | DECLARE_API (help) 130 | { 131 | dprintf("Set Jit Code breakpoint steps:\n"); 132 | dprintf("\t 1> Use !SetBaseAddress to set base, default is 0x10000000\n"); 133 | dprintf("\t 2> Use !SetBpForJitCode to set breakpoint\n\n"); 134 | 135 | dprintf("AS3 method name style in flash player internal is like this:\n"); 136 | dprintf("\t 1> class member method: [package::class/method], example: a_pack::b_class/c_method\n"); 137 | dprintf("\t 2> class constructor: [package::class], example: a_pack::b_class\n"); 138 | dprintf("\t 3> class static method: [package::class$/method], example: a_pack::b_class$/c_static_method\n"); 139 | dprintf("\t 4> if package name is empty then no 'package::' prefix\n"); 140 | 141 | dprintf("Trace Jit Method:\n"); 142 | dprintf("\t 1> !EnableTraceJit <0 or 1>, enable/disable trace jit method call\n"); 143 | dprintf("\t 2> Trace all methods call may be added later....\n"); 144 | } 145 | 146 | int HexCharToInt(char c) { 147 | if ( c >= '0' && c <= '9' ) { 148 | return c - '0'; 149 | } else if ( c >= 'a' && c <= 'f') { 150 | return c - 'a' + 10; 151 | } else if ( c >= 'A' && c <= 'F' ) { 152 | return c - 'A' + 10; 153 | } 154 | return -1; 155 | } 156 | 157 | unsigned HexDecode(char *inbuf, unsigned inLength, char *outbuf, unsigned outLength) { 158 | unsigned decodeLen = 0; 159 | if ( NULL == inbuf || NULL == outbuf || (inLength / 2) > outLength ) { 160 | return 0; 161 | } 162 | for ( unsigned i = 0; i < inLength - 1; i += 2 ) { 163 | int high = HexCharToInt( inbuf[i] ); 164 | int low = HexCharToInt( inbuf[i + 1] ); 165 | if ( high != -1 && low != -1 ) { 166 | outbuf[ decodeLen ++ ] = low | (high << 4) ; 167 | } else { 168 | break; 169 | } 170 | } 171 | return decodeLen; 172 | } 173 | 174 | 175 | bool ExtExecuteCmd(const char* cmd) { 176 | if (gExecuteCmd->Execute(DEBUG_OUTCTL_THIS_CLIENT | DEBUG_OUTCTL_OVERRIDE_MASK | DEBUG_OUTCTL_NOT_LOGGED, 177 | cmd, 178 | DEBUG_EXECUTE_DEFAULT ) != S_OK) 179 | { 180 | dprintf("Executing %s failled\n", cmd); 181 | return false; 182 | } 183 | 184 | return true; 185 | } 186 | 187 | struct HookData { 188 | HookData() { 189 | data_ = 0; 190 | len_ = 0; 191 | } 192 | HookData(char* data, unsigned len) { 193 | data_ = data; 194 | len_ = len; 195 | } 196 | ~HookData() { 197 | //delete data_; 198 | } 199 | char* data_; 200 | unsigned len_; 201 | }; 202 | std::map g_HookMap; 203 | 204 | bool ExtHookAddress(unsigned addr, char* data, unsigned len) { 205 | //dprintf("Begin to hook 0x%08x \n", addr); 206 | if (g_HookMap.find(addr) != g_HookMap.end()) { 207 | dprintf("address is already hooked!\n"); 208 | return true; 209 | } 210 | 211 | ULONG bytes_read = 0; 212 | HookData hook_data; 213 | hook_data.len_ = len; 214 | hook_data.data_ = new char[len]; 215 | 216 | ReadMemory(addr, hook_data.data_, hook_data.len_, &bytes_read); 217 | if (bytes_read != len) { 218 | dprintf("cannot read memory, hook failed!\n"); 219 | return false; 220 | } 221 | 222 | ULONG bytes_write = 0; 223 | WriteMemory(addr, data, len, &bytes_write); 224 | if (bytes_write != len) { 225 | dprintf("cannot write memory, hook failed!\n"); 226 | return false; 227 | } 228 | 229 | g_HookMap[addr] = hook_data; 230 | 231 | return true; 232 | } 233 | 234 | 235 | bool ExtUnHookAddress(unsigned addr) { 236 | //dprintf("Begin to unhook 0x%08x \n", addr); 237 | std::map::iterator iter = g_HookMap.find(addr); 238 | if (iter == g_HookMap.end()) { 239 | dprintf("address is already unhooked!\n"); 240 | return true; 241 | } 242 | 243 | HookData hook_data = iter->second; 244 | 245 | ULONG bytes_write = 0; 246 | WriteMemory(addr, hook_data.data_, hook_data.len_, &bytes_write); 247 | 248 | if (bytes_write != hook_data.len_) { 249 | dprintf("cannot write memory, unhook failed!\n"); 250 | return false; 251 | } 252 | 253 | g_HookMap.erase(addr); 254 | 255 | return true; 256 | } 257 | 258 | bool ExtWriteMemory(char* hex_string, ULONG64 addr, PULONG64 hex_len) { 259 | ULONG len = strlen(hex_string); 260 | char* hex_bin = new char[len / 2]; 261 | HexDecode(hex_string, len + 1, hex_bin, len / 2); 262 | ULONG bytes_write = 0; 263 | WriteMemory(addr, hex_bin, len / 2, &bytes_write); 264 | if (bytes_write != (len / 2)) { 265 | dprintf("write memory %s to 0x%08x failed\n", hex_string, addr); 266 | return false; 267 | } 268 | *hex_len = (len / 2); 269 | return true; 270 | } 271 | 272 | bool ExtAssemble(ULONG64 addr, std::vector& instrs) { 273 | ULONG64 begin = addr; 274 | HRESULT ret; 275 | for (int i = 0; i < instrs.size(); ++i) { 276 | ret = gDebugControl4->Assemble(begin, instrs[i].c_str(), &begin); 277 | if (ret != S_OK) { 278 | dprintf("assemble address 0x%08x failed\n", begin); 279 | return false; 280 | } 281 | } 282 | 283 | return true; 284 | } 285 | 286 | bool ExtAssembleSingle(ULONG64 addr, std::string& instr, PULONG64 end_addr) { 287 | ULONG64 end = addr; 288 | 289 | HRESULT ret = gDebugControl4->Assemble(addr, instr.c_str(), &end); 290 | if (ret != S_OK) { 291 | dprintf("assemble address 0x%08x failed\n", addr); 292 | return false; 293 | } 294 | //dprintf("assemble address 0x%08x succed, end address is 0x%08x \n", addr, end); 295 | *end_addr = end; 296 | return true; 297 | } 298 | 299 | bool ExtMakeSetJitJmpInstr() { 300 | //dprintf("begin to make set jit jmp...\n"); 301 | 302 | std::string instr = "jmp 0x"; 303 | char jmp_offset[9] = {0}; 304 | sprintf_s(jmp_offset, "%08x", g_gabbage_func_found_addr); 305 | instr += jmp_offset; 306 | ULONG64 end_addr = 0; 307 | return ExtAssembleSingle(g_overwrite_address_in_hooked_func, instr, &end_addr); 308 | } 309 | 310 | bool ExtMakeHookingFunc() { 311 | //dprintf("begin to make hooking func...\n"); 312 | 313 | ULONG64 hook_addr = g_gabbage_func_found_addr; 314 | ULONG64 bytes_write = 0; 315 | 316 | // save hooked function instruction 5 bytes 317 | if(!WriteMemory(hook_addr, g_save_hooked_bytes, HOOKED_BYTES_SIZE, (PULONG)&bytes_write)) { 318 | return false; 319 | } 320 | hook_addr += bytes_write; 321 | 322 | // pushad 323 | if(!ExtWriteMemory("60", hook_addr, &bytes_write)) { 324 | return false; 325 | } 326 | hook_addr += bytes_write; 327 | 328 | //// mov ecx,esi 329 | //if(!ExtWriteMemory("8bce", hook_addr, &bytes_write)) { 330 | // return false; 331 | //} 332 | // mov ecx,edi 333 | if(!ExtWriteMemory("8bcf", hook_addr, &bytes_write)) { 334 | return false; 335 | } 336 | hook_addr += bytes_write; 337 | 338 | // call getMethodName 339 | std::string instr_3 = "call 0x"; 340 | char call_offset[9] = {0}; 341 | sprintf_s(call_offset, "%08x", g_get_method_name_found_addr); 342 | instr_3 += call_offset; 343 | //dprintf("call instr is %s\n", instr_3); 344 | if(!ExtAssembleSingle(hook_addr, instr_3, &hook_addr)) { 345 | return false; 346 | } 347 | 348 | // popad 349 | bytes_write = 0; 350 | if(!ExtWriteMemory("61", hook_addr, &bytes_write)) { 351 | return false; 352 | } 353 | hook_addr += bytes_write; 354 | 355 | // jump setJit 356 | std::string instr_5 = "jmp 0x"; 357 | ULONG64 jmp_addr = g_overwrite_address_in_hooked_func + 5; 358 | char jmp_offset[9] = {0}; 359 | sprintf_s(jmp_offset, "%08x", jmp_addr); 360 | instr_5 += jmp_offset; 361 | //dprintf("jmp instr is %s\n", instr_5); 362 | if(!ExtAssembleSingle(hook_addr, instr_5, &hook_addr)) { 363 | return false; 364 | } 365 | 366 | return true; 367 | } 368 | 369 | void ExtSearchMemory(ULONG64 base, ULONG64 range, PVOID pattern, PULONG64 found_addr) { 370 | char* cPattern = (char*)pattern; 371 | ULONG PatternLength = strlen(cPattern); 372 | char* uPattern = new char[PatternLength / 2]; 373 | HexDecode(cPattern, PatternLength + 1, uPattern, PatternLength / 2); 374 | 375 | SearchMemory(base, range, PatternLength / 2, uPattern, found_addr); 376 | delete [] uPattern; 377 | } 378 | 379 | bool ExtSaveHookedBytes() { 380 | ULONG read_bytes = 0; 381 | ReadMemory(g_overwrite_address_in_hooked_func, g_save_hooked_bytes, HOOKED_BYTES_SIZE, &read_bytes); 382 | if (read_bytes != HOOKED_BYTES_SIZE) { 383 | dprintf("Save Hooked Bytes failed!\n"); 384 | return false; 385 | } 386 | 387 | return true; 388 | } 389 | 390 | bool HookJit() { 391 | if (g_base_address == 0) { 392 | dprintf("Please input base address first!\n"); 393 | return false; 394 | } 395 | if (g_hooked) { 396 | return true; 397 | } 398 | 399 | // find set jit function address 400 | char* cPattern = "8B4C2408568B7424088B463025FFFF7F"; 401 | // find verifyMethod 402 | //char* cPattern = "81EC6C010000538B9C2478010000558B"; 403 | ExtSearchMemory(g_base_address, 0x2000000, cPattern, &g_hooked_function_address); 404 | //dprintf("g_hooked_function_address is 0x%08x\n", g_hooked_function_address); 405 | g_overwrite_address_in_hooked_func = g_hooked_function_address + g_overwrite_offset; 406 | 407 | // find get method name address 408 | cPattern = "8B4110A801741383E0FE740C8B400C52"; 409 | ExtSearchMemory(g_base_address, 0x2000000, cPattern, &g_get_method_name_found_addr); 410 | //dprintf("g_get_method_name_found_addr is 0x%08x\n", g_get_method_name_found_addr); 411 | 412 | //cPattern = "8B4C240432D2E8C5890700C20400"; 413 | cPattern = "32D2E8C9FFFFFF8B4C240485C0741568"; 414 | ExtSearchMemory(g_base_address, 0x2000000, cPattern, &g_gabbage_func_found_addr); 415 | //dprintf("g_gabbage_func_found_addr is 0x%08x\n", g_gabbage_func_found_addr); 416 | 417 | if (!ExtSaveHookedBytes()) { 418 | return false; 419 | } 420 | 421 | if (!ExtMakeHookingFunc()) { 422 | dprintf("make hooking func failed!\n"); 423 | return false; 424 | } 425 | 426 | if (!ExtMakeSetJitJmpInstr()) { 427 | dprintf("make set jit jmp failed!\n"); 428 | return false; 429 | } 430 | 431 | std::string bp_1 = "bu 0x"; 432 | char bp1_addr[9] = {0}; 433 | sprintf_s(bp1_addr, "%08x", g_gabbage_func_found_addr); 434 | bp_1 += bp1_addr; 435 | //char* output_method_id_jit_code_addr = " \".echo ****; .printf \\\"method_id = 0x%x, jitcode = 0x%08x\\\", poi(esi+20) , ecx; !HandleHookId poi(esi+20); .echo; g\" "; 436 | char* output_method_id_jit_code_addr = " \"!HandleHookId poi(esi+20); g\" "; 437 | bp_1 += output_method_id_jit_code_addr; 438 | if (!ExtExecuteCmd(bp_1.c_str())) { 439 | return false; 440 | } 441 | 442 | std::string bp_2 = "bu 0x"; 443 | char bp2_addr[9] = {0}; 444 | sprintf_s(bp2_addr, "%08x", g_gabbage_func_found_addr + 0xD); 445 | bp_2 += bp2_addr; 446 | //char* output_method_name = " \".printf \\\"method_name = %ma, addr = %x\\\", poi(eax+8), poi(eax+8); !HandleHookName poi(eax+8); .echo; .echo ****; g\" "; 447 | char* output_method_name = " \"!HandleHookName poi(eax+8); g\" "; 448 | bp_2 += output_method_name; 449 | if (!ExtExecuteCmd(bp_2.c_str())) { 450 | return false; 451 | } 452 | 453 | g_hooked = true; 454 | return true; 455 | } 456 | 457 | std::string ExtGetStringFromAddr(ULONG_PTR addr) { 458 | //dprintf("In ExtGetStringFromAddr, addr is %x\n", addr); 459 | std::string str; 460 | if (!addr) { 461 | return str; 462 | } 463 | char total[256] = {0}; 464 | char* offset = total; 465 | 466 | 467 | bool flag = true; 468 | do { 469 | char buffer[8] = {0}; 470 | ULONG bytes_read = 0; 471 | ReadMemory(addr, buffer, 8, &bytes_read); 472 | if (bytes_read != 8) { 473 | return str; 474 | } 475 | for (int i = 0; i < 8; ++i) { 476 | if (buffer[i] == 0) { 477 | //dprintf("In ExtGetStringFromAddr, read the null char\n"); 478 | flag = false; 479 | strncpy_s(offset, 8, buffer, 8); 480 | break; 481 | } 482 | } 483 | 484 | if (flag) { 485 | memcpy(offset, buffer, 8); 486 | offset += 8; 487 | } 488 | addr += 8; 489 | 490 | } while (flag && (offset - total < 256)); 491 | 492 | if (flag) { 493 | return str; 494 | } 495 | 496 | str = total; 497 | return str; 498 | 499 | } 500 | 501 | /*********************************************************** 502 | * !HookJit 503 | * 504 | * Purpose: WINDBG will call this API when the user types !HookJit 505 | * 506 | * 507 | * Parameters: 508 | * !HookJit 509 | * 510 | * Return Values: 511 | * N/A 512 | * 513 | ***********************************************************/ 514 | DECLARE_API (SetBaseAddress) 515 | { 516 | ULONG_PTR base_address = GetExpression(args); 517 | //dprintf("base address is 0x%08x\n", base_address); 518 | if(!base_address) 519 | { 520 | dprintf("Please input flash player base address!\n"); 521 | return; 522 | } 523 | g_base_address = base_address; 524 | } 525 | 526 | /*********************************************************** 527 | * !SetIdBpForJitCode 528 | * 529 | * Purpose: WINDBG will call this API when the user types !SetIdBpForJitCode 530 | * 531 | * 532 | * Parameters: 533 | * !SetIdBpForJitCode 534 | * 535 | * Return Values: 536 | * N/A 537 | * 538 | ***********************************************************/ 539 | DECLARE_API (SetIdBpForJitCode) 540 | { 541 | if (!HookJit()){ 542 | return; 543 | } 544 | ULONG_PTR method_id = GetExpression(args); 545 | //dprintf("SetBpForJitCode method id is 0x%x\n", method_id); 546 | g_method_ids_need_to_set_bp.insert(method_id); 547 | } 548 | 549 | /*********************************************************** 550 | * !SetBpForJitCode 551 | * 552 | * Purpose: WINDBG will call this API when the user types !SetBpForJitCode 553 | * 554 | * 555 | * Parameters: 556 | * !SetBpForJitCode 557 | * 558 | * Return Values: 559 | * N/A 560 | * 561 | ***********************************************************/ 562 | DECLARE_API (SetBpForJitCode) 563 | { 564 | if (!HookJit()){ 565 | return; 566 | } 567 | 568 | std::string method_name(args); 569 | g_method_name_need_to_set_bp.insert(method_name); 570 | //dprintf("SetBpForJitCode %s\n", args); 571 | } 572 | 573 | /*********************************************************** 574 | * !HandleHookId 575 | * 576 | * Purpose: WINDBG will call this API when the user types !HandleHookBps 577 | * 578 | * 579 | * Parameters: 580 | * !HandleHookId 581 | * 582 | * Return Values: 583 | * N/A 584 | * 585 | ***********************************************************/ 586 | DECLARE_API (HandleHookId) 587 | { 588 | ULONG_PTR method_id = GetExpression(args); 589 | g_last_jit_method_id = method_id; 590 | 591 | ULONG_PTR ecx_val = GetExpression("ecx"); 592 | g_last_jit_code_addr = ecx_val; 593 | 594 | if (g_dump_method_info_detail) { 595 | //dprintf("method id = 0x%x, code address = 0x%08x\n", method_id, ecx_val); 596 | } 597 | 598 | for(auto id : g_method_ids_need_to_set_bp) { 599 | if (id == method_id) { 600 | std::string bp = "bu 0x"; 601 | char bp_addr[9] = {0}; 602 | sprintf_s(bp_addr, "%08x", ecx_val); 603 | bp += bp_addr; 604 | if (!ExtExecuteCmd(bp.c_str())) { 605 | return; 606 | } 607 | break; 608 | } 609 | } 610 | 611 | } 612 | 613 | /*********************************************************** 614 | * !HandleHookName 615 | * 616 | * Purpose: WINDBG will call this API when the user types !HandleHookName 617 | * 618 | * 619 | * Parameters: 620 | * !HandleHookName 621 | * 622 | * Return Values: 623 | * N/A 624 | * 625 | ***********************************************************/ 626 | DECLARE_API (HandleHookName) 627 | { 628 | ULONG_PTR method_name_ptr = GetExpression(args); 629 | std::string method_name = ExtGetStringFromAddr(method_name_ptr); 630 | 631 | if (g_dump_method_info_detail) { 632 | dprintf("Call [%s]\n", method_name.c_str()); 633 | } 634 | 635 | std::set::iterator iter = g_method_name_need_to_set_bp.begin(); 636 | for(; iter != g_method_name_need_to_set_bp.end(); ++iter) { 637 | std::string name = *iter; 638 | if (-1 != method_name.find(name) && -1 != name.find(method_name)) { 639 | std::string bp; 640 | char* cmd = "bu 0x%08x \""; 641 | char* cmd2 = ".echo BreakPoint at [%s];"; 642 | char bp_addr[128] = {0}; 643 | sprintf_s(bp_addr, cmd, g_last_jit_code_addr); 644 | bp += bp_addr; 645 | memset(bp_addr, 0, 128); 646 | sprintf_s(bp_addr, cmd2, method_name.c_str()); 647 | bp += bp_addr; 648 | if (g_dump_method_info_detail_ex) { 649 | bp += "gc"; 650 | } 651 | bp += "\" "; 652 | //dprintf("bp is %s\n", bp.c_str()); 653 | if (!ExtExecuteCmd(bp.c_str())) { 654 | return; 655 | } 656 | break; 657 | } 658 | } 659 | 660 | } 661 | 662 | /*********************************************************** 663 | * !EnableDumpMethodInfo 664 | * 665 | * Purpose: WINDBG will call this API when the user types !EnableDumpMethodInfo 666 | * 667 | * 668 | * Parameters: 669 | * !EnableDumpMethodInfo 670 | * 671 | * Return Values: 672 | * N/A 673 | * 674 | ***********************************************************/ 675 | DECLARE_API (EnableTraceJit) 676 | { 677 | if (!HookJit()){ 678 | return; 679 | } 680 | ULONG_PTR flag = GetExpression(args); 681 | if (flag) { 682 | dprintf("Trace Jit method call is enable!\n"); 683 | g_dump_method_info_detail = true; 684 | } else { 685 | dprintf("Trace Jit method call is disable!\n"); 686 | g_dump_method_info_detail = false; 687 | } 688 | 689 | } 690 | 691 | /*********************************************************** 692 | * !EnableDumpMethodInfo 693 | * 694 | * Purpose: WINDBG will call this API when the user types !EnableDumpMethodInfo 695 | * 696 | * 697 | * Parameters: 698 | * !EnableDumpMethodInfo 699 | * 700 | * Return Values: 701 | * N/A 702 | * 703 | ***********************************************************/ 704 | DECLARE_API (EnableTraceJitEx) 705 | { 706 | if (!HookJit()){ 707 | return; 708 | } 709 | ULONG_PTR flag = GetExpression(args); 710 | if (flag) { 711 | dprintf("Trace Jit method call is enable!\n"); 712 | g_dump_method_info_detail_ex = true; 713 | } else { 714 | dprintf("Trace Jit method call is disable!\n"); 715 | g_dump_method_info_detail_ex = false; 716 | } 717 | 718 | } --------------------------------------------------------------------------------